Skip to content

Commit 4a116bb

Browse files
radimclaude
andcommitted
test: cover PL/pgSQL body not-validated warnings
Verify validate_query emits the "not statically validated" warning for DO blocks and plpgsql functions/procedures (issue #32), so an opaque body never passes as clean. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent e9a95a2 commit 4a116bb

1 file changed

Lines changed: 64 additions & 0 deletions

File tree

internal/query/validate_test.go

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -356,3 +356,67 @@ func TestNonPartitionedTableNoWarning(t *testing.T) {
356356
}
357357
}
358358
}
359+
360+
// issue #32: pg_query treats DO/function bodies as opaque strings, so the
361+
// body escapes static validation. We can't catch the runtime error, but we
362+
// must at least warn that the body wasn't checked instead of claiming clean.
363+
func TestDoBlockBodyNotValidatedWarning(t *testing.T) {
364+
snap := testSchema()
365+
sql := `DO $$
366+
BEGIN
367+
RAISE EXCEPTION 'bad format output: %', format('value %s %s', 'one');
368+
END
369+
$$;`
370+
result, err := ValidateQuery(sql, snap)
371+
if err != nil {
372+
t.Fatal(err)
373+
}
374+
found := false
375+
for _, w := range result.Warnings {
376+
if strings.Contains(w.Message, "DO body") && strings.Contains(w.Message, "not statically validated") {
377+
found = true
378+
}
379+
}
380+
if !found {
381+
t.Errorf("expected DO body not-validated warning, got %+v", result.Warnings)
382+
}
383+
}
384+
385+
func TestPlpgsqlFunctionBodyNotValidatedWarning(t *testing.T) {
386+
snap := testSchema()
387+
cases := []struct {
388+
sql string
389+
kind string
390+
}{
391+
{`CREATE FUNCTION f() RETURNS void AS $$ BEGIN RETURN; END $$ LANGUAGE plpgsql;`, "CREATE FUNCTION body"},
392+
{`CREATE PROCEDURE p() AS $$ BEGIN NULL; END $$ LANGUAGE plpgsql;`, "CREATE PROCEDURE body"},
393+
}
394+
for _, tc := range cases {
395+
result, err := ValidateQuery(tc.sql, snap)
396+
if err != nil {
397+
t.Fatalf("%s: %v", tc.kind, err)
398+
}
399+
found := false
400+
for _, w := range result.Warnings {
401+
if strings.Contains(w.Message, tc.kind) && strings.Contains(w.Message, "plpgsql") {
402+
found = true
403+
}
404+
}
405+
if !found {
406+
t.Errorf("expected %q warning, got %+v", tc.kind, result.Warnings)
407+
}
408+
}
409+
}
410+
411+
func TestPlainSelectNoBodyWarning(t *testing.T) {
412+
snap := testSchema()
413+
result, err := ValidateQuery("SELECT id FROM users", snap)
414+
if err != nil {
415+
t.Fatal(err)
416+
}
417+
for _, w := range result.Warnings {
418+
if strings.Contains(w.Message, "not statically validated") {
419+
t.Errorf("unexpected body warning on plain SELECT: %s", w.Message)
420+
}
421+
}
422+
}

0 commit comments

Comments
 (0)