@@ -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