1
Fork 0

add support for limit and offset

This commit is contained in:
Jake Wheat 2013-12-13 17:27:02 +02:00
parent 1a8551825d
commit a81f62b940
5 changed files with 88 additions and 31 deletions

View file

@ -73,7 +73,8 @@ digitse[+-]digits
> 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"
> ,"on", "using", "when", "then", "case", "end", "order"] > ,"on", "using", "when", "then", "case", "end", "order"
> ,"limit", "offset"]
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.
@ -209,12 +210,16 @@ to be.
= query expressions = query expressions
> duplicates :: P Duplicates
> duplicates = option All $ try $ choice [All <$ keyword_ "all"
> ,Distinct <$ keyword "distinct"]
> selectItem :: P (Maybe String, ScalarExpr) > selectItem :: P (Maybe String, ScalarExpr)
> selectItem = flip (,) <$> scalarExpr <*> optionMaybe (try alias) > selectItem = flip (,) <$> scalarExpr <*> optionMaybe (try alias)
> where alias = optional (try (keyword_ "as")) *> identifierString > where alias = optional (try (keyword_ "as")) *> identifierString
> selectList :: P [(Maybe String,ScalarExpr)] > selectList :: P [(Maybe String,ScalarExpr)]
> selectList = try (keyword_ "select") *> commaSep1 selectItem > selectList = commaSep1 selectItem
> from :: P [TableRef] > from :: P [TableRef]
> from = option [] (try (keyword_ "from") *> commaSep1 tref) > from = option [] (try (keyword_ "from") *> commaSep1 tref)
@ -256,8 +261,11 @@ to be.
> alias j = let a1 = optional (try (keyword_ "as")) *> identifierString > alias j = let a1 = optional (try (keyword_ "as")) *> identifierString
> in option j (JoinAlias j <$> try a1) > in option j (JoinAlias j <$> try a1)
> optionalScalarExpr :: String -> P (Maybe ScalarExpr)
> optionalScalarExpr k = optionMaybe (try (keyword_ k) *> scalarExpr)
> swhere :: P (Maybe ScalarExpr) > swhere :: P (Maybe ScalarExpr)
> swhere = optionMaybe (try (keyword_ "where") *> scalarExpr) > swhere = optionalScalarExpr "where"
> sgroupBy :: P [ScalarExpr] > sgroupBy :: P [ScalarExpr]
> sgroupBy = option [] (try (keyword_ "group") > sgroupBy = option [] (try (keyword_ "group")
@ -265,7 +273,7 @@ to be.
> *> commaSep1 scalarExpr) > *> commaSep1 scalarExpr)
> having :: P (Maybe ScalarExpr) > having :: P (Maybe ScalarExpr)
> having = optionMaybe (try (keyword_ "having") *> scalarExpr) > having = optionalScalarExpr "having"
> orderBy :: P [(ScalarExpr,Direction)] > orderBy :: P [(ScalarExpr,Direction)]
> orderBy = option [] (try (keyword_ "order") > orderBy = option [] (try (keyword_ "order")
@ -276,16 +284,26 @@ to be.
> <*> option Asc (choice [Asc <$ keyword_ "asc" > <*> option Asc (choice [Asc <$ keyword_ "asc"
> ,Desc <$ keyword_ "desc"]) > ,Desc <$ keyword_ "desc"])
> limit :: P (Maybe ScalarExpr)
> limit = optionalScalarExpr "limit"
> offset :: P (Maybe ScalarExpr)
> offset = optionalScalarExpr "offset"
> queryExpr :: P QueryExpr > queryExpr :: P QueryExpr
> queryExpr = > queryExpr =
> try (keyword_ "select") >>
> Select > Select
> <$> selectList > <$> duplicates
> <*> selectList
> <*> from > <*> from
> <*> swhere > <*> swhere
> <*> sgroupBy > <*> sgroupBy
> <*> having > <*> having
> <*> orderBy > <*> orderBy
> <*> limit
> <*> offset
------------------------------------------------ ------------------------------------------------

View file

@ -51,14 +51,20 @@ back into SQL source text. It attempts to format the output nicely.
= query expressions = query expressions
> queryExpr :: QueryExpr -> Doc > queryExpr :: QueryExpr -> Doc
> queryExpr (Select sl fr wh gb hv od) = > queryExpr (Select d sl fr wh gb hv od lm off) =
> sep [text "select" > sep [text "select"
> ,case d of
> All -> empty
> Distinct -> text "distinct"
> ,nest 4 $ sep [selectList sl] > ,nest 4 $ sep [selectList sl]
> ,from fr > ,from fr
> ,whr wh > ,maybeScalarExpr "where" wh
> ,grpBy gb > ,grpBy gb
> ,having hv > ,maybeScalarExpr "having" hv
> ,orderBy od] > ,orderBy od
> ,maybeScalarExpr "limit" lm
> ,maybeScalarExpr "offset" off
> ]
> selectList :: [(Maybe String, ScalarExpr)] -> Doc > selectList :: [(Maybe String, ScalarExpr)] -> Doc
> selectList is = commaSep $ map si is > selectList is = commaSep $ map si is
@ -97,20 +103,16 @@ back into SQL source text. It attempts to format the output nicely.
> joinCond Nothing = empty > joinCond Nothing = empty
> joinCond (Just JoinNatural) = empty > joinCond (Just JoinNatural) = empty
> whr :: Maybe ScalarExpr -> Doc > maybeScalarExpr :: String -> Maybe ScalarExpr -> Doc
> whr = maybe empty > maybeScalarExpr k = maybe empty
> (\w -> sep [text "where" > (\e -> sep [text k
> ,nest 4 $ scalarExpr w]) > ,nest 4 $ scalarExpr e])
> grpBy :: [ScalarExpr] -> Doc > grpBy :: [ScalarExpr] -> Doc
> grpBy [] = empty > grpBy [] = empty
> grpBy gs = sep [text "group by" > grpBy gs = sep [text "group by"
> ,nest 4 $ commaSep $ map scalarExpr gs] > ,nest 4 $ commaSep $ map scalarExpr gs]
> having :: Maybe ScalarExpr -> Doc
> having = maybe empty
> (\w -> sep [text "having"
> ,nest 4 $ scalarExpr w])
> orderBy :: [(ScalarExpr,Direction)] -> Doc > orderBy :: [(ScalarExpr,Direction)] -> Doc
> orderBy [] = empty > orderBy [] = empty
> orderBy os = sep [text "order by" > orderBy os = sep [text "order by"

View file

@ -6,6 +6,7 @@
> ,TableRef(..) > ,TableRef(..)
> ,JoinType(..) > ,JoinType(..)
> ,JoinCondition(..) > ,JoinCondition(..)
> ,Duplicates(..)
> ,Direction(..) > ,Direction(..)
> ) where > ) where
@ -26,23 +27,30 @@
> data QueryExpr > data QueryExpr
> = Select > = Select
> {qeSelectList :: [(Maybe String,ScalarExpr)] > {qeDuplicates :: Duplicates
> ,qeSelectList :: [(Maybe String,ScalarExpr)]
> ,qeFrom :: [TableRef] > ,qeFrom :: [TableRef]
> ,qeWhere :: Maybe ScalarExpr > ,qeWhere :: Maybe ScalarExpr
> ,qeGroupBy :: [ScalarExpr] > ,qeGroupBy :: [ScalarExpr]
> ,qeHaving :: Maybe ScalarExpr > ,qeHaving :: Maybe ScalarExpr
> ,qeOrderBy :: [(ScalarExpr,Direction)] > ,qeOrderBy :: [(ScalarExpr,Direction)]
> ,qeLimit :: Maybe ScalarExpr
> ,qeOffset :: Maybe ScalarExpr
> } deriving (Eq,Show) > } deriving (Eq,Show)
> data Duplicates = Distinct | All deriving (Eq,Show)
> data Direction = Asc | Desc deriving (Eq,Show) > data Direction = Asc | Desc deriving (Eq,Show)
> makeSelect :: QueryExpr > makeSelect :: QueryExpr
> makeSelect = Select {qeSelectList = [] > makeSelect = Select {qeDuplicates = All
> ,qeSelectList = []
> ,qeFrom = [] > ,qeFrom = []
> ,qeWhere = Nothing > ,qeWhere = Nothing
> ,qeGroupBy = [] > ,qeGroupBy = []
> ,qeHaving = Nothing > ,qeHaving = Nothing
> ,qeOrderBy = []} > ,qeOrderBy = []
> ,qeLimit = Nothing
> ,qeOffset = Nothing}
> data TableRef = SimpleTableRef String > data TableRef = SimpleTableRef String

17
TODO
View file

@ -22,12 +22,7 @@ emacs parse error formatting
= sql support = sql support
distinct/all
limit,offset, top
scalar function syntax: scalar function syntax:
aggregate app
window app
cast cast
exists, in subquery exists, in subquery
scalar subquery scalar subquery
@ -35,16 +30,20 @@ scalar function syntax:
any/some/all any/some/all
between between
is null/ is not null is null/ is not null
review all ansi sql operators
interval literal interval literal
typed string lit? typed string lit
aggregate app
window app
review all ansi sql operators
placeholder/positional arg placeholder/positional arg
other missing operators other missing operators
unary + -
row constructors?
extract extract
substring substring
unary + -
row constructors?
except, intersect, union except, intersect, union

View file

@ -89,15 +89,31 @@
> queryExprParserTests :: TestItem > queryExprParserTests :: TestItem
> queryExprParserTests = Group "queryExprParserTests" > queryExprParserTests = Group "queryExprParserTests"
> [selectLists > [duplicates
> ,selectLists
> ,from > ,from
> ,whereClause > ,whereClause
> ,groupByClause > ,groupByClause
> ,having > ,having
> ,orderBy > ,orderBy
> ,limit
> ,fullQueries > ,fullQueries
> ] > ]
> duplicates :: TestItem
> duplicates = Group "duplicates" $ map (uncurry TestQueryExpr)
> [("select a from t" ,ms All)
> ,("select all a from t" ,ms All)
> ,("select distinct a from t", ms Distinct)
> ]
> where
> ms d = makeSelect
> {qeDuplicates = d
> ,qeSelectList = [(Nothing,Iden "a")]
> ,qeFrom = [SimpleTableRef "t"]}
> selectLists :: TestItem > selectLists :: TestItem
> selectLists = Group "selectLists" $ map (uncurry TestQueryExpr) > selectLists = Group "selectLists" $ map (uncurry TestQueryExpr)
> [("select 1", > [("select 1",
@ -212,6 +228,20 @@
> ,qeFrom = [SimpleTableRef "t"] > ,qeFrom = [SimpleTableRef "t"]
> ,qeOrderBy = o} > ,qeOrderBy = o}
> limit :: TestItem
> limit = Group "limit" $ map (uncurry TestQueryExpr)
> [("select a from t limit 10"
> ,ms (Just $ NumLit "10") Nothing)
> ,("select a from t limit 10 offset 10"
> ,ms (Just $ NumLit "10") (Just $ NumLit "10"))
> ]
> where
> ms l o = makeSelect
> {qeSelectList = [(Nothing,Iden "a")]
> ,qeFrom = [SimpleTableRef "t"]
> ,qeLimit = l
> ,qeOffset = o}
> fullQueries :: TestItem > fullQueries :: TestItem
> fullQueries = Group "queries" $ map (uncurry TestQueryExpr) > fullQueries = Group "queries" $ map (uncurry TestQueryExpr)
> [("select count(*) from t" > [("select count(*) from t"