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 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"
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
22
TODO
|
@ -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)
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
Loading…
Reference in a new issue