feat:[TD-32642] add timezone for connection support

This commit is contained in:
wangmm0220 2024-11-28 17:17:16 +08:00
parent 413be29b63
commit 375c3c4873
10 changed files with 96 additions and 65 deletions

View File

@ -21,6 +21,9 @@ extern "C" {
#endif
#define TdEastZone8 8*60*60
#define TZ_UNKNOWN "n/a"
extern void* pTimezoneNameMap;
typedef struct state *timezone_t;
struct tm *localtime_rz(timezone_t , time_t const *, struct tm *);

View File

@ -73,6 +73,14 @@ static timezone_t setConnnectionTz(const char* val){
taosHashSetFreeFp(pTimezoneMap, (_hash_free_fn_t)tzfree);
}
if (pTimezoneNameMap == NULL){
pTimezoneNameMap = taosHashInit(0, taosIntHash_64, false, HASH_ENTRY_LOCK);
if (pTimezoneNameMap == NULL) {
atomic_store_32(&lock_c, 0);
goto END;
}
}
timezone_t *tmp = taosHashGet(pTimezoneMap, val, strlen(val));
if (tmp != NULL && *tmp != NULL){
tz = *tmp;
@ -92,6 +100,14 @@ static timezone_t setConnnectionTz(const char* val){
tz = NULL;
}
time_t tx1 = taosGetTimestampSec();
char output[TD_TIMEZONE_LEN] = {0};
taosFormatTimezoneStr(tx1, val, tz, output);
code = taosHashPut(pTimezoneNameMap, &tz, sizeof(timezone_t), output, strlen(output) + 1);
if (code != 0){
tscError("failed to put timezone %s to map", val);
}
END:
atomic_store_32(&lock_c, 0);
return tz;

View File

@ -460,7 +460,7 @@ TEST(timezoneCase, get_tz_Test) {
// ASSERT_STREQ(tz, "Asia/Shanghai");
//
// getTimezoneStr(tz);
// ASSERT_STREQ(tz, "n/a");
// ASSERT_STREQ(tz, TZ_UNKNOWN);
}
}

View File

@ -326,6 +326,7 @@ bool tsExperimental = true;
int32_t tsMaxTsmaNum = 3;
int32_t tsMaxTsmaCalcDelay = 600;
int64_t tsmaDataDeleteMark = 1000 * 60 * 60 * 24; // in ms, default to 1d
void* pTimezoneNameMap = NULL;
#define TAOS_CHECK_GET_CFG_ITEM(pCfg, pItem, pName) \
if ((pItem = cfgGetItem(pCfg, pName)) == NULL) { \

View File

@ -1663,9 +1663,18 @@ static int32_t translateOutVarchar(SFunctionNode* pFunc, char* pErrBuf, int32_t
case FUNCTION_TYPE_TBNAME:
bytes = TSDB_TABLE_FNAME_LEN - 1 + VARSTR_HEADER_SIZE;
break;
case FUNCTION_TYPE_TIMEZONE:
bytes = TD_TIMEZONE_LEN + VARSTR_HEADER_SIZE;
case FUNCTION_TYPE_TIMEZONE:{
if (pFunc->tz == NULL) {
bytes = VARSTR_HEADER_SIZE + strlen(tsTimezoneStr);
}else{
char *tzName = (char*)taosHashGet(pTimezoneNameMap, &pFunc->tz, sizeof(timezone_t));
if (tzName == NULL){
tzName = TZ_UNKNOWN;
}
bytes = strlen(tzName) + VARSTR_HEADER_SIZE;
}
break;
}
case FUNCTION_TYPE_IRATE_PARTIAL:
bytes = getIrateInfoSize((pFunc->hasPk) ? pFunc->pkBytes : 0) + VARSTR_HEADER_SIZE;
break;

View File

@ -2664,13 +2664,15 @@ int32_t todayFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOut
int32_t timezoneFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput) {
char output[TD_TIMEZONE_LEN + VARSTR_HEADER_SIZE] = {0};
// pInput->tz todo tz
char* tmp = NULL;
if (pInput->tz == NULL) {
(void)memcpy(varDataVal(output), tsTimezoneStr, TD_TIMEZONE_LEN);
} else{
time_t tx1 = taosGetTimestampSec();
SCL_ERR_RET(taosFormatTimezoneStr(tx1, "UTC-test", pInput->tz, varDataVal(output)));
char *tzName = (char*)taosHashGet(pTimezoneNameMap, &pInput->tz, sizeof(timezone_t));
if (tzName == NULL){
tzName = TZ_UNKNOWN;
}
tstrncpy(varDataVal(output), tzName, strlen(tzName) + 1);
}
varDataSetLen(output, strlen(varDataVal(output)));

View File

@ -905,7 +905,7 @@ void getTimezoneStr(char *tz) {
END:
if (tz[0] == '\0') {
memcpy(tz, "n/a", sizeof("n/a"));
memcpy(tz, TZ_UNKNOWN, sizeof(TZ_UNKNOWN));
}
uDebug("[tz] system timezone:%s", tz);
}

View File

@ -914,55 +914,6 @@ enum { SIGNED_PADDING_CHECK_NEEDED = true };
static_assert(! TYPE_SIGNED(time_t) || ! SIGNED_PADDING_CHECK_NEEDED
|| TIME_T_MAX >> (TYPE_BIT(time_t) - 2) == 1);
/* If true, the value returned by an idealized unlimited-range mktime
always fits into an integer type with bounds MIN and MAX.
If false, the value might not fit.
This macro is usable in #if if its arguments are.
Add or subtract 2**31 - 1 for the maximum UT offset allowed in a TZif file,
divide by the maximum number of non-leap seconds in a year,
divide again by two just to be safe,
and account for the tm_year origin (1900) and time_t origin (1970). */
#define MKTIME_FITS_IN(min, max) \
((min) < 0 \
&& ((min) + 0x7fffffff) / 366 / 24 / 60 / 60 / 2 + 1970 - 1900 < INT_MIN \
&& INT_MAX < ((max) - 0x7fffffff) / 366 / 24 / 60 / 60 / 2 + 1970 - 1900)
/* MKTIME_MIGHT_OVERFLOW is true if mktime can fail due to time_t overflow
or if it is not known whether mktime can fail,
and is false if mktime definitely cannot fail.
This macro is usable in #if, and so does not use TIME_T_MAX or sizeof.
If the builder has not configured this macro, guess based on what
known platforms do. When in doubt, guess true. */
#ifndef MKTIME_MIGHT_OVERFLOW
# if defined __FreeBSD__ || defined __NetBSD__ || defined __OpenBSD__
# include <sys/param.h>
# endif
# if ((/* The following heuristics assume native time_t. */ \
defined_time_tz) \
|| ((/* Traditional time_t is 'long', so if 'long' is not wide enough \
assume overflow unless we're on a known-safe host. */ \
!MKTIME_FITS_IN(LONG_MIN, LONG_MAX)) \
&& (/* GNU C Library 2.29 (2019-02-01) and later has 64-bit time_t \
if __TIMESIZE is 64. */ \
!defined __TIMESIZE || __TIMESIZE < 64) \
&& (/* FreeBSD 12 r320347 (__FreeBSD_version 1200036; 2017-06-26), \
and later has 64-bit time_t on all platforms but i386 which \
is currently scheduled for end-of-life on 2028-11-30. */ \
!defined __FreeBSD_version || __FreeBSD_version < 1200036 \
|| defined __i386) \
&& (/* NetBSD 6.0 (2012-10-17) and later has 64-bit time_t. */ \
!defined __NetBSD_Version__ || __NetBSD_Version__ < 600000000) \
&& (/* OpenBSD 5.5 (2014-05-01) and later has 64-bit time_t. */ \
!defined OpenBSD || OpenBSD < 201405)))
# define MKTIME_MIGHT_OVERFLOW true
# else
# define MKTIME_MIGHT_OVERFLOW false
# endif
#endif
/* Check that MKTIME_MIGHT_OVERFLOW is consistent with time_t's range. */
static_assert(MKTIME_MIGHT_OVERFLOW
|| MKTIME_FITS_IN(TIME_T_MIN, TIME_T_MAX));
/*
** 302 / 1000 is log10(2.0) rounded up.
** Subtract one for the sign bit if the type is signed;
@ -995,7 +946,7 @@ static_assert(MKTIME_MIGHT_OVERFLOW
/* strftime.c sometimes needs access to timeoff if it is not already public.
tz_private_timeoff should be used only by localtime.c and strftime.c. */
#if (!defined EXTERN_TIMEOFF && ! (defined USE_TIMEX_T && USE_TIMEX_T) \
#if (!defined EXTERN_TIMEOFF \
&& defined TM_GMTOFF && (200809 < _POSIX_VERSION || ! UNINIT_TRAP))
# ifndef timeoff
# define timeoff tz_private_timeoff

