Skip to content

Commit

Permalink
Allow to create unlogged IMMVs
Browse files Browse the repository at this point in the history
  • Loading branch information
Jamal-B committed Aug 26, 2024
1 parent 90e28a8 commit 9ff132b
Show file tree
Hide file tree
Showing 4 changed files with 20 additions and 5 deletions.
8 changes: 7 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,14 +86,20 @@ When `pg_ivm` is installed, the following objects are created.

Use `create_immv` function to create IMMV.
```
create_immv(immv_name text, view_definition text) RETURNS bigint
create_immv(immv_name text, view_definition text [, unlogged bool DEFAULT false]) RETURNS bigint
```
`create_immv` defines a new IMMV of a query. A table of the name `immv_name` is created and a query specified by `view_definition` is executed and used to populate the IMMV. The query is stored in `pg_ivm_immv`, so that it can be refreshed later upon incremental view maintenance. `create_immv` returns the number of rows in the created IMMV.

When an IMMV is created, some triggers are automatically created so that the view's contents are immediately updated when its base tables are modified. In addition, a unique index is created on the IMMV automatically if possible. If the view definition query has a GROUP BY clause, a unique index is created on the columns of GROUP BY expressions. Also, if the view has DISTINCT clause, a unique index is created on all columns in the target list. Otherwise, if the IMMV contains all primary key attributes of its base tables in the target list, a unique index is created on these attributes. In other cases, no index is created.

Note that if you use PostgreSQL 17 or later, while `create_immv` is running, the `search_path` is temporarily changed to `pg_catalog, pg_temp`.

In some cases (e.g. for very large IMMVs containing volatile data), and only if you really know what you are doing, it may be useful to create an IMMV without writing to the [PostgreSQL Write-Ahead Logs](https://www.postgresql.org/docs/current/wal-intro.html) (the underlying table is created with the `UNLOGGED` parameter). Unlogged tables improve write performance, reduce vacuum impact and produce fewer WALs (thus reducing network usage, backup size and restoration time).
```sql
SELECT create_immv('myview', 'SELECT * FROM mytab', true);
```
**Important:** see the [PostgreSQL documentation](https://www.postgresql.org/docs/current/sql-createtable.html#SQL-CREATETABLE-UNLOGGED) for unlogged tables **DRAWBACKS** (not replicated or included in physical backups, truncated in case of PostgreSQL crash, ...).

#### refresh_immv

Use `refresh_immv` function to refresh IMMV.
Expand Down
12 changes: 10 additions & 2 deletions createas.c
Original file line number Diff line number Diff line change
Expand Up @@ -234,14 +234,22 @@ create_immv_nodata(List *tlist, IntoClause *into)
*/
ObjectAddress
ExecCreateImmv(ParseState *pstate, CreateTableAsStmt *stmt,
ParamListInfo params, QueryEnvironment *queryEnv,
QueryCompletion *qc)
bool unlogged, ParamListInfo params,
QueryEnvironment *queryEnv, QueryCompletion *qc)
{
Query *query = castNode(Query, stmt->query);
IntoClause *into = stmt->into;
bool do_refresh = false;
ObjectAddress address;

/*
* For volatile data, it can be useful not to write to WALs.
* SEE THE POSTGRESQL DOCUMENTATION FOR DRAWBACKS (not replicated or included in physical backups, truncated in case of a crash, ...):
* https://www.postgresql.org/docs/current/sql-createtable.html#SQL-CREATETABLE-UNLOGGED
*/
if (unlogged)
into->rel->relpersistence = RELPERSISTENCE_UNLOGGED;

/* Check if the relation exists or not */
if (CreateTableAsRelExists(stmt))
return InvalidObjectAddress;
Expand Down
3 changes: 2 additions & 1 deletion pg_ivm.c
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,7 @@ create_immv(PG_FUNCTION_ARGS)
{
text *t_relname = PG_GETARG_TEXT_PP(0);
text *t_sql = PG_GETARG_TEXT_PP(1);
bool unlogged = PG_GETARG_BOOL(2);
char *relname = text_to_cstring(t_relname);
char *sql = text_to_cstring(t_sql);
List *parsetree_list;
Expand Down Expand Up @@ -228,7 +229,7 @@ create_immv(PG_FUNCTION_ARGS)
query = transformStmt(pstate, (Node *)ctas);
Assert(query->commandType == CMD_UTILITY && IsA(query->utilityStmt, CreateTableAsStmt));

ExecCreateImmv(pstate, (CreateTableAsStmt *) query->utilityStmt, NULL, NULL, &qc);
ExecCreateImmv(pstate, (CreateTableAsStmt *) query->utilityStmt, unlogged, NULL, NULL, &qc);

PG_RETURN_INT64(qc.nprocessed);
}
Expand Down
2 changes: 1 addition & 1 deletion pg_ivm.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ extern bool isImmv(Oid immv_oid);

/* createas.c */

extern ObjectAddress ExecCreateImmv(ParseState *pstate, CreateTableAsStmt *stmt,
extern ObjectAddress ExecCreateImmv(ParseState *pstate, CreateTableAsStmt *stmt, bool unlogged,
ParamListInfo params, QueryEnvironment *queryEnv,
QueryCompletion *qc);
extern void CreateIvmTriggersOnBaseTables(Query *qry, Oid matviewOid);
Expand Down

0 comments on commit 9ff132b

Please sign in to comment.