1
Fork 0

add support for in list, and fix code for in query expr

This commit is contained in:
Jake Wheat 2013-12-13 21:00:06 +02:00
parent 00269617b3
commit 386d835cf8
4 changed files with 57 additions and 26 deletions

View file

@ -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]

View file

@ -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

View file

@ -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

View file

@ -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