S-JIS[2023-10-09/2025-03-17]

Tsurugiデータ型

TsurugiSQLのデータ型のメモ。


概要

TsurugiのSQLのデータ型は、TsubakuroではAtomType、IceaxeではTgDataTypeという列挙型で表す。
SQLのデータ型では桁数や精度(例:char(10))があるが、AtomTypeやTgDataTypeでは桁数や精度は持たない。

SQLデータ型 リテラルの例 TsubakuroのAtomType IceaxeのTgDataType
boolean true
false
1.0.0-BETA1 BOOLEAN BOOLEAN
unknown 1.0.0-BETA3
tinyint        
smallint        
int 123 1.0.0-BETA1 INT4 INT
bigint 123 1.0.0-BETA1 INT8 LONG
real 123.4e0 1.0.0-BETA5 FLOAT4 FLOAT
double 123.4e0 1.0.0-BETA5 FLOAT8 DOUBLE
decimal(p,s) 123.4 1.0.0-BETA5 DECIMAL DECIMAL
char(n)
varchar(n)
'abc' 1.0.0-BETA1 CHARACTER STRING
binary(n)
varbinary(n)
X'1234' 1.0.0-BETA6 OCTET BYTES
      BIT BITS
date date'2024-08-16' 1.0.0-BETA6 DATE DATE
time time'23:59:59' 1.0.0-BETA6 TIME_OF_DAY TIME
timestamp timestamp'2024-08-16 23:59:59' 1.0.0-BETA6 TIME_POINT DATE_TIME
time with time zone     TIME_OF_DAY_WITH_TIME_ZONE OFFSET_TIME
timestamp with time zone timestamp with time zone'2024-08-16 23:59:59+09:00' 1.0.0-BETA6 TIME_POINT_WITH_TIME_ZONE OFFSET_DATE_TIME
ZONED_DATE_TIME
interval     DATETIME_INTERVAL  
clob 'abc' 1.3.0 CLOB CLOB
blob X'1234' 1.3.0 BLOB BLOB
array        
row        

Tsurugi 1.0.0時点ではまだ対応していないデータ型がある。

リテラルが実装されていないデータ型もあり、そのカラムにはTsurugi SQLコンソールのinsert文ではデータを入れられないが、
TsubakuroIceaxeが対応しているデータ型なら、TsubakuroのプレースホルダーやIceaxeのバインド変数を使ったinsert文、あるいはembulk-output-tsurugidbで値を入れることが出来る。


boolean

真偽値を表すのがboolean型。[2024-08-16]

create tableのデータ型としてはまだ使用できない。

booleanのリテラルとしてはtrue, false, unknownがある。

nullとの比較演算を行うと、結果はunknownになる。
unknownはTsurugiでの値としてはnullである。(表示上はnullになる)
unknownは条件(whereやhaving)で使われるとfalseとして扱われる。

