Skip to content

Commit

Permalink
PostgreSQL, Support for materialized views. [Dave Lee & Yves Senn]
Browse files Browse the repository at this point in the history
Expand the query used in #table_exists? to include materialized views in the
kinds of relations it searches.
  • Loading branch information
kastiglione authored and senny committed Apr 2, 2014
1 parent f159b0a commit def6071
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 12 deletions.
4 changes: 4 additions & 0 deletions activerecord/CHANGELOG.md
@@ -1,3 +1,7 @@
* Enable support for materialized views on PostgreSQL >= 9.3.

*Dave Lee*

* The PostgreSQL adapter supports custom domains. Fixes #14305.

*Yves Senn*
Expand Down
Expand Up @@ -104,14 +104,11 @@ def table_exists?(name)
schema, table = Utils.extract_schema_and_table(name.to_s)
return false unless table

binds = [[nil, table]]
binds << [nil, schema] if schema

exec_query(<<-SQL, 'SCHEMA').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')
WHERE c.relkind IN ('r','v','m') -- (r)elation/table, (v)iew, (m)aterialized view
AND c.relname = '#{table.gsub(/(^"|"$)/,'')}'
AND n.nspname = #{schema ? "'#{schema}'" : 'ANY (current_schemas(false))'}
SQL
Expand Down
Expand Up @@ -454,6 +454,10 @@ def supports_ranges?
postgresql_version >= 90200
end

def supports_materialized_views?
postgresql_version >= 90300
end

def enable_extension(name)
exec_query("CREATE EXTENSION IF NOT EXISTS \"#{name}\"").tap {
reload_type_map
Expand Down
34 changes: 26 additions & 8 deletions activerecord/test/cases/adapters/postgresql/view_test.rb
@@ -1,11 +1,15 @@
require "cases/helper"

class ViewTest < ActiveRecord::TestCase
self.use_transactional_fixtures = false
module ViewTestConcern
extend ActiveSupport::Concern

included do
self.use_transactional_fixtures = false
mattr_accessor :view_type
end

SCHEMA_NAME = 'test_schema'
TABLE_NAME = 'things'
VIEW_NAME = 'view_things'
COLUMNS = [
'id integer',
'name character varying(50)',
Expand All @@ -14,17 +18,19 @@ class ViewTest < ActiveRecord::TestCase
]

class ThingView < ActiveRecord::Base
self.table_name = 'test_schema.view_things'
end

def setup
super
ThingView.table_name = "#{SCHEMA_NAME}.#{view_type}_things"

@connection = ActiveRecord::Base.connection
@connection.execute "CREATE SCHEMA #{SCHEMA_NAME} CREATE TABLE #{TABLE_NAME} (#{COLUMNS.join(',')})"
@connection.execute "CREATE TABLE #{SCHEMA_NAME}.\"#{TABLE_NAME}.table\" (#{COLUMNS.join(',')})"
@connection.execute "CREATE VIEW #{SCHEMA_NAME}.#{VIEW_NAME} AS SELECT id,name,email,moment FROM #{SCHEMA_NAME}.#{TABLE_NAME}"
@connection.execute "CREATE #{view_type.humanize} #{ThingView.table_name} AS SELECT * FROM #{SCHEMA_NAME}.#{TABLE_NAME}"
end

teardown do
def teardown
super
@connection.execute "DROP SCHEMA #{SCHEMA_NAME} CASCADE"
end

Expand All @@ -35,7 +41,7 @@ def test_table_exists

def test_column_definitions
assert_nothing_raised do
assert_equal COLUMNS, columns("#{SCHEMA_NAME}.#{VIEW_NAME}")
assert_equal COLUMNS, columns(ThingView.table_name)
end
end

Expand All @@ -47,3 +53,15 @@ def columns(table_name)
end

end

class ViewTest < ActiveRecord::TestCase
include ViewTestConcern
self.view_type = 'view'
end

if ActiveRecord::Base.connection.supports_materialized_views?
class MaterializedViewTest < ActiveRecord::TestCase
include ViewTestConcern
self.view_type = 'materialized_view'
end
end

0 comments on commit def6071

Please sign in to comment.