👋🏼 Hello! I might have found a bug here courtesy of dry-operation, where we test an optional ActiveRecord extension on JRuby against this adapter's master branch (since no released 80.x/81.x works with JRuby 10.1.x yet).
We don't commit Gemfile.lock, so we pull the very latest master on every run. After #1207 merged (which relaxed the activerecord dependency from ~> 8.0.0 to ~> 8.0), our CI started pulling in activerecord 8.1.3, and our ActiveRecord integration specs started failing on JRuby, after being green in the days earlier.
Our specs do nothing fancy: an in-memory SQLite DB, a one-column table, and a Model.create inside a transaction.
ActiveRecord::Base.establish_connection(adapter: "sqlite3", database: ":memory:")
ActiveRecord::Schema.define do
create_table(:x_ar_foo) { |t| t.string :bar }
end
model = Class.new(ActiveRecord::Base) { self.table_name = :x_ar_foo }
model.create(bar: "bar") # <- this now raises
The create is the first thing to touch the schema cache, which is where it blows up:
NoMethodError:
undefined method 'mutable?' for nil
# ./vendor/bundle/jruby/4.0.0/gems/activerecord-8.1.3/lib/active_record/connection_adapters/column.rb:25:in 'initialize'
# ./vendor/bundle/jruby/4.0.0/bundler/gems/activerecord-jdbc-adapter-424d66984519/lib/arjdbc/sqlite3/column.rb:9:in 'initialize'
# ./vendor/bundle/jruby/4.0.0/gems/activerecord-8.1.3/lib/active_record/connection_adapters/deduplicable.rb:14:in 'new'
# ./vendor/bundle/jruby/4.0.0/bundler/gems/activerecord-jdbc-adapter-424d66984519/lib/arjdbc/sqlite3/adapter.rb:474:in 'new_column_from_field'
The versions at play here:
Likely root cause
ActiveRecord 8.1 added cast_type as a new required second positional argument for Column#initialize:
# activerecord 8.1.3, connection_adapters/column.rb
def initialize(name, cast_type, default, sql_type_metadata = nil, null = true, default_function = nil, collation: nil, comment: nil, **)
...
@default = default.nil? || cast_type.mutable? ? default : cast_type.deserialize(default) # <- Line 25
(In 8.0, the signature was initialize(name, default, sql_type_metadata = nil, ...)).
SQLite3Column#initialize inside this adapter forwards its arguments via super, so the misaligned args come from the call to it in ArJdbc::SQLite3#new_column_from_field.
ActiveRecord::ConnectionAdapters::SQLite3Column.new(
field["name"],
default_value, # <- lands in `cast_type`
type_metadata, # <- lands in `default`
field["notnull"].to_i == 0,
default_function,
collation: field["collation"],
...
)
Here, cast_type receives default_value (nil for these columns) and AR's column.rb:25 calls nil.mutable?.
Fix
I'm not familiar enough with everything here to suggest an exact fix, but it seems like this cast_type will need to be built and passed through conditionally, only when using ActiveRecord 8.1 or later.
For our dry-operation CI in the meantime, we've worked around this by pinning our activerecord-jdbcsqlite3-adapter dependency to the 74aeab0 ref from this repo.
👋🏼 Hello! I might have found a bug here courtesy of dry-operation, where we test an optional ActiveRecord extension on JRuby against this adapter's master branch (since no released 80.x/81.x works with JRuby 10.1.x yet).
We don't commit
Gemfile.lock, so we pull the very latest master on every run. After #1207 merged (which relaxed theactiverecorddependency from~> 8.0.0to~> 8.0), our CI started pulling inactiverecord 8.1.3, and our ActiveRecord integration specs started failing on JRuby, after being green in the days earlier.Our specs do nothing fancy: an in-memory SQLite DB, a one-column table, and a
Model.createinside a transaction.The
createis the first thing to touch the schema cache, which is where it blows up:The versions at play here:
activerecord8.1.3activerecord-jdbcsqlite3-adaptermaster (post-Add Rails 8.1 compatibility #1207)Likely root cause
ActiveRecord 8.1 added
cast_typeas a new required second positional argument forColumn#initialize:(In 8.0, the signature was
initialize(name, default, sql_type_metadata = nil, ...)).SQLite3Column#initializeinside this adapter forwards its arguments viasuper, so the misaligned args come from the call to it inArJdbc::SQLite3#new_column_from_field.Here,
cast_typereceivesdefault_value(nil for these columns) and AR'scolumn.rb:25callsnil.mutable?.Fix
I'm not familiar enough with everything here to suggest an exact fix, but it seems like this cast_type will need to be built and passed through conditionally, only when using ActiveRecord 8.1 or later.
For our dry-operation CI in the meantime, we've worked around this by pinning our activerecord-jdbcsqlite3-adapter dependency to the 74aeab0 ref from this repo.