refactor app parser, from parser
This commit is contained in:
parent
3f08adb4c5
commit
65610af74e
|
@ -125,18 +125,16 @@ The parsing for the aggregate extensions is here as well:
|
||||||
aggregate([all|distinct] args [order by orderitems])
|
aggregate([all|distinct] args [order by orderitems])
|
||||||
|
|
||||||
> aggOrApp :: P ScalarExpr
|
> aggOrApp :: P ScalarExpr
|
||||||
> aggOrApp = do
|
> aggOrApp =
|
||||||
> i <- identifierString
|
> makeApp
|
||||||
> _ <- symbol "("
|
> <$> identifierString
|
||||||
> d <- try duplicates
|
> <*> parens ((,,) <$> try duplicates
|
||||||
> es <- choice [(:[]) <$> try star
|
> <*> choice [(:[]) <$> try star
|
||||||
> ,commaSep scalarExpr']
|
> ,commaSep scalarExpr']
|
||||||
> od <- try $ optionMaybe orderBy
|
> <*> try (optionMaybe orderBy))
|
||||||
> _ <- symbol ")"
|
> where
|
||||||
> case (d,od) of
|
> makeApp i (Nothing,es,Nothing) = App i es
|
||||||
> (Nothing,Nothing) ->
|
> makeApp i (d,es,od) = AggregateApp i d es (fromMaybe [] od)
|
||||||
> return $ App i es
|
|
||||||
> _ -> return $ AggregateApp i d es (fromMaybe [] od)
|
|
||||||
|
|
||||||
> duplicates :: P (Maybe Duplicates)
|
> duplicates :: P (Maybe Duplicates)
|
||||||
> duplicates = optionMaybe $ try $
|
> duplicates = optionMaybe $ try $
|
||||||
|
@ -161,8 +159,7 @@ always used with the optionSuffix combinator.
|
||||||
> <*> option [] orderBy)
|
> <*> option [] orderBy)
|
||||||
> where
|
> where
|
||||||
> partitionBy = try (keyword_ "partition") >>
|
> partitionBy = try (keyword_ "partition") >>
|
||||||
> keyword_ "by" >>
|
> keyword_ "by" >> commaSep1 scalarExpr'
|
||||||
> commaSep1 scalarExpr'
|
|
||||||
> windowSuffix _ = fail ""
|
> windowSuffix _ = fail ""
|
||||||
|
|
||||||
> app :: P ScalarExpr
|
> app :: P ScalarExpr
|
||||||
|
@ -473,60 +470,48 @@ optional or use try itself. The caller could do this.
|
||||||
|
|
||||||
== from
|
== from
|
||||||
|
|
||||||
this parser should be refactored, it is very unclear. Here is the
|
Here is the rough grammar for joins
|
||||||
rough grammar
|
|
||||||
|
|
||||||
tref
|
tref
|
||||||
(cross | [natural]
|
(cross | [natural] ([inner] | (left | right | full) [outer])) join
|
||||||
([inner]
|
tref
|
||||||
| left [outer]
|
|
||||||
| right [outer]
|
|
||||||
| full [outer]
|
|
||||||
)
|
|
||||||
join tref
|
|
||||||
[on expr | using (...)]
|
[on expr | using (...)]
|
||||||
|
|
||||||
|
|
||||||
> from :: P [TableRef]
|
> from :: P [TableRef]
|
||||||
> from = try (keyword_ "from") *> commaSep1 tref
|
> from = try (keyword_ "from") *> commaSep1 tref
|
||||||
> where
|
> where
|
||||||
> tref = choice [try (JoinQueryExpr <$> parens queryExpr)
|
> tref = nonJoinTref >>= optionSuffix joinTrefSuffix
|
||||||
|
> nonJoinTref = choice [try (JoinQueryExpr <$> parens queryExpr)
|
||||||
> ,JoinParens <$> parens tref
|
> ,JoinParens <$> parens tref
|
||||||
> ,SimpleTableRef <$> identifierString]
|
> ,SimpleTableRef <$> identifierString]
|
||||||
> >>= optionSuffix pjoin
|
> >>= optionSuffix aliasSuffix
|
||||||
> >>= optionSuffix alias
|
> aliasSuffix j =
|
||||||
> pjoin tref0 =
|
> let tableAlias = optional (try $ keyword_ "as") *> identifierString
|
||||||
> choice
|
> columnAliases = optionMaybe $ try $ parens
|
||||||
> [try (keyword_ "natural") *> keyword_ "inner"
|
> $ commaSep1 identifierString
|
||||||
> *> conditionlessSuffix tref0 Inner (Just JoinNatural)
|
> in option j (JoinAlias j <$> try tableAlias <*> try columnAliases)
|
||||||
> ,try (keyword_ "join")
|
> joinTrefSuffix t = (do
|
||||||
> *> (JoinTableRef Inner tref0 <$> tref <*> joinExpr)
|
> nat <- option False $ try (True <$ (try $ keyword_ "natural"))
|
||||||
> ,try (keyword_ "inner")
|
> JoinTableRef <$> joinType
|
||||||
> *> conditionSuffix tref0 Inner
|
> <*> return t
|
||||||
> ,try (choice [JLeft <$ keyword_ "left"
|
> <*> nonJoinTref
|
||||||
> ,JRight <$ keyword_ "right"
|
> <*> optionMaybe (joinCondition nat))
|
||||||
> ,Full <$ keyword_ "full"])
|
> >>= optionSuffix joinTrefSuffix
|
||||||
> >>= outerJoinSuffix tref0
|
> joinType = choice
|
||||||
> ,try (keyword_ "cross")
|
> [Cross <$ try (keyword_ "cross")
|
||||||
> *> conditionlessSuffix tref0 Cross Nothing
|
> ,Inner <$ try (keyword_ "inner")
|
||||||
|
> ,choice [JLeft <$ try (keyword_ "left")
|
||||||
|
> ,JRight <$ try (keyword_ "right")
|
||||||
|
> ,Full <$ try (keyword_ "full")]
|
||||||
|
> <* optional (try $ keyword_ "outer")]
|
||||||
|
> <* keyword "join"
|
||||||
|
> joinCondition nat =
|
||||||
|
> choice [guard nat >> return JoinNatural
|
||||||
|
> ,try (keyword_ "on") >>
|
||||||
|
> JoinOn <$> scalarExpr
|
||||||
|
> ,try (keyword_ "using") >>
|
||||||
|
> JoinUsing <$> parens (commaSep1 identifierString)
|
||||||
> ]
|
> ]
|
||||||
> >>= optionSuffix pjoin
|
|
||||||
> outerJoinSuffix tref0 jt =
|
|
||||||
> optional (keyword_ "outer") *> conditionSuffix tref0 jt
|
|
||||||
> conditionSuffix tref0 jt =
|
|
||||||
> keyword_ "join" *> (JoinTableRef jt tref0 <$> tref <*> joinExpr)
|
|
||||||
> conditionlessSuffix tref0 jt jc =
|
|
||||||
> keyword_ "join" *> (JoinTableRef jt tref0 <$> tref <*> return jc)
|
|
||||||
> joinExpr = choice
|
|
||||||
> [(Just . JoinUsing)
|
|
||||||
> <$> (try (keyword_ "using")
|
|
||||||
> *> parens (commaSep1 identifierString))
|
|
||||||
> ,(Just . JoinOn) <$> (try (keyword_ "on") *> scalarExpr)
|
|
||||||
> ,return Nothing
|
|
||||||
> ]
|
|
||||||
> alias j = let a1 = optional (try (keyword_ "as")) *> identifierString
|
|
||||||
> a2 = optionMaybe (try $ parens (commaSep1 identifierString))
|
|
||||||
> in option j (JoinAlias j <$> try a1 <*> try a2)
|
|
||||||
|
|
||||||
== simple other parts
|
== simple other parts
|
||||||
|
|
||||||
|
@ -666,10 +651,12 @@ blacklist of keywords which aren't supported as identifiers.
|
||||||
> letterDigitOrUnderscore = char '_' <|> alphaNum
|
> letterDigitOrUnderscore = char '_' <|> alphaNum
|
||||||
|
|
||||||
> blacklist :: [String]
|
> blacklist :: [String]
|
||||||
> blacklist = ["as", "from", "where", "having", "group", "order"
|
> blacklist =
|
||||||
|
> ["select", "as", "from", "where", "having", "group", "order"
|
||||||
|
> ,"limit", "offset"
|
||||||
> ,"inner", "left", "right", "full", "natural", "join"
|
> ,"inner", "left", "right", "full", "natural", "join"
|
||||||
> ,"on", "using", "when", "then", "case", "end", "order"
|
> ,"cross", "on", "using"
|
||||||
> ,"limit", "offset", "in"
|
> ,"when", "then", "case", "end", "in"
|
||||||
> ,"except", "intersect", "union"]
|
> ,"except", "intersect", "union"]
|
||||||
|
|
||||||
TODO: talk about what must be in the blacklist, and what doesn't need
|
TODO: talk about what must be in the blacklist, and what doesn't need
|
||||||
|
@ -738,6 +725,11 @@ whitespace parser which skips comments also
|
||||||
|
|
||||||
= generic parser helpers
|
= generic parser helpers
|
||||||
|
|
||||||
|
a possible issue with the option suffix is that it enforces left
|
||||||
|
associativity when chaining it recursively. Have to review
|
||||||
|
all these uses and figure out if any should be right associative
|
||||||
|
instead, and create an alternative suffix parser
|
||||||
|
|
||||||
> optionSuffix :: (a -> P a) -> a -> P a
|
> optionSuffix :: (a -> P a) -> a -> P a
|
||||||
> optionSuffix p a = option a (p a)
|
> optionSuffix p a = option a (p a)
|
||||||
|
|
||||||
|
|
|
@ -299,6 +299,14 @@
|
||||||
> ,("select a from (t cross join u) as u"
|
> ,("select a from (t cross join u) as u"
|
||||||
> ,ms [JoinAlias (JoinParens $ JoinTableRef Cross (SimpleTableRef "t")
|
> ,ms [JoinAlias (JoinParens $ JoinTableRef Cross (SimpleTableRef "t")
|
||||||
> (SimpleTableRef "u") Nothing) "u" Nothing])
|
> (SimpleTableRef "u") Nothing) "u" Nothing])
|
||||||
|
> -- todo: not sure if the associativity is correct
|
||||||
|
> ,("select a from t cross join u cross join v",
|
||||||
|
> ms [JoinTableRef Cross
|
||||||
|
> (JoinTableRef Cross (SimpleTableRef "t")
|
||||||
|
> (SimpleTableRef "u")
|
||||||
|
> Nothing)
|
||||||
|
> (SimpleTableRef "v")
|
||||||
|
> Nothing])
|
||||||
> ]
|
> ]
|
||||||
> where
|
> where
|
||||||
> ms f = makeSelect {qeSelectList = [(Nothing,Iden "a")]
|
> ms f = makeSelect {qeSelectList = [(Nothing,Iden "a")]
|
||||||
|
|
Loading…
Reference in a new issue