JRuby

Regression: support of non-sequence primary key lost in 0.9.1

Details

  • Type: Bug Bug
  • Status: Closed Closed
  • Priority: Major Major
  • Resolution: Fixed
  • Affects Version/s: None
  • Fix Version/s: None
  • Component/s: None
  • Labels:
    None
  • Environment:
  • Number of attachments :
    0

Description

Given a postgreSQL schema like this:

Table "urls"
Column | Type | Modifiers
----------------------------------------------------------------------
uhash | text | not null
url | text | not null
Indexes:
"urls_pkey" PRIMARY KEY, btree (uhash)

Which FWIW, was created from a migration like this:

  1. Base Urls table schema
    class BaseUrls < ActiveRecord::Migration
    def self.up
    create_table 'urls', :id => false do |t|
    t.text 'uhash', :null => false
    t.text 'url', :null => false
    end
    execute "ALTER TABLE urls ADD PRIMARY KEY (uhash)"
    end
    def self.down
    drop_table 'urls'
    end
    end

And corresponding class:

class Url < ActiveRecord::Base
set_primary_key :uhash
end

With 0.9.1 the following error occurs on first usage (create!). This does not occur if I downgrade the same setup to 0.9 (no other changes):

ActiveRecord::StatementInvalid: ActiveRecord::ActiveRecordError: ERROR: relation "urls_uhash_seq" does not exist: SELECT currval('urls_uhash_seq')
/opt/jruby/gems/gems/activerecord-2.3.2/lib/active_record/connection_adapters/abstract_adapter.rb:212:in `log'
/opt/jruby/gems/gems/activerecord-jdbc-adapter-0.9.1/lib/active_record/connection_adapters/jdbc_adapter.rb:563:in `execute'
/opt/jruby/gems/gems/activerecord-jdbc-adapter-0.9.1/lib/active_record/connection_adapters/jdbc_adapter.rb:623:in `select'
/opt/jruby/gems/gems/activerecord-jdbc-adapter-0.9.1/lib/active_record/connection_adapters/jdbc_adapter.rb:559:in `select_one'
/opt/jruby/gems/gems/activerecord-2.3.2/lib/active_record/connection_adapters/abstract/database_statements.rb:19:in `select_value'
/opt/jruby/gems/gems/activerecord-jdbc-adapter-0.9.1/lib/jdbc_adapter/jdbc_postgre.rb:289:in `last_insert_id'
/opt/jruby/gems/gems/activerecord-jdbc-adapter-0.9.1/lib/jdbc_adapter/jdbc_postgre.rb:240:in `insert'
/opt/jruby/gems/gems/activerecord-2.3.2/lib/active_record/base.rb:2902:in `create'
/opt/jruby/gems/gems/activerecord-2.3.2/lib/active_record/timestamp.rb:29:in `create_with_timestamps'
/opt/jruby/gems/gems/activerecord-2.3.2/lib/active_record/callbacks.rb:266:in `create_with_callbacks'
/opt/jruby/gems/gems/activerecord-2.3.2/lib/active_record/base.rb:2868:in `create_or_update'
/opt/jruby/gems/gems/activerecord-2.3.2/lib/active_record/callbacks.rb:250:in `create_or_update_with_callbacks'
/opt/jruby/gems/gems/activerecord-2.3.2/lib/active_record/base.rb:2556:in `save!'
/opt/jruby/gems/gems/activerecord-2.3.2/lib/active_record/validations.rb:1019:in `save_with_validation!'
/opt/jruby/gems/gems/activerecord-2.3.2/lib/active_record/dirty.rb:87:in `save_with_dirty!'
/opt/jruby/gems/gems/activerecord-2.3.2/lib/active_record/transactions.rb:200:in `save_with_transactions!'
/opt/jruby/gems/gems/activerecord-2.3.2/lib/active_record/connection_adapters/abstract/database_statements.rb:136:in `transaction'
/opt/jruby/gems/gems/activerecord-2.3.2/lib/active_record/transactions.rb:182:in `transaction'
/opt/jruby/gems/gems/activerecord-2.3.2/lib/active_record/transactions.rb:200:in `save_with_transactions!'
/opt/jruby/gems/gems/activerecord-2.3.2/lib/active_record/transactions.rb:208:in `rollback_active_record_state!'
/opt/jruby/gems/gems/activerecord-2.3.2/lib/active_record/transactions.rb:200:in `save_with_transactions!'
/opt/jruby/gems/gems/activerecord-2.3.2/lib/active_record/validations.rb:990:in `create!'

