From 4b8a5efaa5f788109a20516bdf7d4d22a98be50c Mon Sep 17 00:00:00 2001 From: Veesh Goldman Date: Wed, 20 Nov 2019 23:27:10 +0200 Subject: [PATCH 1/4] implemented material views for pg --- lib/SQL/Translator/Producer/PostgreSQL.pm | 1 + t/47postgres-producer.t | 16 ++++++++++++++++ 2 files changed, 17 insertions(+) diff --git a/lib/SQL/Translator/Producer/PostgreSQL.pm b/lib/SQL/Translator/Producer/PostgreSQL.pm index 8f6c6636e..03e78c4ad 100644 --- a/lib/SQL/Translator/Producer/PostgreSQL.pm +++ b/lib/SQL/Translator/Producer/PostgreSQL.pm @@ -364,6 +364,7 @@ sub create_view { my $extra = $view->extra; $create .= " TEMPORARY" if exists($extra->{temporary}) && $extra->{temporary}; + $create .= " MATERIALIZED" if exists($extra->{materialized}) && $extra->{materialized}; $create .= " VIEW " . $generator->quote($view_name); if ( my @fields = $view->fields ) { diff --git a/t/47postgres-producer.t b/t/47postgres-producer.t index 9c50db736..bd95784c3 100644 --- a/t/47postgres-producer.t +++ b/t/47postgres-producer.t @@ -708,4 +708,20 @@ CREATE VIEW view_foo ( id, name ) AS is($drop_view_9_1_produced, $drop_view_9_1_expected, "My DROP VIEW statement for 9.1 is correct"); +my $mat_view = SQL::Translator::Schema::View->new( + name => 'view_foo', + fields => [qw/id name/], + sql => 'SELECT id, name FROM thing', + extra => { + materialized => 1 + } +); + +my $mat_view_sql = SQL::Translator::Producer::PostgreSQL::create_view($mat_view, { no_comments => 1 }); + +my $mat_view_sql_expected = "CREATE MATERIALIZED VIEW view_foo ( id, name ) AS + SELECT id, name FROM thing +"; + +is($mat_view_sql, $mat_view_sql_expected, 'correct "MATERIALIZED VIEW" SQL'); done_testing; From 321661ddbd7211875d2fda4eb50cac6241913814 Mon Sep 17 00:00:00 2001 From: Veesh Goldman Date: Tue, 10 Aug 2021 23:53:26 +0300 Subject: [PATCH 2/4] start working on the parser for materialized views --- lib/SQL/Translator/Parser/PostgreSQL.pm | 13 +++++++++++++ t/14postgres-parser.t | 6 ++++++ 2 files changed, 19 insertions(+) diff --git a/lib/SQL/Translator/Parser/PostgreSQL.pm b/lib/SQL/Translator/Parser/PostgreSQL.pm index 37f657996..0a9ef1653 100644 --- a/lib/SQL/Translator/Parser/PostgreSQL.pm +++ b/lib/SQL/Translator/Parser/PostgreSQL.pm @@ -264,6 +264,19 @@ create : CREATE or_replace(?) temporary(?) VIEW view_id view_fields(?) /AS/i vie } } +create: CREATE /MATERIALIZED VIEW/i if_not_exists(?) view_id view_fields(?) /AS/i view_target ';' + { + push @views, { + schema_name => $item{view_id}{schema_name}, + view_name => $item{view_id}{view_name}, + sql => $item{view_target}, + fields => $item[5], + extra => { materialized => 1 } + } + } + +if_not_exists : /IF NOT EXISTS/i + trigger_name : NAME trigger_scope : /FOR/i /EACH/i /(ROW|STATEMENT)/i { $return = lc $1 } diff --git a/t/14postgres-parser.t b/t/14postgres-parser.t index 3c9dcd449..5cac28539 100644 --- a/t/14postgres-parser.t +++ b/t/14postgres-parser.t @@ -113,6 +113,12 @@ baz $foo$, alter table t_test1 owner to foo; + -- we should tests views if they're supported, right? + + create or replace temporary view fez (foo, bar) as select foo, count(bar) as bar from baz group by foo; + + create materialized view if not exists baa (black, sheep) as select foo black, bar sheep from baz; + commit; }; From d90e27c3bc965a1322a2eec559b5352372ec2e26 Mon Sep 17 00:00:00 2001 From: Veesh Goldman Date: Fri, 8 Jul 2022 14:07:45 +0300 Subject: [PATCH 3/4] fix conflict w/ Changes --- Changes | 1 + 1 file changed, 1 insertion(+) diff --git a/Changes b/Changes index 7669e1d39..4ae291311 100644 --- a/Changes +++ b/Changes @@ -2,6 +2,7 @@ Changes for SQL::Translator * sqlt-diff: Change producer_args to sqlt_args for better self-documentation * Support INCLUDE on indices for Pg (producer + parser) + * Postgres producer now supports materialized views via $extra->{materialized} 1.62 - 2020-09-14 * Update Pg support to allow version 12 (still supporting back to 7.4) From 8bb9433e2bcc3bf45eefe86cdc21c47534f3ec6b Mon Sep 17 00:00:00 2001 From: Veesh Goldman Date: Fri, 8 Jul 2022 14:19:45 +0300 Subject: [PATCH 4/4] document the `extra` options that are available --- lib/SQL/Translator/Producer/PostgreSQL.pm | 49 +++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/lib/SQL/Translator/Producer/PostgreSQL.pm b/lib/SQL/Translator/Producer/PostgreSQL.pm index fd03c2d3e..79d7c4433 100644 --- a/lib/SQL/Translator/Producer/PostgreSQL.pm +++ b/lib/SQL/Translator/Producer/PostgreSQL.pm @@ -19,6 +19,9 @@ Does not yet support PostGIS Views. =head2 Producer Args +You can change the global behavior of the producer by passing the following options to the +C attribute of C. + =over 4 =item postgres_version @@ -50,6 +53,52 @@ instead of this =back +=head2 Extra args + +Various schema types support various options via the C attribute. + +=over 2 + +=item Tables + +=over 2 + +=item temporary + +Produces a temporary table. + +=back + +=item Views + +=over 2 + +=item temporary + +Produces a temporary view. + +=item materialized + +Produces a materialized view. + +=back + +=item Fields + +=over 2 + +=item list, custom_type_name + +For enum types, list is the list of valid values, and custom_type_name is the name that +the type should have. Defaults to $table_$field_type. + +=item geometry_type, srid, dimensions, geography_type + +Fields for use with PostGIS types. + +=back + +=back =cut