add support for in list, and fix code for in query expr
This commit is contained in:
parent
00269617b3
commit
386d835cf8
|
@ -132,7 +132,7 @@ digitse[+-]digits
|
||||||
> blacklist = ["as", "from", "where", "having", "group", "order"
|
> blacklist = ["as", "from", "where", "having", "group", "order"
|
||||||
> ,"inner", "left", "right", "full", "natural", "join"
|
> ,"inner", "left", "right", "full", "natural", "join"
|
||||||
> ,"on", "using", "when", "then", "case", "end", "order"
|
> ,"on", "using", "when", "then", "case", "end", "order"
|
||||||
> ,"limit", "offset"]
|
> ,"limit", "offset", "in"]
|
||||||
|
|
||||||
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
|
||||||
to be.
|
to be.
|
||||||
|
@ -174,6 +174,18 @@ to be.
|
||||||
> prefixCast = try (CastOp <$> typeName
|
> prefixCast = try (CastOp <$> typeName
|
||||||
> <*> stringLiteral)
|
> <*> stringLiteral)
|
||||||
|
|
||||||
|
> inSuffix :: ScalarExpr -> P ScalarExpr
|
||||||
|
> inSuffix e =
|
||||||
|
> In
|
||||||
|
> <$> inty
|
||||||
|
> <*> return e
|
||||||
|
> <*> parens (choice
|
||||||
|
> [InQueryExpr <$> queryExpr
|
||||||
|
> ,InList <$> commaSep1 scalarExpr])
|
||||||
|
> where
|
||||||
|
> inty = try $ choice [True <$ keyword_ "in"
|
||||||
|
> ,False <$ keyword_ "not" <* keyword_ "in"]
|
||||||
|
|
||||||
> subquery :: P ScalarExpr
|
> subquery :: P ScalarExpr
|
||||||
> subquery =
|
> subquery =
|
||||||
> choice
|
> choice
|
||||||
|
@ -182,7 +194,6 @@ to be.
|
||||||
> where
|
> where
|
||||||
> sqkw = try $ choice
|
> sqkw = try $ choice
|
||||||
> [SqExists <$ keyword_ "exists"
|
> [SqExists <$ keyword_ "exists"
|
||||||
> ,SqIn <$ keyword_ "in"
|
|
||||||
> ,SqAll <$ try (keyword_ "all")
|
> ,SqAll <$ try (keyword_ "all")
|
||||||
> ,SqAny <$ keyword_ "any"
|
> ,SqAny <$ keyword_ "any"
|
||||||
> ,SqSome <$ keyword_ "some"]
|
> ,SqSome <$ keyword_ "some"]
|
||||||
|
@ -232,7 +243,10 @@ to be.
|
||||||
> ,identifier
|
> ,identifier
|
||||||
> ,sparens]
|
> ,sparens]
|
||||||
> trysuffix e = try (suffix e) <|> return e
|
> trysuffix e = try (suffix e) <|> return e
|
||||||
> suffix e0 = (makeOp e0 <$> opSymbol <*> factor) >>= trysuffix
|
> suffix e0 = choice
|
||||||
|
> [makeOp e0 <$> opSymbol <*> factor
|
||||||
|
> ,inSuffix e0
|
||||||
|
> ] >>= trysuffix
|
||||||
> opSymbol = choice (map (try . symbol) binOpSymbolNames
|
> opSymbol = choice (map (try . symbol) binOpSymbolNames
|
||||||
> ++ map (try . keyword) binOpKeywordNames)
|
> ++ map (try . keyword) binOpKeywordNames)
|
||||||
> makeOp e0 op e1 = Op op [e0,e1]
|
> makeOp e0 op e1 = Op op [e0,e1]
|
||||||
|
|
|
@ -59,12 +59,20 @@ back into SQL source text. It attempts to format the output nicely.
|
||||||
> (case ty of
|
> (case ty of
|
||||||
> SqSq -> empty
|
> SqSq -> empty
|
||||||
> SqExists -> text "exists"
|
> SqExists -> text "exists"
|
||||||
> SqIn -> text "in"
|
|
||||||
> SqAll -> text "all"
|
> SqAll -> text "all"
|
||||||
> SqSome -> text "some"
|
> SqSome -> text "some"
|
||||||
> SqAny -> text "any"
|
> SqAny -> text "any"
|
||||||
> ) <+> parens (queryExpr qe)
|
> ) <+> parens (queryExpr qe)
|
||||||
|
|
||||||
|
> scalarExpr (In b se x) =
|
||||||
|
> sep [scalarExpr se
|
||||||
|
> ,if b then empty else text "not"
|
||||||
|
> ,text "in"
|
||||||
|
> ,parens (nest 4 $
|
||||||
|
> case x of
|
||||||
|
> InList es -> commaSep $ map scalarExpr es
|
||||||
|
> InQueryExpr qe -> queryExpr qe)]
|
||||||
|
|
||||||
= query expressions
|
= query expressions
|
||||||
|
|
||||||
> queryExpr :: QueryExpr -> Doc
|
> queryExpr :: QueryExpr -> Doc
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
> (ScalarExpr(..)
|
> (ScalarExpr(..)
|
||||||
> ,TypeName(..)
|
> ,TypeName(..)
|
||||||
> ,SubQueryExprType(..)
|
> ,SubQueryExprType(..)
|
||||||
|
> ,InThing(..)
|
||||||
> ,QueryExpr(..)
|
> ,QueryExpr(..)
|
||||||
> ,makeSelect
|
> ,makeSelect
|
||||||
> ,Duplicates(..)
|
> ,Duplicates(..)
|
||||||
|
@ -28,11 +29,16 @@
|
||||||
> | Cast ScalarExpr TypeName
|
> | Cast ScalarExpr TypeName
|
||||||
> | CastOp TypeName String
|
> | CastOp TypeName String
|
||||||
> | SubQueryExpr SubQueryExprType QueryExpr
|
> | SubQueryExpr SubQueryExprType QueryExpr
|
||||||
|
> | In Bool -- true if in, false if not in
|
||||||
|
> ScalarExpr InThing
|
||||||
> deriving (Eq,Show)
|
> deriving (Eq,Show)
|
||||||
|
|
||||||
> data TypeName = TypeName String deriving (Eq,Show)
|
> data TypeName = TypeName String deriving (Eq,Show)
|
||||||
|
> data InThing = InList [ScalarExpr]
|
||||||
|
> | InQueryExpr QueryExpr
|
||||||
|
> deriving (Eq,Show)
|
||||||
|
|
||||||
> data SubQueryExprType = SqExists | SqIn | SqSq | SqAll | SqSome | SqAny
|
> data SubQueryExprType = SqExists | SqSq | SqAll | SqSome | SqAny
|
||||||
> deriving (Eq,Show)
|
> deriving (Eq,Show)
|
||||||
|
|
||||||
> data QueryExpr
|
> data QueryExpr
|
||||||
|
|
45
Tests.lhs
45
Tests.lhs
|
@ -126,8 +126,10 @@
|
||||||
> subqueries = Group "unaryOperators" $ map (uncurry TestScalarExpr)
|
> subqueries = Group "unaryOperators" $ map (uncurry TestScalarExpr)
|
||||||
> [("exists (select a from t)", SubQueryExpr SqExists ms)
|
> [("exists (select a from t)", SubQueryExpr SqExists ms)
|
||||||
> ,("(select a from t)", SubQueryExpr SqSq ms)
|
> ,("(select a from t)", SubQueryExpr SqSq ms)
|
||||||
> ,("in (select a from t)", SubQueryExpr SqIn ms)
|
> ,("a in (select a from t)"
|
||||||
> ,("not in (select a from t)", Op "not" [SubQueryExpr SqIn ms])
|
> ,In True (Iden "a") (InQueryExpr ms))
|
||||||
|
> ,("a not in (select a from t)"
|
||||||
|
> ,In False (Iden "a") (InQueryExpr ms))
|
||||||
> ,("a > all (select a from t)"
|
> ,("a > all (select a from t)"
|
||||||
> ,Op ">" [Iden "a", SubQueryExpr SqAll ms])
|
> ,Op ">" [Iden "a", SubQueryExpr SqAll ms])
|
||||||
> ,("a = some (select a from t)"
|
> ,("a = some (select a from t)"
|
||||||
|
@ -143,25 +145,26 @@
|
||||||
|
|
||||||
> miscOps :: TestItem
|
> miscOps :: TestItem
|
||||||
> miscOps = Group "unaryOperators" $ map (uncurry TestScalarExpr)
|
> miscOps = Group "unaryOperators" $ map (uncurry TestScalarExpr)
|
||||||
> [{-("a in (1,2,3)", Op "not" [Iden "a"])
|
> [("a in (1,2,3)"
|
||||||
> ,("a between b and c", Op "not" [])
|
> ,In True (Iden "a") $ InList $ map NumLit ["1","2","3"])
|
||||||
> ,("a not between b and c", Op "not" [])
|
> --,("a between b and c", Op "not" [])
|
||||||
> ,("a is null", Op "not" [])
|
> --,("a not between b and c", Op "not" [])
|
||||||
> ,("a is not null", Op "not" [])
|
> --,("a is null", Op "not" [])
|
||||||
> ,("a is distinct from b", Op "not" [])
|
> --,("a is not null", Op "not" [])
|
||||||
> ,("a is not distinct from b", Op "not" [])
|
> --,("a is distinct from b", Op "not" [])
|
||||||
> ,("a is true", Op "not" [])
|
> --,("a is not distinct from b", Op "not" [])
|
||||||
> ,("a s not true", Op "not" [])
|
> --,("a is true", Op "not" [])
|
||||||
> ,("a is false", Op "not" [])
|
> --,("a s not true", Op "not" [])
|
||||||
> ,("a is not false", Op "not" [])
|
> --,("a is false", Op "not" [])
|
||||||
> ,("a is unknown", Op "not" [])
|
> --,("a is not false", Op "not" [])
|
||||||
> ,("a is not unknown", Op "not" [])
|
> --,("a is unknown", Op "not" [])
|
||||||
> ,("a like b", Op "not" [])
|
> --,("a is not unknown", Op "not" [])
|
||||||
> ,("a not like b", Op "not" [])
|
> --,("a like b", Op "not" [])
|
||||||
> ,("a is similar to b", Op "not" [])
|
> --,("a not like b", Op "not" [])
|
||||||
> ,("a is not similar to b", Op "not" [])
|
> --,("a is similar to b", Op "not" [])
|
||||||
> ,("a overlaps b", Op "not" [])
|
> --,("a is not similar to b", Op "not" [])
|
||||||
> ,("extract(day from t)", Op "not" [])-}
|
> --,("a overlaps b", Op "not" [])
|
||||||
|
> --,("extract(day from t)", Op "not" [])
|
||||||
> ]
|
> ]
|
||||||
|
|
||||||
> aggregates :: TestItem
|
> aggregates :: TestItem
|
||||||
|
|
Loading…
Reference in a new issue