View File

@ -39,6 +39,55 @@
#include <locale.h>
#include <stdio.h>
/* If true, the value returned by an idealized unlimited-range mktime
always fits into an integer type with bounds MIN and MAX.
If false, the value might not fit.
This macro is usable in #if if its arguments are.
Add or subtract 2**31 - 1 for the maximum UT offset allowed in a TZif file,
divide by the maximum number of non-leap seconds in a year,
divide again by two just to be safe,
and account for the tm_year origin (1900) and time_t origin (1970). */
#define MKTIME_FITS_IN(min, max) \
((min) < 0 \
&& ((min) + 0x7fffffff) / 366 / 24 / 60 / 60 / 2 + 1970 - 1900 < INT_MIN \
&& INT_MAX < ((max) - 0x7fffffff) / 366 / 24 / 60 / 60 / 2 + 1970 - 1900)
/* MKTIME_MIGHT_OVERFLOW is true if mktime can fail due to time_t overflow
or if it is not known whether mktime can fail,
and is false if mktime definitely cannot fail.
This macro is usable in #if, and so does not use TIME_T_MAX or sizeof.
If the builder has not configured this macro, guess based on what
known platforms do. When in doubt, guess true. */
#ifndef MKTIME_MIGHT_OVERFLOW
# if defined __FreeBSD__ || defined __NetBSD__ || defined __OpenBSD__
# include <sys/param.h>
# endif
# if ((/* The following heuristics assume native time_t. */ \
defined_time_tz) \
|| ((/* Traditional time_t is 'long', so if 'long' is not wide enough \
assume overflow unless we're on a known-safe host. */ \
!MKTIME_FITS_IN(LONG_MIN, LONG_MAX)) \
&& (/* GNU C Library 2.29 (2019-02-01) and later has 64-bit time_t \
if __TIMESIZE is 64. */ \
!defined __TIMESIZE || __TIMESIZE < 64) \
&& (/* FreeBSD 12 r320347 (__FreeBSD_version 1200036; 2017-06-26), \
and later has 64-bit time_t on all platforms but i386 which \
is currently scheduled for end-of-life on 2028-11-30. */ \
!defined __FreeBSD_version || __FreeBSD_version < 1200036 \
|| defined __i386) \
&& (/* NetBSD 6.0 (2012-10-17) and later has 64-bit time_t. */ \
!defined __NetBSD_Version__ || __NetBSD_Version__ < 600000000) \
&& (/* OpenBSD 5.5 (2014-05-01) and later has 64-bit time_t. */ \
!defined OpenBSD || OpenBSD < 201405)))
# define MKTIME_MIGHT_OVERFLOW true
# else
# define MKTIME_MIGHT_OVERFLOW false
# endif
#endif
/* Check that MKTIME_MIGHT_OVERFLOW is consistent with time_t's range. */
static_assert(MKTIME_MIGHT_OVERFLOW
|| MKTIME_FITS_IN(TIME_T_MIN, TIME_T_MAX));
#if MKTIME_MIGHT_OVERFLOW
/* Do this after system includes as it redefines time_t, mktime, timeoff. */
# define USE_TIMEX_T true

