summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ydb/tests/compatibility/test_datetime2.py258
1 files changed, 226 insertions, 32 deletions
diff --git a/ydb/tests/compatibility/test_datetime2.py b/ydb/tests/compatibility/test_datetime2.py
index 986aec3638e..d8269e75171 100644
--- a/ydb/tests/compatibility/test_datetime2.py
+++ b/ydb/tests/compatibility/test_datetime2.py
@@ -3,51 +3,245 @@ import pytest
from ydb.tests.library.compatibility.fixtures import MixedClusterFixture
from ydb.tests.oss.ydb_sdk_import import ydb
-from datetime import datetime, timedelta
+from datetime import datetime, timedelta, timezone
+import random
-class TestDatetime2Format(MixedClusterFixture):
+class TestDatetime2(MixedClusterFixture):
+ rows = 100
+ table_name = 'datetime_test'
+
@pytest.fixture(autouse=True, scope="function")
def setup(self):
yield from self.setup_cluster()
- def test_simple(self):
+ def generate_insert(self):
+ header = (
+ f"UPSERT INTO {self.table_name} "
+ "(id, d, dt, ts, val, rfc822_str, iso8601_str, http_str, x509_str) VALUES\n"
+ )
+
+ rows = []
+ base_dt = datetime(2000, 1, 1, 12, 0, 0, tzinfo=timezone.utc)
+
+ for i in range(1, self.rows + 1):
+ delta = timedelta(days=random.randint(0, 10000), seconds=random.randint(0, 86400))
+ dt = base_dt + delta
+ dt_utc = dt.astimezone(timezone.utc)
+ ts_micro = dt_utc.replace(microsecond=random.randint(0, 999999))
+ val = random.randint(0, 32767)
+
+ rfc822 = dt.strftime("%a, %-d %b %Y %H:%M:%S EST")
+ iso8601 = dt.strftime("%Y-%m-%dT%H:%M:%S+0300")
+ http = dt.strftime("%A, %d-%b-%y %H:%M:%S GMT")
+ x509 = dt.strftime("%Y%m%d%H%M%SZ")
+
+ row = f"""(
+ {i},
+ Date("{dt_utc.date()}"),
+ Datetime("{dt_utc.strftime("%Y-%m-%dT%H:%M:%SZ")}"),
+ Timestamp("{ts_micro.strftime("%Y-%m-%dT%H:%M:%S.%fZ")}"),
+ {val},
+ "{rfc822}",
+ "{iso8601}",
+ "{http}",
+ "{x509}"
+ )"""
+ rows.append(row)
+
+ return header + ",\n".join(rows) + ";"
+
+ def generate_create_table(self):
+ return f"""
+ CREATE TABLE {self.table_name} (
+ id Uint32,
+ d Date,
+ dt Datetime,
+ ts Timestamp,
+ val Int16,
+
+ rfc822_str String,
+ iso8601_str String,
+ http_str String,
+ x509_str String,
+
+ PRIMARY KEY(id)
+ ) WITH (
+ PARTITION_AT_KEYS = ({", ".join(str(i) for i in range(1, self.rows))})
+ );
+ """
+
+ def q_split(self):
+ return f"""
+ SELECT
+ DateTime::MakeDate(DateTime::Split(d)),
+ DateTime::MakeDate(DateTime::Split(dt)),
+ DateTime::MakeDate(DateTime::Split(ts)),
+ DateTime::MakeDate(DateTime::Split(AddTimezone(d, "Europe/Moscow"))),
+ DateTime::MakeDate(DateTime::Split(AddTimezone(dt, "Europe/Moscow"))),
+ DateTime::MakeDate(DateTime::Split(AddTimezone(ts, "Europe/Moscow")))
+ FROM {self.table_name};
+ """
+
+ def q_make(self):
+ table_name = 'datetime_test'
+ return f"""
+ SELECT
+ DateTime::MakeDate(DateTime::Split(d)),
+ DateTime::MakeDatetime(DateTime::Split(d)),
+ DateTime::MakeTimestamp(DateTime::Split(d)),
+
+ -- added DateTime::MakeDate(DateTime::Split( because python sdk doesn't support Tz
+ DateTime::MakeDate(DateTime::Split(DateTime::MakeTzDate(DateTime::Split(d)))),
+ DateTime::MakeDate(DateTime::Split(DateTime::MakeTzDatetime(DateTime::Split(d)))),
+ DateTime::MakeDate(DateTime::Split(DateTime::MakeTzTimestamp(DateTime::Split(d))))
+ FROM `{table_name}`;
+ """
+
+ def q_get(self):
+ return f"""
+ SELECT
+ DateTime::GetYear(DateTime::Split(d)),
+ DateTime::GetDayOfYear(DateTime::Split(d)),
+ DateTime::GetMonth(DateTime::Split(d)),
+ DateTime::GetMonthName(DateTime::Split(d)),
+ DateTime::GetWeekOfYear(DateTime::Split(d)),
+ DateTime::GetWeekOfYearIso8601(DateTime::Split(d)),
+ DateTime::GetDayOfMonth(DateTime::Split(d)),
+ DateTime::GetDayOfWeek(DateTime::Split(d)),
+ DateTime::GetDayOfWeekName(DateTime::Split(d)),
+ DateTime::GetHour(DateTime::Split(d)),
+ DateTime::GetMinute(DateTime::Split(d)),
+ DateTime::GetSecond(DateTime::Split(d)),
+ DateTime::GetMillisecondOfSecond(DateTime::Split(d)),
+ DateTime::GetMicrosecondOfSecond(DateTime::Split(d)),
+ DateTime::GetTimezoneId(DateTime::Split(d)),
+ DateTime::GetTimezoneName(DateTime::Split(d))
+ FROM {self.table_name};
+ """
+
+ def q_update(self):
+ return f"""
+ SELECT
+ DateTime::MakeDate(DateTime::Update(DateTime::Split(d), 2005))
+ FROM {self.table_name};
+ """
+ def q_to_from(self):
+ return f"""
+ SELECT
+ DateTime::FromSeconds(DateTime::ToSeconds(DateTime::MakeDate(DateTime::Split(d)))),
+ DateTime::FromSeconds(DateTime::ToSeconds(DateTime::MakeDatetime(DateTime::Split(d)))),
+ DateTime::FromSeconds(DateTime::ToSeconds(DateTime::MakeTimestamp(DateTime::Split(d)))),
+ DateTime::FromSeconds(DateTime::ToSeconds(DateTime::MakeTzDate(DateTime::Split(d)))),
+ DateTime::FromSeconds(DateTime::ToSeconds(DateTime::MakeTzDatetime(DateTime::Split(d)))),
+ DateTime::FromSeconds(DateTime::ToSeconds(DateTime::MakeTzTimestamp(DateTime::Split(d)))),
+
+ DateTime::FromMilliseconds(DateTime::ToMilliseconds(DateTime::MakeDate(DateTime::Split(d)))),
+ DateTime::FromMilliseconds(DateTime::ToMilliseconds(DateTime::MakeDatetime(DateTime::Split(d)))),
+ DateTime::FromMilliseconds(DateTime::ToMilliseconds(DateTime::MakeTimestamp(DateTime::Split(d)))),
+ DateTime::FromMilliseconds(DateTime::ToMilliseconds(DateTime::MakeTzDate(DateTime::Split(d)))),
+ DateTime::FromMilliseconds(DateTime::ToMilliseconds(DateTime::MakeTzDatetime(DateTime::Split(d)))),
+ DateTime::FromMilliseconds(DateTime::ToMilliseconds(DateTime::MakeTzTimestamp(DateTime::Split(d)))),
+
+ DateTime::FromMicroseconds(DateTime::ToMicroseconds(DateTime::MakeDate(DateTime::Split(d)))),
+ DateTime::FromMicroseconds(DateTime::ToMicroseconds(DateTime::MakeDatetime(DateTime::Split(d)))),
+ DateTime::FromMicroseconds(DateTime::ToMicroseconds(DateTime::MakeTimestamp(DateTime::Split(d)))),
+ DateTime::FromMicroseconds(DateTime::ToMicroseconds(DateTime::MakeTzDate(DateTime::Split(d)))),
+ DateTime::FromMicroseconds(DateTime::ToMicroseconds(DateTime::MakeTzDatetime(DateTime::Split(d)))),
+ DateTime::FromMicroseconds(DateTime::ToMicroseconds(DateTime::MakeTzTimestamp(DateTime::Split(d))))
+ FROM {self.table_name};
+ """
+
+ def q_interval(self):
+ return f"""
+ SELECT
+ DateTime::IntervalFromDays(val),
+ DateTime::IntervalFromHours(val),
+ DateTime::IntervalFromMinutes(val),
+ DateTime::IntervalFromSeconds(val),
+ DateTime::IntervalFromMilliseconds(val),
+ DateTime::IntervalFromMicroseconds(val),
+
+ DateTime::ToDays(DateTime::IntervalFromDays(val)),
+ DateTime::ToHours(DateTime::IntervalFromDays(val)),
+ DateTime::ToMinutes(DateTime::IntervalFromDays(val)),
+ DateTime::ToSeconds(DateTime::IntervalFromDays(val)),
+ DateTime::ToMilliseconds(DateTime::IntervalFromDays(val)),
+ DateTime::ToMicroseconds(DateTime::IntervalFromDays(val))
+ FROM {self.table_name};
+ """
+
+ def q_start_end(self):
+ return f"""
+ SELECT
+ DateTime::MakeDate(DateTime::StartOfYear(DateTime::Split(d))),
+ DateTime::MakeDate(DateTime::EndOfYear(DateTime::Split(d))),
+ DateTime::MakeDate(DateTime::StartOfQuarter(DateTime::Split(d))),
+ DateTime::MakeDate(DateTime::EndOfQuarter(DateTime::Split(d))),
+ DateTime::MakeDate(DateTime::StartOfMonth(DateTime::Split(d))),
+ DateTime::MakeDate(DateTime::EndOfMonth(DateTime::Split(d))),
+ DateTime::MakeDate(DateTime::StartOfWeek(DateTime::Split(d))),
+ DateTime::MakeDate(DateTime::EndOfWeek(DateTime::Split(d))),
+ DateTime::MakeDate(DateTime::StartOfDay(DateTime::Split(d))),
+ DateTime::MakeDate(DateTime::EndOfDay(DateTime::Split(d))),
+ DateTime::MakeDate(DateTime::StartOf(DateTime::Split(d), DateTime::IntervalFromDays(val))),
+ DateTime::MakeDate(DateTime::EndOf(DateTime::Split(d), DateTime::IntervalFromDays(val)))
+ FROM {self.table_name};
+ """
+
+ def q_shift(self):
+ return f"""
+ SELECT
+ DateTime::MakeDate(DateTime::ShiftYears(DateTime::Split(d), 1)),
+ DateTime::MakeDate(DateTime::ShiftQuarters(DateTime::Split(d), 1)),
+ DateTime::MakeDate(DateTime::ShiftMonths(DateTime::Split(d), 1))
+ FROM {self.table_name};
+ """
+
+ def q_format(self):
+ return f"""
+ SELECT
+ DateTime::Format('%Y-%m-%d')(d)
+ FROM {self.table_name};
+ """
+
+ def q_parse(self):
+ return f"""
+ SELECT
+ DateTime::MakeDate(DateTime::ParseRfc822(rfc822_str)),
+ DateTime::MakeDate(DateTime::ParseIso8601(iso8601_str)),
+ DateTime::MakeDate(DateTime::ParseHttp(http_str)),
+ DateTime::MakeDate(DateTime::ParseX509(x509_str)),
+ DateTime::MakeDate(DateTime::Parse("%Y-%m-%dT%H:%M:%S")(iso8601_str))
+ FROM {self.table_name};
+ """
+
+ def test_all(self):
with ydb.QuerySessionPool(self.driver) as session_pool:
- rows = 100
- table_name = 'dates_table'
# ---------------- CREATE TABLE ------------------
- query = f"""
- CREATE TABLE {table_name} (
- id Uint32,
- event_date DateTime,
- PRIMARY KEY (id)
- ) WITH (
- PARTITION_AT_KEYS = ({", ".join(str(i) for i in range(1, rows))})
- );
- """
+ query = self.generate_create_table()
session_pool.execute_with_retries(query)
# ---------------- INSERT ------------------
- start_date = datetime(2023, 1, 1)
- values = []
-
- for i in range(1, rows):
- date = (start_date + timedelta(days=i - 1)).strftime("%Y-%m-%dT%H:%M:%SZ")
- values.append(f"({i}, CAST(\"{date}\" AS DateTime))")
-
- query = f"""
- UPSERT INTO {table_name} (id, event_date) VALUES {",\n ".join(values)};
- """
-
+ query = self.generate_insert()
session_pool.execute_with_retries(query)
# ---------------- SELECT ------------------
- query = f"""
- SELECT
- DateTime::Format('%Y-%m-%d')(event_date) as date
- FROM {table_name} order by date;
- """
- result_sets = session_pool.execute_with_retries(query)
- assert result_sets[0].rows[0]['date'] == b'2023-01-01'
+ queries = [
+ self.q_split(),
+ self.q_make(),
+ self.q_get(),
+ self.q_update(),
+ self.q_to_from(),
+ self.q_interval(),
+ self.q_start_end(),
+ self.q_shift(),
+ self.q_format(),
+ self.q_parse()
+ ]
+
+ for query in queries:
+ result = session_pool.execute_with_retries(query)
+ assert len(result[0].rows) > 0