This project is archived and is in readonly mode.

#6046 ✓invalid
crazycrv

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

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

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.

Comments and changes to this ticket

Create your profile

Help contribute to this project by taking a few moments to create your personal profile. Create your profile »

<h2 style="font-size: 14px">Tickets have moved to Github</h2>

The new ticket tracker is available at <a href="https://github.com/rails/rails/issues">https://github.com/rails/rails/issues</a>

Attachments

Pages