Allow to create unlogged IMMVs

This commit is contained in:
Jamal-B 2024-07-09 13:22:17 +02:00
parent 90e28a8c1b
commit 9ff132b5e6
4 changed files with 20 additions and 5 deletions

View file

@ -86,7 +86,7 @@ When `pg_ivm` is installed, the following objects are created.
Use `create_immv` function to create IMMV. 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. `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.
@ -94,6 +94,12 @@ When an IMMV is created, some triggers are automatically created so that the vie
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`. 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 #### refresh_immv
Use `refresh_immv` function to refresh IMMV. Use `refresh_immv` function to refresh IMMV.

View file

@ -234,14 +234,22 @@ create_immv_nodata(List *tlist, IntoClause *into)
*/ */
ObjectAddress ObjectAddress
ExecCreateImmv(ParseState *pstate, CreateTableAsStmt *stmt, ExecCreateImmv(ParseState *pstate, CreateTableAsStmt *stmt,
ParamListInfo params, QueryEnvironment *queryEnv, bool unlogged, ParamListInfo params,
QueryCompletion *qc) QueryEnvironment *queryEnv, QueryCompletion *qc)
{ {
Query *query = castNode(Query, stmt->query); Query *query = castNode(Query, stmt->query);
IntoClause *into = stmt->into; IntoClause *into = stmt->into;
bool do_refresh = false; bool do_refresh = false;
ObjectAddress address; 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 */ /* Check if the relation exists or not */
if (CreateTableAsRelExists(stmt)) if (CreateTableAsRelExists(stmt))
return InvalidObjectAddress; return InvalidObjectAddress;

View file

@ -173,6 +173,7 @@ create_immv(PG_FUNCTION_ARGS)
{ {
text *t_relname = PG_GETARG_TEXT_PP(0); text *t_relname = PG_GETARG_TEXT_PP(0);
text *t_sql = PG_GETARG_TEXT_PP(1); text *t_sql = PG_GETARG_TEXT_PP(1);
bool unlogged = PG_GETARG_BOOL(2);
char *relname = text_to_cstring(t_relname); char *relname = text_to_cstring(t_relname);
char *sql = text_to_cstring(t_sql); char *sql = text_to_cstring(t_sql);
List *parsetree_list; List *parsetree_list;
@ -228,7 +229,7 @@ create_immv(PG_FUNCTION_ARGS)
query = transformStmt(pstate, (Node *)ctas); query = transformStmt(pstate, (Node *)ctas);
Assert(query->commandType == CMD_UTILITY && IsA(query->utilityStmt, CreateTableAsStmt)); 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); PG_RETURN_INT64(qc.nprocessed);
} }

View file

@ -35,7 +35,7 @@ extern bool isImmv(Oid immv_oid);
/* createas.c */ /* createas.c */
extern ObjectAddress ExecCreateImmv(ParseState *pstate, CreateTableAsStmt *stmt, extern ObjectAddress ExecCreateImmv(ParseState *pstate, CreateTableAsStmt *stmt, bool unlogged,
ParamListInfo params, QueryEnvironment *queryEnv, ParamListInfo params, QueryEnvironment *queryEnv,
QueryCompletion *qc); QueryCompletion *qc);
extern void CreateIvmTriggersOnBaseTables(Query *qry, Oid matviewOid); extern void CreateIvmTriggersOnBaseTables(Query *qry, Oid matviewOid);