Activity

Hide
David Kellum added a comment -

Note I also tried added things like

set_sequence_name nil

to the Url class but this didn't help.

Show
David Kellum added a comment - Note I also tried added things like
set_sequence_name nil
to the Url class but this didn't help.
Hide
David Kellum added a comment -

Found Nick's github mirror, forked and have commits for this regression from the 0.9 jdbc_postgres.rb adapter. Returning a provided id_value on insert(), as is required for non-sequence primary key, was lost during the course of changes in 0.9.1. On the way to discovering this, also found a collateral bug causing postgresql_version to always return 0.

Fork and relevent branch:

http://github.com/dekellum/activerecord-jdbc-adapter/tree/postgres-non-seq-pkey\

Relevent commits (branch postgres-non-seq-pkey):

commit fc1bdf498b7e2ff499520bf2ab1033f26b76ae84
Author: David Kellum <dek-oss@gravitext.com>
Date:   Sat May 9 19:30:56 2009 -0700

    Disable insert_with_returning temporarily
    
    This doesn't work as found now that supports_insert_with_returning? is
    true (with fix for postgresql_version).

M	lib/jdbc_adapter/jdbc_postgre.rb

commit 033e5d7b6b930237496a63557a4bc7acd982a69e
Author: David Kellum <dek-oss@gravitext.com>
Date:   Sat May 9 19:24:00 2009 -0700

    Don't fetch last_insert_id if already have id_value on insert [JRUBY-3616]
    
    This includes the case of a non-sequence primary key.

M	lib/jdbc_adapter/jdbc_postgre.rb

commit 33e9d9fe521cf17e9aaf7508d4662a9ae941c571
Author: David Kellum <dek-oss@gravitext.com>
Date:   Sat May 9 19:16:06 2009 -0700

    Fix assert_equal order.

M	test/postgres_nonseq_pkey.rb

commit 6ad7f9a2f1866c019eb3117f1dfd489598f98245
Author: David Kellum <dek-oss@gravitext.com>
Date:   Sat May 9 18:25:47 2009 -0700

    Fix JdbcSpec::PostgreSQL.postgresql_version (was always returning 0)
    
    This caused supports_insert_with_returning? to always return false,
    and thus never execute the insert optimization provided in
    879300ebc2270bdfd5985607d785d71c8ca4ccfa

M	lib/jdbc_adapter/jdbc_postgre.rb

commit fed5ff384e648da6279f792a93eeb856137ffede
Author: David Kellum <dek-oss@gravitext.com>
Date:   Sat May 9 16:33:14 2009 -0700

    Add test case for postgres non-sequence primary key. [JRUBY-3616]

A	test/postgres_nonseq_pkey.rb

Please let me know what can be done.

Show
David Kellum added a comment - Found Nick's github mirror, forked and have commits for this regression from the 0.9 jdbc_postgres.rb adapter. Returning a provided id_value on insert(), as is required for non-sequence primary key, was lost during the course of changes in 0.9.1. On the way to discovering this, also found a collateral bug causing postgresql_version to always return 0. Fork and relevent branch: http://github.com/dekellum/activerecord-jdbc-adapter/tree/postgres-non-seq-pkey\
Relevent commits (branch postgres-non-seq-pkey):

commit fc1bdf498b7e2ff499520bf2ab1033f26b76ae84
Author: David Kellum <dek-oss@gravitext.com>
Date:   Sat May 9 19:30:56 2009 -0700

    Disable insert_with_returning temporarily
    
    This doesn't work as found now that supports_insert_with_returning? is
    true (with fix for postgresql_version).

M	lib/jdbc_adapter/jdbc_postgre.rb

commit 033e5d7b6b930237496a63557a4bc7acd982a69e
Author: David Kellum <dek-oss@gravitext.com>
Date:   Sat May 9 19:24:00 2009 -0700

    Don't fetch last_insert_id if already have id_value on insert [JRUBY-3616]
    
    This includes the case of a non-sequence primary key.

M	lib/jdbc_adapter/jdbc_postgre.rb

commit 33e9d9fe521cf17e9aaf7508d4662a9ae941c571
Author: David Kellum <dek-oss@gravitext.com>
Date:   Sat May 9 19:16:06 2009 -0700

    Fix assert_equal order.

M	test/postgres_nonseq_pkey.rb

commit 6ad7f9a2f1866c019eb3117f1dfd489598f98245
Author: David Kellum <dek-oss@gravitext.com>
Date:   Sat May 9 18:25:47 2009 -0700

    Fix JdbcSpec::PostgreSQL.postgresql_version (was always returning 0)
    
    This caused supports_insert_with_returning? to always return false,
    and thus never execute the insert optimization provided in
    879300ebc2270bdfd5985607d785d71c8ca4ccfa

M	lib/jdbc_adapter/jdbc_postgre.rb

commit fed5ff384e648da6279f792a93eeb856137ffede
Author: David Kellum <dek-oss@gravitext.com>
Date:   Sat May 9 16:33:14 2009 -0700

    Add test case for postgres non-sequence primary key. [JRUBY-3616]

A	test/postgres_nonseq_pkey.rb

Please let me know what can be done.
Hide
Nick Sieger added a comment -

I'm happy to fix a regression, but I pulled these changes into an integration branch and found that most of the tests failed. Does this patchset assume Postgres 8.3? I'm still using 8.2.4 and I don't want to anyone who wishes to use the adapter to upgrade to 8.3.

Show
Nick Sieger added a comment - I'm happy to fix a regression, but I pulled these changes into an integration branch and found that most of the tests failed. Does this patchset assume Postgres 8.3? I'm still using 8.2.4 and I don't want to anyone who wishes to use the adapter to upgrade to 8.3.
Hide
David Kellum added a comment -

Nick, thanks and sorry about that, I botched the last fc1bdf (Disable insert_with_returning temporarily) as I was reworking it to keep that commit separate from 033e5d (the commit which should be sufficient). See comments in the diff, there is another problem I haven't fixed preventing the insert_with_returning optimization from working.

I've just pushed 74f1ae8 on to same branch and now its working cleanly again (AR 2.3.2, 2.1.2):

% AR_VERSION=2.3.2 NODOT=true jrake test_postgres
(in /home/david/src/activerecord-jdbc)
/opt/dist/jruby/bin/jruby -I"/home/david/src/activerecord-jdbc/lib" -I"/home/david/src/activerecord-jdbc/drivers/postgres/lib" -I"/home/david/src/activerecord-jdbc/adapters/postgresql/lib" -I"/home/david/src/activerecord-jdbc/test" -rjdbc/postgres "/opt/jruby/gems/gems/rake-0.8.4/lib/rake/rake_test_loader.rb" "test/postgres_reserved_test.rb" "test/postgres_simple_test.rb" "test/postgres_mixed_case_test.rb"
Using activerecord version 2.3.2
Specify version with AR_VERSION=={version} or RUBYLIB={path}
Loaded suite /opt/jruby/gems/gems/rake-0.8.4/lib/rake/rake_test_loader
Started
..............................
Finished in 7.094 seconds.

30 tests, 46 assertions, 0 failures, 0 errors

% AR_VERSION=2.1.2 NODOT=true jrake test_postgres
(in /home/david/src/activerecord-jdbc)
/opt/dist/jruby/bin/jruby -I"/home/david/src/activerecord-jdbc/lib" -I"/home/david/src/activerecord-jdbc/drivers/postgres/lib" -I"/home/david/src/activerecord-jdbc/adapters/postgresql/lib" -I"/home/david/src/activerecord-jdbc/test" -rjdbc/postgres "/opt/jruby/gems/gems/rake-0.8.4/lib/rake/rake_test_loader.rb" "test/postgres_reserved_test.rb" "test/postgres_simple_test.rb" "test/postgres_mixed_case_test.rb"
Using activerecord version 2.1.2
Specify version with AR_VERSION=={version} or RUBYLIB={path}
Loaded suite /opt/jruby/gems/gems/rake-0.8.4/lib/rake/rake_test_loader
Started
..............................
Finished in 9.382 seconds.

30 tests, 46 assertions, 0 failures, 0 errors

Also, in retrospect I should have done the postgres jdbc upgrade on a separate branch, as that update is a good idea IMO for 0.9.2 but not required for this fix. The 8.3.604 jdbc driver is compatible with postgres >=7.2 according to docs. I'm testing on postgres 8.2.11 at home and 8.3.7 at work.

--David

