Compare commits

..

1 commit

Author SHA1 Message Date
Yugo Nagata
2949e99d7c Add support for PostgreSQL 18
- Fixed compiler errors and warnings.
- Added expected/pg_ivm_0.out to accommodate message changes introduced in PostgreSQL 18.
2025-07-09 19:13:07 +09:00
10 changed files with 93 additions and 118 deletions

28
.gitignore vendored
View file

@ -1,30 +1,8 @@
# Object files
*.o
# Coverage files
*.gcno
*.gcda
# Libraries
*.lib
*.a
# LLVM bitcode
# Global excludes across all subdirectories
*.bc
# Shared objects (inc. Windows DLLs)
*.dll
*.o
*.so
*.so.*
*.dylib
# Executables
*.exe
*.app
# Dependencies
.deps
regression.*
# Generated subdirectories
/results/
/output_iso/

View file

@ -18,8 +18,8 @@ DATA = pg_ivm--1.0.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.9--1.10.sql \
pg_ivm--1.10.sql \
pg_ivm--1.10--1.11.sql pg_ivm--1.11--1.12.sql
pg_ivm--1.10.sql \
pg_ivm--1.10--1.11.sql
REGRESS = pg_ivm create_immv refresh_immv

View file

@ -2,7 +2,7 @@
The `pg_ivm` module provides Incremental View Maintenance (IVM) feature for PostgreSQL.
The extension is compatible with PostgreSQL 13, 14, 15, 16, 17, and 18.
The extension is compatible with PostgreSQL 13, 14, 15, 16, and 17.
## Description
@ -120,7 +120,7 @@ pgivm.refresh_immv(immv_name text, with_data bool) RETURNS bigint
`refresh_immv` completely replaces the contents of an IMMV as `REFRESH MATERIALIZED VIEW` command does for a materialized view. To execute this function you must be the owner of the IMMV (with PostgreSQL 16 or earlier) or have the `MAINTAIN` privilege on the IMMV (with PostgreSQL 17 or later). The old contents are discarded.
The with_data flag is corresponding to `WITH [NO] DATA` option of `REFRESH MATERIALIZED VIEW` command. If with_data is true, the backing query is executed to provide the new data, and if the IMMV is unpopulated, triggers for maintaining the view are created. Also, a unique index is created for IMMV if it is possible and the view doesn't have that yet. If with_data is false, no new data is generated and the IMMV become unpopulated, and the triggers are dropped from the IMMV. Note that unpopulated IMMV is still scannable although the result is empty. This behaviour may be changed in future to raise an error when an unpopulated IMMV is scanned.
The with_data flag is corresponding to `WITH [NO] DATA` option of REFRESH MATERIALIZED VIEW` command. If with_data is true, the backing query is executed to provide the new data, and if the IMMV is unpopulated, triggers for maintaining the view are created. Also, a unique index is created for IMMV if it is possible and the view doesn't have that yet. If with_data is false, no new data is generated and the IMMV become unpopulated, and the triggers are dropped from the IMMV. Note that unpopulated IMMV is still scannable although the result is empty. This behaviour may be changed in future to raise an error when an unpopulated IMMV is scanned.
`refresh_immv` acquires `AccessExclusiveLock` on the view. However, even if we are able to acquire the lock, a concurrent transaction may have already incrementally updated and committed the view before we can acquire the lock. In `REPEATABLE READ` or `SERIALIZABLE` isolation level, this could lead to an inconsistent state of the view. Therefore, an error is raised to prevent anomalies when this situation is detected.

View file

@ -1533,17 +1533,17 @@ ERROR: VALUES is not supported on incrementally maintainable materialized view
SELECT pgivm.create_immv('mv_ivm_only_values2', 'SELECT * FROM (values(1)) AS tmp');
ERROR: VALUES is not supported on incrementally maintainable materialized view
-- views containing base tables with Row Level Security
DROP USER IF EXISTS regress_ivm_admin;
NOTICE: role "regress_ivm_admin" does not exist, skipping
DROP USER IF EXISTS regress_ivm_user;
NOTICE: role "regress_ivm_user" does not exist, skipping
CREATE USER regress_ivm_admin;
CREATE USER regress_ivm_user;
DROP USER IF EXISTS ivm_admin;
NOTICE: role "ivm_admin" does not exist, skipping
DROP USER IF EXISTS ivm_user;
NOTICE: role "ivm_user" does not exist, skipping
CREATE USER ivm_admin;
CREATE USER ivm_user;
--- create a table with RLS
SET SESSION AUTHORIZATION regress_ivm_admin;
SET SESSION AUTHORIZATION ivm_admin;
CREATE TABLE rls_tbl(id int, data text, owner name);
INSERT INTO rls_tbl VALUES
(1,'foo','regress_ivm_user'),
(1,'foo','ivm_user'),
(2,'bar','postgres');
CREATE TABLE num_tbl(id int, num text);
INSERT INTO num_tbl VALUES
@ -1558,8 +1558,8 @@ CREATE POLICY rls_tbl_policy ON rls_tbl FOR SELECT TO PUBLIC USING(owner = curre
ALTER TABLE rls_tbl ENABLE ROW LEVEL SECURITY;
GRANT ALL on rls_tbl TO PUBLIC;
GRANT ALL on num_tbl TO PUBLIC;
--- create a view owned by regress_ivm_user
SET SESSION AUTHORIZATION regress_ivm_user;
--- create a view owned by ivm_user
SET SESSION AUTHORIZATION ivm_user;
SELECT pgivm.create_immv('ivm_rls', 'SELECT * FROM rls_tbl');
NOTICE: could not create an index on immv "ivm_rls" automatically
DETAIL: This target list does not have all the primary key columns, or this view does not contain GROUP BY or DISTINCT clause.
@ -1570,42 +1570,42 @@ HINT: Create an index on the immv for efficient incremental maintenance.
(1 row)
SELECT id, data, owner FROM ivm_rls ORDER BY 1,2,3;
id | data | owner
----+------+------------------
1 | foo | regress_ivm_user
id | data | owner
----+------+----------
1 | foo | ivm_user
(1 row)
RESET SESSION AUTHORIZATION;
--- inserts rows owned by different users
INSERT INTO rls_tbl VALUES
(3,'baz','regress_ivm_user'),
(3,'baz','ivm_user'),
(4,'qux','postgres');
SELECT id, data, owner FROM ivm_rls ORDER BY 1,2,3;
id | data | owner
----+------+------------------
1 | foo | regress_ivm_user
3 | baz | regress_ivm_user
id | data | owner
----+------+----------
1 | foo | ivm_user
3 | baz | ivm_user
(2 rows)
--- combination of diffent kinds of commands
WITH
i AS (INSERT INTO rls_tbl VALUES(5,'quux','postgres'), (6,'corge','regress_ivm_user')),
i AS (INSERT INTO rls_tbl VALUES(5,'quux','postgres'), (6,'corge','ivm_user')),
u AS (UPDATE rls_tbl SET owner = 'postgres' WHERE id = 1),
u2 AS (UPDATE rls_tbl SET owner = 'regress_ivm_user' WHERE id = 2)
u2 AS (UPDATE rls_tbl SET owner = 'ivm_user' WHERE id = 2)
SELECT;
--
(1 row)
SELECT id, data, owner FROM ivm_rls ORDER BY 1,2,3;
id | data | owner
----+-------+------------------
2 | bar | regress_ivm_user
3 | baz | regress_ivm_user
6 | corge | regress_ivm_user
id | data | owner
----+-------+----------
2 | bar | ivm_user
3 | baz | ivm_user
6 | corge | ivm_user
(3 rows)
---
SET SESSION AUTHORIZATION regress_ivm_user;
SET SESSION AUTHORIZATION ivm_user;
SELECT pgivm.create_immv('ivm_rls2', 'SELECT * FROM rls_tbl JOIN num_tbl USING(id)');
NOTICE: could not create an index on immv "ivm_rls2" automatically
DETAIL: This target list does not have all the primary key columns, or this view does not contain GROUP BY or DISTINCT clause.
@ -1624,11 +1624,11 @@ SELECT;
(1 row)
SELECT * FROM ivm_rls2 ORDER BY 1,2,3;
id | data | owner | num
----+-------+------------------+---------
2 | bar | regress_ivm_user | two
3 | baz_2 | regress_ivm_user | three_2
6 | corge | regress_ivm_user | six
id | data | owner | num
----+-------+----------+---------
2 | bar | ivm_user | two
3 | baz_2 | ivm_user | three_2
6 | corge | ivm_user | six
(3 rows)
DROP TABLE rls_tbl CASCADE;
@ -1636,8 +1636,8 @@ NOTICE: drop cascades to 2 other objects
DETAIL: drop cascades to table ivm_rls
drop cascades to table ivm_rls2
DROP TABLE num_tbl CASCADE;
DROP USER regress_ivm_user;
DROP USER regress_ivm_admin;
DROP USER ivm_user;
DROP USER ivm_admin;
-- automatic index creation
BEGIN;
CREATE TABLE base_a (i int primary key, j int);

View file

@ -1531,17 +1531,17 @@ ERROR: VALUES is not supported on incrementally maintainable materialized view
SELECT pgivm.create_immv('mv_ivm_only_values2', 'SELECT * FROM (values(1)) AS tmp');
ERROR: VALUES is not supported on incrementally maintainable materialized view
-- views containing base tables with Row Level Security
DROP USER IF EXISTS regress_ivm_admin;
NOTICE: role "regress_ivm_admin" does not exist, skipping
DROP USER IF EXISTS regress_ivm_user;
NOTICE: role "regress_ivm_user" does not exist, skipping
CREATE USER regress_ivm_admin;
CREATE USER regress_ivm_user;
DROP USER IF EXISTS ivm_admin;
NOTICE: role "ivm_admin" does not exist, skipping
DROP USER IF EXISTS ivm_user;
NOTICE: role "ivm_user" does not exist, skipping
CREATE USER ivm_admin;
CREATE USER ivm_user;
--- create a table with RLS
SET SESSION AUTHORIZATION regress_ivm_admin;
SET SESSION AUTHORIZATION ivm_admin;
CREATE TABLE rls_tbl(id int, data text, owner name);
INSERT INTO rls_tbl VALUES
(1,'foo','regress_ivm_user'),
(1,'foo','ivm_user'),
(2,'bar','postgres');
CREATE TABLE num_tbl(id int, num text);
INSERT INTO num_tbl VALUES
@ -1556,8 +1556,8 @@ CREATE POLICY rls_tbl_policy ON rls_tbl FOR SELECT TO PUBLIC USING(owner = curre
ALTER TABLE rls_tbl ENABLE ROW LEVEL SECURITY;
GRANT ALL on rls_tbl TO PUBLIC;
GRANT ALL on num_tbl TO PUBLIC;
--- create a view owned by regress_ivm_user
SET SESSION AUTHORIZATION regress_ivm_user;
--- create a view owned by ivm_user
SET SESSION AUTHORIZATION ivm_user;
SELECT pgivm.create_immv('ivm_rls', 'SELECT * FROM rls_tbl');
NOTICE: could not create an index on immv "ivm_rls" automatically
DETAIL: This target list does not have all the primary key columns, or this view does not contain GROUP BY or DISTINCT clause.
@ -1568,42 +1568,42 @@ HINT: Create an index on the immv for efficient incremental maintenance.
(1 row)
SELECT id, data, owner FROM ivm_rls ORDER BY 1,2,3;
id | data | owner
----+------+------------------
1 | foo | regress_ivm_user
id | data | owner
----+------+----------
1 | foo | ivm_user
(1 row)
RESET SESSION AUTHORIZATION;
--- inserts rows owned by different users
INSERT INTO rls_tbl VALUES
(3,'baz','regress_ivm_user'),
(3,'baz','ivm_user'),
(4,'qux','postgres');
SELECT id, data, owner FROM ivm_rls ORDER BY 1,2,3;
id | data | owner
----+------+------------------
1 | foo | regress_ivm_user
3 | baz | regress_ivm_user
id | data | owner
----+------+----------
1 | foo | ivm_user
3 | baz | ivm_user
(2 rows)
--- combination of diffent kinds of commands
WITH
i AS (INSERT INTO rls_tbl VALUES(5,'quux','postgres'), (6,'corge','regress_ivm_user')),
i AS (INSERT INTO rls_tbl VALUES(5,'quux','postgres'), (6,'corge','ivm_user')),
u AS (UPDATE rls_tbl SET owner = 'postgres' WHERE id = 1),
u2 AS (UPDATE rls_tbl SET owner = 'regress_ivm_user' WHERE id = 2)
u2 AS (UPDATE rls_tbl SET owner = 'ivm_user' WHERE id = 2)
SELECT;
--
(1 row)
SELECT id, data, owner FROM ivm_rls ORDER BY 1,2,3;
id | data | owner
----+-------+------------------
2 | bar | regress_ivm_user
3 | baz | regress_ivm_user
6 | corge | regress_ivm_user
id | data | owner
----+-------+----------
2 | bar | ivm_user
3 | baz | ivm_user
6 | corge | ivm_user
(3 rows)
---
SET SESSION AUTHORIZATION regress_ivm_user;
SET SESSION AUTHORIZATION ivm_user;
SELECT pgivm.create_immv('ivm_rls2', 'SELECT * FROM rls_tbl JOIN num_tbl USING(id)');
NOTICE: could not create an index on immv "ivm_rls2" automatically
DETAIL: This target list does not have all the primary key columns, or this view does not contain GROUP BY or DISTINCT clause.
@ -1622,11 +1622,11 @@ SELECT;
(1 row)
SELECT * FROM ivm_rls2 ORDER BY 1,2,3;
id | data | owner | num
----+-------+------------------+---------
2 | bar | regress_ivm_user | two
3 | baz_2 | regress_ivm_user | three_2
6 | corge | regress_ivm_user | six
id | data | owner | num
----+-------+----------+---------
2 | bar | ivm_user | two
3 | baz_2 | ivm_user | three_2
6 | corge | ivm_user | six
(3 rows)
DROP TABLE rls_tbl CASCADE;
@ -1634,8 +1634,8 @@ NOTICE: drop cascades to 2 other objects
DETAIL: drop cascades to table ivm_rls
drop cascades to table ivm_rls2
DROP TABLE num_tbl CASCADE;
DROP USER regress_ivm_user;
DROP USER regress_ivm_admin;
DROP USER ivm_user;
DROP USER ivm_admin;
-- automatic index creation
BEGIN;
CREATE TABLE base_a (i int primary key, j int);

View file

@ -60,7 +60,6 @@ install_data(
'pg_ivm--1.9--1.10.sql',
'pg_ivm--1.10.sql',
'pg_ivm--1.10--1.11.sql',
'pg_ivm--1.11--1.12.sql',
'pg_ivm.control',
install_dir: sharedir / 'extension',
)

View file

View file

@ -1,6 +1,6 @@
# incremental view maintenance extension
comment = 'incremental view maintenance on PostgreSQL'
default_version = '1.12'
default_version = '1.11'
module_pathname = '$libdir/pg_ivm'
relocatable = false
schema = pg_catalog

View file

@ -1,6 +1,6 @@
# How to build RPM:
#
# rpmbuild -bb pg_ivm.spec --define "pgmajorversion 18" --define "pginstdir /usr/pgsql-18"
# rpmbuild -bb pg_ivm.spec --define "pgmajorversion 17" --define "pginstdir /usr/pgsql-17"
%global sname pg_ivm
@ -8,11 +8,11 @@
%global llvm 1
%endif
Summary: Incremental View Maintenance (IVM) feature for PostgreSQL.
Summary: PostgreSQL-based distributed RDBMS
Name: %{sname}_%{pgmajorversion}
Version: 1.12
Version: 1.11
Release: 1%{dist}
License: PostgreSQL
License: BSD
Vendor: IVM Development Group
URL: https://github.com/sraoss/%{sname}
Source0: https://github.com/sraoss/%{sname}/archive/v%{version}.tar.gz
@ -55,10 +55,8 @@ PATH=%{pginstdir}/bin:$PATH %{__make} %{?_smp_mflags} INSTALL_PREFIX=%{buildroot
%endif
%changelog
* Mon Sep 4 2025 - Yugo Nagata <nagata@sraoss.co.jp> 1.12-1
- Update to 1.12
* Mon May 25 2025 - Yugo Nagata <nagata@sraoss.co.jp> 1.11-1
- Update to 1.11
- Update to 1.10
* Tue Mar 11 2025 - Yugo Nagata <nagata@sraoss.co.jp> 1.10-1
- Update to 1.10
* Fri Jul 31 2024 - Yugo Nagata <nagata@sraoss.co.jp> 1.9-1

View file

@ -596,16 +596,16 @@ SELECT pgivm.create_immv('mv_ivm_only_values2', 'SELECT * FROM (values(1)) AS t
-- views containing base tables with Row Level Security
DROP USER IF EXISTS regress_ivm_admin;
DROP USER IF EXISTS regress_ivm_user;
CREATE USER regress_ivm_admin;
CREATE USER regress_ivm_user;
DROP USER IF EXISTS ivm_admin;
DROP USER IF EXISTS ivm_user;
CREATE USER ivm_admin;
CREATE USER ivm_user;
--- create a table with RLS
SET SESSION AUTHORIZATION regress_ivm_admin;
SET SESSION AUTHORIZATION ivm_admin;
CREATE TABLE rls_tbl(id int, data text, owner name);
INSERT INTO rls_tbl VALUES
(1,'foo','regress_ivm_user'),
(1,'foo','ivm_user'),
(2,'bar','postgres');
CREATE TABLE num_tbl(id int, num text);
INSERT INTO num_tbl VALUES
@ -622,28 +622,28 @@ ALTER TABLE rls_tbl ENABLE ROW LEVEL SECURITY;
GRANT ALL on rls_tbl TO PUBLIC;
GRANT ALL on num_tbl TO PUBLIC;
--- create a view owned by regress_ivm_user
SET SESSION AUTHORIZATION regress_ivm_user;
--- create a view owned by ivm_user
SET SESSION AUTHORIZATION ivm_user;
SELECT pgivm.create_immv('ivm_rls', 'SELECT * FROM rls_tbl');
SELECT id, data, owner FROM ivm_rls ORDER BY 1,2,3;
RESET SESSION AUTHORIZATION;
--- inserts rows owned by different users
INSERT INTO rls_tbl VALUES
(3,'baz','regress_ivm_user'),
(3,'baz','ivm_user'),
(4,'qux','postgres');
SELECT id, data, owner FROM ivm_rls ORDER BY 1,2,3;
--- combination of diffent kinds of commands
WITH
i AS (INSERT INTO rls_tbl VALUES(5,'quux','postgres'), (6,'corge','regress_ivm_user')),
i AS (INSERT INTO rls_tbl VALUES(5,'quux','postgres'), (6,'corge','ivm_user')),
u AS (UPDATE rls_tbl SET owner = 'postgres' WHERE id = 1),
u2 AS (UPDATE rls_tbl SET owner = 'regress_ivm_user' WHERE id = 2)
u2 AS (UPDATE rls_tbl SET owner = 'ivm_user' WHERE id = 2)
SELECT;
SELECT id, data, owner FROM ivm_rls ORDER BY 1,2,3;
---
SET SESSION AUTHORIZATION regress_ivm_user;
SET SESSION AUTHORIZATION ivm_user;
SELECT pgivm.create_immv('ivm_rls2', 'SELECT * FROM rls_tbl JOIN num_tbl USING(id)');
RESET SESSION AUTHORIZATION;
@ -656,8 +656,8 @@ SELECT * FROM ivm_rls2 ORDER BY 1,2,3;
DROP TABLE rls_tbl CASCADE;
DROP TABLE num_tbl CASCADE;
DROP USER regress_ivm_user;
DROP USER regress_ivm_admin;
DROP USER ivm_user;
DROP USER ivm_admin;
-- automatic index creation
BEGIN;