SQL: no nodes are extracted from statements wrapped in BEGIN; … COMMIT;
graphifyy 0.9.33 · tree-sitter-sql 0.3.11 · tree-sitter 0.25.2 · Python 3.13.14 · macOS 27 (arm64)
Related to #1745 (the "install graphifyy[sql]" warning). Installing the extra removes the
warning, but SQL files still contribute almost nothing — for a different reason.
Summary
CREATE TABLE statements are extracted correctly on their own, but the same statements
produce no nodes when the file wraps them in a transaction block. Since wrapping a
migration in BEGIN; … COMMIT; is the normal way to make it atomic, this silently hides
entire schemas.
In our repo it hides 59 CREATE TABLE statements across 8 migration files — every table
the application has. The graph looked healthy (the files themselves appear as nodes), so the
loss is invisible unless you count.
Minimal reproduction
Two files, identical except for the transaction wrapper.
sin_transaccion.sql:
CREATE TABLE alfa (id integer PRIMARY KEY);
CREATE TABLE beta (id integer PRIMARY KEY);
con_transaccion.sql:
BEGIN;
CREATE TABLE gamma (id integer PRIMARY KEY);
CREATE TABLE delta (id integer PRIMARY KEY);
COMMIT;
Then:
Expected: four table nodes — alfa, beta, gamma, delta.
Actual: two. Only the ones outside the transaction.
sin_transaccion.sql 'alfa'
sin_transaccion.sql 'beta'
con_transaccion.sql appears as a file node, with nothing inside it. No warning, no error.
What is not the cause
I bisected before filing. Each of these works fine on its own — a table node is produced
with correct source_file and source_location:
| Construct |
Extracted? |
plain CREATE TABLE |
yes |
CREATE TABLE IF NOT EXISTS |
yes |
| leading comment block (incl. non-ASCII) |
yes |
inline CHECK (col IN (…)) |
yes |
ALTER TABLE … ENABLE ROW LEVEL SECURITY between two CREATE TABLEs |
yes, both |
DO $$ … END $$; before a CREATE TABLE |
yes |
BEGIN; … COMMIT; wrapper |
no |
So the dialect features aren't the problem; only the transaction block is.
Secondary oddity: nodes with empty attribution
Running against our real migrations (all of them BEGIN/COMMIT-wrapped), three table nodes
do survive — avisos, sv_casos, sv_motivos_alias — but with empty source_file and
source_location:
label='avisos' source_file='' source_location='' _origin='ast'
label='sv_motivos_alias' source_file='' source_location='' _origin='ast'
label='sv_casos' source_file='' source_location='' _origin='ast'
Nodes that survive the same file keep their attribution (_motivos_nuevos from a
CREATE TEMP TABLE … AS came through with loc=L68 intact), so this looks like partial
recovery after a failed parse rather than a separate issue. Mentioning it in case it points
at the same code path.
Why it matters
The failure is silent. graphify update . reports a healthy rebuild, the .sql files show up
as nodes, and the #1745 warning is gone — so it reads as "SQL support is working". A query
for a table name still returns hits, but they come from the Python that mentions the table,
never from the DDL that defines it. The schema is simply absent from the graph, and nothing
says so.
A count of extracted CREATE TABLE vs. CREATE TABLE occurrences would have caught this, if
that is a cheap check to add.
SQL: no nodes are extracted from statements wrapped in
BEGIN; … COMMIT;graphifyy 0.9.33 · tree-sitter-sql 0.3.11 · tree-sitter 0.25.2 · Python 3.13.14 · macOS 27 (arm64)
Related to #1745 (the "install
graphifyy[sql]" warning). Installing the extra removes thewarning, but SQL files still contribute almost nothing — for a different reason.
Summary
CREATE TABLEstatements are extracted correctly on their own, but the same statementsproduce no nodes when the file wraps them in a transaction block. Since wrapping a
migration in
BEGIN; … COMMIT;is the normal way to make it atomic, this silently hidesentire schemas.
In our repo it hides 59
CREATE TABLEstatements across 8 migration files — every tablethe application has. The graph looked healthy (the files themselves appear as nodes), so the
loss is invisible unless you count.
Minimal reproduction
Two files, identical except for the transaction wrapper.
sin_transaccion.sql:con_transaccion.sql:Then:
Expected: four table nodes —
alfa,beta,gamma,delta.Actual: two. Only the ones outside the transaction.
con_transaccion.sqlappears as a file node, with nothing inside it. No warning, no error.What is not the cause
I bisected before filing. Each of these works fine on its own — a table node is produced
with correct
source_fileandsource_location:CREATE TABLECREATE TABLE IF NOT EXISTSCHECK (col IN (…))ALTER TABLE … ENABLE ROW LEVEL SECURITYbetween twoCREATE TABLEsDO $$ … END $$;before aCREATE TABLEBEGIN; … COMMIT;wrapperSo the dialect features aren't the problem; only the transaction block is.
Secondary oddity: nodes with empty attribution
Running against our real migrations (all of them
BEGIN/COMMIT-wrapped), three table nodesdo survive —
avisos,sv_casos,sv_motivos_alias— but with emptysource_fileandsource_location:Nodes that survive the same file keep their attribution (
_motivos_nuevosfrom aCREATE TEMP TABLE … AScame through withloc=L68intact), so this looks like partialrecovery after a failed parse rather than a separate issue. Mentioning it in case it points
at the same code path.
Why it matters
The failure is silent.
graphify update .reports a healthy rebuild, the.sqlfiles show upas nodes, and the
#1745warning is gone — so it reads as "SQL support is working". A queryfor a table name still returns hits, but they come from the Python that mentions the table,
never from the DDL that defines it. The schema is simply absent from the graph, and nothing
says so.
A count of extracted
CREATE TABLEvs.CREATE TABLEoccurrences would have caught this, ifthat is a cheap check to add.