Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: support set timezone in db #2992

Merged
merged 4 commits into from
Dec 27, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions config/frontend.example.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# Node running mode, see `standalone.example.toml`.
mode = "distributed"
# The default timezone of the server
# default_timezone = "UTC"

[heartbeat]
# Interval for sending heartbeat task to the Metasrv, 5 seconds by default.
Expand Down
2 changes: 2 additions & 0 deletions config/standalone.example.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
mode = "standalone"
# Whether to enable greptimedb telemetry, true by default.
enable_telemetry = true
# The default timezone of the server
# default_timezone = "UTC"

# HTTP server options.
[http]
Expand Down
1 change: 1 addition & 0 deletions src/cmd/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ common-recordbatch.workspace = true
common-telemetry = { workspace = true, features = [
"deadlock_detection",
] }
common-time.workspace = true
config = "0.13"
datanode.workspace = true
datatypes.workspace = true
Expand Down
7 changes: 7 additions & 0 deletions src/cmd/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,12 @@ pub enum Error {
source: common_meta::error::Error,
},

#[snafu(display("Failed to init default timezone"))]
InitTimezone {
location: Location,
source: common_time::error::Error,
},

#[snafu(display("Failed to start procedure manager"))]
StartProcedureManager {
location: Location,
Expand Down Expand Up @@ -268,6 +274,7 @@ impl ErrorExt for Error {
| Error::LoadLayeredConfig { .. }
| Error::IllegalConfig { .. }
| Error::InvalidReplCommand { .. }
| Error::InitTimezone { .. }
| Error::ConnectEtcd { .. }
| Error::NotDataFromOutput { .. }
| Error::CreateDir { .. }
Expand Down
5 changes: 4 additions & 1 deletion src/cmd/src/frontend.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ use client::client_manager::DatanodeClients;
use common_meta::heartbeat::handler::parse_mailbox_message::ParseMailboxMessageHandler;
use common_meta::heartbeat::handler::HandlerGroupExecutor;
use common_telemetry::logging;
use common_time::timezone::set_default_timezone;
use frontend::frontend::FrontendOptions;
use frontend::heartbeat::handler::invalidate_table_cache::InvalidateTableCacheHandler;
use frontend::heartbeat::HeartbeatTask;
Expand All @@ -32,7 +33,7 @@ use servers::tls::{TlsMode, TlsOption};
use servers::Mode;
use snafu::{OptionExt, ResultExt};

use crate::error::{self, MissingConfigSnafu, Result, StartFrontendSnafu};
use crate::error::{self, InitTimezoneSnafu, MissingConfigSnafu, Result, StartFrontendSnafu};
use crate::options::{CliOptions, Options};
use crate::App;

Expand Down Expand Up @@ -217,6 +218,8 @@ impl StartCommand {
logging::info!("Frontend start command: {:#?}", self);
logging::info!("Frontend options: {:#?}", opts);

set_default_timezone(opts.default_timezone.as_deref()).context(InitTimezoneSnafu)?;

let meta_client_options = opts.meta_client.as_ref().context(MissingConfigSnafu {
msg: "'meta_client'",
})?;
Expand Down
11 changes: 9 additions & 2 deletions src/cmd/src/standalone.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ use common_meta::wal::{WalOptionsAllocator, WalOptionsAllocatorRef};
use common_procedure::ProcedureManagerRef;
use common_telemetry::info;
use common_telemetry::logging::LoggingOptions;
use common_time::timezone::set_default_timezone;
use datanode::config::{DatanodeOptions, ProcedureConfig, RegionEngineConfig, StorageConfig};
use datanode::datanode::{Datanode, DatanodeBuilder};
use file_engine::config::EngineConfig as FileEngineConfig;
Expand All @@ -50,8 +51,8 @@ use servers::Mode;
use snafu::ResultExt;

use crate::error::{
CreateDirSnafu, IllegalConfigSnafu, InitDdlManagerSnafu, InitMetadataSnafu, Result,
ShutdownDatanodeSnafu, ShutdownFrontendSnafu, StartDatanodeSnafu, StartFrontendSnafu,
CreateDirSnafu, IllegalConfigSnafu, InitDdlManagerSnafu, InitMetadataSnafu, InitTimezoneSnafu,
Result, ShutdownDatanodeSnafu, ShutdownFrontendSnafu, StartDatanodeSnafu, StartFrontendSnafu,
StartProcedureManagerSnafu, StartWalOptionsAllocatorSnafu, StopProcedureManagerSnafu,
};
use crate::options::{CliOptions, MixOptions, Options};
Expand Down Expand Up @@ -97,6 +98,7 @@ impl SubCommand {
pub struct StandaloneOptions {
pub mode: Mode,
pub enable_telemetry: bool,
pub default_timezone: Option<String>,
pub http: HttpOptions,
pub grpc: GrpcOptions,
pub mysql: MysqlOptions,
Expand All @@ -120,6 +122,7 @@ impl Default for StandaloneOptions {
Self {
mode: Mode::Standalone,
enable_telemetry: true,
default_timezone: None,
http: HttpOptions::default(),
grpc: GrpcOptions::default(),
mysql: MysqlOptions::default(),
Expand All @@ -146,6 +149,7 @@ impl StandaloneOptions {
fn frontend_options(self) -> FrontendOptions {
FrontendOptions {
mode: self.mode,
default_timezone: self.default_timezone,
http: self.http,
grpc: self.grpc,
mysql: self.mysql,
Expand Down Expand Up @@ -366,6 +370,9 @@ impl StartCommand {

info!("Building standalone instance with {opts:#?}");

set_default_timezone(opts.frontend.default_timezone.as_deref())
.context(InitTimezoneSnafu)?;

// Ensure the data_home directory exists.
fs::create_dir_all(path::Path::new(&opts.data_home)).context(CreateDirSnafu {
dir: &opts.data_home,
Expand Down
1 change: 1 addition & 0 deletions src/common/time/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ chrono-tz = "0.8"
chrono.workspace = true
common-error.workspace = true
common-macro.workspace = true
once_cell.workspace = true
serde = { version = "1.0", features = ["derive"] }
serde_json.workspace = true
snafu.workspace = true
Expand Down
15 changes: 8 additions & 7 deletions src/common/time/src/datetime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ use chrono::{Days, LocalResult, Months, NaiveDateTime, TimeZone as ChronoTimeZon
use serde::{Deserialize, Serialize};

use crate::error::{Error, InvalidDateStrSnafu, Result};
use crate::timezone::TimeZone;
use crate::timezone::Timezone;
use crate::util::{format_utc_datetime, local_datetime_to_utc};
use crate::{Date, Interval};

Expand Down Expand Up @@ -110,11 +110,11 @@ impl DateTime {
NaiveDateTime::from_timestamp_millis(self.0)
}

pub fn to_chrono_datetime_with_timezone(&self, tz: Option<TimeZone>) -> Option<NaiveDateTime> {
pub fn to_chrono_datetime_with_timezone(&self, tz: Option<Timezone>) -> Option<NaiveDateTime> {
let datetime = self.to_chrono_datetime();
datetime.map(|v| match tz {
Some(TimeZone::Offset(offset)) => offset.from_utc_datetime(&v).naive_local(),
Some(TimeZone::Named(tz)) => tz.from_utc_datetime(&v).naive_local(),
Some(Timezone::Offset(offset)) => offset.from_utc_datetime(&v).naive_local(),
Some(Timezone::Named(tz)) => tz.from_utc_datetime(&v).naive_local(),
None => Utc.from_utc_datetime(&v).naive_local(),
})
}
Expand Down Expand Up @@ -155,18 +155,19 @@ impl DateTime {
#[cfg(test)]
mod tests {
use super::*;
use crate::timezone::set_default_timezone;

#[test]
pub fn test_new_date_time() {
std::env::set_var("TZ", "Asia/Shanghai");
set_default_timezone(Some("Asia/Shanghai")).unwrap();
assert_eq!("1970-01-01 08:00:00+0800", DateTime::new(0).to_string());
assert_eq!("1970-01-01 08:00:01+0800", DateTime::new(1000).to_string());
assert_eq!("1970-01-01 07:59:59+0800", DateTime::new(-1000).to_string());
}

#[test]
pub fn test_parse_from_string() {
std::env::set_var("TZ", "Asia/Shanghai");
set_default_timezone(Some("Asia/Shanghai")).unwrap();
let time = "1970-01-01 00:00:00+0800";
let dt = DateTime::from_str(time).unwrap();
assert_eq!(time, &dt.to_string());
Expand Down Expand Up @@ -194,7 +195,7 @@ mod tests {

#[test]
fn test_parse_local_date_time() {
std::env::set_var("TZ", "Asia/Shanghai");
set_default_timezone(Some("Asia/Shanghai")).unwrap();
assert_eq!(
-28800000,
DateTime::from_str("1970-01-01 00:00:00").unwrap().val()
Expand Down
16 changes: 8 additions & 8 deletions src/common/time/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,8 @@ pub enum Error {
#[snafu(display("Timestamp arithmetic overflow, msg: {}", msg))]
ArithmeticOverflow { msg: String, location: Location },

#[snafu(display("Invalid time zone offset: {hours}:{minutes}"))]
InvalidTimeZoneOffset {
#[snafu(display("Invalid timezone offset: {hours}:{minutes}"))]
InvalidTimezoneOffset {
hours: i32,
minutes: u32,
location: Location,
Expand All @@ -66,18 +66,18 @@ pub enum Error {
location: Location,
},

#[snafu(display("Invalid time zone string {raw}"))]
ParseTimeZoneName { raw: String, location: Location },
#[snafu(display("Invalid timezone string {raw}"))]
ParseTimezoneName { raw: String, location: Location },
}

impl ErrorExt for Error {
fn status_code(&self) -> StatusCode {
match self {
Error::ParseDateStr { .. }
| Error::ParseTimestamp { .. }
| Error::InvalidTimeZoneOffset { .. }
| Error::InvalidTimezoneOffset { .. }
| Error::ParseOffsetStr { .. }
| Error::ParseTimeZoneName { .. } => StatusCode::InvalidArguments,
| Error::ParseTimezoneName { .. } => StatusCode::InvalidArguments,
Error::TimestampOverflow { .. } => StatusCode::Internal,
Error::InvalidDateStr { .. } | Error::ArithmeticOverflow { .. } => {
StatusCode::InvalidArguments
Expand All @@ -96,9 +96,9 @@ impl ErrorExt for Error {
| Error::TimestampOverflow { location, .. }
| Error::ArithmeticOverflow { location, .. } => Some(*location),
Error::ParseDateStr { .. }
| Error::InvalidTimeZoneOffset { .. }
| Error::InvalidTimezoneOffset { .. }
| Error::ParseOffsetStr { .. }
| Error::ParseTimeZoneName { .. } => None,
| Error::ParseTimezoneName { .. } => None,
Error::InvalidDateStr { location, .. } => Some(*location),
Error::ParseInterval { location, .. } => Some(*location),
}
Expand Down
2 changes: 1 addition & 1 deletion src/common/time/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,4 @@ pub use interval::Interval;
pub use range::RangeMillis;
pub use timestamp::Timestamp;
pub use timestamp_millis::TimestampMillis;
pub use timezone::TimeZone;
pub use timezone::Timezone;
Loading
Loading