View File

@ -150,12 +150,12 @@ class TDTestCase:
tdSql.query(f"select ts from {self.dbname}.d7")
tdSql.checkData(0, 0, "2021-07-01 19:05:00.000")
tdSql.error(f"insert into {self.dbname}.d21 using {self.dbname}.stb tags (1) values ('2021-07-01T00:00:00.000+12:10',1)")
tdSql.error(f"insert into {self.dbname}.d22 using {self.dbname}.stb tags (1) values ('2021-07-01T00:00:00.000-24:10',1)")
tdSql.error(f"insert into {self.dbname}.d23 using {self.dbname}.stb tags (1) values ('2021-07-01T00:00:00.000+12:10',1)")
tdSql.error(f"insert into {self.dbname}.d24 using {self.dbname}.stb tags (1) values ('2021-07-01T00:00:00.000-24:10',1)")
tdSql.error(f"insert into {self.dbname}.d24 using {self.dbname}.stb tags (1) values ('2021-07-01T00:00:00.000-24100',1)")
tdSql.error(f"insert into {self.dbname}.d24 using {self.dbname}.stb tags (1) values ('2021-07-01T00:00:00.000-1210',1)")
# tdSql.error(f"insert into {self.dbname}.d21 using {self.dbname}.stb tags (1) values ('2021-07-01T00:00:00.000+12:10',1)")
# tdSql.error(f"insert into {self.dbname}.d22 using {self.dbname}.stb tags (1) values ('2021-07-01T00:00:00.000-24:10',1)")
# tdSql.error(f"insert into {self.dbname}.d23 using {self.dbname}.stb tags (1) values ('2021-07-01T00:00:00.000+12:10',1)")
# tdSql.error(f"insert into {self.dbname}.d24 using {self.dbname}.stb tags (1) values ('2021-07-01T00:00:00.000-24:10',1)")
# tdSql.error(f"insert into {self.dbname}.d24 using {self.dbname}.stb tags (1) values ('2021-07-01T00:00:00.000-24100',1)")
# tdSql.error(f"insert into {self.dbname}.d24 using {self.dbname}.stb tags (1) values ('2021-07-01T00:00:00.000-1210',1)")
tdSql.execute(f'drop database {self.dbname}')
@ -192,8 +192,8 @@ class TDTestCase:
if tdSql.getData(i, 1).find(timezone) == -1:
tdLog.exit("show timezone:%s != %s"%(tdSql.getData(i, 1),timezone))
def run(self): # sourcery skip: extract-duplicate-method
# timezone = self.get_system_timezone()
timezone = "Asia/Shanghai"
timezone = self.get_system_timezone()
# timezone = "Asia/Shanghai"
self.timezone_check("show local variables", timezone)
self.timezone_check("show dnode 1 variables", timezone)