tgsql> select 1 = null from test;
[@#0: BOOLEAN]
[null]
(1 row)

tgsql> select 1 from test where 1 = null;
[@#0: INT8]
(0 rows)
tgsql> select unknown from test;
[@#0: BOOLEAN]
[null]
(1 row)

tgsql> select 1 from test where unknown;
[@#0: INT8]
(0 rows)
tgsql> select 1=null is true, 1=null is false, 1=null is unknown, 1=null is null from test;
[@#0: BOOLEAN, @#1: BOOLEAN, @#2: BOOLEAN, @#3: BOOLEAN]
[false, false, true, true]
(1 row)

tgsql> select unknown is true, unknown is false, unknown is unknown, unknown is null from test;
[@#0: BOOLEAN, @#1: BOOLEAN, @#2: BOOLEAN, @#3: BOOLEAN]
[false, false, true, true]
(1 row)

tgsql> select null is true, null is false, null is unknown, null is null from test;
[@#0: BOOLEAN, @#1: BOOLEAN, @#2: BOOLEAN, @#3: BOOLEAN]
[false, false, true, true]
(1 row)

char・varchar

Tsurugi 1.0.0-BETA1では、charやvarcharに指定する桁数は、文字数ではなくバイト数。
insertやupdateする際は、UTF-8に変換されて格納される。

現時点の制限事項として、NUL文字(文字コード0)は格納できない。[2024-08-18]


ちなみに、世間では空文字列をnullとして扱うRDBMSもあるようだが、Tsurugiでは空文字列とnullは別物。[2024-08-18]

tgsql> select '' is null from test;
[@#0: BOOLEAN]
[false]
(1 row)

decimal

Tsurugi 1.0.0-BETA5で、123.4といった数値はdecimalで扱えるようになった。[2024-07-11]

insert文やupdate文では、decimalの桁数を超える値を入れようとするとエラーになる。[2024-09-05]
decimalへのキャストの場合、そのdecimalの上限値(decimalに入れられる最大値・最小値)に丸められる。
(charやvarcharで、桁数を超える値をinsert文やupdate文で入れようとするとエラーになるが、キャストすると末尾が切り捨てられる。decimalでも似たような考え方か)


Tsurugi 1.0.0-BETA4以前では、decimalを使ったテーブルは作成できるが、リテラルが実装されていなかった。
ただし、文字列からdecimalへのキャストは実装されているので、それで代用できる。

create table decimal_table (value decimal(15, 2));
×Tsurugi 1.0.0-BETA1ではエラーになる
tgsql> insert into decimal_table values(123.4);
VALUE_EVALUATION_EXCEPTION (SQL-02011: An error occurred in evaluating values. type mismatch: expected decimal(15, 2), value index is 7)
insert into decimal_table values(cast('123.4' as decimal(15, 2)));

double・float

Tsurugi 1.0.0-BETA4で、NaN=NaNがtrueになるよう変更された。[2024-04-11]
(それより前はJavaと同じく、NaN=NaNはfalseだった)

プライマリキーのデータ型がdoubleやfloatだった場合、NaNがNaNと一致しないとプライマリキーNaNのデータが複数入れることが出来てしまうため、一般的な言語の仕様とは違うが、NaN同士が等しいものとして扱う仕様にしたらしい。

Tsurugi 1.0.0-BETA5で、1e2、1e-2、1.0e0 といった指数表記が使えるようになった。[2024-07-11]


日時型

日時系のデータ型はいくつか存在する。[2024-08-16]

日時系のデータ型 説明 日時系のリテラルの例 Java相当
date 年月日(日付) date'2024-08-16' 1.0.0-BETA6 LocalDate
time 時分秒・ナノ秒(時刻) time'23:59:59' 1.0.0-BETA6 LocalTime
timestamp 年月日・時分秒・ナノ秒 timestamp'2024-08-16 23:59:59' 1.0.0-BETA6 LocalDateTime
time with time zone タイムゾーンオフセット付きtime     OffsetTime
timestamp with time zone タイムゾーンオフセット付きtimestamp timestamp with time zone'2024-08-16 23:59:59+09:00' 1.0.0-BETA6 OffsetDateTime

日時型のリテラルについて

Tsurugi内部では、日時系データの「年」は0や負の数も保持できる。
TsubakuroのプレースホルダーやIceaxeのバインド変数で入れることが可能)

しかしリテラルでは、「年」は1以上しか指定できない。


タイムゾーンオフセットについて

with time zoneのデータ型のカラムに対してinsertやupdateで値を登録すると、Tsurugi内部ではUTCに変換されて保持される。
(「Asia/Tokyo」等のタイムゾーン情報は保持されない。そもそも指定することも出来ない)

with time zoneのデータ型の値を取得する際は、セッション(接続)に設定されているタイムゾーンオフセットに変換されて返ってくる。
(つまり、insertやupdateした値とは異なるタイムゾーンオフセットで返ってくる場合がある)


ただし、セッションに対して(動的に)タイムゾーンオフセットを設定することはまだ出来ない。

タイムゾーンオフセットのデフォルト値は構成定義ファイルで指定する。

$TSURUGI_HOME/var/etc/tsurugi.ini:

[session]
    zone_offset=+09:00

現在日時取得関数について

日時系のデータ型ごとに、現在日時を返す関数が提供されている。

現在日時取得関数


binary・varbinary

バイト列を保持するデータ型がbinaryおよびvarbinary。[2024-08-16]
Tsurugi 1.0.0-BETA6から使用可能。

(char/varcharと同様に)binaryは固定長で、varbinaryは可変長。
binaryで指定された桁数に満たない場合は、末尾が00で埋められる。


binary/varbinaryのリテラルは「X'十六進数'」形式。

tgsql> create table bin (
     |   pk int primary key,
     |   value varbinary(16)
     | );
execute succeeded

tgsql> insert into bin values(1, X'1234abcd');
(1 row inserted)

tgsql> select * from bin;
[pk: INT4, value: OCTET]
[1, 1234abcd]
(1 row)

文字列からbinary/varbinaryに変換することも出来る。

tgsql> insert into bin values(2, cast('0123cdef' as varbinary));
(1 row inserted)

tgsql> insert into bin values(3, cast('0123cdef' as varbinary(16)));
(1 row inserted)

blob・clob

大きなサイズのバイト列を保持するデータ型がBLOB、大きなサイズの文字列がCLOB。[2025-03-17]
Tsurugi 1.3.0から使用可能。

BLOB・CLOBは大きなサイズのデータなので、(TsurugiはインメモリーDB(データはメモリー上に置く)ではあるが)Tsurugi内部ではファイルで保管される。
Tsurugi 1.3.0時点では、クライアントとのデータの受け渡しもファイルで行う。

このため、Tsurugi 1.3.0では、クライアントをDBサーバーと同じマシン上で実行しないとBLOB・CLOBを使用できない。
これはセキュリティー上の問題をはらむため、「特権モード」の場合のみ使用可能となっている。
IPC接続はデフォルトで特権モードがオンだが、TCP接続はオフ(ただしDockerイメージのTCP接続はオン)。
特権モードは構成定義ファイルのipc_endpoint/stream_endpointセクションのallow_blob_privilegedで切り替える。(blobという名前だがCLOBも含まれる)

TsubakuroIceaxeではPreparedStatementでのinsertの際にファイルのパスを指定する。
tgsqlではinsertの際にファイルのパスを渡す方法が無いので、リテラルを使用する。

リテラルは、BLOBはvarbinaryと同じ。(X'十六進数'
CLOBはvarcharと同じ。('文字列'

なお、Tsurugi内部ではCLOBはBLOBと共通の実装なので、CLOBを操作してエラーが発生した場合、エラーメッセージでは「BLOB」という言葉になっていることがある。


Tsurugi SQLへ戻る / Tsurugiへ戻る / 技術メモへ戻る
メールの送信先:ひしだま