Repository navigation
Conversation
CoverageTotal: 63.1% (+4.7% vs Coverage in packages changed by this PR:
|
pujitha24
force-pushed
the
auto/issue-1146
branch
2 times, most recently
from
September 25, 2026 14:33
001cdf2 to
7a48214
Compare
Author
|
This is rebased on main and CI is green; let me know if anything would make it easier to review. |
pujitha24
force-pushed
the
auto/issue-1146
branch
3 times, most recently
from
October 7, 2026 13:52
c16c59b to
520789e
Compare
CREATE TRIGGER statements were never replicated in postgres-to-postgres CDC, while DROP TRIGGER statements were. In strict mode, dropping a trigger downstream that was never created there causes pgstream to stop with an error. Motivation: pg_event_trigger_ddl_commands() reports a NULL schema_name for CREATE TRIGGER, since triggers are not schema-qualified catalog objects the way tables or functions are. The pgstream.emit_ddl() event trigger function picks rec_schema_name from the first row this function returns and returns early without emitting anything when it is NULL, so CREATE TRIGGER events were silently dropped. DROP TRIGGER goes through pg_event_trigger_dropped_objects() instead, which does report the schema, so it was emitted, leading to the asymmetry. Approach: Add pgstream.get_trigger_schema(trigger_oid), a small SQL helper that resolves a trigger's schema via pg_trigger -> pg_class -> pg_namespace, mirroring the existing pgstream.get_table_metadata helper. Use it as a fallback wherever emit_ddl() reads schema_name from pg_event_trigger_ddl_commands(): both the rec_schema_name lookup (which gates whether anything is emitted) and the cmd subquery used to build the objects array (whose WHERE filter also excluded the NULL-schema trigger row from affected_objects). Added as new migrations, core/4_fix_create_trigger_schema and injector/6_fix_create_trigger_schema, following this repo's existing pattern for DDL emission fixes (see core/3_fix_duplicate_ddl_emission). Regenerated migrations.go for both packages via make gen-migrations. Validation: This bug lives entirely in a Postgres event trigger function (plpgsql), so it can only be proven against a real Postgres server, not a Go unit test. Docker/testcontainers were unavailable in this environment, so I validated directly against a local PostgreSQL 16 server (wal_level=logical) instead of make integration-test: - Applied the pre-fix migration SQL (core 1-3) and reproduced the reported bug exactly via a real logical replication slot: creating a table, function and trigger, then dropping the trigger, showed 0 CREATE TRIGGER messages and 1 DROP TRIGGER message. - Applied the fix (core 1-4) and reran the same scenario: CREATE TRIGGER now emits a pgstream.ddl message with "schema_name": "public" and the trigger object correctly listed. - Verified the down migration round-trips correctly: after applying up 1-4 then down 4, ALTER TABLE ... DROP COLUMN still emits exactly one message (migration 3's duplicate-emission fix survives the revert), and CREATE TRIGGER correctly stops emitting again; re-applying up 4 restores the fix. - go build, go vet and golangci-lint run --config=.golangci.yml all pass cleanly against ./migrations/... and ./internal/migrator/.... - ./bin/license-header-checker -r ./license-header.txt . go (the exact command make license-check runs) passes: "492 licenses ok, 0 licenses replaced, 0 licenses added". - I could not run go build ./..., make test or make integration-test for the full repository: the sandbox's disk is nearly completely full for reasons unrelated to this change (confirmed the same disk-full errors occur building unrelated large dependency subtrees, while the packages this change touches build and vet cleanly). Base branch CI is green, so this is an environment limitation, not a signal about the change. Report: xataio#1146 Signed-off-by: Pujitha Paladugu <10557236+pujitha24@users.noreply.github.com> Assisted-by: claude-sonnet-5 (via Claude Code)
pujitha24
force-pushed
the
auto/issue-1146
branch
from
October 9, 2026 13:50
520789e to
8494a70
Compare
4 tasks done
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.
Description
CREATE TRIGGERstatements were never replicated in postgres-to-postgres CDC, whileDROP TRIGGERstatements were. In strict mode, dropping a trigger that was never created downstream causes pgstream to stop with an error. This fixes the root cause in thepgstream.emit_ddl()Postgres event trigger function:pg_event_trigger_ddl_commands()reports a NULLschema_nameforCREATE TRIGGER(triggers are not schema-qualified catalog objects the way tables or functions are), andemit_ddl()silently returns without emitting anything when the schema name is NULL.DROP TRIGGERuses a different function,pg_event_trigger_dropped_objects(), which does report the schema, so it was unaffected.Related Issue(s)
Type of Change
Changes Made
pgstream.get_trigger_schema(trigger_oid), a small SQL helper that resolves a trigger's schema viapg_trigger→pg_class→pg_namespace, mirroring the existingpgstream.get_table_metadatahelper.pgstream.emit_ddl()(both the core and injector migration variants) so that wherever it readsschema_namefrompg_event_trigger_ddl_commands(), it falls back topgstream.get_trigger_schema(objid)for trigger objects. This is needed in two places: therec_schema_namelookup (which gates whether anything is emitted at all) and thecmdsubquery used to build theobjectsarray (whoseWHEREfilter also excluded NULL-schema rows, so the trigger object itself was missing fromaffected_objectstoo).core/4_fix_create_trigger_schemaandinjector/6_fix_create_trigger_schema, following this repo's existing pattern for DDL emission fixes (e.g.core/3_fix_duplicate_ddl_emission). Regeneratedmigrations.gofor both packages viamake gen-migrations.Testing
This bug lives entirely in a Postgres event trigger function (plpgsql), so it can only be proven against a real Postgres server, not a Go unit test. Docker/testcontainers were unavailable in the environment this change was built in, so I validated directly against a local PostgreSQL 16 server (Homebrew,
wal_level=logical) instead ofmake integration-test:pg_create_logical_replication_slot+pg_logical_slot_get_changes) showed 0CREATE TRIGGERmessages and 1DROP TRIGGERmessage.CREATE TRIGGERnow emits apgstream.ddlmessage with the correct"schema_name": "public"and the trigger object listed with"schema": "public".ALTER TABLE ... DROP COLUMNstill emits exactly one message (i.e. migration 3's duplicate-emission fix is preserved after reverting 4) and thatCREATE TRIGGERgoes back to emitting nothing (expected, since that reverts to the pre-fix state); then re-applied the up migration and confirmedCREATE TRIGGERworks again.go build,go vet, andgolangci-lint run --config=.golangci.ymlall pass cleanly against the changed packages (./migrations/...,./internal/migrator/...)../bin/license-header-checker -r ./license-header.txt . go(the exact commandmake license-checkruns) passes: "492 licenses ok, 0 licenses replaced, 0 licenses added".go build ./...,make test, ormake integration-testfor the full repository in this environment: the sandbox's disk is nearly completely full for reasons unrelated to this change (confirmed the same "no space left on device" errors occur building unrelated large dependency subtrees, while the specific packages this change touches build and vet cleanly). Base branch CI (gh run list --branch main) is green, so this is an environment limitation, not a signal about the change itself.Checklist
Additional Notes
Note:
make test/make integration-testcould not be run locally due to a disk-space limitation in the build environment, unrelated to this change (see Testing section above for the live-Postgres validation performed instead).Fixes #1146