add support for between
This commit is contained in:
parent
386d835cf8
commit
955658c41f
|
@ -128,6 +128,7 @@ digitse[+-]digits
|
||||||
> where
|
> where
|
||||||
> letterOrUnderscore = char '_' <|> letter
|
> letterOrUnderscore = char '_' <|> letter
|
||||||
> letterDigitOrUnderscore = char '_' <|> alphaNum
|
> letterDigitOrUnderscore = char '_' <|> alphaNum
|
||||||
|
|
||||||
> blacklist :: [String]
|
> blacklist :: [String]
|
||||||
> 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"
|
||||||
|
@ -142,7 +143,7 @@ to be.
|
||||||
|
|
||||||
> dottedIden :: P ScalarExpr
|
> dottedIden :: P ScalarExpr
|
||||||
> dottedIden = Iden2 <$> identifierString
|
> dottedIden = Iden2 <$> identifierString
|
||||||
> <*> (symbol "." *> identifierString)
|
> <*> (symbol "." *> identifierString)
|
||||||
|
|
||||||
> star :: P ScalarExpr
|
> star :: P ScalarExpr
|
||||||
> star = choice [Star <$ symbol "*"
|
> star = choice [Star <$ symbol "*"
|
||||||
|
@ -169,7 +170,7 @@ to be.
|
||||||
> cast = parensCast <|> prefixCast
|
> cast = parensCast <|> prefixCast
|
||||||
> where
|
> where
|
||||||
> parensCast = try (keyword_ "cast") >>
|
> parensCast = try (keyword_ "cast") >>
|
||||||
> parens (Cast <$> scalarExpr
|
> parens (Cast <$> scalarExpr'
|
||||||
> <*> (keyword_ "as" *> typeName))
|
> <*> (keyword_ "as" *> typeName))
|
||||||
> prefixCast = try (CastOp <$> typeName
|
> prefixCast = try (CastOp <$> typeName
|
||||||
> <*> stringLiteral)
|
> <*> stringLiteral)
|
||||||
|
@ -181,11 +182,24 @@ to be.
|
||||||
> <*> return e
|
> <*> return e
|
||||||
> <*> parens (choice
|
> <*> parens (choice
|
||||||
> [InQueryExpr <$> queryExpr
|
> [InQueryExpr <$> queryExpr
|
||||||
> ,InList <$> commaSep1 scalarExpr])
|
> ,InList <$> commaSep1 scalarExpr'])
|
||||||
> where
|
> where
|
||||||
> inty = try $ choice [True <$ keyword_ "in"
|
> inty = try $ choice [True <$ keyword_ "in"
|
||||||
> ,False <$ keyword_ "not" <* keyword_ "in"]
|
> ,False <$ keyword_ "not" <* keyword_ "in"]
|
||||||
|
|
||||||
|
> betweenSuffix :: ScalarExpr -> P ScalarExpr
|
||||||
|
> betweenSuffix e =
|
||||||
|
> makeOp
|
||||||
|
> <$> opName
|
||||||
|
> <*> return e
|
||||||
|
> <*> scalarExpr'' True
|
||||||
|
> <*> (keyword_ "and" *> scalarExpr')
|
||||||
|
> where
|
||||||
|
> opName = try $ choice
|
||||||
|
> ["between" <$ keyword_ "between"
|
||||||
|
> ,"not between" <$ keyword_ "not" <* keyword_ "between"]
|
||||||
|
> makeOp n a b c = Op n [a,b,c]
|
||||||
|
|
||||||
> subquery :: P ScalarExpr
|
> subquery :: P ScalarExpr
|
||||||
> subquery =
|
> subquery =
|
||||||
> choice
|
> choice
|
||||||
|
@ -215,6 +229,11 @@ to be.
|
||||||
> binOpKeywordNames :: [String]
|
> binOpKeywordNames :: [String]
|
||||||
> binOpKeywordNames = ["and", "or", "like"]
|
> binOpKeywordNames = ["and", "or", "like"]
|
||||||
|
|
||||||
|
used for between parsing
|
||||||
|
|
||||||
|
> binOpKeywordNamesNoAnd :: [String]
|
||||||
|
> binOpKeywordNamesNoAnd = filter (/="and") binOpKeywordNames
|
||||||
|
|
||||||
> unOpKeywordNames :: [String]
|
> unOpKeywordNames :: [String]
|
||||||
> unOpKeywordNames = ["not"]
|
> unOpKeywordNames = ["not"]
|
||||||
|
|
||||||
|
@ -224,14 +243,23 @@ to be.
|
||||||
|
|
||||||
> unaryOp :: P ScalarExpr
|
> unaryOp :: P ScalarExpr
|
||||||
> unaryOp =
|
> unaryOp =
|
||||||
> makeOp <$> opSymbol <*> scalarExpr
|
> makeOp <$> opSymbol <*> scalarExpr'
|
||||||
> where
|
> where
|
||||||
> makeOp nm e = Op nm [e]
|
> makeOp nm e = Op nm [e]
|
||||||
> opSymbol = choice (map (try . symbol) unOpSymbolNames
|
> opSymbol = choice (map (try . symbol) unOpSymbolNames
|
||||||
> ++ map (try . keyword) unOpKeywordNames)
|
> ++ map (try . keyword) unOpKeywordNames)
|
||||||
|
|
||||||
> scalarExpr' :: P ScalarExpr
|
> scalarExpr' :: P ScalarExpr
|
||||||
> scalarExpr' = factor >>= trysuffix
|
> scalarExpr' = scalarExpr'' False
|
||||||
|
|
||||||
|
the bexpr is to deal with between x and y
|
||||||
|
|
||||||
|
when we are parsing the scalar expr for x, we don't allow and as a
|
||||||
|
binary operator except nested in parens. This is taken from how
|
||||||
|
postgresql handles this
|
||||||
|
|
||||||
|
> scalarExpr'' :: Bool -> P ScalarExpr
|
||||||
|
> scalarExpr'' bExpr = factor >>= trysuffix
|
||||||
> where
|
> where
|
||||||
> factor = choice [literal
|
> factor = choice [literal
|
||||||
> ,scase
|
> ,scase
|
||||||
|
@ -245,10 +273,14 @@ to be.
|
||||||
> trysuffix e = try (suffix e) <|> return e
|
> trysuffix e = try (suffix e) <|> return e
|
||||||
> suffix e0 = choice
|
> suffix e0 = choice
|
||||||
> [makeOp e0 <$> opSymbol <*> factor
|
> [makeOp e0 <$> opSymbol <*> factor
|
||||||
> ,inSuffix e0
|
> ,inSuffix e0
|
||||||
|
> ,betweenSuffix e0
|
||||||
> ] >>= trysuffix
|
> ] >>= trysuffix
|
||||||
> opSymbol = choice (map (try . symbol) binOpSymbolNames
|
> opSymbol = choice (map (try . symbol) binOpSymbolNames
|
||||||
> ++ map (try . keyword) binOpKeywordNames)
|
> ++ map (try . keyword)
|
||||||
|
> (if bExpr
|
||||||
|
> then binOpKeywordNamesNoAnd
|
||||||
|
> else binOpKeywordNames))
|
||||||
> makeOp e0 op e1 = Op op [e0,e1]
|
> makeOp e0 op e1 = Op op [e0,e1]
|
||||||
|
|
||||||
> sparens :: P ScalarExpr
|
> sparens :: P ScalarExpr
|
||||||
|
|
|
@ -29,6 +29,15 @@ back into SQL source text. It attempts to format the output nicely.
|
||||||
> scalarExpr (Star2 q) = text q <> text "." <> text "*"
|
> scalarExpr (Star2 q) = text q <> text "." <> text "*"
|
||||||
|
|
||||||
> scalarExpr (App f es) = text f <> parens (commaSep (map scalarExpr es))
|
> scalarExpr (App f es) = text f <> parens (commaSep (map scalarExpr es))
|
||||||
|
|
||||||
|
special cases
|
||||||
|
|
||||||
|
> scalarExpr (Op nm [a,b,c]) | nm `elem` ["between", "not between"] =
|
||||||
|
> sep [scalarExpr a
|
||||||
|
> ,text nm <+> scalarExpr b
|
||||||
|
> ,text "and" <+> scalarExpr c]
|
||||||
|
|
||||||
|
|
||||||
> scalarExpr (Op f [e]) = text f <+> scalarExpr e
|
> scalarExpr (Op f [e]) = text f <+> scalarExpr e
|
||||||
> scalarExpr (Op f [e0,e1]) =
|
> scalarExpr (Op f [e0,e1]) =
|
||||||
> sep [scalarExpr e0, text f, scalarExpr e1]
|
> sep [scalarExpr e0, text f, scalarExpr e1]
|
||||||
|
|
|
@ -147,8 +147,12 @@
|
||||||
> miscOps = Group "unaryOperators" $ map (uncurry TestScalarExpr)
|
> miscOps = Group "unaryOperators" $ map (uncurry TestScalarExpr)
|
||||||
> [("a in (1,2,3)"
|
> [("a in (1,2,3)"
|
||||||
> ,In True (Iden "a") $ InList $ map NumLit ["1","2","3"])
|
> ,In True (Iden "a") $ InList $ map NumLit ["1","2","3"])
|
||||||
> --,("a between b and c", Op "not" [])
|
> ,("a between b and c", Op "between" [Iden "a"
|
||||||
> --,("a not between b and c", Op "not" [])
|
> ,Iden "b"
|
||||||
|
> ,Iden "c"])
|
||||||
|
> ,("a not between b and c", Op "not between" [Iden "a"
|
||||||
|
> ,Iden "b"
|
||||||
|
> ,Iden "c"])
|
||||||
> --,("a is null", Op "not" [])
|
> --,("a is null", Op "not" [])
|
||||||
> --,("a is not null", Op "not" [])
|
> --,("a is not null", Op "not" [])
|
||||||
> --,("a is distinct from b", Op "not" [])
|
> --,("a is distinct from b", Op "not" [])
|
||||||
|
|
Loading…
Reference in a new issue