Skip to content

CREATE EXTENSION test_factory_pgtap fails inside BEGIN/COMMIT block #13

Closed

Description

@jnasbyupgrade

Problem

Installing test_factory_pgtap inside a BEGIN/COMMIT transaction block causes COMMIT to fail. This breaks any install script that wraps multiple CREATE EXTENSION calls in a single transaction.

Root Cause

test_factory_pgtap creates a TEMP TABLE ... ON COMMIT DROP during extension installation. When PostgreSQL processes COMMIT, it auto-drops that temp table. However, the table is registered as owned by the extension, so PostgreSQL cannot drop it as part of the commit without removing the extension — causing the commit to fail with an error.

Minimal Reproduction

BEGIN;
CREATE EXTENSION test_factory_pgtap CASCADE;
COMMIT;
-- ERROR: cannot drop table <name> because extension test_factory_pgtap requires it
-- (or similar error preventing the commit)

Working workaround:

-- Install BEFORE the transaction block
CREATE EXTENSION test_factory_pgtap CASCADE;

BEGIN;
-- ... rest of install script ...
COMMIT;

Expected Behavior

CREATE EXTENSION test_factory_pgtap should be safe to run inside a transaction block, like any standard extension.

Fix

The extension should explicitly DROP TABLE the temp table at the end of installation rather than relying on ON COMMIT DROP. This removes the transaction-scoped lifetime dependency, making the extension safe to install inside a BEGIN/COMMIT block.

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