Merge branch '3.0' of https://github.com/taosdata/TDengine into TD-20251
This commit is contained in:
commit
f6d13bb666
|
@ -532,7 +532,12 @@ TIMEDIFF(expr1, expr2 [, time_unit])
|
||||||
#### TIMETRUNCATE
|
#### TIMETRUNCATE
|
||||||
|
|
||||||
```sql
|
```sql
|
||||||
TIMETRUNCATE(expr, time_unit)
|
TIMETRUNCATE(expr, time_unit [, ignore_timezone])
|
||||||
|
|
||||||
|
ignore_timezone: {
|
||||||
|
0
|
||||||
|
| 1
|
||||||
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
**Description**: Truncate the input timestamp with unit specified by `time_unit`
|
**Description**: Truncate the input timestamp with unit specified by `time_unit`
|
||||||
|
@ -548,7 +553,10 @@ TIMETRUNCATE(expr, time_unit)
|
||||||
1b (nanoseconds), 1u (microseconds), 1a (milliseconds), 1s (seconds), 1m (minutes), 1h (hours), 1d (days), or 1w (weeks)
|
1b (nanoseconds), 1u (microseconds), 1a (milliseconds), 1s (seconds), 1m (minutes), 1h (hours), 1d (days), or 1w (weeks)
|
||||||
- The precision of the returned timestamp is same as the precision set for the current data base in use
|
- The precision of the returned timestamp is same as the precision set for the current data base in use
|
||||||
- If the input data is not formatted as a timestamp, the returned value is null.
|
- If the input data is not formatted as a timestamp, the returned value is null.
|
||||||
|
- If `1d` is used as `time_unit` to truncate the timestamp, `ignore_timezone` option can be set to indicate if the returned result is affected by client timezone or not.
|
||||||
|
For example, if client timezone is set to UTC+0800, TIMETRUNCATE('2020-01-01 23:00:00', 1d, 0) will return '2020-01-01 08:00:00'.
|
||||||
|
Otherwise, TIMETRUNCATE('2020-01-01 23:00:00', 1d, 1) will return '2020-01-01 00:00:00'.
|
||||||
|
If `ignore_timezone` option is omitted, the default value is set to 1.
|
||||||
|
|
||||||
#### TIMEZONE
|
#### TIMEZONE
|
||||||
|
|
||||||
|
|
|
@ -5,22 +5,24 @@ namespace Examples
|
||||||
{
|
{
|
||||||
public class WSConnExample
|
public class WSConnExample
|
||||||
{
|
{
|
||||||
static void Main(string[] args)
|
static int Main(string[] args)
|
||||||
{
|
{
|
||||||
string DSN = "ws://root:taosdata@127.0.0.1:6041/test";
|
string DSN = "ws://root:taosdata@127.0.0.1:6041/test";
|
||||||
IntPtr wsConn = LibTaosWS.WSConnectWithDSN(DSN);
|
IntPtr wsConn = LibTaosWS.WSConnectWithDSN(DSN);
|
||||||
|
|
||||||
if (wsConn == IntPtr.Zero)
|
if (wsConn == IntPtr.Zero)
|
||||||
{
|
{
|
||||||
throw new Exception("get WS connection failed");
|
Console.WriteLine("get WS connection failed");
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Console.WriteLine("Establish connect success.");
|
Console.WriteLine("Establish connect success.");
|
||||||
}
|
|
||||||
|
|
||||||
// close connection.
|
// close connection.
|
||||||
LibTaosWS.WSClose(wsConn);
|
LibTaosWS.WSClose(wsConn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -5,7 +5,7 @@ namespace Examples
|
||||||
{
|
{
|
||||||
public class WSInsertExample
|
public class WSInsertExample
|
||||||
{
|
{
|
||||||
static void Main(string[] args)
|
static int Main(string[] args)
|
||||||
{
|
{
|
||||||
string DSN = "ws://root:taosdata@127.0.0.1:6041/test";
|
string DSN = "ws://root:taosdata@127.0.0.1:6041/test";
|
||||||
IntPtr wsConn = LibTaosWS.WSConnectWithDSN(DSN);
|
IntPtr wsConn = LibTaosWS.WSConnectWithDSN(DSN);
|
||||||
|
@ -13,7 +13,8 @@ namespace Examples
|
||||||
// Assert if connection is validate
|
// Assert if connection is validate
|
||||||
if (wsConn == IntPtr.Zero)
|
if (wsConn == IntPtr.Zero)
|
||||||
{
|
{
|
||||||
throw new Exception("get WS connection failed");
|
Console.WriteLine("get WS connection failed");
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -36,6 +37,8 @@ namespace Examples
|
||||||
|
|
||||||
// close connection.
|
// close connection.
|
||||||
LibTaosWS.WSClose(wsConn);
|
LibTaosWS.WSClose(wsConn);
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ValidInsert(string desc, IntPtr wsRes)
|
static void ValidInsert(string desc, IntPtr wsRes)
|
||||||
|
@ -43,7 +46,7 @@ namespace Examples
|
||||||
int code = LibTaosWS.WSErrorNo(wsRes);
|
int code = LibTaosWS.WSErrorNo(wsRes);
|
||||||
if (code != 0)
|
if (code != 0)
|
||||||
{
|
{
|
||||||
throw new Exception($"execute SQL failed: reason: {LibTaosWS.WSErrorStr(wsRes)}, code:{code}");
|
Console.WriteLine($"execute SQL failed: reason: {LibTaosWS.WSErrorStr(wsRes)}, code:{code}");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -7,13 +7,14 @@ namespace Examples
|
||||||
{
|
{
|
||||||
public class WSQueryExample
|
public class WSQueryExample
|
||||||
{
|
{
|
||||||
static void Main(string[] args)
|
static int Main(string[] args)
|
||||||
{
|
{
|
||||||
string DSN = "ws://root:taosdata@127.0.0.1:6041/test";
|
string DSN = "ws://root:taosdata@127.0.0.1:6041/test";
|
||||||
IntPtr wsConn = LibTaosWS.WSConnectWithDSN(DSN);
|
IntPtr wsConn = LibTaosWS.WSConnectWithDSN(DSN);
|
||||||
if (wsConn == IntPtr.Zero)
|
if (wsConn == IntPtr.Zero)
|
||||||
{
|
{
|
||||||
throw new Exception("get WS connection failed");
|
Console.WriteLine("get WS connection failed");
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -28,7 +29,9 @@ namespace Examples
|
||||||
int code = LibTaosWS.WSErrorNo(wsRes);
|
int code = LibTaosWS.WSErrorNo(wsRes);
|
||||||
if (code != 0)
|
if (code != 0)
|
||||||
{
|
{
|
||||||
throw new Exception($"execute SQL failed: reason: {LibTaosWS.WSErrorStr(wsRes)}, code:{code}");
|
Console.WriteLine($"execute SQL failed: reason: {LibTaosWS.WSErrorStr(wsRes)}, code:{code}");
|
||||||
|
LibTaosWS.WSFreeResult(wsRes);
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// get meta data
|
// get meta data
|
||||||
|
@ -58,6 +61,8 @@ namespace Examples
|
||||||
|
|
||||||
// close connection.
|
// close connection.
|
||||||
LibTaosWS.WSClose(wsConn);
|
LibTaosWS.WSClose(wsConn);
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@ namespace Examples
|
||||||
{
|
{
|
||||||
public class WSStmtExample
|
public class WSStmtExample
|
||||||
{
|
{
|
||||||
static void Main(string[] args)
|
static int Main(string[] args)
|
||||||
{
|
{
|
||||||
const string DSN = "ws://root:taosdata@127.0.0.1:6041/test";
|
const string DSN = "ws://root:taosdata@127.0.0.1:6041/test";
|
||||||
const string table = "meters";
|
const string table = "meters";
|
||||||
|
@ -21,7 +21,8 @@ namespace Examples
|
||||||
IntPtr wsConn = LibTaosWS.WSConnectWithDSN(DSN);
|
IntPtr wsConn = LibTaosWS.WSConnectWithDSN(DSN);
|
||||||
if (wsConn == IntPtr.Zero)
|
if (wsConn == IntPtr.Zero)
|
||||||
{
|
{
|
||||||
throw new Exception($"get WS connection failed");
|
Console.WriteLine($"get WS connection failed");
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -66,18 +67,20 @@ namespace Examples
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
throw new Exception("Init STMT failed...");
|
Console.WriteLine("Init STMT failed...");
|
||||||
}
|
}
|
||||||
|
|
||||||
// close connection.
|
// close connection.
|
||||||
LibTaosWS.WSClose(wsConn);
|
LibTaosWS.WSClose(wsConn);
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ValidStmtStep(int code, IntPtr wsStmt, string desc)
|
static void ValidStmtStep(int code, IntPtr wsStmt, string desc)
|
||||||
{
|
{
|
||||||
if (code != 0)
|
if (code != 0)
|
||||||
{
|
{
|
||||||
throw new Exception($"{desc} failed,reason: {LibTaosWS.WSErrorStr(wsStmt)}, code: {code}");
|
Console.WriteLine($"{desc} failed,reason: {LibTaosWS.WSErrorStr(wsStmt)}, code: {code}");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -533,7 +533,12 @@ TIMEDIFF(expr1, expr2 [, time_unit])
|
||||||
#### TIMETRUNCATE
|
#### TIMETRUNCATE
|
||||||
|
|
||||||
```sql
|
```sql
|
||||||
TIMETRUNCATE(expr, time_unit)
|
TIMETRUNCATE(expr, time_unit [, ignore_timezone])
|
||||||
|
|
||||||
|
ignore_timezone: {
|
||||||
|
0
|
||||||
|
| 1
|
||||||
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
**功能说明**:将时间戳按照指定时间单位 time_unit 进行截断。
|
**功能说明**:将时间戳按照指定时间单位 time_unit 进行截断。
|
||||||
|
@ -549,6 +554,11 @@ TIMETRUNCATE(expr, time_unit)
|
||||||
1b(纳秒), 1u(微秒),1a(毫秒),1s(秒),1m(分),1h(小时),1d(天), 1w(周)。
|
1b(纳秒), 1u(微秒),1a(毫秒),1s(秒),1m(分),1h(小时),1d(天), 1w(周)。
|
||||||
- 返回的时间戳精度与当前 DATABASE 设置的时间精度一致。
|
- 返回的时间戳精度与当前 DATABASE 设置的时间精度一致。
|
||||||
- 输入包含不符合时间日期格式的字符串则返回 NULL。
|
- 输入包含不符合时间日期格式的字符串则返回 NULL。
|
||||||
|
- 当使用 1d 作为时间单位对时间戳进行截断时, 可通过设置 ignore_timezone 参数指定返回结果的显示是否忽略客户端时区的影响。
|
||||||
|
例如客户端所配置时区为 UTC+0800, 则 TIMETRUNCATE('2020-01-01 23:00:00', 1d, 0) 返回结果为 '2020-01-01 08:00:00'。
|
||||||
|
而使用 TIMETRUNCATE('2020-01-01 23:00:00', 1d, 1) 设置忽略时区时,返回结果为 '2020-01-01 00:00:00'
|
||||||
|
ignore_timezone 如果忽略的话,则默认值为 1 。
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#### TIMEZONE
|
#### TIMEZONE
|
||||||
|
|
|
@ -397,8 +397,8 @@ void taos_init_imp(void) {
|
||||||
deltaToUtcInitOnce();
|
deltaToUtcInitOnce();
|
||||||
|
|
||||||
if (taosCreateLog("taoslog", 10, configDir, NULL, NULL, NULL, NULL, 1) != 0) {
|
if (taosCreateLog("taoslog", 10, configDir, NULL, NULL, NULL, NULL, 1) != 0) {
|
||||||
tscInitRes = -1;
|
// ignore create log failed, only print
|
||||||
return;
|
printf(" WARING: Create taoslog failed. configDir=%s\n", configDir);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (taosInitCfg(configDir, NULL, NULL, NULL, NULL, 1) != 0) {
|
if (taosInitCfg(configDir, NULL, NULL, NULL, NULL, 1) != 0) {
|
||||||
|
|
|
@ -1924,7 +1924,8 @@ static int32_t translateToUnixtimestamp(SFunctionNode* pFunc, char* pErrBuf, int
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t translateTimeTruncate(SFunctionNode* pFunc, char* pErrBuf, int32_t len) {
|
static int32_t translateTimeTruncate(SFunctionNode* pFunc, char* pErrBuf, int32_t len) {
|
||||||
if (2 != LIST_LENGTH(pFunc->pParameterList)) {
|
int32_t numOfParams = LIST_LENGTH(pFunc->pParameterList);
|
||||||
|
if (2 != numOfParams && 3 != numOfParams) {
|
||||||
return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName);
|
return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1935,9 +1936,7 @@ static int32_t translateTimeTruncate(SFunctionNode* pFunc, char* pErrBuf, int32_
|
||||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||||
}
|
}
|
||||||
|
|
||||||
// add database precision as param
|
|
||||||
uint8_t dbPrec = pFunc->node.resType.precision;
|
uint8_t dbPrec = pFunc->node.resType.precision;
|
||||||
|
|
||||||
int32_t ret = validateTimeUnitParam(dbPrec, (SValueNode*)nodesListGetNode(pFunc->pParameterList, 1));
|
int32_t ret = validateTimeUnitParam(dbPrec, (SValueNode*)nodesListGetNode(pFunc->pParameterList, 1));
|
||||||
if (ret == TIME_UNIT_TOO_SMALL) {
|
if (ret == TIME_UNIT_TOO_SMALL) {
|
||||||
return buildFuncErrMsg(pErrBuf, len, TSDB_CODE_FUNC_FUNTION_ERROR,
|
return buildFuncErrMsg(pErrBuf, len, TSDB_CODE_FUNC_FUNTION_ERROR,
|
||||||
|
@ -1948,11 +1947,30 @@ static int32_t translateTimeTruncate(SFunctionNode* pFunc, char* pErrBuf, int32_
|
||||||
"TIMETRUNCATE function time unit parameter should be one of the following: [1b, 1u, 1a, 1s, 1m, 1h, 1d, 1w]");
|
"TIMETRUNCATE function time unit parameter should be one of the following: [1b, 1u, 1a, 1s, 1m, 1h, 1d, 1w]");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (3 == numOfParams) {
|
||||||
|
uint8_t para3Type = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 2))->resType.type;
|
||||||
|
if (!IS_INTEGER_TYPE(para3Type)) {
|
||||||
|
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||||
|
}
|
||||||
|
SValueNode* pValue = (SValueNode*)nodesListGetNode(pFunc->pParameterList, 2);
|
||||||
|
if (pValue->datum.i != 0 && pValue->datum.i != 1) {
|
||||||
|
return invaildFuncParaValueErrMsg(pErrBuf, len, pFunc->functionName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// add database precision as param
|
||||||
|
|
||||||
int32_t code = addDbPrecisonParam(&pFunc->pParameterList, dbPrec);
|
int32_t code = addDbPrecisonParam(&pFunc->pParameterList, dbPrec);
|
||||||
if (code != TSDB_CODE_SUCCESS) {
|
if (code != TSDB_CODE_SUCCESS) {
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// add client timezone as param
|
||||||
|
code = addTimezoneParam(pFunc->pParameterList);
|
||||||
|
if (code != TSDB_CODE_SUCCESS) {
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
pFunc->node.resType =
|
pFunc->node.resType =
|
||||||
(SDataType){.bytes = tDataTypes[TSDB_DATA_TYPE_TIMESTAMP].bytes, .type = TSDB_DATA_TYPE_TIMESTAMP};
|
(SDataType){.bytes = tDataTypes[TSDB_DATA_TYPE_TIMESTAMP].bytes, .type = TSDB_DATA_TYPE_TIMESTAMP};
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
|
|
|
@ -423,6 +423,8 @@ typedef struct SGroupKeyInfo {
|
||||||
(_p).val = (_v); \
|
(_p).val = (_v); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
|
static int32_t firstLastTransferInfoImpl(SFirstLastRes* pInput, SFirstLastRes* pOutput, bool isFirst);
|
||||||
|
|
||||||
bool functionSetup(SqlFunctionCtx* pCtx, SResultRowEntryInfo* pResultInfo) {
|
bool functionSetup(SqlFunctionCtx* pCtx, SResultRowEntryInfo* pResultInfo) {
|
||||||
if (pResultInfo->initialized) {
|
if (pResultInfo->initialized) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -457,11 +459,12 @@ int32_t firstCombine(SqlFunctionCtx* pDestCtx, SqlFunctionCtx* pSourceCtx) {
|
||||||
SResultRowEntryInfo* pSResInfo = GET_RES_INFO(pSourceCtx);
|
SResultRowEntryInfo* pSResInfo = GET_RES_INFO(pSourceCtx);
|
||||||
SFirstLastRes* pSBuf = GET_ROWCELL_INTERBUF(pSResInfo);
|
SFirstLastRes* pSBuf = GET_ROWCELL_INTERBUF(pSResInfo);
|
||||||
|
|
||||||
if (pSResInfo->numOfRes != 0 && (pDResInfo->numOfRes == 0 || pDBuf->ts > pSBuf->ts)) {
|
if (TSDB_CODE_SUCCESS == firstLastTransferInfoImpl(pSBuf, pDBuf, true)) {
|
||||||
memcpy(pDBuf->buf, pSBuf->buf, bytes);
|
pDBuf->hasResult = true;
|
||||||
pDBuf->ts = pSBuf->ts;
|
|
||||||
pDResInfo->numOfRes = 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pDResInfo->numOfRes = TMAX(pDResInfo->numOfRes, pSResInfo->numOfRes);
|
||||||
|
pDResInfo->isNullRes &= pSResInfo->isNullRes;
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1274,17 +1277,8 @@ int32_t stddevCombine(SqlFunctionCtx* pDestCtx, SqlFunctionCtx* pSourceCtx) {
|
||||||
SStddevRes* pSBuf = GET_ROWCELL_INTERBUF(pSResInfo);
|
SStddevRes* pSBuf = GET_ROWCELL_INTERBUF(pSResInfo);
|
||||||
int16_t type = pDBuf->type == TSDB_DATA_TYPE_NULL ? pSBuf->type : pDBuf->type;
|
int16_t type = pDBuf->type == TSDB_DATA_TYPE_NULL ? pSBuf->type : pDBuf->type;
|
||||||
|
|
||||||
if (IS_SIGNED_NUMERIC_TYPE(type)) {
|
stddevTransferInfo(pSBuf, pDBuf);
|
||||||
pDBuf->isum += pSBuf->isum;
|
|
||||||
pDBuf->quadraticISum += pSBuf->quadraticISum;
|
|
||||||
} else if (IS_UNSIGNED_NUMERIC_TYPE(type)) {
|
|
||||||
pDBuf->usum += pSBuf->usum;
|
|
||||||
pDBuf->quadraticUSum += pSBuf->quadraticUSum;
|
|
||||||
} else {
|
|
||||||
pDBuf->dsum += pSBuf->dsum;
|
|
||||||
pDBuf->quadraticDSum += pSBuf->quadraticDSum;
|
|
||||||
}
|
|
||||||
pDBuf->count += pSBuf->count;
|
|
||||||
pDResInfo->numOfRes = TMAX(pDResInfo->numOfRes, pSResInfo->numOfRes);
|
pDResInfo->numOfRes = TMAX(pDResInfo->numOfRes, pSResInfo->numOfRes);
|
||||||
pDResInfo->isNullRes &= pSResInfo->isNullRes;
|
pDResInfo->isNullRes &= pSResInfo->isNullRes;
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
|
@ -2289,16 +2283,15 @@ int32_t lastFunction(SqlFunctionCtx* pCtx) {
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void firstLastTransferInfo(SqlFunctionCtx* pCtx, SFirstLastRes* pInput, SFirstLastRes* pOutput, bool isFirst,
|
static int32_t firstLastTransferInfoImpl(SFirstLastRes* pInput, SFirstLastRes* pOutput, bool isFirst) {
|
||||||
int32_t rowIndex) {
|
|
||||||
if (pOutput->hasResult) {
|
if (pOutput->hasResult) {
|
||||||
if (isFirst) {
|
if (isFirst) {
|
||||||
if (pInput->ts > pOutput->ts) {
|
if (pInput->ts > pOutput->ts) {
|
||||||
return;
|
return TSDB_CODE_FAILED;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (pInput->ts < pOutput->ts) {
|
if (pInput->ts < pOutput->ts) {
|
||||||
return;
|
return TSDB_CODE_FAILED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2308,10 +2301,16 @@ static void firstLastTransferInfo(SqlFunctionCtx* pCtx, SFirstLastRes* pInput, S
|
||||||
pOutput->bytes = pInput->bytes;
|
pOutput->bytes = pInput->bytes;
|
||||||
|
|
||||||
memcpy(pOutput->buf, pInput->buf, pOutput->bytes);
|
memcpy(pOutput->buf, pInput->buf, pOutput->bytes);
|
||||||
firstlastSaveTupleData(pCtx->pSrcBlock, rowIndex, pCtx, pOutput);
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void firstLastTransferInfo(SqlFunctionCtx* pCtx, SFirstLastRes* pInput, SFirstLastRes* pOutput, bool isFirst,
|
||||||
|
int32_t rowIndex) {
|
||||||
|
if (TSDB_CODE_SUCCESS == firstLastTransferInfoImpl(pInput, pOutput, isFirst)) {
|
||||||
|
firstlastSaveTupleData(pCtx->pSrcBlock, rowIndex, pCtx, pOutput);
|
||||||
pOutput->hasResult = true;
|
pOutput->hasResult = true;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static int32_t firstLastFunctionMergeImpl(SqlFunctionCtx* pCtx, bool isFirstQuery) {
|
static int32_t firstLastFunctionMergeImpl(SqlFunctionCtx* pCtx, bool isFirstQuery) {
|
||||||
SInputColumnInfoData* pInput = &pCtx->input;
|
SInputColumnInfoData* pInput = &pCtx->input;
|
||||||
|
@ -2378,7 +2377,6 @@ int32_t firstLastPartialFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// todo rewrite:
|
|
||||||
int32_t lastCombine(SqlFunctionCtx* pDestCtx, SqlFunctionCtx* pSourceCtx) {
|
int32_t lastCombine(SqlFunctionCtx* pDestCtx, SqlFunctionCtx* pSourceCtx) {
|
||||||
SResultRowEntryInfo* pDResInfo = GET_RES_INFO(pDestCtx);
|
SResultRowEntryInfo* pDResInfo = GET_RES_INFO(pDestCtx);
|
||||||
SFirstLastRes* pDBuf = GET_ROWCELL_INTERBUF(pDResInfo);
|
SFirstLastRes* pDBuf = GET_ROWCELL_INTERBUF(pDResInfo);
|
||||||
|
@ -2387,11 +2385,12 @@ int32_t lastCombine(SqlFunctionCtx* pDestCtx, SqlFunctionCtx* pSourceCtx) {
|
||||||
SResultRowEntryInfo* pSResInfo = GET_RES_INFO(pSourceCtx);
|
SResultRowEntryInfo* pSResInfo = GET_RES_INFO(pSourceCtx);
|
||||||
SFirstLastRes* pSBuf = GET_ROWCELL_INTERBUF(pSResInfo);
|
SFirstLastRes* pSBuf = GET_ROWCELL_INTERBUF(pSResInfo);
|
||||||
|
|
||||||
if (pSResInfo->numOfRes != 0 && (pDResInfo->numOfRes == 0 || pDBuf->ts < pSBuf->ts)) {
|
if (TSDB_CODE_SUCCESS == firstLastTransferInfoImpl(pSBuf, pDBuf, false)) {
|
||||||
memcpy(pDBuf->buf, pSBuf->buf, bytes);
|
pDBuf->hasResult = true;
|
||||||
pDBuf->ts = pSBuf->ts;
|
|
||||||
pDResInfo->numOfRes = 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pDResInfo->numOfRes = TMAX(pDResInfo->numOfRes, pSResInfo->numOfRes);
|
||||||
|
pDResInfo->isNullRes &= pSResInfo->isNullRes;
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1019,8 +1019,8 @@ int main(int argc, char *argv[]) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (udfdInitLog() != 0) {
|
if (udfdInitLog() != 0) {
|
||||||
|
// ignore create log failed, because this error no matter
|
||||||
printf("failed to start since init log error\n");
|
printf("failed to start since init log error\n");
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (taosInitCfg(configDir, NULL, NULL, NULL, NULL, 0) != 0) {
|
if (taosInitCfg(configDir, NULL, NULL, NULL, NULL, 0) != 0) {
|
||||||
|
|
|
@ -1174,12 +1174,35 @@ int32_t toJsonFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOu
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Time functions **/
|
/** Time functions **/
|
||||||
|
static int64_t offsetFromTz(char *timezone, int64_t factor) {
|
||||||
|
char *minStr = &timezone[3];
|
||||||
|
int64_t minutes = taosStr2Int64(minStr, NULL, 10);
|
||||||
|
memset(minStr, 0, strlen(minStr));
|
||||||
|
int64_t hours = taosStr2Int64(timezone, NULL, 10);
|
||||||
|
int64_t seconds = hours * 3600 + minutes * 60;
|
||||||
|
|
||||||
|
return seconds * factor;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
int32_t timeTruncateFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput) {
|
int32_t timeTruncateFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput) {
|
||||||
int32_t type = GET_PARAM_TYPE(&pInput[0]);
|
int32_t type = GET_PARAM_TYPE(&pInput[0]);
|
||||||
|
|
||||||
int64_t timeUnit, timePrec, timeVal = 0;
|
int64_t timeUnit, timePrec, timeVal = 0;
|
||||||
|
bool ignoreTz = true;
|
||||||
|
char timezone[20] = {0};
|
||||||
|
|
||||||
GET_TYPED_DATA(timeUnit, int64_t, GET_PARAM_TYPE(&pInput[1]), pInput[1].columnData->pData);
|
GET_TYPED_DATA(timeUnit, int64_t, GET_PARAM_TYPE(&pInput[1]), pInput[1].columnData->pData);
|
||||||
GET_TYPED_DATA(timePrec, int64_t, GET_PARAM_TYPE(&pInput[2]), pInput[2].columnData->pData);
|
|
||||||
|
int32_t timePrecIdx = 2, timeZoneIdx = 3;
|
||||||
|
if (inputNum == 5) {
|
||||||
|
timePrecIdx += 1;
|
||||||
|
timeZoneIdx += 1;
|
||||||
|
GET_TYPED_DATA(ignoreTz, bool, GET_PARAM_TYPE(&pInput[2]), pInput[2].columnData->pData);
|
||||||
|
}
|
||||||
|
|
||||||
|
GET_TYPED_DATA(timePrec, int64_t, GET_PARAM_TYPE(&pInput[timePrecIdx]), pInput[timePrecIdx].columnData->pData);
|
||||||
|
memcpy(timezone, varDataVal(pInput[timeZoneIdx].columnData->pData), varDataLen(pInput[timeZoneIdx].columnData->pData));
|
||||||
|
|
||||||
int64_t factor = TSDB_TICK_PER_SECOND(timePrec);
|
int64_t factor = TSDB_TICK_PER_SECOND(timePrec);
|
||||||
int64_t unit = timeUnit * 1000 / factor;
|
int64_t unit = timeUnit * 1000 / factor;
|
||||||
|
@ -1294,13 +1317,29 @@ int32_t timeTruncateFunction(SScalarParam *pInput, int32_t inputNum, SScalarPara
|
||||||
}
|
}
|
||||||
case 86400000: { /* 1d */
|
case 86400000: { /* 1d */
|
||||||
if (tsDigits == TSDB_TIME_PRECISION_MILLI_DIGITS) {
|
if (tsDigits == TSDB_TIME_PRECISION_MILLI_DIGITS) {
|
||||||
|
if (ignoreTz) {
|
||||||
|
timeVal = timeVal - (timeVal + offsetFromTz(timezone, 1000)) % (86400L * 1000);
|
||||||
|
} else {
|
||||||
timeVal = timeVal / 1000 / 86400 * 86400 * 1000;
|
timeVal = timeVal / 1000 / 86400 * 86400 * 1000;
|
||||||
|
}
|
||||||
} else if (tsDigits == TSDB_TIME_PRECISION_MICRO_DIGITS) {
|
} else if (tsDigits == TSDB_TIME_PRECISION_MICRO_DIGITS) {
|
||||||
|
if (ignoreTz) {
|
||||||
|
timeVal = timeVal - (timeVal + offsetFromTz(timezone, 1000000)) % (86400L * 1000000);
|
||||||
|
} else {
|
||||||
timeVal = timeVal / 1000000 / 86400 * 86400 * 1000000;
|
timeVal = timeVal / 1000000 / 86400 * 86400 * 1000000;
|
||||||
|
}
|
||||||
} else if (tsDigits == TSDB_TIME_PRECISION_NANO_DIGITS) {
|
} else if (tsDigits == TSDB_TIME_PRECISION_NANO_DIGITS) {
|
||||||
|
if (ignoreTz) {
|
||||||
|
timeVal = timeVal - (timeVal + offsetFromTz(timezone, 1000000000)) % (86400L * 1000000000);
|
||||||
|
} else {
|
||||||
timeVal = timeVal / 1000000000 / 86400 * 86400 * 1000000000;
|
timeVal = timeVal / 1000000000 / 86400 * 86400 * 1000000000;
|
||||||
|
}
|
||||||
} else if (tsDigits <= TSDB_TIME_PRECISION_SEC_DIGITS) {
|
} else if (tsDigits <= TSDB_TIME_PRECISION_SEC_DIGITS) {
|
||||||
|
if (ignoreTz) {
|
||||||
|
timeVal = (timeVal - (timeVal + offsetFromTz(timezone, 1)) % (86400L)) * factor;
|
||||||
|
} else {
|
||||||
timeVal = timeVal * factor / factor / 86400 * 86400 * factor;
|
timeVal = timeVal * factor / factor / 86400 * 86400 * factor;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
colDataAppendNULL(pOutput->columnData, i);
|
colDataAppendNULL(pOutput->columnData, i);
|
||||||
continue;
|
continue;
|
||||||
|
|
|
@ -26,8 +26,6 @@ extern "C" {
|
||||||
#define ENV_TICK_TIMER_MS 1000
|
#define ENV_TICK_TIMER_MS 1000
|
||||||
#define PING_TIMER_MS 5000
|
#define PING_TIMER_MS 5000
|
||||||
#define ELECT_TIMER_MS_MIN 2500
|
#define ELECT_TIMER_MS_MIN 2500
|
||||||
#define ELECT_TIMER_MS_MAX (ELECT_TIMER_MS_MIN * 2)
|
|
||||||
#define ELECT_TIMER_MS_RANGE (ELECT_TIMER_MS_MAX - ELECT_TIMER_MS_MIN)
|
|
||||||
#define HEARTBEAT_TIMER_MS 1000
|
#define HEARTBEAT_TIMER_MS 1000
|
||||||
#define HEARTBEAT_TICK_NUM 20
|
#define HEARTBEAT_TICK_NUM 20
|
||||||
|
|
||||||
|
|
|
@ -1025,8 +1025,8 @@ SSyncNode* syncNodeOpen(SSyncInfo* pSyncInfo) {
|
||||||
}
|
}
|
||||||
// timer ms init
|
// timer ms init
|
||||||
pSyncNode->pingBaseLine = PING_TIMER_MS;
|
pSyncNode->pingBaseLine = PING_TIMER_MS;
|
||||||
pSyncNode->electBaseLine = ELECT_TIMER_MS_MIN;
|
pSyncNode->electBaseLine = tsElectInterval;
|
||||||
pSyncNode->hbBaseLine = HEARTBEAT_TIMER_MS;
|
pSyncNode->hbBaseLine = tsHeartbeatInterval;
|
||||||
|
|
||||||
// init ping timer
|
// init ping timer
|
||||||
pSyncNode->pPingTimer = NULL;
|
pSyncNode->pPingTimer = NULL;
|
||||||
|
@ -2384,7 +2384,7 @@ bool syncNodeHeartbeatReplyTimeout(SSyncNode* pSyncNode) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tsNow - recvTime > SYNC_HEART_TIMEOUT_MS) {
|
if (tsNow - recvTime > tsHeartbeatTimeout) {
|
||||||
toCount++;
|
toCount++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -184,9 +184,9 @@ SPage *tdbPCacheFetch(SPCache *pCache, const SPgid *pPgid, TXN *pTxn) {
|
||||||
// TDB_PAGE_PGNO(pPage), pPage, nRef);
|
// TDB_PAGE_PGNO(pPage), pPage, nRef);
|
||||||
|
|
||||||
if (pPage) {
|
if (pPage) {
|
||||||
tdbDebug("pcache/fetch page %p/%d/%d/%d", pPage, TDB_PAGE_PGNO(pPage), pPage->id, nRef);
|
tdbTrace("pcache/fetch page %p/%d/%d/%d", pPage, TDB_PAGE_PGNO(pPage), pPage->id, nRef);
|
||||||
} else {
|
} else {
|
||||||
tdbDebug("pcache/fetch page %p", pPage);
|
tdbTrace("pcache/fetch page %p", pPage);
|
||||||
}
|
}
|
||||||
|
|
||||||
return pPage;
|
return pPage;
|
||||||
|
@ -202,7 +202,7 @@ void tdbPCacheRelease(SPCache *pCache, SPage *pPage, TXN *pTxn) {
|
||||||
|
|
||||||
tdbPCacheLock(pCache);
|
tdbPCacheLock(pCache);
|
||||||
nRef = tdbUnrefPage(pPage);
|
nRef = tdbUnrefPage(pPage);
|
||||||
tdbDebug("pcache/release page %p/%d/%d/%d", pPage, TDB_PAGE_PGNO(pPage), pPage->id, nRef);
|
tdbTrace("pcache/release page %p/%d/%d/%d", pPage, TDB_PAGE_PGNO(pPage), pPage->id, nRef);
|
||||||
if (nRef == 0) {
|
if (nRef == 0) {
|
||||||
// test the nRef again to make sure
|
// test the nRef again to make sure
|
||||||
// it is safe th handle the page
|
// it is safe th handle the page
|
||||||
|
@ -221,8 +221,6 @@ void tdbPCacheRelease(SPCache *pCache, SPage *pPage, TXN *pTxn) {
|
||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
tdbPCacheUnlock(pCache);
|
tdbPCacheUnlock(pCache);
|
||||||
// printf("thread %" PRId64 " relas page %d pgno %d pPage %p nRef %d\n", taosGetSelfPthreadId(), pPage->id,
|
|
||||||
// TDB_PAGE_PGNO(pPage), pPage, nRef);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int tdbPCacheGetPageSize(SPCache *pCache) { return pCache->szPage; }
|
int tdbPCacheGetPageSize(SPCache *pCache) { return pCache->szPage; }
|
||||||
|
@ -335,8 +333,7 @@ static void tdbPCachePinPage(SPCache *pCache, SPage *pPage) {
|
||||||
|
|
||||||
pCache->nRecyclable--;
|
pCache->nRecyclable--;
|
||||||
|
|
||||||
// printf("pin page %d pgno %d pPage %p\n", pPage->id, TDB_PAGE_PGNO(pPage), pPage);
|
tdbTrace("pcache/pin page %p/%d/%d", pPage, TDB_PAGE_PGNO(pPage), pPage->id);
|
||||||
tdbDebug("pcache/pin page %p/%d/%d", pPage, TDB_PAGE_PGNO(pPage), pPage->id);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -349,7 +346,7 @@ static void tdbPCacheUnpinPage(SPCache *pCache, SPage *pPage) {
|
||||||
|
|
||||||
ASSERT(pPage->pLruNext == NULL);
|
ASSERT(pPage->pLruNext == NULL);
|
||||||
|
|
||||||
tdbDebug("pCache:%p unpin page %p/%d/%d, nPages:%d", pCache, pPage, TDB_PAGE_PGNO(pPage), pPage->id, pCache->nPages);
|
tdbTrace("pCache:%p unpin page %p/%d/%d, nPages:%d", pCache, pPage, TDB_PAGE_PGNO(pPage), pPage->id, pCache->nPages);
|
||||||
if (pPage->id < pCache->nPages) {
|
if (pPage->id < pCache->nPages) {
|
||||||
pPage->pLruPrev = &(pCache->lru);
|
pPage->pLruPrev = &(pCache->lru);
|
||||||
pPage->pLruNext = pCache->lru.pLruNext;
|
pPage->pLruNext = pCache->lru.pLruNext;
|
||||||
|
@ -359,9 +356,9 @@ static void tdbPCacheUnpinPage(SPCache *pCache, SPage *pPage) {
|
||||||
pCache->nRecyclable++;
|
pCache->nRecyclable++;
|
||||||
|
|
||||||
// printf("unpin page %d pgno %d pPage %p\n", pPage->id, TDB_PAGE_PGNO(pPage), pPage);
|
// printf("unpin page %d pgno %d pPage %p\n", pPage->id, TDB_PAGE_PGNO(pPage), pPage);
|
||||||
tdbDebug("pcache/unpin page %p/%d/%d", pPage, TDB_PAGE_PGNO(pPage), pPage->id);
|
tdbTrace("pcache/unpin page %p/%d/%d", pPage, TDB_PAGE_PGNO(pPage), pPage->id);
|
||||||
} else {
|
} else {
|
||||||
tdbDebug("pcache destroy page: %p/%d/%d", pPage, TDB_PAGE_PGNO(pPage), pPage->id);
|
tdbTrace("pcache destroy page: %p/%d/%d", pPage, TDB_PAGE_PGNO(pPage), pPage->id);
|
||||||
|
|
||||||
tdbPCacheRemovePageFromHash(pCache, pPage);
|
tdbPCacheRemovePageFromHash(pCache, pPage);
|
||||||
tdbPageDestroy(pPage, tdbDefaultFree, NULL);
|
tdbPageDestroy(pPage, tdbDefaultFree, NULL);
|
||||||
|
@ -381,7 +378,7 @@ static void tdbPCacheRemovePageFromHash(SPCache *pCache, SPage *pPage) {
|
||||||
// printf("rmv page %d to hash, pgno %d, pPage %p\n", pPage->id, TDB_PAGE_PGNO(pPage), pPage);
|
// printf("rmv page %d to hash, pgno %d, pPage %p\n", pPage->id, TDB_PAGE_PGNO(pPage), pPage);
|
||||||
}
|
}
|
||||||
|
|
||||||
tdbDebug("pcache/remove page %p/%d/%d from hash %" PRIu32, pPage, TDB_PAGE_PGNO(pPage), pPage->id, h);
|
tdbTrace("pcache/remove page %p/%d/%d from hash %" PRIu32, pPage, TDB_PAGE_PGNO(pPage), pPage->id, h);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void tdbPCacheAddPageToHash(SPCache *pCache, SPage *pPage) {
|
static void tdbPCacheAddPageToHash(SPCache *pCache, SPage *pPage) {
|
||||||
|
@ -392,8 +389,7 @@ static void tdbPCacheAddPageToHash(SPCache *pCache, SPage *pPage) {
|
||||||
|
|
||||||
pCache->nPage++;
|
pCache->nPage++;
|
||||||
|
|
||||||
// printf("add page %d to hash, pgno %d, pPage %p\n", pPage->id, TDB_PAGE_PGNO(pPage), pPage);
|
tdbTrace("pcache/add page %p/%d/%d to hash %" PRIu32, pPage, TDB_PAGE_PGNO(pPage), pPage->id, h);
|
||||||
tdbDebug("pcache/add page %p/%d/%d to hash %" PRIu32, pPage, TDB_PAGE_PGNO(pPage), pPage->id, h);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int tdbPCacheOpenImpl(SPCache *pCache) {
|
static int tdbPCacheOpenImpl(SPCache *pCache) {
|
||||||
|
|
|
@ -81,7 +81,7 @@ int tdbPageDestroy(SPage *pPage, void (*xFree)(void *arg, void *ptr), void *arg)
|
||||||
ASSERT(xFree);
|
ASSERT(xFree);
|
||||||
|
|
||||||
for (int iOvfl = 0; iOvfl < pPage->nOverflow; iOvfl++) {
|
for (int iOvfl = 0; iOvfl < pPage->nOverflow; iOvfl++) {
|
||||||
tdbDebug("tdbPage/destroy/free ovfl cell: %p/%p", pPage->apOvfl[iOvfl], pPage);
|
tdbTrace("tdbPage/destroy/free ovfl cell: %p/%p", pPage->apOvfl[iOvfl], pPage);
|
||||||
tdbOsFree(pPage->apOvfl[iOvfl]);
|
tdbOsFree(pPage->apOvfl[iOvfl]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -92,7 +92,7 @@ int tdbPageDestroy(SPage *pPage, void (*xFree)(void *arg, void *ptr), void *arg)
|
||||||
}
|
}
|
||||||
|
|
||||||
void tdbPageZero(SPage *pPage, u8 szAmHdr, int (*xCellSize)(const SPage *, SCell *, int, TXN *, SBTree *pBt)) {
|
void tdbPageZero(SPage *pPage, u8 szAmHdr, int (*xCellSize)(const SPage *, SCell *, int, TXN *, SBTree *pBt)) {
|
||||||
tdbDebug("page/zero: %p %" PRIu8 " %p", pPage, szAmHdr, xCellSize);
|
tdbTrace("page/zero: %p %" PRIu8 " %p", pPage, szAmHdr, xCellSize);
|
||||||
pPage->pPageHdr = pPage->pData + szAmHdr;
|
pPage->pPageHdr = pPage->pData + szAmHdr;
|
||||||
TDB_PAGE_NCELLS_SET(pPage, 0);
|
TDB_PAGE_NCELLS_SET(pPage, 0);
|
||||||
TDB_PAGE_CCELLS_SET(pPage, pPage->pageSize - sizeof(SPageFtr));
|
TDB_PAGE_CCELLS_SET(pPage, pPage->pageSize - sizeof(SPageFtr));
|
||||||
|
@ -109,7 +109,7 @@ void tdbPageZero(SPage *pPage, u8 szAmHdr, int (*xCellSize)(const SPage *, SCell
|
||||||
}
|
}
|
||||||
|
|
||||||
void tdbPageInit(SPage *pPage, u8 szAmHdr, int (*xCellSize)(const SPage *, SCell *, int, TXN *, SBTree *pBt)) {
|
void tdbPageInit(SPage *pPage, u8 szAmHdr, int (*xCellSize)(const SPage *, SCell *, int, TXN *, SBTree *pBt)) {
|
||||||
tdbDebug("page/init: %p %" PRIu8 " %p", pPage, szAmHdr, xCellSize);
|
tdbTrace("page/init: %p %" PRIu8 " %p", pPage, szAmHdr, xCellSize);
|
||||||
pPage->pPageHdr = pPage->pData + szAmHdr;
|
pPage->pPageHdr = pPage->pData + szAmHdr;
|
||||||
pPage->pCellIdx = pPage->pPageHdr + TDB_PAGE_HDR_SIZE(pPage);
|
pPage->pCellIdx = pPage->pPageHdr + TDB_PAGE_HDR_SIZE(pPage);
|
||||||
pPage->pFreeStart = pPage->pCellIdx + TDB_PAGE_OFFSET_SIZE(pPage) * TDB_PAGE_NCELLS(pPage);
|
pPage->pFreeStart = pPage->pCellIdx + TDB_PAGE_OFFSET_SIZE(pPage) * TDB_PAGE_NCELLS(pPage);
|
||||||
|
@ -154,7 +154,7 @@ int tdbPageInsertCell(SPage *pPage, int idx, SCell *pCell, int szCell, u8 asOvfl
|
||||||
pNewCell = (SCell *)tdbOsMalloc(szCell);
|
pNewCell = (SCell *)tdbOsMalloc(szCell);
|
||||||
memcpy(pNewCell, pCell, szCell);
|
memcpy(pNewCell, pCell, szCell);
|
||||||
|
|
||||||
tdbDebug("tdbPage/insert/new ovfl cell: %p/%p", pNewCell, pPage);
|
tdbTrace("tdbPage/insert/new ovfl cell: %p/%p", pNewCell, pPage);
|
||||||
|
|
||||||
pPage->apOvfl[iOvfl] = pNewCell;
|
pPage->apOvfl[iOvfl] = pNewCell;
|
||||||
pPage->aiOvfl[iOvfl] = idx;
|
pPage->aiOvfl[iOvfl] = idx;
|
||||||
|
@ -204,7 +204,7 @@ int tdbPageDropCell(SPage *pPage, int idx, TXN *pTxn, SBTree *pBt) {
|
||||||
if (pPage->aiOvfl[iOvfl] == idx) {
|
if (pPage->aiOvfl[iOvfl] == idx) {
|
||||||
// remove the over flow cell
|
// remove the over flow cell
|
||||||
tdbOsFree(pPage->apOvfl[iOvfl]);
|
tdbOsFree(pPage->apOvfl[iOvfl]);
|
||||||
tdbDebug("tdbPage/drop/free ovfl cell: %p", pPage->apOvfl[iOvfl]);
|
tdbTrace("tdbPage/drop/free ovfl cell: %p", pPage->apOvfl[iOvfl]);
|
||||||
for (; (++iOvfl) < pPage->nOverflow;) {
|
for (; (++iOvfl) < pPage->nOverflow;) {
|
||||||
pPage->aiOvfl[iOvfl - 1] = pPage->aiOvfl[iOvfl] - 1;
|
pPage->aiOvfl[iOvfl - 1] = pPage->aiOvfl[iOvfl] - 1;
|
||||||
pPage->apOvfl[iOvfl - 1] = pPage->apOvfl[iOvfl];
|
pPage->apOvfl[iOvfl - 1] = pPage->apOvfl[iOvfl];
|
||||||
|
@ -257,7 +257,7 @@ void tdbPageCopy(SPage *pFromPage, SPage *pToPage, int deepCopyOvfl) {
|
||||||
int szCell = (*pFromPage->xCellSize)(pFromPage, pFromPage->apOvfl[iOvfl], 0, NULL, NULL);
|
int szCell = (*pFromPage->xCellSize)(pFromPage, pFromPage->apOvfl[iOvfl], 0, NULL, NULL);
|
||||||
pNewCell = (SCell *)tdbOsMalloc(szCell);
|
pNewCell = (SCell *)tdbOsMalloc(szCell);
|
||||||
memcpy(pNewCell, pFromPage->apOvfl[iOvfl], szCell);
|
memcpy(pNewCell, pFromPage->apOvfl[iOvfl], szCell);
|
||||||
tdbDebug("tdbPage/copy/new ovfl cell: %p/%p/%p", pNewCell, pToPage, pFromPage);
|
tdbTrace("tdbPage/copy/new ovfl cell: %p/%p/%p", pNewCell, pToPage, pFromPage);
|
||||||
}
|
}
|
||||||
|
|
||||||
pToPage->apOvfl[iOvfl] = pNewCell;
|
pToPage->apOvfl[iOvfl] = pNewCell;
|
||||||
|
|
|
@ -239,7 +239,7 @@ int tdbPagerWrite(SPager *pPager, SPage *pPage) {
|
||||||
|
|
||||||
// ref page one more time so the page will not be release
|
// ref page one more time so the page will not be release
|
||||||
tdbRefPage(pPage);
|
tdbRefPage(pPage);
|
||||||
tdbDebug("pager/mdirty page %p/%d/%d", pPage, TDB_PAGE_PGNO(pPage), pPage->id);
|
tdbTrace("pager/mdirty page %p/%d/%d", pPage, TDB_PAGE_PGNO(pPage), pPage->id);
|
||||||
|
|
||||||
// Set page as dirty
|
// Set page as dirty
|
||||||
pPage->isDirty = 1;
|
pPage->isDirty = 1;
|
||||||
|
|
|
@ -28,10 +28,10 @@ taos -s "drop database if exists test"
|
||||||
dotnet run --project optsJSON/optsJSON.csproj
|
dotnet run --project optsJSON/optsJSON.csproj
|
||||||
|
|
||||||
taos -s "create database if not exists test"
|
taos -s "create database if not exists test"
|
||||||
# dotnet run --project wsConnect/wsConnect.csproj
|
dotnet run --project wsConnect/wsConnect.csproj
|
||||||
# dotnet run --project wsInsert/wsInsert.csproj
|
dotnet run --project wsInsert/wsInsert.csproj
|
||||||
# dotnet run --project wsStmt/wsStmt.csproj
|
dotnet run --project wsStmt/wsStmt.csproj
|
||||||
# dotnet run --project wsQuery/wsQuery.csproj
|
dotnet run --project wsQuery/wsQuery.csproj
|
||||||
|
|
||||||
taos -s "drop database if exists test"
|
taos -s "drop database if exists test"
|
||||||
taos -s "drop database if exists power"
|
taos -s "drop database if exists power"
|
|
@ -197,4 +197,98 @@ if $data01 != 1 then
|
||||||
return -1
|
return -1
|
||||||
endi
|
endi
|
||||||
|
|
||||||
|
sql create database test1 vgroups 1;
|
||||||
|
sql use test1;
|
||||||
|
sql create table t1(ts timestamp, a int, b int , c int, d double);
|
||||||
|
sql create stream streams3 trigger at_once into streamt3 as select _wstart, count(*) c1 from t1 where a > 5 session(ts, 5s);
|
||||||
|
sql insert into t1 values(1648791213000,1,2,3,1.0);
|
||||||
|
|
||||||
|
$loop_count = 0
|
||||||
|
loop13:
|
||||||
|
sleep 200
|
||||||
|
|
||||||
|
sql select * from streamt3;
|
||||||
|
|
||||||
|
$loop_count = $loop_count + 1
|
||||||
|
if $loop_count == 10 then
|
||||||
|
return -1
|
||||||
|
endi
|
||||||
|
|
||||||
|
# row 0
|
||||||
|
if $rows != 0 then
|
||||||
|
print =====rows=$rows
|
||||||
|
goto loop13
|
||||||
|
endi
|
||||||
|
|
||||||
|
sql insert into t1 values(1648791213000,6,2,3,1.0);
|
||||||
|
|
||||||
|
$loop_count = 0
|
||||||
|
loop14:
|
||||||
|
sleep 200
|
||||||
|
sql select * from streamt3;
|
||||||
|
|
||||||
|
$loop_count = $loop_count + 1
|
||||||
|
if $loop_count == 10 then
|
||||||
|
return -1
|
||||||
|
endi
|
||||||
|
|
||||||
|
if $data01 != 1 then
|
||||||
|
print =====data01=$data01
|
||||||
|
goto loop14
|
||||||
|
endi
|
||||||
|
|
||||||
|
sql insert into t1 values(1648791213000,2,2,3,1.0);
|
||||||
|
|
||||||
|
$loop_count = 0
|
||||||
|
loop15:
|
||||||
|
sleep 200
|
||||||
|
sql select * from streamt3;
|
||||||
|
|
||||||
|
$loop_count = $loop_count + 1
|
||||||
|
if $loop_count == 10 then
|
||||||
|
return -1
|
||||||
|
endi
|
||||||
|
|
||||||
|
if $rows != 0 then
|
||||||
|
print =====rows=$rows
|
||||||
|
goto loop15
|
||||||
|
endi
|
||||||
|
|
||||||
|
|
||||||
|
sql insert into t1 values(1648791223000,2,2,3,1.0);
|
||||||
|
sql insert into t1 values(1648791223000,10,2,3,1.0);
|
||||||
|
sql insert into t1 values(1648791233000,10,2,3,1.0);
|
||||||
|
|
||||||
|
$loop_count = 0
|
||||||
|
loop16:
|
||||||
|
sleep 200
|
||||||
|
sql select * from streamt3;
|
||||||
|
|
||||||
|
$loop_count = $loop_count + 1
|
||||||
|
if $loop_count == 10 then
|
||||||
|
return -1
|
||||||
|
endi
|
||||||
|
|
||||||
|
if $rows != 2 then
|
||||||
|
print =====rows=$rows
|
||||||
|
goto loop16
|
||||||
|
endi
|
||||||
|
|
||||||
|
sql insert into t1 values(1648791233000,2,2,3,1.0);
|
||||||
|
|
||||||
|
$loop_count = 0
|
||||||
|
loop17:
|
||||||
|
sleep 200
|
||||||
|
sql select * from streamt3;
|
||||||
|
|
||||||
|
$loop_count = $loop_count + 1
|
||||||
|
if $loop_count == 10 then
|
||||||
|
return -1
|
||||||
|
endi
|
||||||
|
|
||||||
|
if $rows != 1 then
|
||||||
|
print =====rows=$rows
|
||||||
|
goto loop17
|
||||||
|
endi
|
||||||
|
|
||||||
system sh/exec.sh -n dnode1 -s stop -x SIGINT
|
system sh/exec.sh -n dnode1 -s stop -x SIGINT
|
||||||
|
|
|
@ -30,7 +30,7 @@ class TDTestCase:
|
||||||
self.stbname = f'{self.dbname}.stb'
|
self.stbname = f'{self.dbname}.stb'
|
||||||
self.ctbname = f'{self.dbname}.ctb'
|
self.ctbname = f'{self.dbname}.ctb'
|
||||||
|
|
||||||
def check_ms_timestamp(self,unit,date_time):
|
def check_ms_timestamp(self,unit,date_time, ignore_tz):
|
||||||
if unit.lower() == '1a':
|
if unit.lower() == '1a':
|
||||||
for i in range(len(self.ts_str)):
|
for i in range(len(self.ts_str)):
|
||||||
ts_result = self.get_time.get_ms_timestamp(str(tdSql.queryResult[i][0]))
|
ts_result = self.get_time.get_ms_timestamp(str(tdSql.queryResult[i][0]))
|
||||||
|
@ -50,13 +50,17 @@ class TDTestCase:
|
||||||
elif unit.lower() == '1d':
|
elif unit.lower() == '1d':
|
||||||
for i in range(len(self.ts_str)):
|
for i in range(len(self.ts_str)):
|
||||||
ts_result = self.get_time.get_ms_timestamp(str(tdSql.queryResult[i][0]))
|
ts_result = self.get_time.get_ms_timestamp(str(tdSql.queryResult[i][0]))
|
||||||
|
if ignore_tz == 0:
|
||||||
tdSql.checkEqual(ts_result,int(date_time[i]/1000/60/60/24)*24*60*60*1000)
|
tdSql.checkEqual(ts_result,int(date_time[i]/1000/60/60/24)*24*60*60*1000)
|
||||||
|
else:
|
||||||
|
# assuming the client timezone is UTC+0800
|
||||||
|
tdSql.checkEqual(ts_result,int(date_time[i] - (date_time[i] + 8 * 3600 * 1000) % (86400 * 1000)))
|
||||||
elif unit.lower() == '1w':
|
elif unit.lower() == '1w':
|
||||||
for i in range(len(self.ts_str)):
|
for i in range(len(self.ts_str)):
|
||||||
ts_result = self.get_time.get_ms_timestamp(str(tdSql.queryResult[i][0]))
|
ts_result = self.get_time.get_ms_timestamp(str(tdSql.queryResult[i][0]))
|
||||||
tdSql.checkEqual(ts_result,int(date_time[i]/1000/60/60/24/7)*7*24*60*60*1000)
|
tdSql.checkEqual(ts_result,int(date_time[i]/1000/60/60/24/7)*7*24*60*60*1000)
|
||||||
|
|
||||||
def check_us_timestamp(self,unit,date_time):
|
def check_us_timestamp(self,unit,date_time, ignore_tz):
|
||||||
if unit.lower() == '1u':
|
if unit.lower() == '1u':
|
||||||
for i in range(len(self.ts_str)):
|
for i in range(len(self.ts_str)):
|
||||||
ts_result = self.get_time.get_us_timestamp(str(tdSql.queryResult[i][0]))
|
ts_result = self.get_time.get_us_timestamp(str(tdSql.queryResult[i][0]))
|
||||||
|
@ -80,13 +84,17 @@ class TDTestCase:
|
||||||
elif unit.lower() == '1d':
|
elif unit.lower() == '1d':
|
||||||
for i in range(len(self.ts_str)):
|
for i in range(len(self.ts_str)):
|
||||||
ts_result = self.get_time.get_us_timestamp(str(tdSql.queryResult[i][0]))
|
ts_result = self.get_time.get_us_timestamp(str(tdSql.queryResult[i][0]))
|
||||||
|
if ignore_tz == 0:
|
||||||
tdSql.checkEqual(ts_result,int(date_time[i]/1000/1000/60/60/24)*24*60*60*1000*1000 )
|
tdSql.checkEqual(ts_result,int(date_time[i]/1000/1000/60/60/24)*24*60*60*1000*1000 )
|
||||||
|
else:
|
||||||
|
# assuming the client timezone is UTC+0800
|
||||||
|
tdSql.checkEqual(ts_result,int(date_time[i] - (date_time[i] + 8 * 3600 * 1000000) % (86400 * 1000000)))
|
||||||
elif unit.lower() == '1w':
|
elif unit.lower() == '1w':
|
||||||
for i in range(len(self.ts_str)):
|
for i in range(len(self.ts_str)):
|
||||||
ts_result = self.get_time.get_us_timestamp(str(tdSql.queryResult[i][0]))
|
ts_result = self.get_time.get_us_timestamp(str(tdSql.queryResult[i][0]))
|
||||||
tdSql.checkEqual(ts_result,int(date_time[i]/1000/1000/60/60/24/7)*7*24*60*60*1000*1000)
|
tdSql.checkEqual(ts_result,int(date_time[i]/1000/1000/60/60/24/7)*7*24*60*60*1000*1000)
|
||||||
|
|
||||||
def check_ns_timestamp(self,unit,date_time):
|
def check_ns_timestamp(self,unit,date_time, ignore_tz):
|
||||||
if unit.lower() == '1b':
|
if unit.lower() == '1b':
|
||||||
for i in range(len(self.ts_str)):
|
for i in range(len(self.ts_str)):
|
||||||
if self.rest_tag != 'rest':
|
if self.rest_tag != 'rest':
|
||||||
|
@ -114,21 +122,26 @@ class TDTestCase:
|
||||||
elif unit.lower() == '1d':
|
elif unit.lower() == '1d':
|
||||||
for i in range(len(self.ts_str)):
|
for i in range(len(self.ts_str)):
|
||||||
if self.rest_tag != 'rest':
|
if self.rest_tag != 'rest':
|
||||||
|
if ignore_tz == 0:
|
||||||
tdSql.checkEqual(tdSql.queryResult[i][0],int(date_time[i]*1000/1000/1000/1000/1000/60/60/24)*24*60*60*1000*1000*1000 )
|
tdSql.checkEqual(tdSql.queryResult[i][0],int(date_time[i]*1000/1000/1000/1000/1000/60/60/24)*24*60*60*1000*1000*1000 )
|
||||||
|
else:
|
||||||
|
# assuming the client timezone is UTC+0800
|
||||||
|
tdSql.checkEqual(tdSql.queryResult[i][0],int(date_time[i] - (date_time[i] + 8 * 3600 * 1000000) % (86400 * 1000000)))
|
||||||
elif unit.lower() == '1w':
|
elif unit.lower() == '1w':
|
||||||
for i in range(len(self.ts_str)):
|
for i in range(len(self.ts_str)):
|
||||||
if self.rest_tag != 'rest':
|
if self.rest_tag != 'rest':
|
||||||
tdSql.checkEqual(tdSql.queryResult[i][0],int(date_time[i]*1000/1000/1000/1000/1000/60/60/24/7)*7*24*60*60*1000*1000*1000)
|
tdSql.checkEqual(tdSql.queryResult[i][0],int(date_time[i]*1000/1000/1000/1000/1000/60/60/24/7)*7*24*60*60*1000*1000*1000)
|
||||||
|
|
||||||
def check_tb_type(self,unit,tb_type):
|
def check_tb_type(self,unit,tb_type,ignore_tz):
|
||||||
if tb_type.lower() == 'ntb':
|
if tb_type.lower() == 'ntb':
|
||||||
tdSql.query(f'select timetruncate(ts,{unit}) from {self.ntbname}')
|
tdSql.query(f'select timetruncate(ts,{unit},{ignore_tz}) from {self.ntbname}')
|
||||||
elif tb_type.lower() == 'ctb':
|
elif tb_type.lower() == 'ctb':
|
||||||
tdSql.query(f'select timetruncate(ts,{unit}) from {self.ctbname}')
|
tdSql.query(f'select timetruncate(ts,{unit},{ignore_tz}) from {self.ctbname}')
|
||||||
elif tb_type.lower() == 'stb':
|
elif tb_type.lower() == 'stb':
|
||||||
tdSql.query(f'select timetruncate(ts,{unit}) from {self.stbname}')
|
tdSql.query(f'select timetruncate(ts,{unit},{ignore_tz}) from {self.stbname}')
|
||||||
|
|
||||||
def data_check(self,date_time,precision,tb_type):
|
def data_check(self,date_time,precision,tb_type):
|
||||||
|
tz_options = [0, 1]
|
||||||
for unit in self.time_unit:
|
for unit in self.time_unit:
|
||||||
if (unit.lower() == '1u' and precision.lower() == 'ms') or (unit.lower() == '1b' and precision.lower() == 'us') or (unit.lower() == '1b' and precision.lower() == 'ms'):
|
if (unit.lower() == '1u' and precision.lower() == 'ms') or (unit.lower() == '1b' and precision.lower() == 'us') or (unit.lower() == '1b' and precision.lower() == 'ms'):
|
||||||
if tb_type.lower() == 'ntb':
|
if tb_type.lower() == 'ntb':
|
||||||
|
@ -138,17 +151,20 @@ class TDTestCase:
|
||||||
elif tb_type.lower() == 'stb':
|
elif tb_type.lower() == 'stb':
|
||||||
tdSql.error(f'select timetruncate(ts,{unit}) from {self.stbname}')
|
tdSql.error(f'select timetruncate(ts,{unit}) from {self.stbname}')
|
||||||
elif precision.lower() == 'ms':
|
elif precision.lower() == 'ms':
|
||||||
self.check_tb_type(unit,tb_type)
|
for ignore_tz in tz_options:
|
||||||
|
self.check_tb_type(unit,tb_type,ignore_tz)
|
||||||
tdSql.checkRows(len(self.ts_str))
|
tdSql.checkRows(len(self.ts_str))
|
||||||
self.check_ms_timestamp(unit,date_time)
|
self.check_ms_timestamp(unit,date_time,ignore_tz)
|
||||||
elif precision.lower() == 'us':
|
elif precision.lower() == 'us':
|
||||||
self.check_tb_type(unit,tb_type)
|
for ignore_tz in tz_options:
|
||||||
|
self.check_tb_type(unit,tb_type,ignore_tz)
|
||||||
tdSql.checkRows(len(self.ts_str))
|
tdSql.checkRows(len(self.ts_str))
|
||||||
self.check_us_timestamp(unit,date_time)
|
self.check_us_timestamp(unit,date_time,ignore_tz)
|
||||||
elif precision.lower() == 'ns':
|
elif precision.lower() == 'ns':
|
||||||
self.check_tb_type(unit,tb_type)
|
for ignore_tz in tz_options:
|
||||||
|
self.check_tb_type(unit,tb_type, ignore_tz)
|
||||||
tdSql.checkRows(len(self.ts_str))
|
tdSql.checkRows(len(self.ts_str))
|
||||||
self.check_ns_timestamp(unit,date_time)
|
self.check_ns_timestamp(unit,date_time,ignore_tz)
|
||||||
for unit in self.error_unit:
|
for unit in self.error_unit:
|
||||||
if tb_type.lower() == 'ntb':
|
if tb_type.lower() == 'ntb':
|
||||||
tdSql.error(f'select timetruncate(ts,{unit}) from {self.ntbname}')
|
tdSql.error(f'select timetruncate(ts,{unit}) from {self.ntbname}')
|
||||||
|
|
|
@ -113,6 +113,13 @@ int32_t shellRunSingleCommand(char *command) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void shellRecordCommandToHistory(char *command) {
|
void shellRecordCommandToHistory(char *command) {
|
||||||
|
if (strncasecmp(command, "create user ", 12) == 0 || strncasecmp(command, "alter user ", 11) == 0) {
|
||||||
|
if (taosStrCaseStr(command, " pass ")) {
|
||||||
|
// have password command forbid record to history because security
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
SShellHistory *pHistory = &shell.history;
|
SShellHistory *pHistory = &shell.history;
|
||||||
if (pHistory->hstart == pHistory->hend ||
|
if (pHistory->hstart == pHistory->hend ||
|
||||||
pHistory->hist[(pHistory->hend + SHELL_MAX_HISTORY_SIZE - 1) % SHELL_MAX_HISTORY_SIZE] == NULL ||
|
pHistory->hist[(pHistory->hend + SHELL_MAX_HISTORY_SIZE - 1) % SHELL_MAX_HISTORY_SIZE] == NULL ||
|
||||||
|
@ -135,7 +142,7 @@ int32_t shellRunCommand(char *command, bool recordHistory) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// add help or help;
|
// add help or help;
|
||||||
if(strcmp(command, "help") == 0 || strcmp(command, "help;") == 0) {
|
if(strncasecmp(command, "help;", 5) == 0) {
|
||||||
showHelp();
|
showHelp();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue