1
Fork 0

add support for ansi standard offset and fetch syntax

This commit is contained in:
Jake Wheat 2013-12-17 16:00:17 +02:00
parent 8093498f2d
commit b2728ec9bf
5 changed files with 47 additions and 39 deletions

View file

@ -12,6 +12,7 @@
> import Data.Char > import Data.Char
> import Text.Parsec hiding (ParseError) > import Text.Parsec hiding (ParseError)
> import qualified Text.Parsec as P > import qualified Text.Parsec as P
> import Text.Parsec.Perm
> import Language.SQL.SimpleSQL.Syntax > import Language.SQL.SimpleSQL.Syntax
> import Language.SQL.SimpleSQL.Fixity > import Language.SQL.SimpleSQL.Fixity
@ -572,11 +573,26 @@ where, having, limit, offset).
> <*> option Asc (choice [Asc <$ keyword_ "asc" > <*> option Asc (choice [Asc <$ keyword_ "asc"
> ,Desc <$ keyword_ "desc"]) > ,Desc <$ keyword_ "desc"])
> limit :: P ScalarExpr allows offset and fetch in either order
> limit = keywordScalarExpr "limit" + postgresql offset without row(s) and limit instead of fetch also
> offsetFetch :: P (Maybe ScalarExpr, Maybe ScalarExpr)
> offsetFetch = permute ((,) <$?> (Nothing, Just <$> offset)
> <|?> (Nothing, Just <$> fetch))
> offset :: P ScalarExpr > offset :: P ScalarExpr
> offset = keywordScalarExpr "offset" > offset = try (keyword_ "offset") *> scalarExpr
> <* option () (try $ choice [try (keyword_ "rows"),keyword_ "row"])
> fetch :: P ScalarExpr
> fetch = choice [ansiFetch, limit]
> where
> ansiFetch = try (keyword_ "fetch") >>
> choice [keyword_ "first",keyword_ "next"]
> *> scalarExpr
> <* choice [keyword_ "rows",keyword_ "row"]
> <* keyword_ "only"
> limit = try (keyword_ "limit") *> scalarExpr
== common table expressions == common table expressions
@ -601,7 +617,7 @@ and union, etc..
> >>= optionSuffix queryExprSuffix] > >>= optionSuffix queryExprSuffix]
> where > where
> select = try (keyword_ "select") >> > select = try (keyword_ "select") >>
> Select > mkSelect
> <$> (fromMaybe All <$> duplicates) > <$> (fromMaybe All <$> duplicates)
> <*> selectList > <*> selectList
> <*> option [] from > <*> option [] from
@ -609,8 +625,9 @@ and union, etc..
> <*> option [] sgroupBy > <*> option [] sgroupBy
> <*> optionMaybe having > <*> optionMaybe having
> <*> option [] orderBy > <*> option [] orderBy
> <*> optionMaybe limit > <*> offsetFetch
> <*> optionMaybe offset > mkSelect d sl f w g h od (ofs,fe) =
> Select d sl f w g h od ofs fe
> values = try (keyword_ "values") > values = try (keyword_ "values")
> >> Values <$> commaSep (parens (commaSep scalarExpr)) > >> Values <$> commaSep (parens (commaSep scalarExpr))
> table = try (keyword_ "table") >> Table <$> name > table = try (keyword_ "table") >> Table <$> name
@ -698,7 +715,7 @@ keyword parser also
> blacklist :: [String] > blacklist :: [String]
> blacklist = > blacklist =
> ["select", "as", "from", "where", "having", "group", "order" > ["select", "as", "from", "where", "having", "group", "order"
> ,"limit", "offset" > ,"limit", "offset", "fetch"
> ,"inner", "left", "right", "full", "natural", "join" > ,"inner", "left", "right", "full", "natural", "join"
> ,"cross", "on", "using", "lateral" > ,"cross", "on", "using", "lateral"
> ,"when", "then", "case", "end", "in" > ,"when", "then", "case", "end", "in"

View file

@ -149,7 +149,7 @@
= query expressions = query expressions
> queryExpr :: QueryExpr -> Doc > queryExpr :: QueryExpr -> Doc
> queryExpr (Select d sl fr wh gb hv od lm off) = > queryExpr (Select d sl fr wh gb hv od off fe) =
> sep [text "select" > sep [text "select"
> ,case d of > ,case d of
> All -> empty > All -> empty
@ -160,8 +160,9 @@
> ,grpBy gb > ,grpBy gb
> ,maybeScalarExpr "having" hv > ,maybeScalarExpr "having" hv
> ,orderBy od > ,orderBy od
> ,maybeScalarExpr "limit" lm > ,maybe empty (\e -> text "offset" <+> scalarExpr e <+> text "rows") off
> ,maybeScalarExpr "offset" off > ,maybe empty (\e -> text "fetch next" <+> scalarExpr e
> <+> text "rows only") fe
> ] > ]
> queryExpr (CombineQueryExpr q1 ct d c q2) = > queryExpr (CombineQueryExpr q1 ct d c q2) =
> sep [queryExpr q1 > sep [queryExpr q1

View file

@ -145,8 +145,8 @@
> ,qeGroupBy :: [ScalarExpr] > ,qeGroupBy :: [ScalarExpr]
> ,qeHaving :: Maybe ScalarExpr > ,qeHaving :: Maybe ScalarExpr
> ,qeOrderBy :: [(ScalarExpr,Direction)] > ,qeOrderBy :: [(ScalarExpr,Direction)]
> ,qeLimit :: Maybe ScalarExpr
> ,qeOffset :: Maybe ScalarExpr > ,qeOffset :: Maybe ScalarExpr
> ,qeFetch :: Maybe ScalarExpr
> } > }
> | CombineQueryExpr > | CombineQueryExpr
> {qe0 :: QueryExpr > {qe0 :: QueryExpr
@ -177,8 +177,8 @@ I'm not sure if this is valid syntax or not.
> ,qeGroupBy = [] > ,qeGroupBy = []
> ,qeHaving = Nothing > ,qeHaving = Nothing
> ,qeOrderBy = [] > ,qeOrderBy = []
> ,qeLimit = Nothing > ,qeOffset = Nothing
> ,qeOffset = Nothing} > ,qeFetch = Nothing}
> -- | represents the Distinct or All keywords, which can be used > -- | represents the Distinct or All keywords, which can be used

22
TODO
View file

@ -1,33 +1,17 @@
next release: next release:
ansi standard versions of limit and offset
OFFSET start { ROW | ROWS }
FETCH { FIRST | NEXT } [ count ] { ROW | ROWS } ONLY
-> + fix the abstract syntax to match this instead of postgres
(keep the postgres syntax version parser)
in the postgresql docs, the start and count must be in parens unless
they are a single integer
select * from generate_series(0,99) offset 5 fetch next 5 row only;
select * from generate_series(0,99) offset 5;
select * from generate_series(0,99) fetch next 5 row only;
+ sql server top syntax
more dots: implement as dot operator
more symbolic operators, array access a[5]? don't think this is more symbolic operators, array access a[5]? don't think this is
standard sql, if not, leave for now. There is something about standard sql, if not, leave for now. There is something about
arrays in sql:2008 arrays in sql:2008
row ctor: row(a,b) is fine, but also when there is 2 or more elements,
the word row can be omitted: (a,b)
fix lateral binding issue fix lateral binding issue
row ctor: row(a,b) is fine, but also when there is 2 or more elements,
the word row can be omitted: (a,b)
window frames and named windows window frames and named windows
@ -74,6 +58,8 @@ review abstract syntax (e.g. combine App with SpecialOp?)
Later general tasks: Later general tasks:
sql server top syntax
extended string literals, escapes and other flavours (like pg and extended string literals, escapes and other flavours (like pg and
oracle custom delimiters) oracle custom delimiters)

View file

@ -126,18 +126,22 @@ These are a few misc tests which don't fit anywhere else.
> limit :: TestItem > limit :: TestItem
> limit = Group "limit" $ map (uncurry TestQueryExpr) > limit = Group "limit" $ map (uncurry TestQueryExpr)
> [("select a from t limit 10" > [-- ansi standard
> ,ms (Just $ NumLit "10") Nothing) > ("select a from t offset 5 rows fetch next 10 rows only"
> ,ms (Just $ NumLit "5") (Just $ NumLit "10"))
> ,("select a from t limit 10 offset 10" > ,("select a from t offset 5 rows;"
> ,ms (Just $ NumLit "10") (Just $ NumLit "10")) > ,ms (Just $ NumLit "5") Nothing)
> ,("select a from t fetch next 10 row only;"
> ,ms Nothing (Just $ NumLit "10"))
> ,("select a from t offset 5 row fetch first 10 row only"
> ,ms (Just $ NumLit "5") (Just $ NumLit "10"))
> ] > ]
> where > where
> ms l o = makeSelect > ms o l = makeSelect
> {qeSelectList = [(Nothing,Iden "a")] > {qeSelectList = [(Nothing,Iden "a")]
> ,qeFrom = [TRSimple "t"] > ,qeFrom = [TRSimple "t"]
> ,qeLimit = l > ,qeOffset = o
> ,qeOffset = o} > ,qeFetch = l}
> combos :: TestItem > combos :: TestItem
> combos = Group "combos" $ map (uncurry TestQueryExpr) > combos = Group "combos" $ map (uncurry TestQueryExpr)