技術メモのかけら

内容はもとより調べたことすら忘れてしまうので個人的なメモです。とにかく短く、結論だけ書いていきます。

PostgreSQLの識別子63バイト制限は別名にも適用される

試した環境: PostgreSQL 11

PostgreSQLのテーブル名や列名など識別子には最大63バイトの制限があり、それ以上の長さは切り捨てられる。
例えば、123456789A123456789B123456789C123456789D123456789E123456789F123456789Gと70バイトの名前をつけようとすると、勝手に63バイトで切り捨てられて123456789A123456789B123456789C123456789D123456789E123456789F123 という名前になる。

postgres=# create table
postgres=# "123456789A123456789B123456789C123456789D123456789E123456789F123456789G"
postgres=# (col1 text);

NOTICE:  identifier "123456789A123456789B123456789C123456789D123456789E123456789F123456789G" will be truncated to "123456789A123456789B123456789C123456789D123456789E123456789F123"
CREATE TABLE

エラーではなく切り捨てられるのは意外だったが、列名やテーブル名にASでつけた別名にも同じ制限が掛かるのはもっと意外だった。

postgres=# select 1 as "123456789A123456789B123456789C123456789D123456789E123456789F123456789G";

NOTICE:  identifier "123456789A123456789B123456789C123456789D123456789E123456789F123456789G" will be truncated to "123456789A123456789B123456789C123456789D123456789E123456789F123"
 123456789A123456789B123456789C123456789D123456789E123456789F123
-----------------------------------------------------------------
                                                               1
(1 row)

ただし、同じSQL内で別名を参照している場合、切り捨てたとNOTICEは出ているものの、長い名前の参照が問題なく行えます。

postgres=# select * from (
postgres=#   select 1 as "123456789A123456789B123456789C123456789D123456789E123456789F123456789G") as a
postgres=# where "123456789A123456789B123456789C123456789D123456789E123456789F123456789G" = 1;

NOTICE:  identifier "123456789A123456789B123456789C123456789D123456789E123456789F123456789G" will be truncated to "123456789A123456789B123456789C123456789D123456789E123456789F123"
NOTICE:  identifier "123456789A123456789B123456789C123456789D123456789E123456789F123456789G" will be truncated to "123456789A123456789B123456789C123456789D123456789E123456789F123"
 123456789A123456789B123456789C123456789D123456789E123456789F123
-----------------------------------------------------------------
                                                               1
(1 row)

SELECTした結果、別名をMAPのキーにして返すような実装をしていると見事にハマるので注意が必要。
そんな長い名前の別名をつけることないですが。