From bf6c81110671565057d8039f4f6f5b8e0c893b98 Mon Sep 17 00:00:00 2001 From: Jeremy Palmer Date: Tue, 27 Feb 2024 21:23:11 +1100 Subject: [PATCH] feat: Support auto revisions --- .github/workflows/test.yml | 211 ++---------------------------- .pre-commit-config.yaml | 6 - Dockerfile | 43 +++++- doc/table_version.md | 53 +++++++- sql/01-enable_versioning.sql | 10 +- sql/03-create_revision.sql | 32 +++-- sql/04-complete_revision.sql | 14 +- sql/05-delete_revision.sql | 7 +- sql/13-create_version_trigger.sql | 24 ++-- sql/14-common.sql | 35 ----- test/ci/install-from-source.bash | 10 -- test/sql/base.pg | 88 ++++++++++++- 12 files changed, 232 insertions(+), 301 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 795ba961..bbae39cf 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -17,218 +17,27 @@ jobs: steps: - name: Check out repository uses: actions/checkout@v3.5.2 - - - name: Install Nix - uses: cachix/install-nix-action@v21 - + - name: Install python + uses: actions/setup-python@v3 - name: Run pre-commit hooks - run: nix-shell --pure --run 'pre-commit run --all-files' + uses: pre-commit/action@v3.0.1 test-install-from-source: name: Test PostgreSQL ${{ matrix.pg }} source install on Ubuntu ${{ matrix.release }} - runs-on: ubuntu-20.04 - strategy: - fail-fast: false - matrix: - pg: ['11', '12', '13', '14', '15'] - release: [focal, jammy] - steps: - - name: Check out repository - uses: actions/checkout@v3.5.2 - - - name: Build Docker container - run: docker build --build-arg=RELEASE=${{ matrix.release }} --tag=tester . - - - name: Install from source - run: docker run --rm tester ./test/ci/install-from-source.bash ${{ matrix.pg }} - - test-package-upgrade: - name: Test PostgreSQL ${{ matrix.pg }} package upgrade on Ubuntu ${{ matrix.release }} - runs-on: ubuntu-20.04 - strategy: - fail-fast: false - matrix: - pg: ['11', '12', '13', '14'] # TODO: '15' - release: [focal] # TODO: jammy - steps: - - name: Check out repository - uses: actions/checkout@v3.5.2 - with: - fetch-depth: 0 - - - name: Build package - uses: linz/linz-software-repository@v15 - with: - release: ${{ matrix.release }} - packages: jq - - - name: Build Docker container - run: docker build --build-arg=RELEASE=${{ matrix.release }} --tag=tester . - - - name: Upgrade from latest release - run: - docker run --rm --volume="${PWD}/build-area:/packages" tester - ./test/ci/package-upgrade.bash ${{ matrix.pg }} - - - name: Archive generated packages - uses: actions/upload-artifact@v3.1.2 - with: - name: PostgreSQL ${{ matrix.pg }} packages for Ubuntu ${{ matrix.release }} - path: 'build-area/*.deb' - if: failure() - - test-source-upgrade: - name: Test PostgreSQL ${{ matrix.pg }} source upgrade on Ubuntu ${{ matrix.release }} - runs-on: ubuntu-20.04 - strategy: - fail-fast: false - matrix: - pg: ['11', '12', '13', '14'] # TODO: '15' - release: [focal] # TODO: jammy - steps: - - name: Check out repository - uses: actions/checkout@v3.5.2 - - - name: Build Docker container - run: docker build --build-arg=RELEASE=${{ matrix.release }} --tag=tester . - - - name: Upgrade from source - run: docker run --rm tester ./test/ci/source-upgrade.bash ${{ matrix.pg }} - - test-source-upgrade-using-loader: - name: - Test PostgreSQL ${{ matrix.pg }} package upgrade using loader on Ubuntu ${{ matrix.release }} - runs-on: ubuntu-20.04 - strategy: - fail-fast: false - matrix: - pg: ['11', '12', '13', '14'] # TODO: '15' - release: [focal] # TODO: jammy - steps: - - name: Check out repository - uses: actions/checkout@v3.5.2 - - - name: Build Docker container - run: docker build --build-arg=RELEASE=${{ matrix.release }} --tag=tester . - - - name: Upgrade from latest release - run: docker run --rm tester ./test/ci/source-upgrade-using-loader.bash ${{ matrix.pg }} - - test-source-upgrade-using-loader-without-extension-support: - name: - Test PostgreSQL ${{ matrix.pg }} package upgrade using loader without extension support on - Ubuntu ${{ matrix.release }} - runs-on: ubuntu-20.04 - strategy: - fail-fast: false - matrix: - pg: ['11', '12', '13', '14'] # TODO: '15' - release: [focal] # TODO: jammy - steps: - - name: Check out repository - uses: actions/checkout@v3.5.2 - - - name: Build Docker container - run: docker build --build-arg=RELEASE=${{ matrix.release }} --tag=tester . - - - name: Upgrade from latest release - run: - docker run --rm tester - ./test/ci/source-upgrade-using-loader-without-extension-support.bash ${{ matrix.pg }} - - test-package: - name: Test PostgreSQL ${{ matrix.pg }} package install on ${{ matrix.release }} - runs-on: ubuntu-20.04 + runs-on: ubuntu-22.04 strategy: fail-fast: false matrix: - pg: ['11', '12', '13', '14'] # TODO: '15' - release: [focal] # TODO: jammy + pg: ['12', '13', '14', '15', '16'] + release: [20.04, 22.04] steps: - name: Check out repository uses: actions/checkout@v3.5.2 - with: - fetch-depth: 0 - - - name: Build package - uses: linz/linz-software-repository@v15 - with: - release: ${{ matrix.release }} - packages: jq - name: Build Docker container - run: docker build --build-arg=RELEASE=${{ matrix.release }} --tag=tester . - - - name: Upgrade from latest release run: - docker run --rm --volume="${PWD}/build-area:/packages" tester - ./test/ci/install-local-package.bash ${{ matrix.pg }} + docker build --build-arg=RELEASE=${{ matrix.release }} --build-arg="PG_VERSION=${{ + matrix.pg }}" --tag=tester . - package: - needs: - - lint - - test-install-from-source - - test-package - - test-package-upgrade - - test-source-upgrade - - test-source-upgrade-using-loader - - test-source-upgrade-using-loader-without-extension-support - name: Package for Ubuntu ${{ matrix.release }} - runs-on: ubuntu-20.04 - strategy: - fail-fast: false - matrix: - release: [focal, jammy] - max-parallel: 1 - steps: - - name: Check out repository - uses: actions/checkout@v3.5.2 - with: - fetch-depth: 0 - - - name: Determine packagecloud publication target - run: | - # TODO: it would be nice to turn this into a single-liner in - # github-action syntax - echo "GitHub ref: ${{ github.ref }}" - echo "GitHub event_name: ${{ github.event_name }}" - REPO= - if test "${{ github.event_name }}" = 'push'; then - if expr "${{ github.ref }}" : "refs/tags/" > /dev/null; then - REPO=test - git remote set-url origin https://x-access-token:${{ secrets.GITHUB_TOKEN }}@github.com/$GITHUB_REPOSITORY - elif test "${{ github.ref }}" = 'refs/heads/packagecloud' \ - -o "${{ github.ref }}" = 'refs/heads/master' - then - REPO=dev - fi - fi - echo "REPO=$REPO" | tee --append $GITHUB_ENV - - - name: Build and release package - uses: linz/linz-software-repository@v15 - with: - release: ${{ matrix.release }} - packages: jq - packagecloud_token: ${{ secrets.LINZCI_PACKAGECLOUD_TOKEN }} - packagecloud_repository: ${{ env.REPO }} - push_to_git_remote: origin - - finalise: - name: Verify all dependencies passed - if: always() - needs: - - lint - - package - - test-install-from-source - - test-package - - test-package-upgrade - - test-source-upgrade - - test-source-upgrade-using-loader - - test-source-upgrade-using-loader-without-extension-support - runs-on: ubuntu-22.04 - steps: - - name: Decide whether the needed jobs succeeded or failed - uses: re-actors/alls-green@v1.2.2 - with: - jobs: ${{ toJSON(needs) }} + - name: Install from source + run: docker run --rm tester ./test/ci/install-from-source.bash diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 44244076..f8b41f79 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -8,12 +8,6 @@ repos: - id: hadolint-docker stages: [commit] - - repo: https://github.com/nix-community/nixpkgs-fmt - rev: 6740ea881d3ac5942d4fbf124f5956b896666c76 # frozen: v1.3.0 - hooks: - - id: nixpkgs-fmt - stages: [commit] - - repo: https://github.com/pre-commit/mirrors-prettier rev: cafd5506f18eea191804850dacc0a4264772d59d # frozen: v3.0.0-alpha.4 hooks: diff --git a/Dockerfile b/Dockerfile index f6cb222f..4519c96c 100644 --- a/Dockerfile +++ b/Dockerfile @@ -2,13 +2,19 @@ ARG RELEASE FROM ubuntu:${RELEASE} ARG RELEASE +ENV TZ=Pacific/Auckland + SHELL ["/bin/bash", "-o", "errexit", "-o", "nounset", "-o", "pipefail", "-O", "failglob", "-O", "inherit_errexit", "-c"] # hadolint ignore=DL3008 RUN apt-get update \ && apt-get --assume-yes install --no-install-recommends \ + build-essential \ + libmodule-build-perl \ ca-certificates \ + lsb-release \ curl \ + vim \ git \ gnupg \ make \ @@ -16,14 +22,39 @@ RUN apt-get update \ && rm -rf /var/lib/apt/lists/* # Enable PostgreSQL package repository +ARG PG_VERSION=15 RUN curl https://www.postgresql.org/media/keys/ACCC4CF8.asc | apt-key add - -RUN echo "deb http://apt.postgresql.org/pub/repos/apt/ ${RELEASE}-pgdg main" > /etc/apt/sources.list.d/pgdg.list +RUN echo "deb http://apt.postgresql.org/pub/repos/apt/ $(lsb_release -cs)-pgdg main" > /etc/apt/sources.list.d/pgdg.list +# hadolint ignore=DL3008 +RUN apt-get update \ + && DEBIAN_FRONTEND=noninteractive apt-get -y install --no-install-recommends postgresql-${PG_VERSION} \ + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* + +# Trust postgres user connections +RUN sed -i -e'/^local\s\+all\s\+postgres\s\+peer$/ s/peer/trust/' /etc/postgresql/${PG_VERSION}/main/pg_hba.conf + +# Install pgTap and pg_prove +# hadolint ignore=DL3003 +RUN git clone https://github.com/theory/pgtap.git \ + && cd pgtap \ + && make \ + && make install \ + && make clean +# hadolint ignore=DL3003 +RUN git clone https://github.com/theory/tap-parser-sourcehandler-pgtap.git \ + && cd tap-parser-sourcehandler-pgtap \ + && perl Build.PL \ + && ./Build install # Enable LINZ package repository -RUN curl https://packagecloud.io/install/repositories/linz/prod/script.deb.sh > script.deb.sh \ - && chmod u+x script.deb.sh \ - && os=ubuntu dist=${RELEASE} ./script.deb.sh \ - && rm script.deb.sh +RUN curl -s https://packagecloud.io/install/repositories/linz/prod/script.deb.sh | bash + +# hadolint ignore=DL3001 +RUN service postgresql start \ + && su --command='createuser --superuser root' postgres \ + && service postgresql stop + +ENTRYPOINT ["/bin/sh", "-c" , "service postgresql start && /bin/bash"] -COPY . /src WORKDIR /src diff --git a/doc/table_version.md b/doc/table_version.md index 3fff32da..f5fac402 100644 --- a/doc/table_version.md +++ b/doc/table_version.md @@ -160,7 +160,7 @@ upgrade it to a properly packaged extension with: CREATE EXTENSION table_version FROM unpackaged; -## Usage +## General Usage Take the following example. We have a table `bar` in schema `foo` and insert some data: @@ -261,6 +261,57 @@ Finally if you would like to remove versioning for the table call: SELECT table_version.ver_disable_versioning('foo', 'bar'); +## Auto revisions + +You can if you don't want to call the API functions of `ver_create_revision` and +`ver_complete_revision` explicitly. This can be useful if your application can't use the call the +API functions before editing. e.g. ongoing logical replication. + +Under this auto-revision mode, revision edits are grouped by transactions. + + CREATE EXTENSION table_version; + + CREATE SCHEMA foo; + + CREATE TABLE foo.bar ( + id INTEGER NOT NULL PRIMARY KEY, + baz TEXT + ); + + SELECT table_version.ver_enable_versioning('foo', 'bar'); + + BEGIN; + INSERT INTO foo.bar (id, baz) VALUES (1, 'foo bar 1'); + INSERT INTO foo.bar (id, baz) VALUES (2, 'foo bar 2'); + INSERT INTO foo.bar (id, baz) VALUES (3, 'foo bar 3'); + COMMIT; + + BEGIN; + UPDATE foo.bar + SET baz = 'foo bar 1 edit' + WHERE id = 1; + COMMIT; + + + SELECT * FROM table_version.foo_bar_revision; + + _revision_created | _revision_expired | id | baz + -------------------+-------------------+----+---------------- + 1001 | | 2 | foo bar 2 + 1001 | | 3 | foo bar 3 + 1001 | 1002 | 1 | foo bar 1 + 1002 | | 1 | foo bar 1 edit + + (3 row) + +The revision message will be automatically created for you based on the transaction ID. + + id | revision_time | start_time | user_name | schema_change | comment + ------+----------------------------+----------------------------+-----------+---------------+--------------- + 1001 | 2024-02-26 22:10:30.751895 | 2024-02-26 22:10:30.758708 | postgres | f | Auto Txn 4859 + 1002 | 2024-02-27 08:38:44.548215 | 2024-02-27 08:38:44.556542 | root | f | Auto Txn 4860 + (2 rows) + ## Replicate data using table differences If you would like to maintain a copy of table data on a remote system this is easily done with this diff --git a/sql/01-enable_versioning.sql b/sql/01-enable_versioning.sql index 1d7ac12e..9a60dca9 100644 --- a/sql/01-enable_versioning.sql +++ b/sql/01-enable_versioning.sql @@ -120,14 +120,8 @@ BEGIN INTO v_table_has_data; IF v_table_has_data THEN - IF @extschema@._ver_get_reversion_temp_table('_changeset_revision') THEN - SELECT - max(VER.revision) - INTO - v_revision - FROM - _changeset_revision VER; - + IF coalesce(current_setting('table_version.current_revision', TRUE), '') <> '' THEN + v_revision := current_setting('table_version.current_revision', TRUE)::INTEGER; v_revision_exists := TRUE; ELSE SELECT @extschema@.ver_create_revision( diff --git a/sql/03-create_revision.sql b/sql/03-create_revision.sql index 246d5057..397f9b95 100644 --- a/sql/03-create_revision.sql +++ b/sql/03-create_revision.sql @@ -9,20 +9,36 @@ $$ DECLARE v_revision @extschema@.revision.id%TYPE; BEGIN - IF @extschema@._ver_get_reversion_temp_table('_changeset_revision') THEN + SELECT @extschema@._ver_create_revision(p_comment, p_revision_time, p_schema_change) + INTO v_revision; + PERFORM set_config('table_version.manual_revision', 't', FALSE); + RETURN v_revision; +END; +$$ LANGUAGE plpgsql SECURITY DEFINER; + + + +CREATE OR REPLACE FUNCTION _ver_create_revision( + p_comment TEXT, + p_revision_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + p_schema_change BOOLEAN DEFAULT FALSE +) +RETURNS INTEGER AS +$$ +DECLARE + v_revision @extschema@.revision.id%TYPE; +BEGIN + IF coalesce(current_setting('table_version.manual_revision', TRUE), '') <> '' AND + coalesce(current_setting('table_version.current_revision', TRUE), '') <> '' + THEN RAISE EXCEPTION 'A revision changeset is still in progress. Please complete the revision before starting a new one'; END IF; INSERT INTO @extschema@.revision (revision_time, schema_change, comment, user_name) VALUES (p_revision_time, p_schema_change, p_comment, SESSION_USER) RETURNING id INTO v_revision; - - CREATE TEMP TABLE _changeset_revision( - revision INTEGER NOT NULL PRIMARY KEY - ); - INSERT INTO _changeset_revision(revision) VALUES (v_revision); - ANALYSE _changeset_revision; - + + PERFORM set_config('table_version.current_revision', v_revision::VARCHAR, FALSE); RETURN v_revision; END; $$ LANGUAGE plpgsql SECURITY DEFINER; diff --git a/sql/04-complete_revision.sql b/sql/04-complete_revision.sql index c68c3b75..d2274a6c 100644 --- a/sql/04-complete_revision.sql +++ b/sql/04-complete_revision.sql @@ -5,22 +5,24 @@ DECLARE v_user_name TEXT; BEGIN - IF NOT @extschema@._ver_get_reversion_temp_table('_changeset_revision') THEN + IF coalesce(current_setting('table_version.current_revision', TRUE), '') = '' THEN + RAISE EXCEPTION 'No in-progress revision'; RETURN FALSE; END IF; SELECT user_name - FROM @extschema@.revision r, _changeset_revision t - WHERE r.id = t.revision - INTO v_user_name; + FROM @extschema@.revision r + WHERE r.id = current_setting('table_version.current_revision', TRUE)::INTEGER + INTO v_user_name; IF NOT pg_has_role(session_user, v_user_name, 'usage') THEN RAISE EXCEPTION 'In-progress revision can only be completed ' 'by its creator user %', v_user_name; END IF; - DROP TABLE _changeset_revision; - + PERFORM set_config('table_version.current_revision', '', FALSE); + PERFORM set_config('table_version.manual_revision', '', FALSE); + RETURN TRUE; END; $$ LANGUAGE plpgsql SECURITY DEFINER; diff --git a/sql/05-delete_revision.sql b/sql/05-delete_revision.sql index 339e62b9..991a19ea 100644 --- a/sql/05-delete_revision.sql +++ b/sql/05-delete_revision.sql @@ -22,12 +22,9 @@ BEGIN RETURN FALSE; END IF; - IF @extschema@._ver_get_reversion_temp_table('_changeset_revision') + IF coalesce(current_setting('table_version.current_revision', TRUE), '') <> '' THEN - IF EXISTS ( - SELECT * FROM _changeset_revision - WHERE revision = p_revision - ) THEN + IF current_setting('table_version.current_revision', TRUE)::INTEGER = p_revision THEN RAISE WARNING 'Revision % is in progress, please complete it' ' before attempting to delete it.', p_revision; RETURN FALSE; diff --git a/sql/13-create_version_trigger.sql b/sql/13-create_version_trigger.sql index e2597701..fd5a6e9a 100644 --- a/sql/13-create_version_trigger.sql +++ b/sql/13-create_version_trigger.sql @@ -97,21 +97,17 @@ CREATE OR REPLACE FUNCTION %revision_table%() RETURNS trigger AS $TRIGGER$ RAISE EXCEPTION 'TRUNCATE is not supported on versioned tables'; END IF; - BEGIN - SELECT - max(VER.revision) - INTO - v_revision - FROM - _changeset_revision VER; - - IF v_revision IS NULL THEN - RAISE EXCEPTION 'Versioning system information is missing'; + IF coalesce(current_setting('table_version.manual_revision', TRUE), '') = '' THEN + IF coalesce(current_setting('table_version.last_txid', TRUE), '') = '' OR + current_setting('table_version.last_txid', TRUE)::INTEGER <> txid_current() + THEN + PERFORM table_version._ver_create_revision('Auto Txn ' || txid_current()); + PERFORM set_config('table_version.last_txid', txid_current()::VARCHAR, false); END IF; - EXCEPTION - WHEN undefined_table THEN - RAISE EXCEPTION 'To begin editing %full_table_name% you need to create a revision'; - END; + END IF; + + v_revision := current_setting('table_version.current_revision', TRUE)::INTEGER; + assert v_revision IS NOT NULL, 'Versioning system information is missing'; SELECT VTB.id diff --git a/sql/14-common.sql b/sql/14-common.sql index 9e519555..640b7b9b 100644 --- a/sql/14-common.sql +++ b/sql/14-common.sql @@ -136,41 +136,6 @@ RETURNS VARCHAR AS $$ SELECT ('@extschema@.' || quote_ident('ver_get_' || $1 || '_' || $2 || '_revision') || '(p_revision INTEGER)'); $$ LANGUAGE sql IMMUTABLE; -/** -* Determine if a temp table exists within the current SQL session. -* -* @param p_table_name The name of the temp table -* @return If true if the table exists. -*/ -CREATE OR REPLACE FUNCTION _ver_get_reversion_temp_table( - p_table_name NAME -) -RETURNS BOOLEAN AS -$$ -DECLARE - v_exists BOOLEAN; -BEGIN - SELECT - TRUE - INTO - v_exists - FROM - pg_catalog.pg_class c - LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace - WHERE - n.nspname LIKE 'pg_temp_%' AND - pg_catalog.pg_table_is_visible(c.oid) AND - c.relkind = 'r' AND - c.relname = p_table_name; - - IF v_exists IS NULL THEN - v_exists := FALSE; - END IF; - - RETURN v_exists; -END; -$$ LANGUAGE plpgsql SECURITY DEFINER; - /** * Get the owner for a table * diff --git a/test/ci/install-from-source.bash b/test/ci/install-from-source.bash index a973cdc6..08d51855 100755 --- a/test/ci/install-from-source.bash +++ b/test/ci/install-from-source.bash @@ -3,16 +3,6 @@ set -o errexit -o noclobber -o nounset -o pipefail -o xtrace shopt -s failglob inherit_errexit -postgresql_version="$1" -# shellcheck disable=SC2034 -readonly postgresql_version - -script_dir="$(dirname "${BASH_SOURCE[0]}")" -readonly script_dir - -# shellcheck source=test/ci/setup-postgresql.bash -. "${script_dir}/setup-postgresql.bash" - make make check make install diff --git a/test/sql/base.pg b/test/sql/base.pg index cf44a9b8..94d806e8 100644 --- a/test/sql/base.pg +++ b/test/sql/base.pg @@ -17,7 +17,7 @@ BEGIN; -SELECT plan(181); +SELECT plan(190); SELECT has_schema( 'table_version' ); SELECT has_table( 'table_version', 'revision', 'Should have revision table' ); @@ -696,6 +696,8 @@ SELECT throws_like( 'Table % is already versioned', 'ver_enable_versioning throws when called on already-versioned table'); +SELECT table_version.ver_disable_versioning('foo.dropme'); + SELECT has_function( 'table_version', 'ver_version'::name ); SELECT has_function( 'table_version', 'ver_enable_versioning', ARRAY['regclass'] ); @@ -763,6 +765,8 @@ PREPARE "test2" AS SELECT T.id, T.code SELECT lives_ok('"test1"','1. Request char/integer set result'); SELECT lives_ok('"test2"','2. Request char/varchar set result'); +DROP SCHEMA test_schema CASCADE; + --------------------------------------- -- Test for ver_fix_revision_disorder --------------------------------------- @@ -914,6 +918,88 @@ SELECT results_eq($$ FROM table_version.revision $$, $$ VALUES (TRUE) $$ ); +RESET SESSION AUTHORIZATION; +DROP SCHEMA foo CASCADE; +DROP ROLE test_owner; +DROP ROLE test_user; + +COMMIT; + +------------------------------------------------------------- +-- Test for without explicitly calling ver_create_revision/ +-- ver_complete_revision +------------------------------------------------------------- + +CREATE SCHEMA auto; + +SELECT lives_ok('CREATE TABLE auto.revision (id int primary key, d1 text)'); +SELECT lives_ok($$ SELECT table_version.ver_enable_versioning('auto','revision') $$); + +SELECT table_version.ver_get_last_revision() + 2 as last_revision \gset + +-- First create a revision via create complete APIs + +SELECT is(table_version.ver_create_revision('Manual edit 1'), + :last_revision, 'Create edit 1 revision'); +INSERT INTO auto.revision (id, d1) VALUES (1, 'manual 1'); +SELECT ok(table_version.ver_complete_revision(), 'Complete edit 1 revision'); + +-- Now try a auto revision. +BEGIN; + +INSERT INTO auto.revision (id, d1) VALUES (2, 'auto 2'); +INSERT INTO auto.revision (id, d1) VALUES (3, 'auto 3'); +INSERT INTO auto.revision (id, d1) VALUES (4, 'auto 4'); + +COMMIT; + +\set last_revision :last_revision + 1 + +SELECT results_eq( + format($$ + SELECT * FROM table_version.ver_get_auto_revision_diff(%1$s-1, %1$s) + ORDER BY id$$, :last_revision), + $$VALUES ('I'::char, 2, 'auto 2'), + ('I'::char, 3, 'auto 3'), + ('I'::char, 4, 'auto 4')$$, + 'Ensure that updates are grouped by transaction #1' +); + +-- Do another insert and ensure it's in a new transaction +BEGIN; + +UPDATE auto.revision +SET d1 = 'auto 1 edit' +WHERE id = 1; + +\set last_revision :last_revision + 1 + +COMMIT; + +SELECT results_eq( + format($$ + SELECT * FROM table_version.ver_get_auto_revision_diff(%1$s-1, %1$s) + ORDER BY id$$, :last_revision), + $$VALUES ('U'::char, 1, 'auto 1 edit')$$, + 'Ensure that updates are grouped by transaction #2' +); + +-- End with a revision via create complete APIs to ensure no +-- effects from the auto revision mode + +\set last_revision :last_revision + 1 + +SELECT is(table_version.ver_create_revision('Manual edit 2'), + :last_revision, 'Create edit 2 revision'); +UPDATE auto.revision +SET d1 = 'manual 2 edit' +WHERE id = 2; +SELECT ok(table_version.ver_complete_revision(), 'Complete edit 2 revision'); + +SELECT ok(table_version.ver_disable_versioning('auto', 'revision'), 'Disable versioning on auto.revision'); + +DROP SCHEMA auto CASCADE; + --------------------------------------- -- End of tests ---------------------------------------