Lighthouse has a new layout. Prefer the old one? Return to the old layout, and switch back any time from the link at the top of each page.

This project is archived and is in readonly mode.

Improper quoting of composite primary key in postgresql_adapter.rb (quote_column_name)

#6046

This is regarding a small issue in postgresql adapter for rails. The issue is observed with postgresql 9.0 database with rails 2.3.8 and pg adapter 0.9.0 x86-mswin32.

For example one rails app has roles and users models associated with each other through a bridge table roles_users.

In roles_user.rb the composite primary key is specified as "set_primary_keys :user_id, :role_id" using composite_primary_keys (2.3.2) gem

Calling

user.roles.push(Role.find(:first, :conditions => {:name => 'user'}))

gives following error -

ActiveRecord::StatementInvalid: PGError: ERROR:  column "user_id,role_id" does not exist
LINE 1: ..., "role_id") VALUES (NULL, NULL, 20, 1) RETURNING "user_id,r...
                                                         ^
: INSERT INTO "roles_users" ("updated_at", "created_at", "user_id", "role_id") VALUES (NULL, NULL, 20, 1) RETURNING "user_id,role_id"
    from d:/ruby/lib/ruby/gems/1.8/gems/activerecord-2.3.8/lib/active_record/connection_adapters/abstract_adapter.rb:221:in `log'
    from d:/ruby/lib/ruby/gems/1.8/gems/activerecord-2.3.8/lib/active_record/connection_adapters/postgresql_adapter.rb:524:in `execute'
    from d:/ruby/lib/ruby/gems/1.8/gems/activerecord-2.3.8/lib/active_record/connection_adapters/postgresql_adapter.rb:1006:in `select_raw'
    from d:/ruby/lib/ruby/gems/1.8/gems/activerecord-2.3.8/lib/active_record/connection_adapters/postgresql_adapter.rb:993:in `select'
    from d:/ruby/lib/ruby/gems/1.8/gems/activerecord-2.3.8/lib/active_record/connection_adapters/abstract/database_statements.rb:7:in `select_all_without_query_cache'
    from d:/ruby/lib/ruby/gems/1.8/gems/activerecord-2.3.8/lib/active_record/connection_adapters/abstract/query_cache.rb:62:in `select_all'
    from d:/ruby/lib/ruby/gems/1.8/gems/activerecord-2.3.8/lib/active_record/connection_adapters/abstract/database_statements.rb:13:in `select_one'
    from d:/ruby/lib/ruby/gems/1.8/gems/activerecord-2.3.8/lib/active_record/connection_adapters/abstract/database_statements.rb:19:in `select_value'
    from d:/ruby/lib/ruby/gems/1.8/gems/activerecord-2.3.8/lib/active_record/connection_adapters/postgresql_adapter.rb:464:in `insert'
    from d:/ruby/lib/ruby/gems/1.8/gems/composite_primary_keys-2.3.2/lib

This is due to following method of postgrsql_adapter.rb

def quote_column_name(name) #:nodoc:
  PGconn.quote_ident(name.to_s)
end

On executing the roles.push query, this method is being passed following input by insert method in the same file
Input: [:user_id, :role_id]

The method calls quote_indent and generates following output which causes PG Error mentioned above.
Output: ""user_id,role_id""

To solve this, I have changed the method as given below and it worked fine.

def quote_column_name(name) #:nodoc:
  if name.is_a?(Array)
    name.collect { |n| PGconn.quote_ident(n.to_s) }.join(',')          
  else
    PGconn.quote_ident(name.to_s)
  end        
end

With this new code the output generated for the same input is ""user_id","role_id""

Will soon submit the patch for review.

Reported by crazycrv · November 23rd, 2010 @ 03:56 PM

State: invalid
Milestone: none
Assigned to: nobody
Importance: Low

Activity

  1. crazycrv
    crazycrv

    Fix for the "Improper quoting of composite primary key in postgresql_adapter.rb (quote_column_name method)"

    See the patch file attached with this ticket.

    November 23rd, 2010 @ 04:48 PM

  2. crazycrv
  3. Aaron Patterson
    Aaron Patterson
    • State changed from new to invalid
    • Importance changed from to Low

    This seems like a bug in the composite_primary_keys gem. An Array should not be passed to quote_column_name in the first place.

    November 29th, 2010 @ 05:52 PM