From 04e1186f0836ba20e5015d5df9662f416150602a Mon Sep 17 00:00:00 2001 From: calebmer Date: Sun, 20 Dec 2015 15:07:12 -0500 Subject: [PATCH 1/2] Consistent read query escaping --- CHANGELOG.md | 5 ++++- src/PostgREST/QueryBuilder.hs | 12 ++++++------ 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 96c82b7f4..ab12292f9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,8 +3,11 @@ All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org/). -#Unreleased +## Unreleased + +### Fixed - Fix bug in many-many relation detection - @ruslantalpa +- Inconsistent escaping of table names in read queries - @calebmer ## [0.3.0.2] - 2015-12-16 diff --git a/src/PostgREST/QueryBuilder.hs b/src/PostgREST/QueryBuilder.hs index d4e916631..aebcded84 100644 --- a/src/PostgREST/QueryBuilder.hs +++ b/src/PostgREST/QueryBuilder.hs @@ -271,20 +271,20 @@ requestToQuery schema (DbRead (Node (Select colSelects tbls conditions ord, (nod getQueryParts (Node n@(_, (name, Just (Relation {relType=Child,relTable=Table{tableName=table}}))) forst) (j,s) = (j,sel:s) where sel = "COALESCE((" - <> "SELECT array_to_json(array_agg(row_to_json("<>table<>"))) " - <> "FROM (" <> subquery <> ") " <> table + <> "SELECT array_to_json(array_agg(row_to_json("<>pgFmtIdent table<>"))) " + <> "FROM (" <> subquery <> ") " <> pgFmtIdent table <> "), '[]') AS " <> pgFmtIdent name where subquery = requestToQuery schema (DbRead (Node n forst)) getQueryParts (Node n@(_, (name, Just (Relation {relType=Parent,relTable=Table{tableName=table}}))) forst) (j,s) = (joi:j,sel:s) where - sel = "row_to_json(" <> table <> ".*) AS "<>pgFmtIdent name --TODO must be singular - joi = ("( " <> subquery <> " ) AS " <> table, table) + sel = "row_to_json(" <> pgFmtIdent table <> ".*) AS "<>pgFmtIdent name --TODO must be singular + joi = ("( " <> subquery <> " ) AS " <> pgFmtIdent table, table) where subquery = requestToQuery schema (DbRead (Node n forst)) getQueryParts (Node n@(_, (name, Just (Relation {relType=Many,relTable=Table{tableName=table}}))) forst) (j,s) = (j,sel:s) where sel = "COALESCE ((" - <> "SELECT array_to_json(array_agg(row_to_json("<>table<>"))) " - <> "FROM (" <> subquery <> ") " <> table + <> "SELECT array_to_json(array_agg(row_to_json("<>pgFmtIdent table<>"))) " + <> "FROM (" <> subquery <> ") " <> pgFmtIdent table <> "), '[]') AS " <> pgFmtIdent name where subquery = requestToQuery schema (DbRead (Node n forst)) --the following is just to remove the warning From 3a3d4038cb0a9d6a3ce38c53730dd07ab02235cc Mon Sep 17 00:00:00 2001 From: calebmer Date: Wed, 23 Dec 2015 12:27:00 -0500 Subject: [PATCH 2/2] Add tests for wierd usecases --- test/Feature/QuerySpec.hs | 15 +++++++++++++++ test/Feature/StructureSpec.hs | 4 +++- test/fixtures/data.sql | 5 +++++ test/fixtures/privileges.sql | 2 ++ test/fixtures/schema.sql | 9 +++++++++ 5 files changed, 34 insertions(+), 1 deletion(-) diff --git a/test/Feature/QuerySpec.hs b/test/Feature/QuerySpec.hs index 914078e71..4cdfcf86f 100644 --- a/test/Feature/QuerySpec.hs +++ b/test/Feature/QuerySpec.hs @@ -387,3 +387,18 @@ spec struct pool = around (withApp cfgDefault struct pool) $ do it "returns proper json" $ post "/rpc/sayhello" [json| { "name": "world" } |] `shouldRespondWith` [json| [{"sayhello":"Hello, world"}] |] + + describe "weird requests" $ do + it "can query as normal" $ do + get "/Escap3e;" `shouldRespondWith` + [json| [{"so6meIdColumn":1},{"so6meIdColumn":2},{"so6meIdColumn":3},{"so6meIdColumn":4},{"so6meIdColumn":5}] |] + get "/ghostBusters" `shouldRespondWith` + [json| [{"escapeId":1},{"escapeId":3},{"escapeId":5}] |] + + it "will embed a collection" $ + get "/Escap3e;?select=ghostBusters{*}" `shouldRespondWith` + [json| [{"ghostBusters":[{"escapeId":1}]},{"ghostBusters":[]},{"ghostBusters":[{"escapeId":3}]},{"ghostBusters":[]},{"ghostBusters":[{"escapeId":5}]}] |] + + it "will embed using a column" $ + get "/ghostBusters?select=escapeId{*}" `shouldRespondWith` + [json| [{"escapeId":{"so6meIdColumn":1}},{"escapeId":{"so6meIdColumn":3}},{"escapeId":{"so6meIdColumn":5}}] |] diff --git a/test/Feature/StructureSpec.hs b/test/Feature/StructureSpec.hs index d8b06ed7f..e13f207b0 100644 --- a/test/Feature/StructureSpec.hs +++ b/test/Feature/StructureSpec.hs @@ -18,13 +18,15 @@ spec struct pool = around (withApp cfgDefault struct pool) $ do it "lists views in schema" $ request methodGet "/" [] "" `shouldRespondWith` [json| [ - {"schema":"test","name":"articleStars","insertable":true} + {"schema":"test","name":"Escap3e;","insertable":true} + , {"schema":"test","name":"articleStars","insertable":true} , {"schema":"test","name":"articles","insertable":true} , {"schema":"test","name":"auto_incrementing_pk","insertable":true} , {"schema":"test","name":"clients","insertable":true} , {"schema":"test","name":"comments","insertable":true} , {"schema":"test","name":"complex_items","insertable":true} , {"schema":"test","name":"compound_pk","insertable":true} + , {"schema":"test","name":"ghostBusters","insertable":true} , {"schema":"test","name":"has_count_column","insertable":false} , {"schema":"test","name":"has_fk","insertable":true} , {"schema":"test","name":"insertable_view_with_join","insertable":true} diff --git a/test/fixtures/data.sql b/test/fixtures/data.sql index 260039a5f..3cc537eb3 100644 --- a/test/fixtures/data.sql +++ b/test/fixtures/data.sql @@ -260,6 +260,11 @@ INSERT INTO users_projects VALUES (2, 4); INSERT INTO users_projects VALUES (3, 1); INSERT INTO users_projects VALUES (3, 3); +TRUNCATE TABLE "Escap3e;" CASCADE; +INSERT INTO "Escap3e;" VALUES (1), (2), (3), (4), (5); + +TRUNCATE TABLE "ghostBusters" CASCADE; +INSERT INTO "ghostBusters" VALUES (1), (3), (5); -- -- PostgreSQL database dump complete diff --git a/test/fixtures/privileges.sql b/test/fixtures/privileges.sql index be3bc8ca7..cebb5ef0d 100644 --- a/test/fixtures/privileges.sql +++ b/test/fixtures/privileges.sql @@ -32,6 +32,8 @@ GRANT ALL ON TABLE , users , users_projects , users_tasks + , "Escap3e;" + , "ghostBusters" TO postgrest_test_anonymous; GRANT INSERT ON TABLE insertonly TO postgrest_test_anonymous; diff --git a/test/fixtures/schema.sql b/test/fixtures/schema.sql index d2f43c72b..08d264262 100755 --- a/test/fixtures/schema.sql +++ b/test/fixtures/schema.sql @@ -591,6 +591,15 @@ CREATE TABLE users_tasks ( ); +CREATE TABLE "Escap3e;" ( + "so6meIdColumn" integer primary key +); + +CREATE TABLE "ghostBusters" ( + "escapeId" integer not null references "Escap3e;"("so6meIdColumn") +); + + -- -- Name: id; Type: DEFAULT; Schema: test; Owner: - --