fix(pg_introspect): emit FK DDL before function stubs so unparseable routines can't drop references edges (#1854)#1927
Open
sekmur wants to merge 1 commit into
Conversation
…routines can't drop references edges (Graphify-Labs#1854) A C-language routine's body from information_schema.routines is just the C symbol name, so its reconstructed stub (CREATE FUNCTION ... AS $gfx$ name $gfx$ LANGUAGE c) is unparseable by tree-sitter-sql, and the parser's error recovery consumes the statements that follow. With FK ALTER TABLEs emitted last, every references edge was silently lost on any DB with a common extension installed (uuid-ossp, pgcrypto, pg_trgm, fuzzystrmatch, ...). Emit the FK block before the routine DDL. FK statements only reference tables, which are emitted first, so the order is always safe. On a real DB with 35 tables / 41 FKs / 41 extension routines: 41/41 references edges vs 1/41 before. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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.
Problem
The dropped-FK half of #1854 (closed as fixed-by-#1746, but reproducible on a fresh 0.9.16 —
graphify/pg_introspect.pyandgraphify/extractors/sql.pyare byte-identical from v0.9.14 through v0.9.16).introspect_postgres()reconstructs one synthetic DDL document in the order tables → views → functions → FKs and hands it toextract_sql()in a single tree-sitter parse. A C-language routine'sroutine_definitionis just the C symbol name, so its stub:is unparseable, and tree-sitter's error recovery consumes the statements after it. With the FK
ALTER TABLEs emitted last, they're what gets eaten — so any DB with a common extension installed (uuid-ossp, pgcrypto, pg_trgm, fuzzystrmatch, unaccent, PostGIS, …) silently loses itsreferencesedges. This is distinct from #1746 (FK reading privileges): the failure is downstream of a correct catalog read, in the parse.Fix
Emit the FK block before the routine DDL — a pure block move. FK statements only reference tables, which are emitted first, so the order is always safe; an unparseable stub can now only damage what follows it (the remaining stubs, which contribute no edges from their bodies anyway).
Measured on a real DB (35 tables / 41 FKs / 41 extension routines from fuzzystrmatch + pg_trgm): 1/41 references edges before, 41/41 after.
Test
test_pg_introspect_fk_edges_survive_unparseable_function_stubs— 7 tables, 6 FKs, oneLANGUAGE croutine + one plpgsql routine, asserts all 6referencesedges survive. Fails on current v8 (0 or partial edges, statement-mix-dependent), passes with the fix. The existing baseline test never caught this because its mock routines only useSQL/PLPGSQLlanguages, neverC.Longer term this path may not need a parse at all —
introspect_postgres()already holds tables and FK pairs as structured rows frompg_catalog, so emitting nodes/edges directly (instead of round-tripping through synthetic DDL) would make this failure class impossible. This PR is the minimal ordering fix; happy to discuss the direct-emission approach separately.🤖 Generated with Claude Code