S-JIS[2023-10-09/2025-03-17]
|
TsurugiのSQLのデータ型は、TsubakuroではAtomType、IceaxeではTgDataTypeという列挙型で表す。
SQLのデータ型では桁数や精度(例:char(10)
)があるが、AtomTypeやTgDataTypeでは桁数や精度は持たない。
SQLデータ型 | リテラルの例 | TsubakuroのAtomType | IceaxeのTgDataType | |
---|---|---|---|---|
boolean |
true |
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) |
'abc' |
1.0.0-BETA1 | CHARACTER |
STRING |
binary(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 |
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文ではデータを入れられないが、
TsubakuroやIceaxeが対応しているデータ型なら、TsubakuroのプレースホルダーやIceaxeのバインド変数を使ったinsert文、あるいはembulk-output-tsurugidbで値を入れることが出来る。
真偽値を表すのが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)
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)
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)));
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した値とは異なるタイムゾーンオフセットで返ってくる場合がある)
ただし、セッションに対して(動的に)タイムゾーンオフセットを設定することはまだ出来ない。
タイムゾーンオフセットのデフォルト値は構成定義ファイルで指定する。
[session] zone_offset=+09:00
日時系のデータ型ごとに、現在日時を返す関数が提供されている。
バイト列を保持するデータ型が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。[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も含まれる)
TsubakuroやIceaxeではPreparedStatementでのinsertの際にファイルのパスを指定する。
tgsqlではinsertの際にファイルのパスを渡す方法が無いので、リテラルを使用する。
リテラルは、BLOBはvarbinaryと同じ。(X'十六進数'
)
CLOBはvarcharと同じ。('文字列'
)
なお、Tsurugi内部ではCLOBはBLOBと共通の実装なので、CLOBを操作してエラーが発生した場合、エラーメッセージでは「BLOB」という言葉になっていることがある。