diff options
| author | Ryuta Kamizono <kamipo@gmail.com> | 2019-03-03 13:08:50 +0900 | 
|---|---|---|
| committer | Ryuta Kamizono <kamipo@gmail.com> | 2019-03-06 08:12:41 +0900 | 
| commit | a67841eb61f808a965da0d61ea47e2d9810436b0 (patch) | |
| tree | 0939b4bdf517e277c637d2c2f65ee78e3206f825 | |
| parent | 91ed21b304c468db8ce9fd830312c151432935d0 (diff) | |
| download | rails-a67841eb61f808a965da0d61ea47e2d9810436b0.tar.gz rails-a67841eb61f808a965da0d61ea47e2d9810436b0.tar.bz2 rails-a67841eb61f808a965da0d61ea47e2d9810436b0.zip  | |
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.
5 files changed, 25 insertions, 26 deletions
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+`?\.)?`?(?<table>\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  | 
