diff --git a/src/PostgREST/DbStructure.hs b/src/PostgREST/DbStructure.hs index c1e717cfb..8c141d622 100644 --- a/src/PostgREST/DbStructure.hs +++ b/src/PostgREST/DbStructure.hs @@ -710,13 +710,13 @@ allComputedRels = ), computed_rels as ( select - p.pronamespace::regnamespace::text as schema, - p.proname::text as name, - arg_schema.nspname::text as rel_table_schema, - arg_name.typname::text as rel_table_name, - ret_schema.nspname::text as rel_ftable_schema, - ret_name.typname::text as rel_ftable_name, - p.prorows = 1 as single_row + (parse_ident(p.pronamespace::regnamespace::text))[1] as schema, + p.proname::text as name, + arg_schema.nspname::text as rel_table_schema, + arg_name.typname::text as rel_table_name, + ret_schema.nspname::text as rel_ftable_schema, + ret_name.typname::text as rel_ftable_name, + p.prorows = 1 as single_row from pg_proc p join pg_type arg_name on arg_name.oid = p.proargtypes[0] join pg_namespace arg_schema on arg_schema.oid = arg_name.typnamespace diff --git a/test/spec/Feature/Query/MultipleSchemaSpec.hs b/test/spec/Feature/Query/MultipleSchemaSpec.hs index 28bb2ab3f..0f726a27e 100644 --- a/test/spec/Feature/Query/MultipleSchemaSpec.hs +++ b/test/spec/Feature/Query/MultipleSchemaSpec.hs @@ -74,10 +74,33 @@ spec = } it "succeeds in reading a table from a schema with uppercase and special characters in its name" $ - request methodGet "/names" [("Accept-Profile", "SPECIAL \"@/\\#~_-")] "" `shouldRespondWith` + request methodGet "/names?select=id,name" [("Accept-Profile", "SPECIAL \"@/\\#~_-")] "" `shouldRespondWith` [json|[ - {"id":1,"name":"John"}, - {"id":2,"name":"Mary"} + {"id": 1, "name":"John"}, + {"id": 2, "name":"Mary"}, + {"id": 3, "name":"José"} + ]|] + { + matchStatus = 200 + , matchHeaders = [matchContentTypeJson, "Content-Profile" <:> "SPECIAL \"@/\\#~_-"] + } + + it "succeeds in embedding with FK when the schema name has special characters" $ + request methodGet "/names?select=name,languages(name)&id=in.(1,3)" [("Accept-Profile", "SPECIAL \"@/\\#~_-")] "" `shouldRespondWith` + [json|[ + {"name": "John", languages: {"name": "English"}}, + {"name": "José", languages: {"name": "Spanish"}} + ]|] + { + matchStatus = 200 + , matchHeaders = [matchContentTypeJson, "Content-Profile" <:> "SPECIAL \"@/\\#~_-"] + } + + it "succeeds in embedding with computed relationships when the schema name has special characters" $ + request methodGet "/names?select=name,computed_languages(name)&id=in.(1,3)" [("Accept-Profile", "SPECIAL \"@/\\#~_-")] "" `shouldRespondWith` + [json|[ + {"name": "John", computed_languages: {"name": "English"}}, + {"name": "José", computed_languages: {"name": "Spanish"}} ]|] { matchStatus = 200 diff --git a/test/spec/fixtures/data.sql b/test/spec/fixtures/data.sql index 63aba4f5a..aee8e421f 100644 --- a/test/spec/fixtures/data.sql +++ b/test/spec/fixtures/data.sql @@ -792,8 +792,10 @@ INSERT INTO shop_bles(id, name, coords, shop_id, range_area) VALUES(1, 'Beacon-1 INSERT INTO shop_bles(id, name, coords, shop_id, range_area) VALUES(2, 'Beacon-2', 'SRID=4326;POINT(-71.10044 42.373695)', 1, extensions.ST_GeomFromGeoJSON('{"type": "Polygon", "coordinates": [ [ [ -71.10034391283989, 42.37385299961788 ], [ -71.10036939382553, 42.373756895982865 ], [ -71.1002916097641, 42.373745997623224 ], [ -71.1002641171217, 42.37384408279195 ], [ -71.10034391283989, 42.37385299961788 ] ] ]}')); +TRUNCATE TABLE "SPECIAL ""@/\#~_-".languages CASCADE; +INSERT INTO "SPECIAL ""@/\#~_-".languages (id, name) VALUES (1, 'English'), (2, 'Spanish'); TRUNCATE TABLE "SPECIAL ""@/\#~_-".names CASCADE; -INSERT INTO "SPECIAL ""@/\#~_-".names (id, name) VALUES (1, 'John'), (2, 'Mary'); +INSERT INTO "SPECIAL ""@/\#~_-".names (id, name, language_id) VALUES (1, 'John', 1), (2, 'Mary', 1), (3, 'José', 2); TRUNCATE TABLE do$llar$s CASCADE; INSERT INTO do$llar$s (a$num$) VALUES (100), (200), (300); diff --git a/test/spec/fixtures/privileges.sql b/test/spec/fixtures/privileges.sql index e43508cb3..2c583a2cf 100644 --- a/test/spec/fixtures/privileges.sql +++ b/test/spec/fixtures/privileges.sql @@ -191,6 +191,7 @@ GRANT ALL ON TABLE , view_test , shops , shop_bles + , "SPECIAL ""@/\#~_-".languages , "SPECIAL ""@/\#~_-".names , do$llar$s , safe_update_items diff --git a/test/spec/fixtures/schema.sql b/test/spec/fixtures/schema.sql index cfa821c12..a240b10fc 100644 --- a/test/spec/fixtures/schema.sql +++ b/test/spec/fixtures/schema.sql @@ -2660,11 +2660,21 @@ create function get_shop(id int) returns shops as $$ select * from shops where id = $1; $$ language sql; -CREATE TABLE "SPECIAL ""@/\#~_-".names( +CREATE TABLE "SPECIAL ""@/\#~_-".languages( id INT PRIMARY KEY, name TEXT ); +CREATE TABLE "SPECIAL ""@/\#~_-".names( + id INT PRIMARY KEY, + name TEXT, + language_id INT REFERENCES "SPECIAL ""@/\#~_-".languages(id) +); + +CREATE FUNCTION "SPECIAL ""@/\#~_-".computed_languages("SPECIAL ""@/\#~_-".names) RETURNS SETOF "SPECIAL ""@/\#~_-".languages ROWS 1 AS $$ + SELECT * FROM "SPECIAL ""@/\#~_-".languages where id = $1.language_id; +$$ LANGUAGE sql; + CREATE FUNCTION "EXTRA ""@/\#~_-".get_val_special(val text) RETURNS text AS $$ SELECT val; $$ LANGUAGE sql;