Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow to create unlogged IMMVs #91

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ EXTENSION = pg_ivm
DATA = pg_ivm--1.0.sql \
pg_ivm--1.0--1.1.sql pg_ivm--1.1--1.2.sql pg_ivm--1.2--1.3.sql \
pg_ivm--1.3--1.4.sql pg_ivm--1.4--1.5.sql pg_ivm--1.5--1.6.sql \
pg_ivm--1.6--1.7.sql pg_ivm--1.7--1.8.sql pg_ivm--1.8--1.9.sql
pg_ivm--1.6--1.7.sql pg_ivm--1.7--1.8.sql pg_ivm--1.8--1.9.sql \
pg_ivm--1.9--1.10.sql

REGRESS = pg_ivm create_immv refresh_immv

Expand Down
12 changes: 9 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,15 +86,21 @@ 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`.

#### refresh_imm
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 Expand Up @@ -267,7 +273,7 @@ If some base tables have row level security policy, rows that are not visible to

IVM is effective when we want to keep an IMMV up-to-date and small fraction of a base table is modified infrequently. Due to the overhead of immediate maintenance, IVM is not effective when a base table is modified frequently. Also, when a large part of a base table is modified or large data is inserted into a base table, IVM is not effective and the cost of maintenance can be larger than refresh from scratch.

In such situation, we can use `refesh_immv` function with `with_data = false` to disable immediate maintenance before modifying a base table. After a base table modification, call `refresh_immv`with `with_data = true` to refresh the view data and enable immediate maintenance.
In such situation, we can use `refresh_immv` function with `with_data = false` to disable immediate maintenance before modifying a base table. After a base table modification, call `refresh_immv`with `with_data = true` to refresh the view data and enable immediate maintenance.

## Authors
IVM Development Group
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
9 changes: 9 additions & 0 deletions pg_ivm--1.9--1.10.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
-- functions

CREATE FUNCTION create_immv(text, text, boolean default false)
RETURNS bigint
STRICT
AS 'MODULE_PATHNAME', 'create_immv'
LANGUAGE C;

DROP FUNCTION create_immv(text, text);
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.control
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# incremental view maintenance extension_
comment = 'incremental view maintenance on PostgreSQL'
default_version = '1.9'
default_version = '1.10'
module_pathname = '$libdir/pg_ivm'
relocatable = false
schema = pg_catalog
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
4 changes: 3 additions & 1 deletion rpm/pg_ivm.spec
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

Summary: PostgreSQL-based distributed RDBMS
Name: %{sname}_%{pgmajorversion}
Version: 1.9
Version: 1.10
Release: 1%{dist}
License: BSD
Vendor: IVM Development Group
Expand Down Expand Up @@ -55,6 +55,8 @@ PATH=%{pginstdir}/bin:$PATH %{__make} %{?_smp_mflags} INSTALL_PREFIX=%{buildroot
%endif

%changelog
* Mon Aug 26 2024 - Jamal Boukaffal <[email protected]> 1.10-1
- Update to 1.10
* Fri Jul 31 2024 - Yugo Nagata <[email protected]> 1.9-1
- Update to 1.9
* Fri Mar 1 2024 - Yugo Nagata <[email protected]> 1.8-1
Expand Down