add support for ansi standard offset and fetch syntax
This commit is contained in:
parent
8093498f2d
commit
b2728ec9bf
|
@ -12,6 +12,7 @@
|
|||
> import Data.Char
|
||||
> import Text.Parsec hiding (ParseError)
|
||||
> import qualified Text.Parsec as P
|
||||
> import Text.Parsec.Perm
|
||||
|
||||
> import Language.SQL.SimpleSQL.Syntax
|
||||
> import Language.SQL.SimpleSQL.Fixity
|
||||
|
@ -572,11 +573,26 @@ where, having, limit, offset).
|
|||
> <*> option Asc (choice [Asc <$ keyword_ "asc"
|
||||
> ,Desc <$ keyword_ "desc"])
|
||||
|
||||
> limit :: P ScalarExpr
|
||||
> limit = keywordScalarExpr "limit"
|
||||
allows offset and fetch in either order
|
||||
+ 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 = 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
|
||||
|
||||
|
@ -601,7 +617,7 @@ and union, etc..
|
|||
> >>= optionSuffix queryExprSuffix]
|
||||
> where
|
||||
> select = try (keyword_ "select") >>
|
||||
> Select
|
||||
> mkSelect
|
||||
> <$> (fromMaybe All <$> duplicates)
|
||||
> <*> selectList
|
||||
> <*> option [] from
|
||||
|
@ -609,8 +625,9 @@ and union, etc..
|
|||
> <*> option [] sgroupBy
|
||||
> <*> optionMaybe having
|
||||
> <*> option [] orderBy
|
||||
> <*> optionMaybe limit
|
||||
> <*> optionMaybe offset
|
||||
> <*> offsetFetch
|
||||
> 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 <$> commaSep (parens (commaSep scalarExpr))
|
||||
> table = try (keyword_ "table") >> Table <$> name
|
||||
|
@ -698,7 +715,7 @@ keyword parser also
|
|||
> blacklist :: [String]
|
||||
> blacklist =
|
||||
> ["select", "as", "from", "where", "having", "group", "order"
|
||||
> ,"limit", "offset"
|
||||
> ,"limit", "offset", "fetch"
|
||||
> ,"inner", "left", "right", "full", "natural", "join"
|
||||
> ,"cross", "on", "using", "lateral"
|
||||
> ,"when", "then", "case", "end", "in"
|
||||
|
|
|
@ -149,7 +149,7 @@
|
|||
= query expressions
|
||||
|
||||
> 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"
|
||||
> ,case d of
|
||||
> All -> empty
|
||||
|
@ -160,8 +160,9 @@
|
|||
> ,grpBy gb
|
||||
> ,maybeScalarExpr "having" hv
|
||||
> ,orderBy od
|
||||
> ,maybeScalarExpr "limit" lm
|
||||
> ,maybeScalarExpr "offset" off
|
||||
> ,maybe empty (\e -> text "offset" <+> scalarExpr e <+> text "rows") off
|
||||
> ,maybe empty (\e -> text "fetch next" <+> scalarExpr e
|
||||
> <+> text "rows only") fe
|
||||
> ]
|
||||
> queryExpr (CombineQueryExpr q1 ct d c q2) =
|
||||
> sep [queryExpr q1
|
||||
|
|
|
@ -145,8 +145,8 @@
|
|||
> ,qeGroupBy :: [ScalarExpr]
|
||||
> ,qeHaving :: Maybe ScalarExpr
|
||||
> ,qeOrderBy :: [(ScalarExpr,Direction)]
|
||||
> ,qeLimit :: Maybe ScalarExpr
|
||||
> ,qeOffset :: Maybe ScalarExpr
|
||||
> ,qeFetch :: Maybe ScalarExpr
|
||||
> }
|
||||
> | CombineQueryExpr
|
||||
> {qe0 :: QueryExpr
|
||||
|
@ -177,8 +177,8 @@ I'm not sure if this is valid syntax or not.
|
|||
> ,qeGroupBy = []
|
||||
> ,qeHaving = Nothing
|
||||
> ,qeOrderBy = []
|
||||
> ,qeLimit = Nothing
|
||||
> ,qeOffset = Nothing}
|
||||
> ,qeOffset = Nothing
|
||||
> ,qeFetch = Nothing}
|
||||
|
||||
|
||||
> -- | represents the Distinct or All keywords, which can be used
|
||||
|
|
22
TODO
22
TODO
|
@ -1,33 +1,17 @@
|
|||
|
||||
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
|
||||
standard sql, if not, leave for now. There is something about
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
|
@ -74,6 +58,8 @@ review abstract syntax (e.g. combine App with SpecialOp?)
|
|||
|
||||
Later general tasks:
|
||||
|
||||
sql server top syntax
|
||||
|
||||
extended string literals, escapes and other flavours (like pg and
|
||||
oracle custom delimiters)
|
||||
|
||||
|
|
|
@ -126,18 +126,22 @@ These are a few misc tests which don't fit anywhere else.
|
|||
|
||||
> 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"))
|
||||
> [-- ansi standard
|
||||
> ("select a from t offset 5 rows fetch next 10 rows only"
|
||||
> ,ms (Just $ NumLit "5") (Just $ NumLit "10"))
|
||||
> ,("select a from t offset 5 rows;"
|
||||
> ,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
|
||||
> ms l o = makeSelect
|
||||
> ms o l = makeSelect
|
||||
> {qeSelectList = [(Nothing,Iden "a")]
|
||||
> ,qeFrom = [TRSimple "t"]
|
||||
> ,qeLimit = l
|
||||
> ,qeOffset = o}
|
||||
> ,qeOffset = o
|
||||
> ,qeFetch = l}
|
||||
|
||||
> combos :: TestItem
|
||||
> combos = Group "combos" $ map (uncurry TestQueryExpr)
|
||||
|
|
Loading…
Reference in a new issue