fix: Stricter query string parsing - no jsonpath in embedding

Signed-off-by: Wolfgang Walther <walther@technowledgy.de>
This commit is contained in:
Wolfgang Walther
2022-10-27 21:54:44 +02:00
committed by Wolfgang Walther
parent 7c7a04a27e
commit ae8625a7b6
4 changed files with 22 additions and 12 deletions
+1
View File
@@ -27,6 +27,7 @@ This project adheres to [Semantic Versioning](http://semver.org/).
- #2444, Removed `db-pool-timeout` option, because this was removed upstream in hasql-pool. - @robx - #2444, Removed `db-pool-timeout` option, because this was removed upstream in hasql-pool. - @robx
- #2343, PATCH requests that don't affect any rows no longer return 404 - @wolfgangwalther - #2343, PATCH requests that don't affect any rows no longer return 404 - @wolfgangwalther
- #2537, Stricter parsing of query string. Instead of silently ignoring, the parser now throws on invalid syntax like json paths for embeddings etc. - @wolfgangwalther
### Deprecated ### Deprecated
+19 -10
View File
@@ -309,10 +309,10 @@ pTreePath = do
-- Right [Node {rootLabel = SelectField {selField = ("id",[]), selCast = Nothing, selAlias = Nothing}, subForest = []}] -- Right [Node {rootLabel = SelectField {selField = ("id",[]), selCast = Nothing, selAlias = Nothing}, subForest = []}]
-- --
-- >>> P.parse pFieldForest "" "client(id)" -- >>> P.parse pFieldForest "" "client(id)"
-- Right [Node {rootLabel = SelectRelation {selField = ("client",[]), selAlias = Nothing, selHint = Nothing, selJoinType = Nothing}, subForest = [Node {rootLabel = SelectField {selField = ("id",[]), selCast = Nothing, selAlias = Nothing}, subForest = []}]}] -- Right [Node {rootLabel = SelectRelation {selRelation = "client", selAlias = Nothing, selHint = Nothing, selJoinType = Nothing}, subForest = [Node {rootLabel = SelectField {selField = ("id",[]), selCast = Nothing, selAlias = Nothing}, subForest = []}]}]
-- --
-- >>> P.parse pFieldForest "" "*,client(*,nested(*))" -- >>> P.parse pFieldForest "" "*,client(*,nested(*))"
-- Right [Node {rootLabel = SelectField {selField = ("*",[]), selCast = Nothing, selAlias = Nothing}, subForest = []},Node {rootLabel = SelectRelation {selField = ("client",[]), selAlias = Nothing, selHint = Nothing, selJoinType = Nothing}, subForest = [Node {rootLabel = SelectField {selField = ("*",[]), selCast = Nothing, selAlias = Nothing}, subForest = []},Node {rootLabel = SelectRelation {selField = ("nested",[]), selAlias = Nothing, selHint = Nothing, selJoinType = Nothing}, subForest = [Node {rootLabel = SelectField {selField = ("*",[]), selCast = Nothing, selAlias = Nothing}, subForest = []}]}]}] -- Right [Node {rootLabel = SelectField {selField = ("*",[]), selCast = Nothing, selAlias = Nothing}, subForest = []},Node {rootLabel = SelectRelation {selRelation = "client", selAlias = Nothing, selHint = Nothing, selJoinType = Nothing}, subForest = [Node {rootLabel = SelectField {selField = ("*",[]), selCast = Nothing, selAlias = Nothing}, subForest = []},Node {rootLabel = SelectRelation {selRelation = "nested", selAlias = Nothing, selHint = Nothing, selJoinType = Nothing}, subForest = [Node {rootLabel = SelectField {selField = ("*",[]), selCast = Nothing, selAlias = Nothing}, subForest = []}]}]}]
pFieldForest :: Parser [Tree SelectItem] pFieldForest :: Parser [Tree SelectItem]
pFieldForest = pFieldTree `sepBy1` lexeme (char ',') pFieldForest = pFieldTree `sepBy1` lexeme (char ',')
where where
@@ -384,29 +384,38 @@ aliasSeparator = char ':' >> notFollowedBy (char ':')
-- Parse regular fields in select -- Parse regular fields in select
-- --
-- >>> P.parse pRelationSelect "" "rel(*)" -- >>> P.parse pRelationSelect "" "rel(*)"
-- Right (SelectRelation {selField = ("rel",[]), selAlias = Nothing, selHint = Nothing, selJoinType = Nothing}) -- Right (SelectRelation {selRelation = "rel", selAlias = Nothing, selHint = Nothing, selJoinType = Nothing})
-- --
-- >>> P.parse pRelationSelect "" "alias:rel(*)" -- >>> P.parse pRelationSelect "" "alias:rel(*)"
-- Right (SelectRelation {selField = ("rel",[]), selAlias = Just "alias", selHint = Nothing, selJoinType = Nothing}) -- Right (SelectRelation {selRelation = "rel", selAlias = Just "alias", selHint = Nothing, selJoinType = Nothing})
-- --
-- >>> P.parse pRelationSelect "" "rel!hint(*)" -- >>> P.parse pRelationSelect "" "rel!hint(*)"
-- Right (SelectRelation {selField = ("rel",[]), selAlias = Nothing, selHint = Just "hint", selJoinType = Nothing}) -- Right (SelectRelation {selRelation = "rel", selAlias = Nothing, selHint = Just "hint", selJoinType = Nothing})
-- --
-- >>> P.parse pRelationSelect "" "rel!inner(*)" -- >>> P.parse pRelationSelect "" "rel!inner(*)"
-- Right (SelectRelation {selField = ("rel",[]), selAlias = Nothing, selHint = Nothing, selJoinType = Just JTInner}) -- Right (SelectRelation {selRelation = "rel", selAlias = Nothing, selHint = Nothing, selJoinType = Just JTInner})
-- --
-- >>> P.parse pRelationSelect "" "rel!hint!inner(*)" -- >>> P.parse pRelationSelect "" "rel!hint!inner(*)"
-- Right (SelectRelation {selField = ("rel",[]), selAlias = Nothing, selHint = Just "hint", selJoinType = Just JTInner}) -- Right (SelectRelation {selRelation = "rel", selAlias = Nothing, selHint = Just "hint", selJoinType = Just JTInner})
-- --
-- >>> P.parse pRelationSelect "" "alias:rel!inner!hint(*)" -- >>> P.parse pRelationSelect "" "alias:rel!inner!hint(*)"
-- Right (SelectRelation {selField = ("rel",[]), selAlias = Just "alias", selHint = Just "hint", selJoinType = Just JTInner}) -- Right (SelectRelation {selRelation = "rel", selAlias = Just "alias", selHint = Just "hint", selJoinType = Just JTInner})
--
-- >>> P.parse pRelationSelect "" "rel->jsonpath(*)"
-- Left (line 1, column 6):
-- unexpected '>'
--
-- >>> P.parse pRelationSelect "" "rel->jsonpath!hint(*)"
-- Left (line 1, column 6):
-- unexpected '>'
pRelationSelect :: Parser SelectItem pRelationSelect :: Parser SelectItem
pRelationSelect = lexeme $ try ( do pRelationSelect = lexeme $ try ( do
alias <- optionMaybe ( try(pFieldName <* aliasSeparator) ) alias <- optionMaybe ( try(pFieldName <* aliasSeparator) )
fld <- pField name <- pFieldName
prm1 <- optionMaybe pEmbedParam prm1 <- optionMaybe pEmbedParam
prm2 <- optionMaybe pEmbedParam prm2 <- optionMaybe pEmbedParam
return $ SelectRelation fld alias (embedParamHint prm1 <|> embedParamHint prm2) (embedParamJoin prm1 <|> embedParamJoin prm2) try (void $ lookAhead (string "("))
return $ SelectRelation name alias (embedParamHint prm1 <|> embedParamHint prm2) (embedParamJoin prm1 <|> embedParamJoin prm2)
) )
where where
pEmbedParam :: Parser EmbedParam pEmbedParam :: Parser EmbedParam
+1 -1
View File
@@ -46,7 +46,7 @@ data SelectItem
, selAlias :: Maybe Alias , selAlias :: Maybe Alias
} }
| SelectRelation | SelectRelation
{ selField :: Field { selRelation :: FieldName
, selAlias :: Maybe Alias , selAlias :: Maybe Alias
, selHint :: Maybe Hint , selHint :: Maybe Hint
, selJoinType :: Maybe JoinType , selJoinType :: Maybe JoinType
+1 -1
View File
@@ -113,7 +113,7 @@ initReadRequest qi@QualifiedIdentifier{..} =
let nxtDepth = succ depth in let nxtDepth = succ depth in
Node q $ Node q $
foldr (treeEntry nxtDepth) foldr (treeEntry nxtDepth)
(Node defReadPlan{from=QualifiedIdentifier qiSchema (fst selField), relName=fst selField, relAlias=selAlias, relHint=selHint, relJoinType=selJoinType, depth=nxtDepth} []) (Node defReadPlan{from=QualifiedIdentifier qiSchema selRelation, relName=selRelation, relAlias=selAlias, relHint=selHint, relJoinType=selJoinType, depth=nxtDepth} [])
fldForest:rForest fldForest:rForest
treeEntry _ (Node SelectField{..} _) (Node q rForest) = Node q{select=(selField, selCast, selAlias):select q} rForest treeEntry _ (Node SelectField{..} _) (Node q rForest) = Node q{select=(selField, selCast, selAlias):select q} rForest