fix: Allow schema names with special characters in the search path

Fixes regression where the search path did not recognize schemas with uppercase, spaces and other special characters in their names.
This commit is contained in:
Laurence Isla
2022-06-23 18:54:43 -05:00
committed by GitHub
parent 870f7a39b0
commit f7745e1569
11 changed files with 60 additions and 13 deletions
+1
View File
@@ -12,6 +12,7 @@ main =
, "-XNoImplicitPrelude"
, "-XStandaloneDeriving"
, "-isrc"
, "src/PostgREST/Query/SqlFragment.hs"
, "src/PostgREST/Request/Preferences.hs"
, "src/PostgREST/Request/QueryParams.hs"
]
+4 -4
View File
@@ -645,7 +645,7 @@ def test_db_schema_reload(tmp_path, defaultenv):
with run(configfile, env=defaultenv) as postgrest:
response = postgrest.session.get("/rpc/get_guc_value?name=search_path")
assert response.text == '"public, public"'
assert response.text == '"\\"public\\", \\"public\\""'
# change setting
configfile.write_text(
@@ -663,7 +663,7 @@ def test_db_schema_reload(tmp_path, defaultenv):
time.sleep(1)
response = postgrest.session.get("/rpc/get_guc_value?name=search_path")
assert response.text == '"v1, public"'
assert response.text == '"\\"v1\\", \\"public\\""'
def test_db_schema_notify_reload(defaultenv):
@@ -673,7 +673,7 @@ def test_db_schema_notify_reload(defaultenv):
with run(env=env) as postgrest:
response = postgrest.session.get("/rpc/get_guc_value?name=search_path")
assert response.text == '"public, public"'
assert response.text == '"\\"public\\", \\"public\\""'
# change db-schemas config on the db and reload config and cache with notify
postgrest.session.post(
@@ -683,7 +683,7 @@ def test_db_schema_notify_reload(defaultenv):
time.sleep(0.1)
response = postgrest.session.get("/rpc/get_guc_value?name=search_path")
assert response.text == '"v1, public"'
assert response.text == '"\\"v1\\", \\"public\\""'
# reset db-schemas config on the db
response = postgrest.session.post("/rpc/reset_db_schema_config")
+5
View File
@@ -58,5 +58,10 @@ spec = describe "extra search path" $ do
`shouldRespondWith` [json|true|]
{ matchHeaders = [matchContentTypeJson] }
it "finds a function on a schema with uppercase and special characters in its name" $
request methodGet "/rpc/special_extended_schema?val=value" [] ""
`shouldRespondWith` [json|"value"|]
{ matchHeaders = [matchContentTypeJson] }
it "can detect fk relations through multiple views recursively when middle views are in extra search path" $
get "/consumers_extra_view?select=*,orders_view(*)" `shouldRespondWith` 200
+14 -3
View File
@@ -68,11 +68,22 @@ spec =
it "fails trying to read table from unkown schema" $
request methodGet "/parents" [("Accept-Profile", "unkown")] "" `shouldRespondWith`
[json|{"message":"The schema must be one of the following: v1, v2","code":"PGRST106","details":null,"hint":null}|]
[json|{"message":"The schema must be one of the following: v1, v2, SPECIAL \"@/\\#~_-","code":"PGRST106","details":null,"hint":null}|]
{
matchStatus = 406
}
it "succeeds in reading a table from a schema with uppercase and special characters in its name" $
request methodGet "/names" [("Accept-Profile", "SPECIAL \"@/\\#~_-")] "" `shouldRespondWith`
[json|[
{"id":1,"name":"John"},
{"id":2,"name":"Mary"}
]|]
{
matchStatus = 200
, matchHeaders = [matchContentTypeJson, "Content-Profile" <:> "SPECIAL \"@/\\#~_-"]
}
context "Inserting tables on different schemas" $ do
it "succeeds inserting on default schema and returning it" $
request methodPost "/children"
@@ -111,7 +122,7 @@ spec =
request methodPost "/children" [("Content-Profile", "unknown")]
[json|{"name": "child 4", "parent_id": 4}|]
`shouldRespondWith`
[json|{"message":"The schema must be one of the following: v1, v2","code":"PGRST106","details":null,"hint":null}|]
[json|{"message":"The schema must be one of the following: v1, v2, SPECIAL \"@/\\#~_-","code":"PGRST106","details":null,"hint":null}|]
{
matchStatus = 406
}
@@ -325,7 +336,7 @@ spec =
it "fails trying to read definitions from unkown schema" $
request methodGet "/" [("Accept-Profile", "unkown")] "" `shouldRespondWith`
[json|{"message":"The schema must be one of the following: v1, v2","code":"PGRST106","details":null,"hint":null}|]
[json|{"message":"The schema must be one of the following: v1, v2, SPECIAL \"@/\\#~_-","code":"PGRST106","details":null,"hint":null}|]
{
matchStatus = 406
}
+2 -2
View File
@@ -170,7 +170,7 @@ testNonexistentSchemaCfg :: AppConfig
testNonexistentSchemaCfg = baseCfg { configDbSchemas = fromList ["nonexistent"] }
testCfgExtraSearchPath :: AppConfig
testCfgExtraSearchPath = baseCfg { configDbExtraSearchPath = ["public", "extensions"] }
testCfgExtraSearchPath = baseCfg { configDbExtraSearchPath = ["public", "extensions", "EXTRA \"@/\\#~_-"] }
testCfgRootSpec :: AppConfig
testCfgRootSpec = baseCfg { configDbRootSpec = Just $ QualifiedIdentifier mempty "root"}
@@ -182,7 +182,7 @@ testCfgResponseHeaders :: AppConfig
testCfgResponseHeaders = baseCfg { configDbPreRequest = Just $ QualifiedIdentifier mempty "custom_headers" }
testMultipleSchemaCfg :: AppConfig
testMultipleSchemaCfg = baseCfg { configDbSchemas = fromList ["v1", "v2"] }
testMultipleSchemaCfg = baseCfg { configDbSchemas = fromList ["v1", "v2", "SPECIAL \"@/\\#~_-"] }
testCfgLegacyGucs :: AppConfig
testCfgLegacyGucs = baseCfg { configDbUseLegacyGucs = False }
+3
View File
@@ -795,3 +795,6 @@ INSERT INTO shop_bles(id, name, coords, shop_id, range_area) VALUES(1, 'Beacon-1
extensions.ST_GeomFromGeoJSON('{"type": "Polygon", "coordinates": [ [ [ -71.10045254230499, 42.37387083326593 ], [ -71.10048070549963, 42.37377126199953 ], [ -71.10039688646793, 42.37375838212269 ], [ -71.10037006437777, 42.37385844878863 ], [ -71.10045254230499, 42.37387083326593 ] ] ]}'));
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 ""@/\#~_-".names CASCADE;
INSERT INTO "SPECIAL ""@/\#~_-".names (id, name) VALUES (1, 'John'), (2, 'Mary');
+3
View File
@@ -8,6 +8,8 @@ GRANT USAGE ON SCHEMA
, extensions
, v1
, v2
, "SPECIAL ""@/\#~_-"
, "EXTRA ""@/\#~_-"
TO postgrest_test_anonymous;
-- Schema test objects
@@ -190,6 +192,7 @@ GRANT ALL ON TABLE
, bulk_update_items_cpk
, shops
, shop_bles
, "SPECIAL ""@/\#~_-".names
TO postgrest_test_anonymous;
GRANT INSERT ON TABLE insertonly TO postgrest_test_anonymous;
+15
View File
@@ -20,6 +20,8 @@ CREATE SCHEMA تست;
CREATE SCHEMA extensions;
CREATE SCHEMA v1;
CREATE SCHEMA v2;
CREATE SCHEMA "SPECIAL ""@/\#~_-";
CREATE SCHEMA "EXTRA ""@/\#~_-";
COMMENT ON SCHEMA v1 IS 'v1 schema';
COMMENT ON SCHEMA v2 IS 'v2 schema';
@@ -2669,3 +2671,16 @@ create table shop_bles (
create function get_shop(id int) returns shops as $$
select * from shops where id = $1;
$$ language sql;
CREATE TABLE "SPECIAL ""@/\#~_-".names(
id INT PRIMARY KEY,
name TEXT
);
CREATE FUNCTION "EXTRA ""@/\#~_-".get_val_special(val text) RETURNS text AS $$
SELECT val;
$$ LANGUAGE sql;
CREATE FUNCTION test.special_extended_schema(val text) RETURNS text AS $$
SELECT get_val_special(val);
$$ LANGUAGE sql;