メインコンテンツまでスキップ
に最終更新

TIMESTAMPTZ

説明​

TIMESTAMPTZ は、タイムゾーンを認識して日付と時刻の情報を格納するために Doris で使用されるデータ型であり、標準 SQL の TIMESTAMP WITH TIME ZONE に対応します。

データベースシステムによって、タイムゾーン対応のタイムスタンプ型にはさまざまな命名規則があります。

  • PostgreSQL と Oracle は TIMESTAMP WITH TIME ZONE を使用します
  • SQL Server は DATETIMEOFFSET を使用します
  • その他の一部のデータベースは TIMESTAMP WITH LOCAL TIME ZONE を使用します

SQL 標準では、単独の TIMESTAMP 型にタイムゾーン情報を付けるべきではありません(TIMESTAMP WITHOUT TIME ZONE と同等です)。ユーザーの慣習と使いやすさを考慮し、Doris では、タイムゾーン付きのタイムスタンプ型を表す名前として、より簡潔な TIMESTAMPTZ を採用しています。現在、Doris には独立した TIMESTAMP 型がないことに注意してください。ユーザーは DATETIME を使用して時刻情報を実質的に格納できます。

TIMESTAMPTZ の範囲は DATETIME と同じで、[0000-01-01 00:00:00.000000, 9999-12-31 23:59:59.999999] です。 TIMESTAMPTZ では、TIMESTAMPTZ(p) 形式で精度を指定できます。p は精度を表し、範囲は [0, 6]、デフォルト値は 0 です。つまり、TIMESTAMPTZ は TIMESTAMPTZ(0) と同等です。デフォルトの出力形式は 'yyyy-MM-dd HH:mm:ss.SSSSSS +XX:XX' です。ここで、+XX:XX はタイムゾーンオフセットを表します(SSSSSS の桁数は精度 p によって決まります)。

TIMESTAMPTZ 型は、主キー、パーティション列、バケット列として使用できます。

動作原理​

TIMESTAMPTZ の実装では、各データ行にタイムゾーン情報を格納せず、次の仕組みを採用しています。

  1. 保存時:入力された時刻値を UTC(協定世界時)に変換します。
  2. クエリ時:セッションのタイムゾーン設定(time_zone 変数で指定)に基づいて、UTC 時刻を表示用の対応するタイムゾーンへ自動的に変換します。

したがって、TIMESTAMPTZ はタイムゾーン変換機能を備えた DATETIME 型と考えることができ、Doris が内部でタイムゾーン変換を自動的に処理します。

タイムゾーン処理ルール​

  • 入力文字列にタイムゾーン情報(例:"2020-01-01 00:00:00 +03:00")が含まれている場合、Doris はそのタイムゾーン情報を使用して変換します。
  • 入力文字列にタイムゾーン情報(例:"2020-01-01 00:00:00")が含まれていない場合、Doris は現在のセッションのタイムゾーン設定を使用して変換します。

4.1.5 以降、出力では、秒精度を持つ過去の IANA タイムゾーンオフセットが +HH:MM:SS として保持されます。入力タイムスタンプの数値オフセットには、固定セッションオフセットとは異なる制約があります。入力値の時は 24 未満、分と秒は 60 未満でなければなりません。固定セッションオフセットは引き続き -12:00 から +14:00 に制限されます。変換後のローカル年が 0 から 9999 の範囲外になる場合、セッションタイムゾーンへの変換は失敗します。

4.1.5 以降、Catalog は外部のタイムゾーン対応タイムスタンプ型を常に TIMESTAMPTZ にマッピングします。互換性プロパティ enable.mapping.timestamp_tz=false を設定しても、以前の DATETIME マッピングには戻せません。Arrow Flight SQL は、タイムゾーン注釈付きの Arrow Timestamp 値として時点を伝送します。クエリスキーマではセッションタイムゾーンを使用します(Z は UTC に正規化されます)。DATETIME ではタイムゾーン注釈のない Timestamp を使用します。

ストレージと使用方法​

Doris では、TIMESTAMPTZ 型のフィールドは 8 バイトのストレージ領域を使用します。

TIMESTAMPTZ 型と DATETIME 型は相互変換をサポートし、変換中にタイムゾーンに応じた適切な調整が行われます。TIMESTAMPTZ は DATETIME への暗黙的な変換をサポートするため、TIMESTAMPTZ を直接サポートしていない関数でもこの種類のデータを処理できます。

例​

-- Using the current time zone (assuming +08:00) to convert a time string without time zone information
select cast("2020-01-01 00:00:00" as timestamptz);
+--------------------------------------------+
| cast("2020-01-01 00:00:00" as timestamptz) |
+--------------------------------------------+
| 2020-01-01 00:00:00 +08:00 |
+--------------------------------------------+
-- TIMESTAMPTZ supports microseconds
select cast("2020-01-01 00:00:00.123456" as timestamptz(5));
+------------------------------------------------------+
| cast("2020-01-01 00:00:00.123456" as timestamptz(5)) |
+------------------------------------------------------+
| 2020-01-01 00:00:00.12345 +08:00 |
+------------------------------------------------------+
-- Using a time string with time zone information
select cast("2020-01-01 00:00:00 +03:00" as timestamptz);
+---------------------------------------------------+
| cast("2020-01-01 00:00:00 +03:00" as timestamptz) |
+---------------------------------------------------+
| 2020-01-01 05:00:00 +08:00 |
+---------------------------------------------------+
-- Converting TIMESTAMPTZ to DATETIME (with time zone conversion based on current time zone)
select cast(cast("2020-01-01 00:00:00 +03:00" as timestamptz) as datetime);
+---------------------------------------------------------------------+
| cast(cast("2020-01-01 00:00:00 +03:00" as timestamptz) as datetime) |
+---------------------------------------------------------------------+
| 2020-01-01 05:00:00 |
+---------------------------------------------------------------------+
-- Converting DATETIME to TIMESTAMPTZ
select cast(cast('2023-01-02 01:00:00' as datetime) as timestamptz);
+--------------------------------------------------------------+
| cast(cast('2023-01-02 01:00:00' as datetime) as timestamptz) |
+--------------------------------------------------------------+
| 2023-01-02 01:00:00 +08:00 |
+--------------------------------------------------------------+
-- Using TIMESTAMPTZ in functions
select HOUR(cast("2020-01-01 00:00:00 +03:00" as timestamptz));
+---------------------------------------------------------+
| HOUR(cast("2020-01-01 00:00:00 +03:00" as timestamptz)) |
+---------------------------------------------------------+
| 5 |
+---------------------------------------------------------+