1
Fork 0

add support for subqueries in scalar expressions

This commit is contained in:
Jake Wheat 2013-12-13 20:43:28 +02:00
parent d6d91b1935
commit 00269617b3
4 changed files with 53 additions and 13 deletions

View file

@ -174,6 +174,19 @@ to be.
> prefixCast = try (CastOp <$> typeName > prefixCast = try (CastOp <$> typeName
> <*> stringLiteral) > <*> stringLiteral)
> subquery :: P ScalarExpr
> subquery =
> choice
> [try $ SubQueryExpr SqSq <$> parens queryExpr
> ,SubQueryExpr <$> try sqkw <*> parens queryExpr]
> where
> sqkw = try $ choice
> [SqExists <$ keyword_ "exists"
> ,SqIn <$ keyword_ "in"
> ,SqAll <$ try (keyword_ "all")
> ,SqAny <$ keyword_ "any"
> ,SqSome <$ keyword_ "some"]
> typeName :: P TypeName > typeName :: P TypeName
> typeName = choice > typeName = choice
> [TypeName "double precision" > [TypeName "double precision"
@ -212,6 +225,7 @@ to be.
> factor = choice [literal > factor = choice [literal
> ,scase > ,scase
> ,cast > ,cast
> ,subquery
> ,unaryOp > ,unaryOp
> ,try app > ,try app
> ,try dottedIden > ,try dottedIden
@ -226,6 +240,8 @@ to be.
> sparens :: P ScalarExpr > sparens :: P ScalarExpr
> sparens = Parens <$> parens scalarExpr' > sparens = Parens <$> parens scalarExpr'
attempt to fix the precedence and associativity. Doesn't work
> toHaskell :: ScalarExpr -> HSE.Exp > toHaskell :: ScalarExpr -> HSE.Exp
> toHaskell e = case e of > toHaskell e = case e of
> Iden i -> HSE.Var $ HSE.UnQual $ HSE.Ident i > Iden i -> HSE.Var $ HSE.UnQual $ HSE.Ident i
@ -248,6 +264,7 @@ to be.
> (HSE.List [ltoh $ maybeToList v > (HSE.List [ltoh $ maybeToList v
> ,HSE.List $ map (ltoh . (\(a,b) -> [a,b])) ts > ,HSE.List $ map (ltoh . (\(a,b) -> [a,b])) ts
> ,ltoh $ maybeToList el]) > ,ltoh $ maybeToList el])
> _ -> error "please fix me 1"
> where > where
> ltoh = HSE.List . map toHaskell > ltoh = HSE.List . map toHaskell
@ -294,14 +311,14 @@ to be.
> ++ HSE.infixl_ 1 ["and"] > ++ HSE.infixl_ 1 ["and"]
> ++ HSE.infixl_ 0 ["or"] > ++ HSE.infixl_ 0 ["or"]
> fixFixity :: ScalarExpr -> ScalarExpr > _fixFixity :: ScalarExpr -> ScalarExpr
> fixFixity se = runIdentity $ > _fixFixity se = runIdentity $
> toSql <$> HSE.applyFixities sqlFixities (toHaskell se) > toSql <$> HSE.applyFixities sqlFixities (toHaskell se)
> scalarExpr :: P ScalarExpr > scalarExpr :: P ScalarExpr
> scalarExpr = > scalarExpr =
> choice [try star > choice [try star
> ,fixFixity <$> scalarExpr'] > ,{-fixFixity <$>-} scalarExpr']
------------------------------------------------- -------------------------------------------------

View file

@ -55,6 +55,16 @@ back into SQL source text. It attempts to format the output nicely.
> scalarExpr (CastOp (TypeName tn) s) = > scalarExpr (CastOp (TypeName tn) s) =
> text tn <+> quotes (text s) > text tn <+> quotes (text s)
> scalarExpr (SubQueryExpr ty qe) =
> (case ty of
> SqSq -> empty
> SqExists -> text "exists"
> SqIn -> text "in"
> SqAll -> text "all"
> SqSome -> text "some"
> SqAny -> text "any"
> ) <+> parens (queryExpr qe)
= query expressions = query expressions
> queryExpr :: QueryExpr -> Doc > queryExpr :: QueryExpr -> Doc

View file

@ -2,6 +2,7 @@
> module Language.SQL.SimpleSQL.Syntax > module Language.SQL.SimpleSQL.Syntax
> (ScalarExpr(..) > (ScalarExpr(..)
> ,TypeName(..) > ,TypeName(..)
> ,SubQueryExprType(..)
> ,QueryExpr(..) > ,QueryExpr(..)
> ,makeSelect > ,makeSelect
> ,Duplicates(..) > ,Duplicates(..)
@ -26,10 +27,14 @@
> | Parens ScalarExpr > | Parens ScalarExpr
> | Cast ScalarExpr TypeName > | Cast ScalarExpr TypeName
> | CastOp TypeName String > | CastOp TypeName String
> | SubQueryExpr SubQueryExprType QueryExpr
> deriving (Eq,Show) > deriving (Eq,Show)
> data TypeName = TypeName String deriving (Eq,Show) > data TypeName = TypeName String deriving (Eq,Show)
> data SubQueryExprType = SqExists | SqIn | SqSq | SqAll | SqSome | SqAny
> deriving (Eq,Show)
> data QueryExpr > data QueryExpr
> = Select > = Select
> {qeDuplicates :: Duplicates > {qeDuplicates :: Duplicates

View file

@ -124,14 +124,22 @@
> subqueries :: TestItem > subqueries :: TestItem
> subqueries = Group "unaryOperators" $ map (uncurry TestScalarExpr) > subqueries = Group "unaryOperators" $ map (uncurry TestScalarExpr)
> [{-("exists (select * from t)", Op "not" [Iden "a"]) > [("exists (select a from t)", SubQueryExpr SqExists ms)
> ,("(select a from t)", Op "not" [Op "not" [Iden "a"]]) > ,("(select a from t)", SubQueryExpr SqSq ms)
> ,("in (select a from t)", Op "+" [Iden "a"]) > ,("in (select a from t)", SubQueryExpr SqIn ms)
> ,("not in (select a from t)", Op "+" [Iden "a"]) > ,("not in (select a from t)", Op "not" [SubQueryExpr SqIn ms])
> ,("a > ALL (select a from t)", Op "-" [Iden "a"]) > ,("a > all (select a from t)"
> ,("a > SOME (select a from t)", Op "-" [Iden "a"]) > ,Op ">" [Iden "a", SubQueryExpr SqAll ms])
> ,("a > ANY (select a from t)", Op "-" [Iden "a"])-} > ,("a = some (select a from t)"
> ,Op "=" [Iden "a", SubQueryExpr SqSome ms])
> ,("a <= any (select a from t)"
> ,Op "<=" [Iden "a", SubQueryExpr SqAny ms])
> ] > ]
> where
> ms = makeSelect
> {qeSelectList = [(Nothing,Iden "a")]
> ,qeFrom = [SimpleTableRef "t"]
> }
> miscOps :: TestItem > miscOps :: TestItem
> miscOps = Group "unaryOperators" $ map (uncurry TestScalarExpr) > miscOps = Group "unaryOperators" $ map (uncurry TestScalarExpr)