Redshift で timestamp
というカラム名を持つテーブルを SELECT しようとしてハマったので簡単にまとめておく.事象を簡潔に書くと,SELECT で timestamp
の後に他のカラムを指定するとシンタックスエラーになるというもの.
結論から言えば,Redshift でも PostgreSQL でも timestamp
は予約語ではないんだけど,データ型名ではあるので,SELECT するときは必ず引用符で囲ってあげる必要があって,考慮が面倒なのでカラム名にしない方が良いよねっていう話.ただし,動作確認をしてみたところ,Redshift では再現して,PostgreSQL では再現しなかったので,もしかしたら Redshift だけの制約なのかもしれないけど,代替のカラム名が用意できるならその方が良いと思う.
マニュアル (PostgreSQL: Documentation: 9.3: Lexical Structure) にも似たようなことが書かれている.
A delimited identifier is always an identifier, never a key word. So "select" could be used to refer to a column or table named "select", whereas an unquoted select would be taken as a key word and would therefore provoke a parse error when used where a table or column name is expected.
せっかくなので,動作確認をしたログを残しておく.
Redshift で動作確認
id
と timestamp
というカラムを持つ sample_table
テーブルを定義して,サンプルデータを1件挿入する.
xxx=> create table sample_table (id integer, timestamp timestamp); CREATE TABLE xxx=> insert into sample_table values (1, '2014-01-01 00:00:00'); INSERT 0 1
id
, timestamp
の順番だと SELECT は正常に機能する.
xxx=> select id, timestamp from sample_table; id | timestamp ----+--------------------- 1 | 2014-01-01 00:00:00 (1 row)
逆に timestamp
, id
の順番にするとシンタックスエラーが出る.
xxx=> select timestamp, id from sample_table; ERROR: syntax error at or near "," LINE 1: select timestamp, id from sample_table; ^
これを解決するためには,ダブルクォーテーションで囲ったり,as
で別名を定義したりすれば機能するようになる.
xxx=> select "timestamp", id from sample_table; timestamp | id ---------------------+---- 2014-01-01 00:00:00 | 1 (1 row)
xxx=> select timestamp as timestamp, id from sample_table; timestamp | id ---------------------+---- 2014-01-01 00:00:00 | 1 (1 row)
PostgreSQL で動作確認
id
と timestamp
というカラムを持つ sample_table
テーブルを定義して,サンプルデータを1件挿入する.
postgres=# create table sample_table (id integer, timestamp timestamp); CREATE TABLE postgres=# insert into sample_table values (1, '2014-01-01 00:00:00'); INSERT 0 1
id
, timestamp
の順番だと SELECT は正常に機能する.
postgres=# select id, timestamp from sample_table; id | timestamp ----+--------------------- 1 | 2014-01-01 00:00:00 (1 row)
PostgreSQL の場合は,timestamp
, id
の順番でも正常に機能する.
postgres=# select timestamp, id from sample_table; timestamp | id ---------------------+---- 2014-01-01 00:00:00 | 1 (1 row)
当然ながら,ダブルクォーテーションで囲ったり,as
で別名を定義しても正常に機能する.
postgres=# select "timestamp", id from sample_table; timestamp | id ---------------------+---- 2014-01-01 00:00:00 | 1 (1 row)
postgres=# select timestamp as timestamp, id from sample_table; timestamp | id ---------------------+---- 2014-01-01 00:00:00 | 1 (1 row)