Skip to content

test_factory_pgtap extension fails to install on PostgreSQL 17: ON COMMIT DROP conflicts with extension ownership #12

Closed

Description

@jnasbyupgrade

Bug Description

CREATE EXTENSION test_factory_pgtap always fails on PostgreSQL 17 (and likely other versions) due to a conflict between ON COMMIT DROP and PostgreSQL's extension ownership tracking.

Root Cause

test_factory_pgtap--0.1.0.sql begins with:

CREATE TEMP TABLE original_role ON COMMIT DROP AS SELECT current_user AS original_role;

When CREATE EXTENSION runs this SQL, PostgreSQL records the temp table as extension-owned. At commit time, ON COMMIT DROP fires and attempts to drop the table — but PostgreSQL refuses because the extension owns it:

ERROR:  cannot drop table original_role because extension test_factory_pgtap requires it
HINT:  You can drop extension test_factory_pgtap instead.

This causes CREATE EXTENSION test_factory_pgtap to always fail (the transaction is rolled back), making the extension completely uninstallable.

Steps to Reproduce

CREATE EXTENSION test_factory_pgtap CASCADE;
-- ERROR:  cannot drop table original_role because extension test_factory_pgtap requires it
-- HINT:  You can drop extension test_factory_pgtap instead.

Expected Behavior

Extension installs successfully.

Affected Versions

  • PostgreSQL 17 (confirmed)
  • Likely all PostgreSQL versions that enforce extension ownership on objects created during CREATE EXTENSION

Suggested Fix

Remove ON COMMIT DROP from the temp table creation:

-- Before (broken):
CREATE TEMP TABLE original_role ON COMMIT DROP AS SELECT current_user AS original_role;

-- After (fixed):
CREATE TEMP TABLE original_role AS SELECT current_user AS original_role;

The table is only used during extension installation to restore the original role at the end of the script. It will be cleaned up automatically at session end (which is fine for a temp table used only during installation).

Additionally, the explicit DROP TABLE pg_temp.original_role; at line 39 of the script should be kept or also removed — it currently runs before the ON COMMIT DROP would fire, so it was the intended cleanup mechanism. With ON COMMIT DROP removed, the explicit DROP TABLE at the end of the script remains the correct approach and can stay as-is.

File Reference

sql/test_factory_pgtap--0.1.0.sql, lines 2 and 39.

Activity

  1. jnasbyupgrade commented on Jul 14, 2026

    @jnasbyupgrade
    CollaboratorAuthor

    Resolving as part of the test_factory pgxntool-sync + test/install/ + fix work.

    Root cause is the install-time CREATE TEMP TABLE original_role ON COMMIT DROP used to save the caller's role — an extension-owned temp object, which is inherently fragile (also causes a name-collision failure if the caller already has an original_role temp table). The specific commit-time failure reported here has been masked since commit 0a51bf7 (2025-06, predates these issues) by an explicit DROP TABLE before commit, so it no longer reproduces on current code.

    The proper fix removes the temp table entirely: save the caller's role via set_config('test_factory.original_role', current_user, true) and restore it with SET ROLE at end of script — no extension-owned temp object, no ON COMMIT DROP, no collision. This is being done on top of the pgxntool sync (#19), switching the install test to pgxntool's committed test/install/ path. Closing per maintainer direction.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions