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 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"

View file

@ -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

View file

@ -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
View file

@ -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)

View file

@ -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)