From a982443ae5bd12535405dbdb40f27df2d612256e Mon Sep 17 00:00:00 2001 From: Daniel Schierbeck Date: Sat, 9 Jul 2011 14:24:28 +0200 Subject: Make #extract_schema_and_table an instance method in Utils Also, move the utils test into its own test case. --- .../lib/active_record/connection_adapters/postgresql_adapter.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb') diff --git a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb index a84f73c73f..df753d087c 100644 --- a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb +++ b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb @@ -948,6 +948,8 @@ module ActiveRecord end module Utils + extend self + # Returns an array of [schema_name, table_name] extracted from +name+. # +schema_name+ is nil if not specified in +name+. # +schema_name+ and +table_name+ exclude surrounding quotes (regardless of whether provided in +name+) @@ -958,7 +960,7 @@ module ActiveRecord # * schema_name.table_name # * schema_name."table.name" # * "schema.name"."table name" - def self.extract_schema_and_table(name) + def extract_schema_and_table(name) table, schema = name.scan(/[^".\s]+|"[^"]*"/)[0..1].collect{|m| m.gsub(/(^"|"$)/,'') }.reverse [schema, table] end -- cgit v1.2.3 From 54b7e783ef202d022a57dcdd54f7edf021c1df78 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Tue, 6 Sep 2011 16:47:34 -0700 Subject: Database adapters use a statement pool. Database adapters use a statement pool for limiting the number of open prepared statments on the database. The limit defaults to 1000, but can be adjusted in your database config by changing 'statement_limit'. --- .../connection_adapters/postgresql_adapter.rb | 46 +++++++++++++++++++--- 1 file changed, 41 insertions(+), 5 deletions(-) (limited to 'activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb') diff --git a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb index ba4a6c7a78..a09bf9c73f 100644 --- a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb +++ b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb @@ -1,5 +1,6 @@ require 'active_record/connection_adapters/abstract_adapter' require 'active_support/core_ext/object/blank' +require 'active_record/connection_adapters/statement_pool' # Make sure we're using pg high enough for PGResult#values gem 'pg', '~> 0.11' @@ -246,6 +247,43 @@ module ActiveRecord true end + class StatementPool < ConnectionAdapters::StatementPool + def initialize(connection, max) + super + @counter = 0 + @cache = {} + end + + def each(&block); @cache.each(&block); end + def key?(key); @cache.key?(key); end + def [](key); @cache[key]; end + def length; @cache.length; end + + def next_key + "a#{@counter + 1}" + end + + def []=(sql, key) + while @max <= @cache.size + dealloc(@cache.shift.last) + end + @counter += 1 + @cache[sql] = key + end + + def clear + @cache.each_value do |stmt_key| + dealloc stmt_key + end + @cache.clear + end + + private + def dealloc(key) + @connection.query "DEALLOCATE #{key}" + end + end + # Initializes and connects a PostgreSQL adapter. def initialize(connection, logger, connection_parameters, config) super(connection, logger) @@ -254,9 +292,10 @@ module ActiveRecord # @local_tz is initialized as nil to avoid warnings when connect tries to use it @local_tz = nil @table_alias_length = nil - @statements = {} connect + @statements = StatementPool.new @connection, + config.fetch(:statement_limit) { 1000 } if postgresql_version < 80200 raise "Your version of PostgreSQL (#{postgresql_version}) is too old, please upgrade!" @@ -271,9 +310,6 @@ module ActiveRecord # Clears the prepared statements cache. def clear_cache! - @statements.each_value do |value| - @connection.query "DEALLOCATE #{value}" - end @statements.clear end @@ -996,7 +1032,7 @@ module ActiveRecord def exec_cache(sql, binds) unless @statements.key? sql - nextkey = "a#{@statements.length + 1}" + nextkey = @statements.next_key @connection.prepare nextkey, sql @statements[sql] = nextkey end -- cgit v1.2.3 From f5ea24b3db952071eea73cdef7fd52e38e7e540f Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Wed, 7 Sep 2011 10:24:25 -0700 Subject: Merge commit 'refs/pull/2909/head' of https://github.com/rails/rails into rawr * https://github.com/rails/rails: Postgresql adapter: added current_schema check for table_exists? Postgresql adapter: added current_schema check for table_exists? --- .../active_record/connection_adapters/postgresql_adapter.rb | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb') diff --git a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb index a09bf9c73f..9181cc78fc 100644 --- a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb +++ b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb @@ -719,12 +719,10 @@ module ActiveRecord binds << [nil, schema] if schema exec_query(<<-SQL, 'SCHEMA', binds).rows.first[0].to_i > 0 - SELECT COUNT(*) - FROM pg_class c - LEFT JOIN pg_namespace n ON n.oid = c.relnamespace - WHERE c.relkind in ('v','r') - AND c.relname = $1 - AND n.nspname = #{schema ? '$2' : 'ANY (current_schemas(false))'} + SELECT COUNT(*) + FROM pg_tables + WHERE tablename = $1 + AND schemaname = #{schema ? "'#{schema}'" : "ANY (current_schemas(false))"} SQL end -- cgit v1.2.3 From d9a20711da15efb781a8b8402871be4890d05c6d Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Wed, 7 Sep 2011 10:30:30 -0700 Subject: use the supplied bind values --- .../lib/active_record/connection_adapters/postgresql_adapter.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb') diff --git a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb index 9181cc78fc..45ca104ad3 100644 --- a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb +++ b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb @@ -722,7 +722,7 @@ module ActiveRecord SELECT COUNT(*) FROM pg_tables WHERE tablename = $1 - AND schemaname = #{schema ? "'#{schema}'" : "ANY (current_schemas(false))"} + AND schemaname = #{schema ? "$2" : "ANY (current_schemas(false))"} SQL end -- cgit v1.2.3 From b9f66f4db157eb6c85e1c72d9b1d577cd93cf9de Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Wed, 7 Sep 2011 10:44:18 -0700 Subject: fixing view queries --- .../lib/active_record/connection_adapters/postgresql_adapter.rb | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb') diff --git a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb index 45ca104ad3..272663a91d 100644 --- a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb +++ b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb @@ -720,9 +720,11 @@ module ActiveRecord exec_query(<<-SQL, 'SCHEMA', binds).rows.first[0].to_i > 0 SELECT COUNT(*) - FROM pg_tables - WHERE tablename = $1 - AND schemaname = #{schema ? "$2" : "ANY (current_schemas(false))"} + FROM pg_class c + LEFT JOIN pg_namespace n ON n.oid = c.relnamespace + WHERE c.relkind in ('v','r') + AND c.relname = $1 + AND n.nspname = #{schema ? '$2' : 'ANY (current_schemas(false))'} SQL end -- cgit v1.2.3 From 834d429e849b590ee7a283909eda9affed065387 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Wed, 7 Sep 2011 15:06:42 -0700 Subject: LRU should cache per process in postgresql. fixes #1339 --- .../connection_adapters/postgresql_adapter.rb | 24 +++++++++++++--------- 1 file changed, 14 insertions(+), 10 deletions(-) (limited to 'activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb') diff --git a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb index 272663a91d..5402918b1d 100644 --- a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb +++ b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb @@ -251,34 +251,38 @@ module ActiveRecord def initialize(connection, max) super @counter = 0 - @cache = {} + @cache = Hash.new { |h,pid| h[pid] = {} } end - def each(&block); @cache.each(&block); end - def key?(key); @cache.key?(key); end - def [](key); @cache[key]; end - def length; @cache.length; end + def each(&block); cache.each(&block); end + def key?(key); cache.key?(key); end + def [](key); cache[key]; end + def length; cache.length; end def next_key "a#{@counter + 1}" end def []=(sql, key) - while @max <= @cache.size - dealloc(@cache.shift.last) + while @max <= cache.size + dealloc(cache.shift.last) end @counter += 1 - @cache[sql] = key + cache[sql] = key end def clear - @cache.each_value do |stmt_key| + cache.each_value do |stmt_key| dealloc stmt_key end - @cache.clear + cache.clear end private + def cache + @cache[$$] + end + def dealloc(key) @connection.query "DEALLOCATE #{key}" end -- cgit v1.2.3