Show
David Kellum added a comment - Nick, thanks and sorry about that, I botched the last fc1bdf (Disable insert_with_returning temporarily) as I was reworking it to keep that commit separate from 033e5d (the commit which should be sufficient). See comments in the diff, there is another problem I haven't fixed preventing the insert_with_returning optimization from working. I've just pushed 74f1ae8 on to same branch and now its working cleanly again (AR 2.3.2, 2.1.2): % AR_VERSION=2.3.2 NODOT=true jrake test_postgres (in /home/david/src/activerecord-jdbc) /opt/dist/jruby/bin/jruby -I"/home/david/src/activerecord-jdbc/lib" -I"/home/david/src/activerecord-jdbc/drivers/postgres/lib" -I"/home/david/src/activerecord-jdbc/adapters/postgresql/lib" -I"/home/david/src/activerecord-jdbc/test" -rjdbc/postgres "/opt/jruby/gems/gems/rake-0.8.4/lib/rake/rake_test_loader.rb" "test/postgres_reserved_test.rb" "test/postgres_simple_test.rb" "test/postgres_mixed_case_test.rb" Using activerecord version 2.3.2 Specify version with AR_VERSION=={version} or RUBYLIB={path} Loaded suite /opt/jruby/gems/gems/rake-0.8.4/lib/rake/rake_test_loader Started .............................. Finished in 7.094 seconds. 30 tests, 46 assertions, 0 failures, 0 errors % AR_VERSION=2.1.2 NODOT=true jrake test_postgres (in /home/david/src/activerecord-jdbc) /opt/dist/jruby/bin/jruby -I"/home/david/src/activerecord-jdbc/lib" -I"/home/david/src/activerecord-jdbc/drivers/postgres/lib" -I"/home/david/src/activerecord-jdbc/adapters/postgresql/lib" -I"/home/david/src/activerecord-jdbc/test" -rjdbc/postgres "/opt/jruby/gems/gems/rake-0.8.4/lib/rake/rake_test_loader.rb" "test/postgres_reserved_test.rb" "test/postgres_simple_test.rb" "test/postgres_mixed_case_test.rb" Using activerecord version 2.1.2 Specify version with AR_VERSION=={version} or RUBYLIB={path} Loaded suite /opt/jruby/gems/gems/rake-0.8.4/lib/rake/rake_test_loader Started .............................. Finished in 9.382 seconds. 30 tests, 46 assertions, 0 failures, 0 errors Also, in retrospect I should have done the postgres jdbc upgrade on a separate branch, as that update is a good idea IMO for 0.9.2 but not required for this fix. The 8.3.604 jdbc driver is compatible with postgres >=7.2 according to docs. I'm testing on postgres 8.2.11 at home and 8.3.7 at work. --David
Hide
Simon Brandhof added a comment -

I've got the same error with Oracle 10XE :

org.jruby.rack.RackInitializationException: An error has occurred, all later migrations canceled:

ActiveRecord::ActiveRecordError: ORA-02289: la séquence n'existe pas
: select schema_migrations_seq.nextval id from dual
	from C:/svn/sonar/trunk/sonar-application/target/sonar-1.10-SNAPSHOT/war/sonar-web/WEB-INF/gems/gems/activerecord-jdbc-adapter-0.9.1/lib/active_record/connection_adapters/jdbc_adapter.rb:563:in `execute'
	from C:/svn/sonar/trunk/sonar-application/target/sonar-1.10-SNAPSHOT/war/sonar-web/WEB-INF/gems/gems/activerecord-jdbc-adapter-0.9.1/lib/jdbc_adapter/jdbc_oracle.rb:360:in `select'
	from C:/svn/sonar/trunk/sonar-application/target/sonar-1.10-SNAPSHOT/war/sonar-web/WEB-INF/gems/gems/activerecord-jdbc-adapter-0.9.1/lib/active_record/connection_adapters/jdbc_adapter.rb:559:in `select_one'
	from C:/svn/sonar/trunk/sonar-application/target/sonar-1.10-SNAPSHOT/war/sonar-web/WEB-INF/gems/gems/activerecord-jdbc-adapter-0.9.1/lib/jdbc_adapter/jdbc_oracle.rb:142:in `insert'
	from C:/svn/sonar/trunk/sonar-application/target/sonar-1.10-SNAPSHOT/war/sonar-web/WEB-INF/gems/gems/activerecord-2.2.2/lib/active_record/migration.rb:539:in `record_version_state_after_migrating'
	from C:/svn/sonar/trunk/sonar-application/target/sonar-1.10-SNAPSHOT/war/sonar-web/WEB-INF/gems/gems/activerecord-2.2.2/lib/active_record/migration.rb:481:in `migrate'
	from C:/svn/sonar/trunk/sonar-application/target/sonar-1.10-SNAPSHOT/war/sonar-web/WEB-INF/gems/gems/activerecord-2.2.2/lib/active_record/migration.rb:556:in `call'
	from C:/svn/sonar/trunk/sonar-application/target/sonar-1.10-SNAPSHOT/war/sonar-web/WEB-INF/gems/gems/activerecord-2.2.2/lib/active_record/migration.rb:556:in `ddl_transaction'
	 ... 12 levels...
	from file:/C:/svn/sonar/trunk/sonar-application/target/sonar-1.10-SNAPSHOT/war/sonar-web/WEB-INF/lib/jruby-rack-0.9.4.jar!/rack/builder.rb:29:in `instance_eval'
	from file:/C:/svn/sonar/trunk/sonar-application/target/sonar-1.10-SNAPSHOT/war/sonar-web/WEB-INF/lib/jruby-rack-0.9.4.jar!/rack/builder.rb:29:in `initialize'
	from <script>:2
