LoginSignup
5
5

More than 5 years have passed since last update.

RailsのArelでPostgreSQL Syntaxエラー

Last updated at Posted at 2015-07-12

RailsでArelからSQLを発行した場合、
PostgreSQLのバージョン9.2でエラーが出る。9.4の場合にはエラーが出ない。
CIとして利用しているサービスのPostgreSQLバージョン次第ではローカルでエラーにならずに、
CI上でエラーになったりして混乱するのでメモ。

エラー内容

ActiveRecord::StatementInvalid:
       PG::SyntaxError: ERROR:  syntax error at or near "FROM"
       LINE 1: ...ions".* FROM "reservations" WHERE (EXISTS (SELECT FROM "stor...
                                                                    ^
       : SELECT "reservations".* FROM "reservations" WHERE (EXISTS (SELECT FROM "stored_reservations" WHERE "reservations"."id" = "stored_reservations"."id"))

Railsのモデルでのscope

以下のように記述していた。

  scope :exists_in_stored, -> do
    arel_stored_reservations = Stored::Reservation.arel_table

    condition = reservations[:id].eq(arel_stored_reservations[:id])
    where(arel_stored_reservations.where(condition).exists)
  end

SQL

上記のscopeは以下のSQLを発行する。

SELECT "reservations".* 
FROM "reservations" 
WHERE (EXISTS (
    SELECT FROM "stored_reservations" 
    WHERE "reservations"."id" = "stored_reservations"."id")
)

原因

EXISTS内のSELECT後にFROMが来る場合にSyntaxエラーとなる。
PostgreSQLのバージョンが9.2の場合にエラーとなる。

解決策

scopeの記述を以下のように変更する。

  scope :exists_in_stored, -> do
    arel_stored_reservations = Stored::Reservation.arel_table

    condition = reservations[:id].eq(arel_stored_reservations[:id])
    where(Stored::Reservation.where(condition).exists)
  end

すると、SQLは以下のようになる。

SELECT "reservations".* 
FROM "reservations" 
WHERE (EXISTS (
    SELECT "stored_reservations".* FROM "stored_reservations" 
    WHERE "reservations"."id" = "stored_reservations"."id")
)

これならPostgreSQL9.2でもエラーにならない。

ちなみにwerckerでPostgreSQLのバージョンを指定するには、wercker.ymlで以下のように記述する。

wercker.yml

box: wercker/rvm
no-response-timeout: 10

services:
    # 使用できるserviceを検索するには以下を参照
    # https://app.wercker.com/#explore/boxes/search/ 
    #- wercker/postgresql
    #- wercker/postgresql@0.0.4
    - wercker/postgresql9.2@0.0.7
    #- bolek-kurowski/postgresql9.3@0.0.8
    #- userminddeployer/postgresql9.3@0.0.7-usermind-9.3-1
    #- userminddeployer/postgresql9.4@0.0.7-usermind-9.4-3

    #- wercker/redis@1.0.1
    - wercker/redis
build:
    steps:
      - rvm-use:
5
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
5