From a67841eb61f808a965da0d61ea47e2d9810436b0 Mon Sep 17 00:00:00 2001 From: Ryuta Kamizono Date: Sun, 3 Mar 2019 13:08:50 +0900 Subject: Ensure `clear_cache!` clears the prepared statements cache Since #23461, all adapters supports prepared statements, so that clears the prepared statements cache is no longer database specific. Actually, I struggled to identify the cause of random CI failure in #23461, that was missing `@statements.clear` in `clear_cache!`. This extracts `clear_cache!` to ensure the common concerns in the abstract adapter. --- .../active_record/connection_adapters/abstract_adapter.rb | 10 ++++++---- .../connection_adapters/abstract_mysql_adapter.rb | 11 ++++++----- .../connection_adapters/postgresql_adapter.rb | 14 ++++---------- .../active_record/connection_adapters/sqlite3_adapter.rb | 12 +++++------- activerecord/test/cases/bind_parameter_test.rb | 4 ++++ 5 files changed, 25 insertions(+), 26 deletions(-) (limited to 'activerecord') diff --git a/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb b/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb index cf6a1217a0..c2087b8216 100644 --- a/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb @@ -120,6 +120,7 @@ module ActiveRecord @quoted_column_names, @quoted_table_names = {}, {} @prevent_writes = false @visitor = arel_visitor + @statements = build_statement_pool @lock = ActiveSupport::Concurrency::LoadInterlockAwareMonitor.new if self.class.type_cast_config_to_boolean(config.fetch(:prepared_statements) { true }) @@ -492,11 +493,9 @@ module ActiveRecord # this should be overridden by concrete adapters end - ### - # Clear any caching the database adapter may be doing, for example - # clearing the prepared statement cache. This is database specific. + # Clear any caching the database adapter may be doing. def clear_cache! - # this should be overridden by concrete adapters + @lock.synchronize { @statements.clear } if @statements end # Returns true if its required to reload the connection between requests for development mode. @@ -718,6 +717,9 @@ module ActiveRecord def arel_visitor Arel::Visitors::ToSql.new(self) end + + def build_statement_pool + end end end end diff --git a/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb b/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb index 1aab36c865..d99c9b9d02 100644 --- a/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb @@ -53,8 +53,6 @@ module ActiveRecord def initialize(connection, logger, connection_options, config) super(connection, logger, config) - - @statements = StatementPool.new(self.class.type_cast_config_to_integer(config[:statement_limit])) end def version #:nodoc: @@ -162,10 +160,9 @@ module ActiveRecord # CONNECTION MANAGEMENT ==================================== - # Clears the prepared statements cache. - def clear_cache! + def clear_cache! # :nodoc: reload_type_map - @statements.clear + super end #-- @@ -806,6 +803,10 @@ module ActiveRecord Arel::Visitors::MySQL.new(self) end + def build_statement_pool + StatementPool.new(self.class.type_cast_config_to_integer(@config[:statement_limit])) + end + def mismatched_foreign_key(message, sql:, binds:) match = %r/ (?:CREATE|ALTER)\s+TABLE\s*(?:`?\w+`?\.)?`?(?\w+)`?.+? diff --git a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb index 5919801519..05d8d5ac00 100644 --- a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb +++ b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb @@ -253,9 +253,6 @@ module ActiveRecord configure_connection add_pg_encoders - @statements = StatementPool.new @connection, - self.class.type_cast_config_to_integer(config[:statement_limit]) - add_pg_decoders @type_map = Type::HashLookupTypeMap.new @@ -264,13 +261,6 @@ module ActiveRecord @use_insert_returning = @config.key?(:insert_returning) ? self.class.type_cast_config_to_boolean(@config[:insert_returning]) : true end - # Clears the prepared statements cache. - def clear_cache! - @lock.synchronize do - @statements.clear - end - end - def truncate(table_name, name = nil) exec_query "TRUNCATE TABLE #{quote_table_name(table_name)}", name, [] end @@ -828,6 +818,10 @@ module ActiveRecord Arel::Visitors::PostgreSQL.new(self) end + def build_statement_pool + StatementPool.new(@connection, self.class.type_cast_config_to_integer(@config[:statement_limit])) + end + def can_perform_case_insensitive_comparison_for?(column) @case_insensitive_cache ||= {} @case_insensitive_cache[column.sql_type] ||= begin diff --git a/activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb b/activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb index 0ed7f3988d..cb3d34a740 100644 --- a/activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb +++ b/activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb @@ -96,8 +96,7 @@ module ActiveRecord def initialize(connection, logger, connection_options, config) super(connection, logger, config) - @active = true - @statements = StatementPool.new(self.class.type_cast_config_to_integer(config[:statement_limit])) + @active = true configure_connection end @@ -156,11 +155,6 @@ module ActiveRecord @connection.close rescue nil end - # Clears the prepared statements cache. - def clear_cache! - @statements.clear - end - def truncate(table_name, name = nil) execute "DELETE FROM #{quote_table_name(table_name)}", name end @@ -613,6 +607,10 @@ module ActiveRecord Arel::Visitors::SQLite.new(self) end + def build_statement_pool + StatementPool.new(self.class.type_cast_config_to_integer(@config[:statement_limit])) + end + def configure_connection execute("PRAGMA foreign_keys = ON", "SCHEMA") end diff --git a/activerecord/test/cases/bind_parameter_test.rb b/activerecord/test/cases/bind_parameter_test.rb index 03cc0dffbc..eb8b45431f 100644 --- a/activerecord/test/cases/bind_parameter_test.rb +++ b/activerecord/test/cases/bind_parameter_test.rb @@ -41,6 +41,10 @@ if ActiveRecord::Base.connection.prepared_statements topics = Topic.where(id: 1) assert_equal [1], topics.map(&:id) assert_includes statement_cache, to_sql_key(topics.arel) + + @connection.clear_cache! + + assert_not_includes statement_cache, to_sql_key(topics.arel) end def test_statement_cache_with_query_cache -- cgit v1.2.3