diff --git a/src/PostgREST/PgQuery.hs b/src/PostgREST/PgQuery.hs index 9d3d43a01..c8d14003c 100644 --- a/src/PostgREST/PgQuery.hs +++ b/src/PostgREST/PgQuery.hs @@ -116,7 +116,7 @@ asJsonWithCount = withCount . asJson asJson :: StatementT asJson s = s { B.stmtTemplate = - "array_to_json(array_agg(row_to_json(t)))::character varying from (" + "array_to_json(coalesce(array_agg(row_to_json(t)), '{}'))::character varying from (" <> B.stmtTemplate s <> ") t" } withCount :: StatementT diff --git a/test/Feature/QuerySpec.hs b/test/Feature/QuerySpec.hs index 04bdfee88..b643cbf02 100644 --- a/test/Feature/QuerySpec.hs +++ b/test/Feature/QuerySpec.hs @@ -310,6 +310,11 @@ spec = post "/rpc/getitemrange" [json| { "min": 2, "max": 4 } |] `shouldRespondWith` [json| [ {"id": 3}, {"id":4} ] |] + context "a proc that returns an empty rowset" $ + it "returns empty json array" $ + post "/rpc/test_empty_rowset" [json| {} |] `shouldRespondWith` + [json| [] |] + context "a proc that returns plain text" $ it "returns proper json" $ post "/rpc/sayhello" [json| { "name": "world" } |] `shouldRespondWith` diff --git a/test/fixtures/schema.sql b/test/fixtures/schema.sql index b69e45d38..6128beee5 100755 --- a/test/fixtures/schema.sql +++ b/test/fixtures/schema.sql @@ -297,7 +297,9 @@ CREATE FUNCTION "1".getitemrange(min bigint, max bigint) RETURNS SETOF "1".items SELECT * FROM "1".items WHERE id > $1 AND id <= $2; $$ LANGUAGE SQL; - +CREATE FUNCTION "1".test_empty_rowset() RETURNS SETOF int AS $$ + SELECT null::int FROM (SELECT 1) a WHERE false; +$$ LANGUAGE SQL; CREATE FUNCTION "1".sayhello(name text) RETURNS text AS $$ SELECT 'Hello, ' || $1; @@ -663,6 +665,10 @@ REVOKE ALL ON FUNCTION getitemrange(bigint, bigint) FROM postgrest_test; GRANT EXECUTE ON FUNCTION getitemrange(bigint, bigint) TO postgrest_test; GRANT EXECUTE ON FUNCTION getitemrange(bigint, bigint) TO postgrest_anonymous; +REVOKE ALL ON FUNCTION test_empty_rowset() FROM PUBLIC; +REVOKE ALL ON FUNCTION test_empty_rowset() FROM postgrest_test; +GRANT EXECUTE ON FUNCTION test_empty_rowset() TO postgrest_test; +GRANT EXECUTE ON FUNCTION test_empty_rowset() TO postgrest_anonymous; REVOKE ALL ON FUNCTION sayhello(text) FROM PUBLIC; REVOKE ALL ON FUNCTION sayhello(text) FROM postgrest_test;