diff --git a/lib/scenic/adapters/postgres.rb b/lib/scenic/adapters/postgres.rb index acef6f62..2faa4c34 100644 --- a/lib/scenic/adapters/postgres.rb +++ b/lib/scenic/adapters/postgres.rb @@ -124,7 +124,7 @@ def drop_view(name) # @param sql_definition The SQL schema that defines the materialized view. # @param no_data [Boolean] Default: false. Set to true to create # materialized view without running the associated query. You will need - # to perform a non-concurrent refresh to populate with data. + # to perform a refresh to populate with data. # # This is typically called in a migration via {Statements#create_view}. # @@ -154,7 +154,7 @@ def create_materialized_view(name, sql_definition, no_data: false) # @param sql_definition The SQL schema for the updated view. # @param no_data [Boolean] Default: false. Set to true to create # materialized view without running the associated query. You will need - # to perform a non-concurrent refresh to populate with data. + # to perform a refresh to populate with data. # # @raise [MaterializedViewsNotSupportedError] if the version of Postgres # in use does not support materialized views. @@ -193,7 +193,10 @@ def drop_materialized_view(name) # refreshed without locking the view for select but requires that the # table have at least one unique index that covers all rows. Attempts to # refresh concurrently without a unique index will raise a descriptive - # error. + # error. This option is ignored if the view is not populated, as it + # would cause an error to be raised by Postgres. Default: false. + # @param cascade [Boolean] Whether to refresh dependent materialized + # views. Default: false. # # @raise [MaterializedViewsNotSupportedError] if the version of Postgres # in use does not support materialized views. @@ -205,6 +208,8 @@ def drop_materialized_view(name) # Scenic.database.refresh_materialized_view(:search_results) # @example Concurrent refresh # Scenic.database.refresh_materialized_view(:posts, concurrently: true) + # @example Cascade refresh + # Scenic.database.refresh_materialized_view(:posts, cascade: true) # # @return [void] def refresh_materialized_view(name, concurrently: false, cascade: false) @@ -222,9 +227,7 @@ def refresh_materialized_view(name, concurrently: false, cascade: false) end end - # True if supplied relation name is populated. Useful for checking the - # state of materialized views which may error if created `WITH NO DATA` - # and used before they are refreshed. True for all other relation types. + # True if supplied relation name is populated. # # @param name The name of the relation # diff --git a/spec/scenic/adapters/postgres_spec.rb b/spec/scenic/adapters/postgres_spec.rb index 66819aa7..6bceda68 100644 --- a/spec/scenic/adapters/postgres_spec.rb +++ b/spec/scenic/adapters/postgres_spec.rb @@ -149,6 +149,15 @@ module Adapters adapter.refresh_materialized_view(:tests, concurrently: true) }.to raise_error e end + + it "falls back to non-concurrent refresh if not populated" do + adapter = Postgres.new + adapter.create_materialized_view(:testing, "SELECT unnest('{1, 2}'::int[])", no_data: true) + e = Scenic::Adapters::Postgres::ConcurrentRefreshesNotSupportedError + + expect { adapter.refresh_materialized_view(:tests, concurrently: true) } + .not_to raise_error(e) + end end end