Skip to content

Commit

Permalink
feat!: do not get TZ info from server local env (#2905)
Browse files Browse the repository at this point in the history
* feat: do not get TZ info from server local env

Signed-off-by: Ruihang Xia <waynestxia@gmail.com>

* add sqlness case

Signed-off-by: Ruihang Xia <waynestxia@gmail.com>

* add empty line

Signed-off-by: Ruihang Xia <waynestxia@gmail.com>

* fix typo

Signed-off-by: Ruihang Xia <waynestxia@gmail.com>

---------

Signed-off-by: Ruihang Xia <waynestxia@gmail.com>
  • Loading branch information
waynexia authored Dec 12, 2023
1 parent 3463555 commit 0ce2b50
Show file tree
Hide file tree
Showing 5 changed files with 63 additions and 83 deletions.
96 changes: 15 additions & 81 deletions src/common/time/src/timestamp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,14 @@ use std::time::Duration;

use arrow::datatypes::TimeUnit as ArrowTimeUnit;
use chrono::{
DateTime, Days, LocalResult, Months, NaiveDate, NaiveDateTime, NaiveTime,
TimeZone as ChronoTimeZone, Utc,
DateTime, Days, Months, NaiveDate, NaiveDateTime, NaiveTime, TimeZone as ChronoTimeZone, Utc,
};
use serde::{Deserialize, Serialize};
use snafu::{OptionExt, ResultExt};

use crate::error::{ArithmeticOverflowSnafu, Error, ParseTimestampSnafu, TimestampOverflowSnafu};
use crate::timezone::TimeZone;
use crate::util::{div_ceil, format_utc_datetime, local_datetime_to_utc};
use crate::util::{div_ceil, format_utc_datetime};
use crate::{error, Interval};

/// Timestamp represents the value of units(seconds/milliseconds/microseconds/nanoseconds) elapsed
Expand Down Expand Up @@ -364,11 +363,11 @@ impl FromStr for Timestamp {
/// Supported format:
/// - `2022-09-20T14:16:43.012345Z` (Zulu timezone)
/// - `2022-09-20T14:16:43.012345+08:00` (Explicit offset)
/// - `2022-09-20T14:16:43.012345` (local timezone, with T)
/// - `2022-09-20T14:16:43` (local timezone, no fractional seconds, with T)
/// - `2022-09-20T14:16:43.012345` (Zulu timezone, with T)
/// - `2022-09-20T14:16:43` (Zulu timezone, no fractional seconds, with T)
/// - `2022-09-20 14:16:43.012345Z` (Zulu timezone, without T)
/// - `2022-09-20 14:16:43` (local timezone, without T)
/// - `2022-09-20 14:16:43.012345` (local timezone, without T)
/// - `2022-09-20 14:16:43` (Zulu timezone, without T)
/// - `2022-09-20 14:16:43.012345` (Zulu timezone, without T)
#[allow(deprecated)]
fn from_str(s: &str) -> Result<Self, Self::Err> {
// RFC3339 timestamp (with a T)
Expand Down Expand Up @@ -407,18 +406,13 @@ impl FromStr for Timestamp {
}

/// Converts the naive datetime (which has no specific timezone) to a
/// nanosecond epoch timestamp relative to UTC.
/// This code is copied from [arrow-datafusion](https://github.com/apache/arrow-datafusion/blob/arrow2/datafusion-physical-expr/src/arrow_temporal_util.rs#L137).
/// nanosecond epoch timestamp in UTC.
fn naive_datetime_to_timestamp(
s: &str,
datetime: NaiveDateTime,
) -> crate::error::Result<Timestamp> {
match local_datetime_to_utc(&datetime) {
LocalResult::None => ParseTimestampSnafu { raw: s }.fail(),
LocalResult::Single(utc) | LocalResult::Ambiguous(utc, _) => {
Timestamp::from_chrono_datetime(utc).context(ParseTimestampSnafu { raw: s })
}
}
Timestamp::from_chrono_datetime(Utc.from_utc_datetime(&datetime).naive_utc())
.context(ParseTimestampSnafu { raw: s })
}

impl From<i64> for Timestamp {
Expand Down Expand Up @@ -562,7 +556,6 @@ impl Hash for Timestamp {
mod tests {
use std::collections::hash_map::DefaultHasher;

use chrono::{Local, Offset};
use rand::Rng;
use serde_json::Value;

Expand Down Expand Up @@ -783,71 +776,11 @@ mod tests {
check_from_str("2020-09-08 13:42:29Z", "2020-09-08 13:42:29");
check_from_str("2020-09-08T13:42:29+08:00", "2020-09-08 05:42:29");

check_from_str(
"2020-09-08 13:42:29",
&NaiveDateTime::from_timestamp_opt(
1599572549
- Local
.timestamp_opt(0, 0)
.unwrap()
.offset()
.fix()
.local_minus_utc() as i64,
0,
)
.unwrap()
.to_string(),
);

check_from_str(
"2020-09-08T13:42:29",
&NaiveDateTime::from_timestamp_opt(
1599572549
- Local
.timestamp_opt(0, 0)
.unwrap()
.offset()
.fix()
.local_minus_utc() as i64,
0,
)
.unwrap()
.to_string(),
);
check_from_str("2020-09-08 13:42:29", "2020-09-08 13:42:29");

check_from_str(
"2020-09-08 13:42:29.042",
&NaiveDateTime::from_timestamp_opt(
1599572549
- Local
.timestamp_opt(0, 0)
.unwrap()
.offset()
.fix()
.local_minus_utc() as i64,
42000000,
)
.unwrap()
.to_string(),
);
check_from_str("2020-09-08 13:42:29.042Z", "2020-09-08 13:42:29.042");
check_from_str("2020-09-08 13:42:29.042+08:00", "2020-09-08 05:42:29.042");
check_from_str(
"2020-09-08T13:42:29.042",
&NaiveDateTime::from_timestamp_opt(
1599572549
- Local
.timestamp_opt(0, 0)
.unwrap()
.offset()
.fix()
.local_minus_utc() as i64,
42000000,
)
.unwrap()
.to_string(),
);
check_from_str("2020-09-08T13:42:29+08:00", "2020-09-08 05:42:29");

check_from_str(
"2020-09-08T13:42:29.0042+08:00",
"2020-09-08 05:42:29.004200",
Expand Down Expand Up @@ -1119,21 +1052,22 @@ mod tests {
assert_eq!(TimeUnit::Second, res.unit);
}

// $TZ doesn't take effort.
#[test]
fn test_parse_in_time_zone() {
std::env::set_var("TZ", "Asia/Shanghai");
assert_eq!(
Timestamp::new(0, TimeUnit::Nanosecond),
Timestamp::new(28800, TimeUnit::Second),
Timestamp::from_str("1970-01-01 08:00:00.000").unwrap()
);

assert_eq!(
Timestamp::new(0, TimeUnit::Second),
Timestamp::new(28800, TimeUnit::Second),
Timestamp::from_str("1970-01-01 08:00:00").unwrap()
);

assert_eq!(
Timestamp::new(0, TimeUnit::Second),
Timestamp::new(28800, TimeUnit::Second),
Timestamp::from_str(" 1970-01-01 08:00:00 ").unwrap()
);
}
Expand Down
8 changes: 7 additions & 1 deletion src/datatypes/src/types/date_type.rs
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ mod tests {

use super::*;

// $TZ doesn't take effort
#[test]
fn test_date_cast() {
std::env::set_var("TZ", "Asia/Shanghai");
Expand All @@ -113,9 +114,14 @@ mod tests {
let date = ConcreteDataType::date_datatype().try_cast(ts).unwrap();
assert_eq!(date, Value::Date(Date::from_str("2000-01-01").unwrap()));

// this case bind with local timezone.
// this case bind with Zulu timezone.
let ts = Value::Timestamp(Timestamp::from_str("2000-01-02 07:59:59").unwrap());
let date = ConcreteDataType::date_datatype().try_cast(ts).unwrap();
assert_eq!(date, Value::Date(Date::from_str("2000-01-02").unwrap()));

// while this case is offsetted to Asia/Shanghai.
let ts = Value::Timestamp(Timestamp::from_str("2000-01-02 07:59:59+08:00").unwrap());
let date = ConcreteDataType::date_datatype().try_cast(ts).unwrap();
assert_eq!(date, Value::Date(Date::from_str("2000-01-01").unwrap()));

// Int32 -> date
Expand Down
4 changes: 3 additions & 1 deletion src/datatypes/src/types/timestamp_type.rs
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,7 @@ mod tests {
);
}

// $TZ doesn't take effort
#[test]
fn test_timestamp_cast() {
std::env::set_var("TZ", "Asia/Shanghai");
Expand All @@ -235,7 +236,8 @@ mod tests {
let ts = ConcreteDataType::timestamp_second_datatype()
.try_cast(s)
.unwrap();
assert_eq!(ts, Value::Timestamp(Timestamp::new_second(1609434123)));
// 1609462923 is 2021-01-01T01:02:03Z
assert_eq!(ts, Value::Timestamp(Timestamp::new_second(1609462923)));
// String cast failed
let s = Value::String("12345".to_string().into());
let ts = ConcreteDataType::timestamp_second_datatype().try_cast(s);
Expand Down
28 changes: 28 additions & 0 deletions tests/cases/standalone/common/timestamp/timestamp.result
Original file line number Diff line number Diff line change
Expand Up @@ -82,3 +82,31 @@ DROP TABLE timestamp_with_precision;

Affected Rows: 0

CREATE TABLE plain_timestamp (ts TIMESTAMP TIME INDEX);

Affected Rows: 0

INSERT INTO plain_timestamp VALUES (1);

Affected Rows: 1

SELECT * FROM plain_timestamp;

+-------------------------+
| ts |
+-------------------------+
| 1970-01-01T00:00:00.001 |
+-------------------------+

SELECT * FROM plain_timestamp where ts = '1970-01-01 00:00:00.001000';

+-------------------------+
| ts |
+-------------------------+
| 1970-01-01T00:00:00.001 |
+-------------------------+

DROP TABLE plain_timestamp;

Affected Rows: 0

10 changes: 10 additions & 0 deletions tests/cases/standalone/common/timestamp/timestamp.sql
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,13 @@ INSERT INTO timestamp_with_precision(ts,cnt) VALUES ('2262-04-11 23:47:16.854775
SELECT * FROM timestamp_with_precision ORDER BY ts ASC;

DROP TABLE timestamp_with_precision;

CREATE TABLE plain_timestamp (ts TIMESTAMP TIME INDEX);

INSERT INTO plain_timestamp VALUES (1);

SELECT * FROM plain_timestamp;

SELECT * FROM plain_timestamp where ts = '1970-01-01 00:00:00.001000';

DROP TABLE plain_timestamp;

0 comments on commit 0ce2b50

Please sign in to comment.