Show
Simon Brandhof added a comment - I've got the same error with Oracle 10XE :
org.jruby.rack.RackInitializationException: An error has occurred, all later migrations canceled:

ActiveRecord::ActiveRecordError: ORA-02289: la séquence n'existe pas
: select schema_migrations_seq.nextval id from dual
	from C:/svn/sonar/trunk/sonar-application/target/sonar-1.10-SNAPSHOT/war/sonar-web/WEB-INF/gems/gems/activerecord-jdbc-adapter-0.9.1/lib/active_record/connection_adapters/jdbc_adapter.rb:563:in `execute'
	from C:/svn/sonar/trunk/sonar-application/target/sonar-1.10-SNAPSHOT/war/sonar-web/WEB-INF/gems/gems/activerecord-jdbc-adapter-0.9.1/lib/jdbc_adapter/jdbc_oracle.rb:360:in `select'
	from C:/svn/sonar/trunk/sonar-application/target/sonar-1.10-SNAPSHOT/war/sonar-web/WEB-INF/gems/gems/activerecord-jdbc-adapter-0.9.1/lib/active_record/connection_adapters/jdbc_adapter.rb:559:in `select_one'
	from C:/svn/sonar/trunk/sonar-application/target/sonar-1.10-SNAPSHOT/war/sonar-web/WEB-INF/gems/gems/activerecord-jdbc-adapter-0.9.1/lib/jdbc_adapter/jdbc_oracle.rb:142:in `insert'
	from C:/svn/sonar/trunk/sonar-application/target/sonar-1.10-SNAPSHOT/war/sonar-web/WEB-INF/gems/gems/activerecord-2.2.2/lib/active_record/migration.rb:539:in `record_version_state_after_migrating'
	from C:/svn/sonar/trunk/sonar-application/target/sonar-1.10-SNAPSHOT/war/sonar-web/WEB-INF/gems/gems/activerecord-2.2.2/lib/active_record/migration.rb:481:in `migrate'
	from C:/svn/sonar/trunk/sonar-application/target/sonar-1.10-SNAPSHOT/war/sonar-web/WEB-INF/gems/gems/activerecord-2.2.2/lib/active_record/migration.rb:556:in `call'
	from C:/svn/sonar/trunk/sonar-application/target/sonar-1.10-SNAPSHOT/war/sonar-web/WEB-INF/gems/gems/activerecord-2.2.2/lib/active_record/migration.rb:556:in `ddl_transaction'
	 ... 12 levels...
	from file:/C:/svn/sonar/trunk/sonar-application/target/sonar-1.10-SNAPSHOT/war/sonar-web/WEB-INF/lib/jruby-rack-0.9.4.jar!/rack/builder.rb:29:in `instance_eval'
	from file:/C:/svn/sonar/trunk/sonar-application/target/sonar-1.10-SNAPSHOT/war/sonar-web/WEB-INF/lib/jruby-rack-0.9.4.jar!/rack/builder.rb:29:in `initialize'
	from <script>:2
Hide
Nick Sieger added a comment -

Applied in ar-jdbc f2afdf5.

Show
Nick Sieger added a comment - Applied in ar-jdbc f2afdf5.

People

Vote (2)
Watch (1)

Dates

  • Created:
    Updated:
    Resolved: