rails
rails copied to clipboard
`ConnectionNotEstablished` when accessing column data with `check_schema_cache_dump_version = false` on postgres
Steps to reproduce
I started looking into the schema cache functionality that Rails offers. When loading the cache and setting check_schema_cache_dump_version
to false, accessing column information still queries the database somewhere.
This is not the case on main anymore. Perhaps because of #49378, #49415 or similar work that has been done in that regard.
# frozen_string_literal: true
require "bundler/inline"
gemfile(true) do
source "https://rubygems.org"
git_source(:github) { |repo| "https://github.com/#{repo}.git" }
# Activate the gem you are reporting the issue against.
gem "rails", github: "rails/rails", branch: "main"
gem "pg"
end
require "active_record/railtie"
require "minitest/autorun"
require "logger"
class TestApp < Rails::Application
config.load_defaults 7.1
config.eager_load = false
config.root = __dir__
config.logger = Logger.new($stdout)
Rails.logger = config.logger
config.active_record.check_schema_cache_dump_version = false
end
schema_yml = <<~YML
--- !ruby/object:ActiveRecord::ConnectionAdapters::SchemaCache
columns:
ar_internal_metadata:
- !ruby/object:ActiveRecord::ConnectionAdapters::PostgreSQL::Column
serial:
generated: ''
name: key
sql_type_metadata: &1 !ruby/object:ActiveRecord::ConnectionAdapters::PostgreSQL::TypeMetadata
delegate_dc_obj: !ruby/object:ActiveRecord::ConnectionAdapters::SqlTypeMetadata
sql_type: character varying
type: :string
limit:
precision:
scale:
oid: 1043
fmod: -1
'null': false
default:
default_function:
collation:
comment:
- !ruby/object:ActiveRecord::ConnectionAdapters::PostgreSQL::Column
serial:
generated: ''
name: value
sql_type_metadata: *1
'null': true
default:
default_function:
collation:
comment:
- !ruby/object:ActiveRecord::ConnectionAdapters::PostgreSQL::Column
serial:
generated: ''
name: created_at
sql_type_metadata: &2 !ruby/object:ActiveRecord::ConnectionAdapters::PostgreSQL::TypeMetadata
delegate_dc_obj: !ruby/object:ActiveRecord::ConnectionAdapters::SqlTypeMetadata
sql_type: timestamp(6) with time zone
type: :datetime
limit:
precision: 6
scale:
oid: 1184
fmod: 6
'null': false
default:
default_function:
collation:
comment:
- !ruby/object:ActiveRecord::ConnectionAdapters::PostgreSQL::Column
serial:
generated: ''
name: updated_at
sql_type_metadata: *2
'null': false
default:
default_function:
collation:
comment:
posts:
- !ruby/object:ActiveRecord::ConnectionAdapters::PostgreSQL::Column
serial: true
generated: ''
name: id
sql_type_metadata: !ruby/object:ActiveRecord::ConnectionAdapters::PostgreSQL::TypeMetadata
delegate_dc_obj: !ruby/object:ActiveRecord::ConnectionAdapters::SqlTypeMetadata
sql_type: bigint
type: :integer
limit: 8
precision:
scale:
oid: 20
fmod: -1
'null': false
default:
default_function: nextval('posts_id_seq'::regclass)
collation:
comment:
schema_migrations:
- !ruby/object:ActiveRecord::ConnectionAdapters::PostgreSQL::Column
serial:
generated: ''
name: version
sql_type_metadata: *1
'null': false
default:
default_function:
collation:
comment:
primary_keys:
ar_internal_metadata: key
posts: id
schema_migrations: version
data_sources:
ar_internal_metadata: true
posts: true
schema_migrations: true
indexes:
ar_internal_metadata: []
posts: []
schema_migrations: []
version: 20230922142507
database_version: 150004
YML
file = Tempfile.new(["schema" ".yml"])
file.write(schema_yml)
file.rewind
ENV["DATABASE_URL"] = "postgresql://localhost:5432/doesnt_exist"
Rails.application.initialize!
class Post < ActiveRecord::Base
end
cache = ActiveRecord::ConnectionAdapters::SchemaCache._load_from(file.path)
ActiveRecord::Base.connection_pool.schema_reflection.instance_variable_set(:@cache, cache)
require "active_record/testing/query_assertions"
class BugTest < ActiveSupport::TestCase
include ActiveRecord::Assertions::QueryAssertions
def test_accessing_column_names_with_loaded_query_cache_makes_no_queries
assert_nothing_raised do
assert_no_queries do
assert_equal(["id"], Post.column_names)
end
end
end
def test_accessing_default_attributes_with_loaded_query_cache_makes_no_queries
assert_nothing_raised do
assert_no_queries do
assert_equal(["id"], Post._default_attributes.keys)
end
end
end
def test_instantiating_activerecord_class_with_loaded_query_cache_makes_no_queries
assert_nothing_raised do
assert_no_queries do
assert_nil Post.new
end
end
end
end
Expected behavior
No attempted connection to the database.
Actual behavior
Attempted connection to the database.
System configuration
Rails version: 7.1.1
Ruby version: 3.2.2