From the manual
CREATE MATERIALIZED VIEW is similar to CREATE TABLE AS, except that it also remembers the query used to initialize the view, so that it can be refreshed later upon demand.
As I understand refreshing a materialized view should have the same effect as recreate view as
. But it is not what happens here.
Create a table with a single column
drop table if exists t cascade;
create table t (a int);
insert into t (a) values (1);
Create the materialized view
create materialized view mat_view_t as
select * from t ;
select * from mat_view_t;
a
---
1
Now a column is added to the source table
alter table t add column b int;
\d t
Table "public.t"
Column | Type | Modifiers
--------+---------+-----------
a | integer |
b | integer |
And then the materialized view is refreshed
refresh materialized view mat_view_t;
select * from mat_view_t;
a
---
1
\d mat_view_t
Materialized view "public.mat_view_t"
Column | Type | Modifiers
--------+---------+-----------
a | integer |
Where is the new column? Is it the expected behaviour? If it is then I think the manual is misleading.
SELECT *
is expanded at execution time, just like with all similar operations (CREATE VIEW
, CREATE TABLE AS
)
The key word is "early binding" as opposed to "late binding". Postgres saves the list of columns present at execution time of SELECT *
, columns added later are not included automatically. The query string itself is not saved, only the internal representation after expanding SELECT *
and other stuff like resolving all identifiers.
REFRESH MATERIALIZED VIEW
never changes the data definition, only data:
REFRESH MATERIALIZED VIEW
completely replaces the contents of a materialized view.
The manual could be more explicit about it, but the comparison to the behavior of CREATE TABLE AS
made it clear for me:
CREATE MATERIALIZED VIEW
is similar toCREATE TABLE AS
, except that it also remembers the query used to initialize the view.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With