Add extension upgrade template regression test#2364
Merged
MuhammadTahaNaveed merged 1 commit intoapache:masterfrom Apr 6, 2026
Merged
Add extension upgrade template regression test#2364MuhammadTahaNaveed merged 1 commit intoapache:masterfrom
MuhammadTahaNaveed merged 1 commit intoapache:masterfrom
Conversation
There was a problem hiding this comment.
Pull request overview
Adds a new regression test that simulates an in-place Apache AGE extension upgrade (via the upgrade template) during make installcheck, and updates build/install infrastructure to make upgrade scripts available to ALTER EXTENSION ... UPDATE.
Changes:
- Add
age_upgraderegression test (regress/sql/age_upgrade.sql) with expected output (regress/expected/age_upgrade.out) to validate upgrade-template correctness and post-upgrade data/index integrity. - Update the
Makefileto install real upgrade scripts into$(SHAREDIR)/extension/, generate synthetic “next” version SQL + stamped upgrade SQL for testing, and conditionally include the new regression test.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 6 comments.
| File | Description |
|---|---|
| Makefile | Adds conditional upgrade-test infrastructure, installs upgrade scripts, and stages synthetic upgrade artifacts for installcheck. |
| regress/sql/age_upgrade.sql | New upgrade regression test that creates graphs/indexes, upgrades the extension, and validates data/index survival. |
| regress/expected/age_upgrade.out | Expected output for the new age_upgrade test. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
8d51ffa to
9d7d7ea
Compare
Note: This PR was created with AI tools and a human. Add a version-agnostic regression test (age_upgrade) that validates the upgrade template (age--<VER>--y.y.y.sql) works correctly by simulating a full extension version upgrade within "make installcheck". Add full upgrade scripts to the install path (DATA) in the Makefile, excluding template upgrade files. This enables the install to copy all version upgrade files into the PG AGE install. This is needed for ALTER EXTENSION Adjusted installcheck.yaml to allow git commit history for this test. Makefile infrastructure: - Build the install SQL (age--<CURR>.sql) from the initial version-bump commit in git history, so CREATE EXTENSION installs "day-one" SQL while the .so comes from current HEAD — implicitly testing backward compat. - Build a synthetic "next" version (age--<NEXT>.sql) from HEAD and stamp the upgrade template to produce age--<CURR>--<NEXT>.sql. - Add an installcheck prerequisite that temporarily installs both synthetic files into the PG extension directory; a generated cleanup script removes them at the end of the test via \! shell escape. EXTRA_CLEAN catches stragglers on "make clean". - Skip the test automatically when: (a) no git history (tarball builds), (b) no upgrade template exists, or (c) a real upgrade script from the current version is already committed (detected via git ls-files).o Regression test (regress/sql/age_upgrade.sql): - Creates 3 graphs (company, network, routes) with 8 vertex labels, 8 edge labels, 23 vertices, 28 edges, and 4 GIN indexes. - Records integrity checksums (agtype sums), vertex/edge counts, and label counts before the upgrade; repeats all checks after ALTER EXTENSION UPDATE to the synthetic next version. - Verifies structural queries: VLE management chains, circular follow chains, flight distances with edge properties. - Verifies all 4 GIN indexes survive the upgrade via pg_indexes. - Uses ORDER BY on all multi-row queries for deterministic output. - Returns agtype natively (no ::numeric casts) for portability. - Avoids version-dependent output (checks boolean IS NOT NULL instead of printing the version string). - Uses JOIN-based label counts to avoid NULL comparison bugs with the internal _ag_catalog graph. - Cleans up all 3 graphs and restores the default AGE version. modified: Makefile new file: regress/expected/age_upgrade.out new file: regress/sql/age_upgrade.sql modified: .github/workflows/installcheck.yaml
9d7d7ea to
2b5c485
Compare
MuhammadTahaNaveed
approved these changes
Apr 6, 2026
jrgemignani
added a commit
to jrgemignani/age
that referenced
this pull request
Apr 10, 2026
Note: This PR was created with AI tools and a human. This is an addendum to PR apache#2364 with three improvements. Makefile: - Replace awk-based synthetic version (minor+1) with an _upgrade_test suffix (e.g., 1.7.0 -> 1.7.0_upgrade_test). The awk approach produced numeric versions like 1.8.0 that could collide with real future upgrade scripts, and the ::int[] cast in the SQL version lookup fails on non-numeric version strings. The _upgrade_test suffix avoids both issues and is unambiguously synthetic. - Extend the generated cleanup script to also remove repo-root copies of the synthetic files and to self-delete, preventing stale artifacts from accumulating across repeated test runs. Regression test (regress/sql/age_upgrade.sql): - Simplify version lookup to directly select the _upgrade_test version via LIKE '%_upgrade_test' instead of picking the highest non-default version with string_to_array(version, '.')::int[] DESC. The old approach would fail with a cast error on the _upgrade_test suffix and was unnecessarily indirect — the test knows exactly what synthetic version the Makefile installed. modified: Makefile modified: regress/expected/age_upgrade.out modified: regress/sql/age_upgrade.sql Co-authored-by: Claude <noreply@anthropic.com>
jrgemignani
added a commit
to jrgemignani/age
that referenced
this pull request
Apr 14, 2026
Note: This PR was created with AI tools and a human. This is an addendum to PR apache#2364 with three improvements. Makefile: - Replace awk-based synthetic version (minor+1) with an _upgrade_test suffix (e.g., 1.7.0 -> 1.7.0_upgrade_test). The awk approach produced numeric versions like 1.8.0 that could collide with real future upgrade scripts, and the ::int[] cast in the SQL version lookup fails on non-numeric version strings. The _upgrade_test suffix avoids both issues and is unambiguously synthetic. - Extend the generated cleanup script to also remove repo-root copies of the synthetic files and to self-delete, preventing stale artifacts from accumulating across repeated test runs. Regression test (regress/sql/age_upgrade.sql): - Simplify version lookup to directly select the _upgrade_test version via LIKE '%_upgrade_test' instead of picking the highest non-default version with string_to_array(version, '.')::int[] DESC. The old approach would fail with a cast error on the _upgrade_test suffix and was unnecessarily indirect — the test knows exactly what synthetic version the Makefile installed. modified: Makefile modified: regress/expected/age_upgrade.out modified: regress/sql/age_upgrade.sql Co-authored-by: Claude <noreply@anthropic.com>
MuhammadTahaNaveed
pushed a commit
that referenced
this pull request
Apr 15, 2026
Note: This PR was created with AI tools and a human. This is an addendum to PR #2364 with three improvements. Makefile: - Replace awk-based synthetic version (minor+1) with an _upgrade_test suffix (e.g., 1.7.0 -> 1.7.0_upgrade_test). The awk approach produced numeric versions like 1.8.0 that could collide with real future upgrade scripts, and the ::int[] cast in the SQL version lookup fails on non-numeric version strings. The _upgrade_test suffix avoids both issues and is unambiguously synthetic. - Extend the generated cleanup script to also remove repo-root copies of the synthetic files and to self-delete, preventing stale artifacts from accumulating across repeated test runs. Regression test (regress/sql/age_upgrade.sql): - Simplify version lookup to directly select the _upgrade_test version via LIKE '%_upgrade_test' instead of picking the highest non-default version with string_to_array(version, '.')::int[] DESC. The old approach would fail with a cast error on the _upgrade_test suffix and was unnecessarily indirect — the test knows exactly what synthetic version the Makefile installed. modified: Makefile modified: regress/expected/age_upgrade.out modified: regress/sql/age_upgrade.sql Co-authored-by: Claude <noreply@anthropic.com>
jrgemignani
added a commit
to jrgemignani/age
that referenced
this pull request
Apr 22, 2026
The age_upgrade regression test (added in apache#2364, improved in apache#2377, apache#2397) was designed to validate the upgrade template (age--<VER>--y.y.y.sql) by creating graph data before the upgrade and verifying it survived afterward. This approach had two fundamental problems: 1. It did not detect incomplete upgrade templates. The test verified that graph data (vertices, edges, checksums, GIN indexes) survived ALTER EXTENSION UPDATE, but never checked whether new SQL objects (functions, views, relations, indexes, types, operators, casts, constraints) were actually created by the template. A developer could add a new function to sql/ and sql_files, forget to add it to the upgrade template, and all tests would pass — the function existed via the fresh CREATE EXTENSION install that ran before the upgrade test, but would be missing for users who upgraded via ALTER EXTENSION UPDATE. 2. The data-integrity checks relied on cypher queries (MATCH/RETURN) within the same backend session after DROP EXTENSION + CREATE EXTENSION. This caused intermittent failures on some PostgreSQL versions where AGE's internal type cache (agtype OID) was not properly refreshed after the extension was dropped and recreated, resulting in 'type with OID 0 does not exist' errors. The data-integrity aspect was also redundant — ALTER EXTENSION UPDATE runs DDL statements and does not touch heap data, so data survival is guaranteed by PostgreSQL and not a meaningful test. The fix replaces the entire test with a comprehensive catalog comparison: 1. Snapshot the ag_catalog schema from the fresh install across seven PostgreSQL system catalogs: - pg_proc: functions, aggregates, procedures (name, args, and properties: volatility, strictness, kind, return type, setof) - pg_class: tables, views, sequences, indexes (name, kind) - pg_type: types (name, type category) - pg_operator: operators (name, left/right operand types) - pg_cast: casts involving AGE types (source, target, context) - pg_opclass: operator classes (name, access method) - pg_constraint: constraints (name, type, table, referenced table) 2. DROP EXTENSION, CREATE EXTENSION at the synthetic initial version, then ALTER EXTENSION UPDATE to the current version via the stamped upgrade template. 3. Snapshot the catalog again after upgrade. 4. Compare: any object present in the fresh snapshot but missing after upgrade means the template is incomplete. Any object present after upgrade but not in the fresh snapshot means the template creates something unexpected. Function properties (volatility, strictness, prokind, return type) are also compared for functions that exist in both — catching cases where a CREATE OR REPLACE in the template changes a function's signature or behavior. Additional improvements from code review feedback: - Graph cleanup in Step 1 uses a DO block with PERFORM and suppressed NOTICEs to produce deterministic output regardless of prior test state. - The pg_class snapshot includes indexes (relkind 'i') in addition to tables, views, and sequences. - Diagnostic output includes relkind/typtype suffixes for actionable diffs. - Summary uses boolean equality checks (funcs_match, rels_match, etc.) instead of absolute counts, so the expected output does not need updating when new objects are added to AGE. Developers who correctly add objects to both sql/ and the template will never need to modify this test or its expected output. This approach: - Catches the actual failure mode: incomplete upgrade templates. - Covers all SQL object categories: functions (including aggregates), relations, types, operators, casts, operator classes, and constraints. - Detects property changes on existing functions (volatility, strictness, kind, return type changes). - Uses only plain SQL catalog queries — no cypher, no .so cache issues. - Works reliably across all PostgreSQL versions. - Reports the exact missing/extra/changed object in the diff output. - Is maintenance-free: no expected output changes needed when AGE grows. Makefile: updated step 5 comment to reflect catalog comparison approach. All 33 regression tests pass. Co-authored-by: Claude <noreply@anthropic.com> modified: Makefile modified: regress/expected/age_upgrade.out modified: regress/sql/age_upgrade.sql
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Note: This PR was created with AI tools and a human.
Add a version-agnostic regression test (age_upgrade) that validates the upgrade template (age----y.y.y.sql) works correctly by simulating a full extension version upgrade within "make installcheck".
Add full upgrade scripts to the install path (DATA) in the Makefile, excluding template upgrade files. This enables the install to copy all version upgrade files into the PG AGE install. This is needed for ALTER EXTENSION
Adjusted installcheck.yaml to allow git commit history for this test.
Makefile infrastructure:
Regression test (regress/sql/age_upgrade.sql):
modified: Makefile
new file: regress/expected/age_upgrade.out
new file: regress/sql/age_upgrade.sql
modified: .github/workflows/installcheck.yaml