1
Fork 0

switch tests to hspec, improve error messages

This commit is contained in:
Jake Wheat 2024-02-04 16:00:59 +00:00
parent fadd010942
commit c11bee4a9c
36 changed files with 2570 additions and 1809 deletions

View file

@ -4,15 +4,19 @@ module Language.SQL.SimpleSQL.CreateIndex where
import Language.SQL.SimpleSQL.Syntax
import Language.SQL.SimpleSQL.TestTypes
import Language.SQL.SimpleSQL.TestRunners
import Data.Text (Text)
createIndexTests :: TestItem
createIndexTests = Group "create index tests"
[TestStatement ansi2011 "create index a on tbl(c1)"
[s "create index a on tbl(c1)"
$ CreateIndex False [nm "a"] [nm "tbl"] [nm "c1"]
,TestStatement ansi2011 "create index a.b on sc.tbl (c1, c2)"
,s "create index a.b on sc.tbl (c1, c2)"
$ CreateIndex False [nm "a", nm "b"] [nm "sc", nm "tbl"] [nm "c1", nm "c2"]
,TestStatement ansi2011 "create unique index a on tbl(c1)"
,s "create unique index a on tbl(c1)"
$ CreateIndex True [nm "a"] [nm "tbl"] [nm "c1"]
]
where
nm = Name Nothing
s :: HasCallStack => Text -> Statement -> TestItem
s src ast = testStatement ansi2011 src ast

View file

@ -3,26 +3,30 @@
module Language.SQL.SimpleSQL.CustomDialect (customDialectTests) where
import Language.SQL.SimpleSQL.TestTypes
import Language.SQL.SimpleSQL.TestRunners
import Data.Text (Text)
customDialectTests :: TestItem
customDialectTests = Group "custom dialect tests" (map (uncurry ParseQueryExpr) passTests
++ map (uncurry ParseScalarExprFails) failTests )
customDialectTests = Group "custom dialect tests" $
[q ansi2011 "SELECT a b"
,q noDateKeyword "SELECT DATE('2000-01-01')"
,q noDateKeyword "SELECT DATE"
,q dateApp "SELECT DATE('2000-01-01')"
,q dateIden "SELECT DATE"
,f ansi2011 "SELECT DATE('2000-01-01')"
,f ansi2011 "SELECT DATE"
,f dateApp "SELECT DATE"
,f dateIden "SELECT DATE('2000-01-01')"
-- show this never being allowed as an alias
,f ansi2011 "SELECT a date"
,f dateApp "SELECT a date"
,f dateIden "SELECT a date"
]
where
failTests = [(ansi2011,"SELECT DATE('2000-01-01')")
,(ansi2011,"SELECT DATE")
,(dateApp,"SELECT DATE")
,(dateIden,"SELECT DATE('2000-01-01')")
-- show this never being allowed as an alias
,(ansi2011,"SELECT a date")
,(dateApp,"SELECT a date")
,(dateIden,"SELECT a date")
]
passTests = [(ansi2011,"SELECT a b")
,(noDateKeyword,"SELECT DATE('2000-01-01')")
,(noDateKeyword,"SELECT DATE")
,(dateApp,"SELECT DATE('2000-01-01')")
,(dateIden,"SELECT DATE")
]
noDateKeyword = ansi2011 {diKeywords = filter (/="date") (diKeywords ansi2011)}
dateIden = ansi2011 {diIdentifierKeywords = "date" : diIdentifierKeywords ansi2011}
dateApp = ansi2011 {diAppKeywords = "date" : diAppKeywords ansi2011}
q :: HasCallStack => Dialect -> Text -> TestItem
q d src = testParseQueryExpr d src
f :: HasCallStack => Dialect -> Text -> TestItem
f d src = testParseQueryExprFails d src

View file

@ -3,19 +3,26 @@ module Language.SQL.SimpleSQL.EmptyStatement where
import Language.SQL.SimpleSQL.Syntax
import Language.SQL.SimpleSQL.TestTypes
import Language.SQL.SimpleSQL.TestRunners
import Data.Text (Text)
emptyStatementTests :: TestItem
emptyStatementTests = Group "empty statement"
[ TestStatement ansi2011 ";" EmptyStatement
, TestStatements ansi2011 ";" [EmptyStatement]
, TestStatements ansi2011 ";;" [EmptyStatement, EmptyStatement]
, TestStatements ansi2011 ";;;" [EmptyStatement, EmptyStatement, EmptyStatement]
, TestStatement ansi2011 "/* comment */ ;" EmptyStatement
, TestStatements ansi2011 "" []
, TestStatements ansi2011 "/* comment */" []
, TestStatements ansi2011 "/* comment */ ;" [EmptyStatement]
, TestStatements ansi2011 "/* comment */ ; /* comment */ ;"
[ s ";" EmptyStatement
, t ";" [EmptyStatement]
, t ";;" [EmptyStatement, EmptyStatement]
, t ";;;" [EmptyStatement, EmptyStatement, EmptyStatement]
, s "/* comment */ ;" EmptyStatement
, t "" []
, t "/* comment */" []
, t "/* comment */ ;" [EmptyStatement]
, t "/* comment */ ; /* comment */ ;"
[EmptyStatement, EmptyStatement]
, TestStatements ansi2011 "/* comment */ ; /* comment */ ; /* comment */ ;"
, t "/* comment */ ; /* comment */ ; /* comment */ ;"
[EmptyStatement, EmptyStatement, EmptyStatement]
]
where
s :: HasCallStack => Text -> Statement -> TestItem
s src a = testStatement ansi2011 src a
t :: HasCallStack => Text -> [Statement] -> TestItem
t src a = testStatements ansi2011 src a

View file

@ -1,156 +1,82 @@
{-
Want to work on the error messages. Ultimately, parsec won't give the
best error message for a parser combinator library in haskell. Should
check out the alternatives such as polyparse and uu-parsing.
See the file examples/ErrorMessagesTool.hs for some work on this
For now the plan is to try to get the best out of parsec. Skip heavy
work on this until the parser is more left factored?
Ideas:
1. generate large lists of invalid syntax
2. create table of the sql source and the error message
3. save these tables and compare from version to version. Want to
catch improvements and regressions and investigate. Have to do this
manually
= generating bad sql source
take good sql statements or expressions. Convert them into sequences
of tokens - want to preserve the whitespace and comments perfectly
here. Then modify these lists by either adding a token, removing a
token, or modifying a token (including creating bad tokens of raw
strings which don't represent anything than can be tokenized.
Now can see the error message for all of these bad strings. Probably
have to generate and prune this list manually in stages since there
will be too many.
Contexts:
another area to focus on is contexts: for instance, we have a set of
e.g. 1000 bad scalar expressions with error messages. Now can put
those bad scalar expressions into various contexts and see that the
error messages are still good.
plan:
1. create a list of all the value expression, with some variations for
each
2. manually create some error variations for each expression
3. create a renderer which will create a csv of the expressions and
the errors
this is to load as a spreadsheet to investigate more
4. create a renderer for the csv which will create a markdown file for
the website. this is to demonstrate the error messages in the
documentation
Then create some contexts for all of these: inside another value
expression, or inside a query expression. Do the same: render and
review the error messages.
Then, create some query expressions to focus on the non value
expression parts.
-}
module Language.SQL.SimpleSQL.ErrorMessages where
{-import Language.SQL.SimpleSQL.Parser
import Data.List
import Text.Groom
valueExpressions :: [String]
valueExpressions =
["10.."
,"..10"
,"10e1e2"
,"10e--3"
,"1a"
,"1%"
,"'b'ad'"
,"'bad"
,"bad'"
,"interval '5' ay"
,"interval '5' day (4.4)"
,"interval '5' day (a)"
,"intervala '5' day"
,"interval 'x' day (3"
,"interval 'x' day 3)"
,"1badiden"
,"$"
,"!"
,"*.a"
,"??"
,"3?"
,"?a"
,"row"
,"row 1,2"
,"row(1,2"
,"row 1,2)"
,"row(1 2)"
,"f("
,"f)"
,"f(a"
,"f a)"
,"f(a b)"
{-
TODO:
case
operators
-}
,"a + (b + c"
add simple test to check the error and quoting on later line in multi
line input for lexing and parsing; had a regression here that made it
to a release
{-
casts
subqueries: + whole set of parentheses use
in list
'keyword' functions
aggregates
window functions
-}
]
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE QuasiQuotes #-}
module Language.SQL.SimpleSQL.ErrorMessages
(errorMessageTests
) where
queryExpressions :: [String]
queryExpressions =
map sl1 valueExpressions
++ map sl2 valueExpressions
++ map sl3 valueExpressions
++
["select a from t inner jin u"]
import Language.SQL.SimpleSQL.TestTypes
import Language.SQL.SimpleSQL.Parse
import qualified Language.SQL.SimpleSQL.Lex as L
import Language.SQL.SimpleSQL.TestRunners
--import Language.SQL.SimpleSQL.Syntax
import Language.SQL.SimpleSQL.Expectations
import Test.Hspec (it)
import Debug.Trace
import Data.Text (Text)
import qualified Data.Text as T
import qualified Text.RawString.QQ as R
errorMessageTests :: TestItem
errorMessageTests = Group "error messages"
[gp (parseQueryExpr ansi2011 "" Nothing) prettyError [R.r|
select
a
from t
where
something
order by 1,2,3 where
|]
[R.r|8:16:
|
8 | order by 1,2,3 where
| ^^^^^
unexpected where
|]
,gp (L.lexSQL ansi2011 False "" Nothing) L.prettyError [R.r|
select
a
from t
where
something
order by 1,2,3 $@
|]
[R.r|8:16:
|
8 | order by 1,2,3 $@
| ^
unexpected '$'
|]
]
where
sl1 x = "select " ++ x ++ " from t"
sl2 x = "select " ++ x ++ ", y from t"
sl3 x = "select " ++ x ++ " fom t"
valExprs :: [String] -> [(String,String)]
valExprs = map parseOne
where
parseOne x = let p = parseValueExpr "" Nothing x
in (x,either peFormattedError (\x -> "ERROR: parsed ok " ++ groom x) p)
queryExprs :: [String] -> [(String,String)]
queryExprs = map parseOne
where
parseOne x = let p = parseQueryExpr "" Nothing x
in (x,either peFormattedError (\x -> "ERROR: parsed ok " ++ groom x) p)
pExprs :: [String] -> [String] -> String
pExprs x y =
let l = valExprs x ++ queryExprs y
in intercalate "\n\n\n\n" $ map (\(a,b) -> a ++ "\n" ++ b) l
-}
gp :: (Show a, HasCallStack) => (Text -> Either e a) -> (e -> Text) -> Text -> Text -> TestItem
gp parse pret src err =
GeneralParseFailTest src err $
it (T.unpack src) $
let f1 = parse src
ex = shouldFailWith pret
quickTrace =
case f1 of
Left f | pret f /= err ->
trace (T.unpack ("check\n[" <> pret f <>"]\n["<> err <> "]\n"))
_ -> id
in quickTrace (f1 `ex` err)

View file

@ -0,0 +1,61 @@
module Language.SQL.SimpleSQL.Expectations
(shouldParseA
,shouldParseL
,shouldParse1
,shouldFail
,shouldSucceed
,shouldFailWith
) where
import Language.SQL.SimpleSQL.Parse
import qualified Language.SQL.SimpleSQL.Lex as Lex
import qualified Data.Text as T
import Data.Text (Text)
import Test.Hspec.Expectations
(Expectation
,HasCallStack
,expectationFailure
)
import Test.Hspec
(shouldBe
)
shouldParseA :: (HasCallStack,Eq a, Show a) => Either ParseError a -> a -> Expectation
shouldParseA = shouldParse1 (T.unpack . prettyError)
shouldParseL :: (HasCallStack,Eq a, Show a) => Either Lex.ParseError a -> a -> Expectation
shouldParseL = shouldParse1 (T.unpack . Lex.prettyError)
shouldParse1 :: (HasCallStack, Show a, Eq a) =>
(e -> String)
-> Either e a
-> a
-> Expectation
shouldParse1 prettyErr r v = case r of
Left e ->
expectationFailure $
"expected: "
++ show v
++ "\nbut parsing failed with error:\n"
++ prettyErr e
Right x -> x `shouldBe` v
shouldFail :: (HasCallStack, Show a) => Either e a -> Expectation
shouldFail r = case r of
Left _ -> (1 :: Int) `shouldBe` 1
Right a -> expectationFailure $ "expected parse failure, but succeeded with " <> show a
shouldFailWith :: (HasCallStack, Show a) => (e -> Text) -> Either e a -> Text -> Expectation
shouldFailWith p r e = case r of
Left e1 -> p e1 `shouldBe` e
Right a -> expectationFailure $ "expected parse failure, but succeeded with " <> show a
shouldSucceed :: (HasCallStack) => (e -> String) -> Either e a -> Expectation
shouldSucceed pe r = case r of
Left e -> expectationFailure $ "expected parse success, but got: " <> pe e
Right _ -> (1 :: Int) `shouldBe` 1

View file

@ -6,24 +6,24 @@ module Language.SQL.SimpleSQL.FullQueries (fullQueriesTests) where
import Language.SQL.SimpleSQL.TestTypes
import Language.SQL.SimpleSQL.Syntax
import Language.SQL.SimpleSQL.TestRunners
import Data.Text (Text)
fullQueriesTests :: TestItem
fullQueriesTests = Group "queries" $ map (uncurry (TestQueryExpr ansi2011))
[("select count(*) from t"
,toQueryExpr $ makeSelect
fullQueriesTests = Group "queries" $
[q "select count(*) from t"
$ toQueryExpr $ makeSelect
{msSelectList = [(App [Name Nothing "count"] [Star], Nothing)]
,msFrom = [TRSimple [Name Nothing "t"]]
}
)
,("select a, sum(c+d) as s\n\
,q "select a, sum(c+d) as s\n\
\ from t,u\n\
\ where a > 5\n\
\ group by a\n\
\ having count(1) > 5\n\
\ order by s"
,toQueryExpr $ makeSelect
$ toQueryExpr $ makeSelect
{msSelectList = [(Iden [Name Nothing "a"], Nothing)
,(App [Name Nothing "sum"]
[BinOp (Iden [Name Nothing "c"])
@ -36,5 +36,8 @@ fullQueriesTests = Group "queries" $ map (uncurry (TestQueryExpr ansi2011))
[Name Nothing ">"] (NumLit "5")
,msOrderBy = [SortSpec (Iden [Name Nothing "s"]) DirDefault NullsOrderDefault]
}
)
]
where
q :: HasCallStack => Text -> QueryExpr -> TestItem
q src a = testQueryExpr ansi2011 src a

View file

@ -6,6 +6,8 @@ module Language.SQL.SimpleSQL.GroupBy (groupByTests) where
import Language.SQL.SimpleSQL.TestTypes
import Language.SQL.SimpleSQL.Syntax
import Language.SQL.SimpleSQL.TestRunners
import Data.Text (Text)
groupByTests :: TestItem
@ -15,23 +17,31 @@ groupByTests = Group "groupByTests"
,randomGroupBy
]
q :: HasCallStack => Text -> QueryExpr -> TestItem
q src a = testQueryExpr ansi2011 src a
p :: HasCallStack => Text -> TestItem
p src = testParseQueryExpr ansi2011 src
simpleGroupBy :: TestItem
simpleGroupBy = Group "simpleGroupBy" $ map (uncurry (TestQueryExpr ansi2011))
[("select a,sum(b) from t group by a"
,toQueryExpr $ makeSelect {msSelectList = [(Iden [Name Nothing "a"],Nothing)
simpleGroupBy = Group "simpleGroupBy"
[q "select a,sum(b) from t group by a"
$ toQueryExpr $ makeSelect {msSelectList = [(Iden [Name Nothing "a"],Nothing)
,(App [Name Nothing "sum"] [Iden [Name Nothing "b"]],Nothing)]
,msFrom = [TRSimple [Name Nothing "t"]]
,msGroupBy = [SimpleGroup $ Iden [Name Nothing "a"]]
})
}
,("select a,b,sum(c) from t group by a,b"
,toQueryExpr $ makeSelect {msSelectList = [(Iden [Name Nothing "a"],Nothing)
,q "select a,b,sum(c) from t group by a,b"
$ toQueryExpr $ makeSelect {msSelectList = [(Iden [Name Nothing "a"],Nothing)
,(Iden [Name Nothing "b"],Nothing)
,(App [Name Nothing "sum"] [Iden [Name Nothing "c"]],Nothing)]
,msFrom = [TRSimple [Name Nothing "t"]]
,msGroupBy = [SimpleGroup $ Iden [Name Nothing "a"]
,SimpleGroup $ Iden [Name Nothing "b"]]
})
}
]
{-
@ -40,15 +50,15 @@ sure which sql version they were introduced, 1999 or 2003 I think).
-}
newGroupBy :: TestItem
newGroupBy = Group "newGroupBy" $ map (uncurry (TestQueryExpr ansi2011))
[("select * from t group by ()", ms [GroupingParens []])
,("select * from t group by grouping sets ((), (a))"
,ms [GroupingSets [GroupingParens []
,GroupingParens [SimpleGroup $ Iden [Name Nothing "a"]]]])
,("select * from t group by cube(a,b)"
,ms [Cube [SimpleGroup $ Iden [Name Nothing "a"], SimpleGroup $ Iden [Name Nothing "b"]]])
,("select * from t group by rollup(a,b)"
,ms [Rollup [SimpleGroup $ Iden [Name Nothing "a"], SimpleGroup $ Iden [Name Nothing "b"]]])
newGroupBy = Group "newGroupBy"
[q "select * from t group by ()" $ ms [GroupingParens []]
,q "select * from t group by grouping sets ((), (a))"
$ ms [GroupingSets [GroupingParens []
,GroupingParens [SimpleGroup $ Iden [Name Nothing "a"]]]]
,q "select * from t group by cube(a,b)"
$ ms [Cube [SimpleGroup $ Iden [Name Nothing "a"], SimpleGroup $ Iden [Name Nothing "b"]]]
,q "select * from t group by rollup(a,b)"
$ ms [Rollup [SimpleGroup $ Iden [Name Nothing "a"], SimpleGroup $ Iden [Name Nothing "b"]]]
]
where
ms g = toQueryExpr $ makeSelect {msSelectList = [(Star,Nothing)]
@ -56,21 +66,21 @@ newGroupBy = Group "newGroupBy" $ map (uncurry (TestQueryExpr ansi2011))
,msGroupBy = g}
randomGroupBy :: TestItem
randomGroupBy = Group "randomGroupBy" $ map (ParseQueryExpr ansi2011)
["select * from t GROUP BY a"
,"select * from t GROUP BY GROUPING SETS((a))"
,"select * from t GROUP BY a,b,c"
,"select * from t GROUP BY GROUPING SETS((a,b,c))"
,"select * from t GROUP BY ROLLUP(a,b)"
,"select * from t GROUP BY GROUPING SETS((a,b),\n\
randomGroupBy = Group "randomGroupBy"
[p "select * from t GROUP BY a"
,p "select * from t GROUP BY GROUPING SETS((a))"
,p "select * from t GROUP BY a,b,c"
,p "select * from t GROUP BY GROUPING SETS((a,b,c))"
,p "select * from t GROUP BY ROLLUP(a,b)"
,p "select * from t GROUP BY GROUPING SETS((a,b),\n\
\(a),\n\
\() )"
,"select * from t GROUP BY ROLLUP(b,a)"
,"select * from t GROUP BY GROUPING SETS((b,a),\n\
,p "select * from t GROUP BY ROLLUP(b,a)"
,p "select * from t GROUP BY GROUPING SETS((b,a),\n\
\(b),\n\
\() )"
,"select * from t GROUP BY CUBE(a,b,c)"
,"select * from t GROUP BY GROUPING SETS((a,b,c),\n\
,p "select * from t GROUP BY CUBE(a,b,c)"
,p "select * from t GROUP BY GROUPING SETS((a,b,c),\n\
\(a,b),\n\
\(a,c),\n\
\(b,c),\n\
@ -78,33 +88,33 @@ randomGroupBy = Group "randomGroupBy" $ map (ParseQueryExpr ansi2011)
\(b),\n\
\(c),\n\
\() )"
,"select * from t GROUP BY ROLLUP(Province, County, City)"
,"select * from t GROUP BY ROLLUP(Province, (County, City))"
,"select * from t GROUP BY ROLLUP(Province, (County, City))"
,"select * from t GROUP BY GROUPING SETS((Province, County, City),\n\
,p "select * from t GROUP BY ROLLUP(Province, County, City)"
,p "select * from t GROUP BY ROLLUP(Province, (County, City))"
,p "select * from t GROUP BY ROLLUP(Province, (County, City))"
,p "select * from t GROUP BY GROUPING SETS((Province, County, City),\n\
\(Province),\n\
\() )"
,"select * from t GROUP BY GROUPING SETS((Province, County, City),\n\
,p "select * from t GROUP BY GROUPING SETS((Province, County, City),\n\
\(Province, County),\n\
\(Province),\n\
\() )"
,"select * from t GROUP BY a, ROLLUP(b,c)"
,"select * from t GROUP BY GROUPING SETS((a,b,c),\n\
,p "select * from t GROUP BY a, ROLLUP(b,c)"
,p "select * from t GROUP BY GROUPING SETS((a,b,c),\n\
\(a,b),\n\
\(a) )"
,"select * from t GROUP BY a, b, ROLLUP(c,d)"
,"select * from t GROUP BY GROUPING SETS((a,b,c,d),\n\
,p "select * from t GROUP BY a, b, ROLLUP(c,d)"
,p "select * from t GROUP BY GROUPING SETS((a,b,c,d),\n\
\(a,b,c),\n\
\(a,b) )"
,"select * from t GROUP BY ROLLUP(a), ROLLUP(b,c)"
,"select * from t GROUP BY GROUPING SETS((a,b,c),\n\
,p "select * from t GROUP BY ROLLUP(a), ROLLUP(b,c)"
,p "select * from t GROUP BY GROUPING SETS((a,b,c),\n\
\(a,b),\n\
\(a),\n\
\(b,c),\n\
\(b),\n\
\() )"
,"select * from t GROUP BY ROLLUP(a), CUBE(b,c)"
,"select * from t GROUP BY GROUPING SETS((a,b,c),\n\
,p "select * from t GROUP BY ROLLUP(a), CUBE(b,c)"
,p "select * from t GROUP BY GROUPING SETS((a,b,c),\n\
\(a,b),\n\
\(a,c),\n\
\(a),\n\
@ -112,8 +122,8 @@ randomGroupBy = Group "randomGroupBy" $ map (ParseQueryExpr ansi2011)
\(b),\n\
\(c),\n\
\() )"
,"select * from t GROUP BY CUBE(a,b), ROLLUP(c,d)"
,"select * from t GROUP BY GROUPING SETS((a,b,c,d),\n\
,p "select * from t GROUP BY CUBE(a,b), ROLLUP(c,d)"
,p "select * from t GROUP BY GROUPING SETS((a,b,c,d),\n\
\(a,b,c),\n\
\(a,b),\n\
\(a,c,d),\n\
@ -125,16 +135,16 @@ randomGroupBy = Group "randomGroupBy" $ map (ParseQueryExpr ansi2011)
\(c,d),\n\
\(c),\n\
\() )"
,"select * from t GROUP BY a, ROLLUP(a,b)"
,"select * from t GROUP BY GROUPING SETS((a,b),\n\
,p "select * from t GROUP BY a, ROLLUP(a,b)"
,p "select * from t GROUP BY GROUPING SETS((a,b),\n\
\(a) )"
,"select * from t GROUP BY Region,\n\
,p "select * from t GROUP BY Region,\n\
\ROLLUP(Sales_Person, WEEK(Sales_Date)),\n\
\CUBE(YEAR(Sales_Date), MONTH (Sales_Date))"
,"select * from t GROUP BY ROLLUP (Region, Sales_Person, WEEK(Sales_Date),\n\
,p "select * from t GROUP BY ROLLUP (Region, Sales_Person, WEEK(Sales_Date),\n\
\YEAR(Sales_Date), MONTH(Sales_Date) )"
,"SELECT WEEK(SALES_DATE) AS WEEK,\n\
,p "SELECT WEEK(SALES_DATE) AS WEEK,\n\
\DAYOFWEEK(SALES_DATE) AS DAY_WEEK,\n\
\SALES_PERSON, SUM(SALES) AS UNITS_SOLD\n\
\FROM SALES\n\
@ -142,7 +152,7 @@ randomGroupBy = Group "randomGroupBy" $ map (ParseQueryExpr ansi2011)
\GROUP BY WEEK(SALES_DATE), DAYOFWEEK(SALES_DATE), SALES_PERSON\n\
\ORDER BY WEEK, DAY_WEEK, SALES_PERSON"
,"SELECT WEEK(SALES_DATE) AS WEEK,\n\
,p "SELECT WEEK(SALES_DATE) AS WEEK,\n\
\DAYOFWEEK(SALES_DATE) AS DAY_WEEK,\n\
\SALES_PERSON, SUM(SALES) AS UNITS_SOLD\n\
\FROM SALES\n\
@ -151,7 +161,7 @@ randomGroupBy = Group "randomGroupBy" $ map (ParseQueryExpr ansi2011)
\(DAYOFWEEK(SALES_DATE), SALES_PERSON))\n\
\ORDER BY WEEK, DAY_WEEK, SALES_PERSON"
,"SELECT WEEK(SALES_DATE) AS WEEK,\n\
,p "SELECT WEEK(SALES_DATE) AS WEEK,\n\
\DAYOFWEEK(SALES_DATE) AS DAY_WEEK,\n\
\SALES_PERSON, SUM(SALES) AS UNITS_SOLD\n\
\FROM SALES\n\
@ -159,7 +169,7 @@ randomGroupBy = Group "randomGroupBy" $ map (ParseQueryExpr ansi2011)
\GROUP BY ROLLUP ( WEEK(SALES_DATE), DAYOFWEEK(SALES_DATE), SALES_PERSON )\n\
\ORDER BY WEEK, DAY_WEEK, SALES_PERSON"
,"SELECT WEEK(SALES_DATE) AS WEEK,\n\
,p "SELECT WEEK(SALES_DATE) AS WEEK,\n\
\DAYOFWEEK(SALES_DATE) AS DAY_WEEK,\n\
\SALES_PERSON, SUM(SALES) AS UNITS_SOLD\n\
\FROM SALES\n\
@ -167,7 +177,7 @@ randomGroupBy = Group "randomGroupBy" $ map (ParseQueryExpr ansi2011)
\GROUP BY CUBE ( WEEK(SALES_DATE), DAYOFWEEK(SALES_DATE), SALES_PERSON )\n\
\ORDER BY WEEK, DAY_WEEK, SALES_PERSON"
,"SELECT SALES_PERSON,\n\
,p "SELECT SALES_PERSON,\n\
\MONTH(SALES_DATE) AS MONTH,\n\
\SUM(SALES) AS UNITS_SOLD\n\
\FROM SALES\n\
@ -176,21 +186,21 @@ randomGroupBy = Group "randomGroupBy" $ map (ParseQueryExpr ansi2011)
\)\n\
\ORDER BY SALES_PERSON, MONTH"
,"SELECT WEEK(SALES_DATE) AS WEEK,\n\
,p "SELECT WEEK(SALES_DATE) AS WEEK,\n\
\DAYOFWEEK(SALES_DATE) AS DAY_WEEK,\n\
\SUM(SALES) AS UNITS_SOLD\n\
\FROM SALES\n\
\GROUP BY ROLLUP ( WEEK(SALES_DATE), DAYOFWEEK(SALES_DATE) )\n\
\ORDER BY WEEK, DAY_WEEK"
,"SELECT MONTH(SALES_DATE) AS MONTH,\n\
,p "SELECT MONTH(SALES_DATE) AS MONTH,\n\
\REGION,\n\
\SUM(SALES) AS UNITS_SOLD\n\
\FROM SALES\n\
\GROUP BY ROLLUP ( MONTH(SALES_DATE), REGION )\n\
\ORDER BY MONTH, REGION"
,"SELECT WEEK(SALES_DATE) AS WEEK,\n\
,p "SELECT WEEK(SALES_DATE) AS WEEK,\n\
\DAYOFWEEK(SALES_DATE) AS DAY_WEEK,\n\
\MONTH(SALES_DATE) AS MONTH,\n\
\REGION,\n\
@ -200,7 +210,7 @@ randomGroupBy = Group "randomGroupBy" $ map (ParseQueryExpr ansi2011)
\ROLLUP( MONTH(SALES_DATE), REGION ) )\n\
\ORDER BY WEEK, DAY_WEEK, MONTH, REGION"
,"SELECT R1, R2,\n\
,p "SELECT R1, R2,\n\
\WEEK(SALES_DATE) AS WEEK,\n\
\DAYOFWEEK(SALES_DATE) AS DAY_WEEK,\n\
\MONTH(SALES_DATE) AS MONTH,\n\
@ -211,7 +221,7 @@ randomGroupBy = Group "randomGroupBy" $ map (ParseQueryExpr ansi2011)
\(R2,ROLLUP( MONTH(SALES_DATE), REGION ) ))\n\
\ORDER BY WEEK, DAY_WEEK, MONTH, REGION"
{-,"SELECT COALESCE(R1,R2) AS GROUP,\n\
{-,p "SELECT COALESCE(R1,R2) AS GROUP,\n\
\WEEK(SALES_DATE) AS WEEK,\n\
\DAYOFWEEK(SALES_DATE) AS DAY_WEEK,\n\
\MONTH(SALES_DATE) AS MONTH,\n\
@ -226,7 +236,7 @@ randomGroupBy = Group "randomGroupBy" $ map (ParseQueryExpr ansi2011)
-- decimal as a function not allowed due to the reserved keyword
-- handling: todo, review if this is ansi standard function or
-- if there are places where reserved keywords can still be used
,"SELECT MONTH(SALES_DATE) AS MONTH,\n\
,p "SELECT MONTH(SALES_DATE) AS MONTH,\n\
\REGION,\n\
\SUM(SALES) AS UNITS_SOLD,\n\
\MAX(SALES) AS BEST_SALE,\n\

View file

@ -23,6 +23,7 @@ import Language.SQL.SimpleSQL.Lex
(Token(..)
,tokenListWillPrintAndLex
)
import Language.SQL.SimpleSQL.TestRunners
import qualified Data.Text as T
import Data.Text (Text)
@ -39,50 +40,57 @@ lexerTests = Group "lexerTests" $
,sqlServerLexerTests
,oracleLexerTests
,mySqlLexerTests
,odbcLexerTests]
,odbcLexerTests
]
-- quick sanity tests to see something working
bootstrapTests :: TestItem
bootstrapTests = Group "bootstrap tests" [Group "bootstrap tests" $
map (uncurry (LexTest ansi2011)) (
[("iden", [Identifier Nothing "iden"])
,("'string'", [SqlString "'" "'" "string"])
bootstrapTests = Group "bootstrap tests" $
[t "iden" [Identifier Nothing "iden"]
,(" ", [Whitespace " "])
,("\t ", [Whitespace "\t "])
,(" \n ", [Whitespace " \n "])
,t "\"a1normal \"\" iden\"" [Identifier (Just ("\"","\"")) "a1normal \"\" iden"]
,("--", [LineComment "--"])
,("--\n", [LineComment "--\n"])
,("--stuff", [LineComment "--stuff"])
,("-- stuff", [LineComment "-- stuff"])
,("-- stuff\n", [LineComment "-- stuff\n"])
,("--\nstuff", [LineComment "--\n", Identifier Nothing "stuff"])
,("-- com \nstuff", [LineComment "-- com \n", Identifier Nothing "stuff"])
,t "'string'" [SqlString "'" "'" "string"]
,("/*test1*/", [BlockComment "/*test1*/"])
,("/**/", [BlockComment "/**/"])
,("/***/", [BlockComment "/***/"])
,("/* * */", [BlockComment "/* * */"])
,("/*test*/", [BlockComment "/*test*/"])
,("/*te/*st*/", [BlockComment "/*te/*st*/"])
,("/*te*st*/", [BlockComment "/*te*st*/"])
,("/*lines\nmore lines*/", [BlockComment "/*lines\nmore lines*/"])
,("/*test1*/\n", [BlockComment "/*test1*/", Whitespace "\n"])
,("/*test1*/stuff", [BlockComment "/*test1*/", Identifier Nothing "stuff"])
,t " " [Whitespace " "]
,t "\t " [Whitespace "\t "]
,t " \n " [Whitespace " \n "]
,t "--" [LineComment "--"]
,t "--\n" [LineComment "--\n"]
,t "--stuff" [LineComment "--stuff"]
,t "-- stuff" [LineComment "-- stuff"]
,t "-- stuff\n" [LineComment "-- stuff\n"]
,t "--\nstuff" [LineComment "--\n", Identifier Nothing "stuff"]
,t "-- com \nstuff" [LineComment "-- com \n", Identifier Nothing "stuff"]
,("1", [SqlNumber "1"])
,("42", [SqlNumber "42"])
,t "/*test1*/" [BlockComment "/*test1*/"]
,t "/**/" [BlockComment "/**/"]
,t "/***/" [BlockComment "/***/"]
,t "/* * */" [BlockComment "/* * */"]
,t "/*test*/" [BlockComment "/*test*/"]
,t "/*te/*st*/*/" [BlockComment "/*te/*st*/*/"]
,t "/*te*st*/" [BlockComment "/*te*st*/"]
,t "/*lines\nmore lines*/" [BlockComment "/*lines\nmore lines*/"]
,t "/*test1*/\n" [BlockComment "/*test1*/", Whitespace "\n"]
,t "/*test1*/stuff" [BlockComment "/*test1*/", Identifier Nothing "stuff"]
-- have to fix the dialect handling in the tests
--,("$1", [PositionalArg 1])
--,("$200", [PositionalArg 200])
,t "1" [SqlNumber "1"]
,t "42" [SqlNumber "42"]
,(":test", [PrefixedVariable ':' "test"])
,tp "$1" [PositionalArg 1]
,tp "$200" [PositionalArg 200]
] ++ map (\a -> (a, [Symbol a])) (
,t ":test" [PrefixedVariable ':' "test"]
] ++ map (\a -> t a [Symbol a]) (
["!=", "<>", ">=", "<=", "||"]
++ map T.singleton ("(),-+*/<>=." :: [Char])))]
++ map T.singleton ("(),-+*/<>=." :: [Char]))
where
t :: HasCallStack => Text -> [Token] -> TestItem
t src ast = testLex ansi2011 src ast
tp :: HasCallStack => Text -> [Token] -> TestItem
tp src ast = testLex ansi2011{diPositionalArg=True} src ast
ansiLexerTable :: [(Text,[Token])]
@ -103,7 +111,7 @@ ansiLexerTable =
)
-- quoted identifiers with embedded double quotes
-- the lexer doesn't unescape the quotes
++ [("\"normal \"\" iden\"", [Identifier (Just ("\"","\"")) "normal \"\" iden"])]
++ [("\"anormal \"\" iden\"", [Identifier (Just ("\"","\"")) "anormal \"\" iden"])]
-- strings
-- the lexer doesn't apply escapes at all
++ [("'string'", [SqlString "'" "'" "string"])
@ -137,39 +145,44 @@ ansiLexerTable =
ansiLexerTests :: TestItem
ansiLexerTests = Group "ansiLexerTests" $
[Group "ansi lexer token tests" $ [LexTest ansi2011 s t | (s,t) <- ansiLexerTable]
[Group "ansi lexer token tests" $ [l s t | (s,t) <- ansiLexerTable]
,Group "ansi generated combination lexer tests" $
[ LexTest ansi2011 (s <> s1) (t <> t1)
| (s,t) <- ansiLexerTable
, (s1,t1) <- ansiLexerTable
, tokenListWillPrintAndLex ansi2011 $ t <> t1
[ l (s <> s1) (t <> t1)
| (s,t) <- ansiLexerTable
, (s1,t1) <- ansiLexerTable
, tokenListWillPrintAndLex ansi2011 $ t <> t1
]
]
,Group "ansiadhoclexertests" $
map (uncurry $ LexTest ansi2011)
[("", [])
,("-- line com\nstuff", [LineComment "-- line com\n",Identifier Nothing "stuff"])
] ++
[-- want to make sure this gives a parse error
LexFails ansi2011 "*/"
-- combinations of pipes: make sure they fail because they could be
-- ambiguous and it is really unclear when they are or not, and
-- what the result is even when they are not ambiguous
,LexFails ansi2011 "|||"
,LexFails ansi2011 "||||"
,LexFails ansi2011 "|||||"
-- another user experience thing: make sure extra trailing
-- number chars are rejected rather than attempting to parse
-- if the user means to write something that is rejected by this code,
-- then they can use whitespace to make it clear and then it will parse
,LexFails ansi2011 "12e3e4"
,LexFails ansi2011 "12e3e4"
,LexFails ansi2011 "12e3e4"
,LexFails ansi2011 "12e3.4"
,LexFails ansi2011 "12.4.5"
,LexFails ansi2011 "12.4e5.6"
,LexFails ansi2011 "12.4e5e7"]
]
[l "" []
,l "-- line com\nstuff" [LineComment "-- line com\n",Identifier Nothing "stuff"]
] ++
[-- want to make sure this gives a parse error
f "*/"
-- combinations of pipes: make sure they fail because they could be
-- ambiguous and it is really unclear when they are or not, and
-- what the result is even when they are not ambiguous
,f "|||"
,f "||||"
,f "|||||"
-- another user experience thing: make sure extra trailing
-- number chars are rejected rather than attempting to parse
-- if the user means to write something that is rejected by this code,
-- then they can use whitespace to make it clear and then it will parse
,f "12e3e4"
,f "12e3e4"
,f "12e3e4"
,f "12e3.4"
,f "12.4.5"
,f "12.4e5.6"
,f "12.4e5e7"]
]
where
l :: HasCallStack => Text -> [Token] -> TestItem
l src ast = testLex ansi2011 src ast
f :: HasCallStack => Text -> TestItem
f src = lexFails ansi2011 src
{-
todo: lexing tests
@ -303,22 +316,21 @@ somePostgresOpsWhichWontAddTrailingPlusMinus l =
, not (T.last x `T.elem` "+-")
]
postgresLexerTests :: TestItem
postgresLexerTests = Group "postgresLexerTests" $
[Group "postgres lexer token tests" $
[LexTest postgres s t | (s,t) <- postgresLexerTable]
[l s t | (s,t) <- postgresLexerTable]
,Group "postgres generated lexer token tests" $
[LexTest postgres s t | (s,t) <- postgresShortOperatorTable ++ postgresExtraOperatorTable]
[l s t | (s,t) <- postgresShortOperatorTable ++ postgresExtraOperatorTable]
,Group "postgres generated combination lexer tests" $
[ LexTest postgres (s <> s1) (t <> t1)
[ l (s <> s1) (t <> t1)
| (s,t) <- postgresLexerTable ++ postgresShortOperatorTable
, (s1,t1) <- postgresLexerTable ++ postgresShortOperatorTable
, tokenListWillPrintAndLex postgres $ t ++ t1
]
,Group "generated postgres edgecase lexertests" $
[LexTest postgres s t
[l s t
| (s,t) <- edgeCaseCommentOps
++ edgeCasePlusMinusOps
++ edgeCasePlusMinusComments]
@ -326,22 +338,23 @@ postgresLexerTests = Group "postgresLexerTests" $
,Group "adhoc postgres lexertests" $
-- need more tests for */ to make sure it is caught if it is in the middle of a
-- sequence of symbol letters
[LexFails postgres "*/"
,LexFails postgres ":::"
,LexFails postgres "::::"
,LexFails postgres ":::::"
,LexFails postgres "@*/"
,LexFails postgres "-*/"
,LexFails postgres "12e3e4"
,LexFails postgres "12e3e4"
,LexFails postgres "12e3e4"
,LexFails postgres "12e3.4"
,LexFails postgres "12.4.5"
,LexFails postgres "12.4e5.6"
,LexFails postgres "12.4e5e7"
[f "*/"
,f ":::"
,f "::::"
,f ":::::"
,f "@*/"
,f "-*/"
,f "12e3e4"
,f "12e3e4"
,f "12e3e4"
,f "12e3.4"
,f "12.4.5"
,f "12.4e5.6"
,f "12.4e5e7"
-- special case allow this to lex to 1 .. 2
-- this is for 'for loops' in plpgsql
,LexTest postgres "1..2" [SqlNumber "1", Symbol "..", SqlNumber "2"]]
,l "1..2" [SqlNumber "1", Symbol "..", SqlNumber "2"]
]
]
where
edgeCaseCommentOps =
@ -365,14 +378,21 @@ postgresLexerTests = Group "postgresLexerTests" $
,("-/**/", [Symbol "-", BlockComment "/**/"])
,("+/**/", [Symbol "+", BlockComment "/**/"])
]
l :: HasCallStack => Text -> [Token] -> TestItem
l src ast = testLex postgres src ast
f :: HasCallStack => Text -> TestItem
f src = lexFails postgres src
sqlServerLexerTests :: TestItem
sqlServerLexerTests = Group "sqlServerLexTests" $
[ LexTest sqlserver s t | (s,t) <-
[l s t | (s,t) <-
[("@variable", [(PrefixedVariable '@' "variable")])
,("#variable", [(PrefixedVariable '#' "variable")])
,("[quoted identifier]", [(Identifier (Just ("[", "]")) "quoted identifier")])
]]
where
l :: HasCallStack => Text -> [Token] -> TestItem
l src ast = testLex sqlserver src ast
oracleLexerTests :: TestItem
oracleLexerTests = Group "oracleLexTests" $
@ -380,19 +400,29 @@ oracleLexerTests = Group "oracleLexTests" $
mySqlLexerTests :: TestItem
mySqlLexerTests = Group "mySqlLexerTests" $
[ LexTest mysql s t | (s,t) <-
[ l s t | (s,t) <-
[("`quoted identifier`", [(Identifier (Just ("`", "`")) "quoted identifier")])
]
]
where
l :: HasCallStack => Text -> [Token] -> TestItem
l src ast = testLex mysql src ast
odbcLexerTests :: TestItem
odbcLexerTests = Group "odbcLexTests" $
[ LexTest sqlserver {diOdbc = True} s t | (s,t) <-
[ lo s t | (s,t) <-
[("{}", [Symbol "{", Symbol "}"])
]]
++ [LexFails sqlserver {diOdbc = False} "{"
,LexFails sqlserver {diOdbc = False} "}"]
++ [lno "{"
,lno "}"]
where
lo :: HasCallStack => Text -> [Token] -> TestItem
lo src ast = testLex (sqlserver {diOdbc = True}) src ast
lno :: HasCallStack => Text -> TestItem
lno src = lexFails (sqlserver{diOdbc = False}) src
combos :: [Char] -> Int -> [Text]
combos _ 0 = [T.empty]
combos l n = [ T.cons x tl | x <- l, tl <- combos l (n - 1) ]

View file

@ -6,6 +6,7 @@ module Language.SQL.SimpleSQL.MySQL (mySQLTests) where
import Language.SQL.SimpleSQL.TestTypes
import Language.SQL.SimpleSQL.Syntax
import Language.SQL.SimpleSQL.TestRunners
mySQLTests :: TestItem
mySQLTests = Group "mysql dialect"
@ -21,21 +22,16 @@ limit syntax
-}
backtickQuotes :: TestItem
backtickQuotes = Group "backtickQuotes" (map (uncurry (TestScalarExpr mysql))
[("`test`", Iden [Name (Just ("`","`")) "test"])
]
++ [ParseScalarExprFails ansi2011 "`test`"]
)
backtickQuotes = Group "backtickQuotes"
[testScalarExpr mysql "`test`" $ Iden [Name (Just ("`","`")) "test"]
,testParseScalarExprFails ansi2011 "`test`"]
limit :: TestItem
limit = Group "queries" ( map (uncurry (TestQueryExpr mysql))
[("select * from t limit 5"
,toQueryExpr $ sel {msFetchFirst = Just (NumLit "5")}
)
]
++ [ParseQueryExprFails mysql "select a from t fetch next 10 rows only;"
,ParseQueryExprFails ansi2011 "select * from t limit 5"]
)
limit = Group "queries"
[testQueryExpr mysql "select * from t limit 5"
$ toQueryExpr $ sel {msFetchFirst = Just (NumLit "5")}
,testParseQueryExprFails mysql "select a from t fetch next 10 rows only;"
,testParseQueryExprFails ansi2011 "select * from t limit 5"]
where
sel = makeSelect
{msSelectList = [(Star, Nothing)]

View file

@ -4,6 +4,8 @@ module Language.SQL.SimpleSQL.Odbc (odbcTests) where
import Language.SQL.SimpleSQL.TestTypes
import Language.SQL.SimpleSQL.Syntax
import Language.SQL.SimpleSQL.TestRunners
import Data.Text (Text)
odbcTests :: TestItem
odbcTests = Group "odbc" [
@ -30,14 +32,14 @@ odbcTests = Group "odbc" [
,iden "SQL_DATE"])
]
,Group "outer join" [
TestQueryExpr ansi2011 {diOdbc=True}
q
"select * from {oj t1 left outer join t2 on expr}"
$ toQueryExpr $ makeSelect
{msSelectList = [(Star,Nothing)]
,msFrom = [TROdbc $ TRJoin (TRSimple [Name Nothing "t1"]) False JLeft (TRSimple [Name Nothing "t2"])
(Just $ JoinOn $ Iden [Name Nothing "expr"])]}]
,Group "check parsing bugs" [
TestQueryExpr ansi2011 {diOdbc=True}
q
"select {fn CONVERT(cint,SQL_BIGINT)} from t;"
$ toQueryExpr $ makeSelect
{msSelectList = [(OdbcFunc (ap "CONVERT"
@ -46,7 +48,12 @@ odbcTests = Group "odbc" [
,msFrom = [TRSimple [Name Nothing "t"]]}]
]
where
e = TestScalarExpr ansi2011 {diOdbc = True}
e :: HasCallStack => Text -> ScalarExpr -> TestItem
e src ast = testScalarExpr ansi2011{diOdbc = True} src ast
q :: HasCallStack => Text -> QueryExpr -> TestItem
q src ast = testQueryExpr ansi2011{diOdbc = True} src ast
--tsql = ParseProcSql defaultParseFlags {pfDialect=sqlServerDialect}
ap n = App [Name Nothing n]
iden n = Iden [Name Nothing n]

View file

@ -6,6 +6,7 @@ module Language.SQL.SimpleSQL.Oracle (oracleTests) where
import Language.SQL.SimpleSQL.TestTypes
import Language.SQL.SimpleSQL.Syntax
import Language.SQL.SimpleSQL.TestRunners
oracleTests :: TestItem
oracleTests = Group "oracle dialect"
@ -13,18 +14,18 @@ oracleTests = Group "oracle dialect"
oracleLobUnits :: TestItem
oracleLobUnits = Group "oracleLobUnits" (map (uncurry (TestScalarExpr oracle))
[("cast (a as varchar2(3 char))"
,Cast (Iden [Name Nothing "a"]) (
PrecLengthTypeName [Name Nothing "varchar2"] 3 Nothing (Just PrecCharacters)))
,("cast (a as varchar2(3 byte))"
,Cast (Iden [Name Nothing "a"]) (
PrecLengthTypeName [Name Nothing "varchar2"] 3 Nothing (Just PrecOctets)))
]
++ [TestStatement oracle
oracleLobUnits = Group "oracleLobUnits"
[testScalarExpr oracle "cast (a as varchar2(3 char))"
$ Cast (Iden [Name Nothing "a"]) (
PrecLengthTypeName [Name Nothing "varchar2"] 3 Nothing (Just PrecCharacters))
,testScalarExpr oracle "cast (a as varchar2(3 byte))"
$ Cast (Iden [Name Nothing "a"]) (
PrecLengthTypeName [Name Nothing "varchar2"] 3 Nothing (Just PrecOctets))
,testStatement oracle
"create table t (a varchar2(55 BYTE));"
$ CreateTable [Name Nothing "t"]
[TableColumnDef $ ColumnDef (Name Nothing "a")
(PrecLengthTypeName [Name Nothing "varchar2"] 55 Nothing (Just PrecOctets))
Nothing []]]
)
Nothing []]
]

View file

@ -9,9 +9,11 @@ revisited when the dialect support is added.
module Language.SQL.SimpleSQL.Postgres (postgresTests) where
import Language.SQL.SimpleSQL.TestTypes
import Language.SQL.SimpleSQL.TestRunners
import Data.Text (Text)
postgresTests :: TestItem
postgresTests = Group "postgresTests" $ map (ParseQueryExpr ansi2011)
postgresTests = Group "postgresTests"
{-
lexical syntax section
@ -22,129 +24,129 @@ TODO: get all the commented out tests working
[-- "SELECT 'foo'\n\
-- \'bar';" -- this should parse as select 'foobar'
-- ,
"SELECT name, (SELECT max(pop) FROM cities\n\
t "SELECT name, (SELECT max(pop) FROM cities\n\
\ WHERE cities.state = states.name)\n\
\ FROM states;"
,"SELECT ROW(1,2.5,'this is a test');"
,t "SELECT ROW(1,2.5,'this is a test');"
,"SELECT ROW(t.*, 42) FROM t;"
,"SELECT ROW(t.f1, t.f2, 42) FROM t;"
,"SELECT getf1(CAST(ROW(11,'this is a test',2.5) AS myrowtype));"
,t "SELECT ROW(t.*, 42) FROM t;"
,t "SELECT ROW(t.f1, t.f2, 42) FROM t;"
,t "SELECT getf1(CAST(ROW(11,'this is a test',2.5) AS myrowtype));"
,"SELECT ROW(1,2.5,'this is a test') = ROW(1, 3, 'not the same');"
,t "SELECT ROW(1,2.5,'this is a test') = ROW(1, 3, 'not the same');"
-- table is a reservered keyword?
--,"SELECT ROW(table.*) IS NULL FROM table;"
,"SELECT ROW(tablex.*) IS NULL FROM tablex;"
--,t "SELECT ROW(table.*) IS NULL FROM table;"
,t "SELECT ROW(tablex.*) IS NULL FROM tablex;"
,"SELECT true OR somefunc();"
,t "SELECT true OR somefunc();"
,"SELECT somefunc() OR true;"
,t "SELECT somefunc() OR true;"
-- queries section
,"SELECT * FROM t1 CROSS JOIN t2;"
,"SELECT * FROM t1 INNER JOIN t2 ON t1.num = t2.num;"
,"SELECT * FROM t1 INNER JOIN t2 USING (num);"
,"SELECT * FROM t1 NATURAL INNER JOIN t2;"
,"SELECT * FROM t1 LEFT JOIN t2 ON t1.num = t2.num;"
,"SELECT * FROM t1 LEFT JOIN t2 USING (num);"
,"SELECT * FROM t1 RIGHT JOIN t2 ON t1.num = t2.num;"
,"SELECT * FROM t1 FULL JOIN t2 ON t1.num = t2.num;"
,"SELECT * FROM t1 LEFT JOIN t2 ON t1.num = t2.num AND t2.value = 'xxx';"
,"SELECT * FROM t1 LEFT JOIN t2 ON t1.num = t2.num WHERE t2.value = 'xxx';"
,t "SELECT * FROM t1 CROSS JOIN t2;"
,t "SELECT * FROM t1 INNER JOIN t2 ON t1.num = t2.num;"
,t "SELECT * FROM t1 INNER JOIN t2 USING (num);"
,t "SELECT * FROM t1 NATURAL INNER JOIN t2;"
,t "SELECT * FROM t1 LEFT JOIN t2 ON t1.num = t2.num;"
,t "SELECT * FROM t1 LEFT JOIN t2 USING (num);"
,t "SELECT * FROM t1 RIGHT JOIN t2 ON t1.num = t2.num;"
,t "SELECT * FROM t1 FULL JOIN t2 ON t1.num = t2.num;"
,t "SELECT * FROM t1 LEFT JOIN t2 ON t1.num = t2.num AND t2.value = 'xxx';"
,t "SELECT * FROM t1 LEFT JOIN t2 ON t1.num = t2.num WHERE t2.value = 'xxx';"
,"SELECT * FROM some_very_long_table_name s\n\
,t "SELECT * FROM some_very_long_table_name s\n\
\JOIN another_fairly_long_name a ON s.id = a.num;"
,"SELECT * FROM people AS mother JOIN people AS child\n\
,t "SELECT * FROM people AS mother JOIN people AS child\n\
\ ON mother.id = child.mother_id;"
,"SELECT * FROM my_table AS a CROSS JOIN my_table AS b;"
,"SELECT * FROM (my_table AS a CROSS JOIN my_table) AS b;"
,"SELECT * FROM getfoo(1) AS t1;"
,"SELECT * FROM foo\n\
,t "SELECT * FROM my_table AS a CROSS JOIN my_table AS b;"
,t "SELECT * FROM (my_table AS a CROSS JOIN my_table) AS b;"
,t "SELECT * FROM getfoo(1) AS t1;"
,t "SELECT * FROM foo\n\
\ WHERE foosubid IN (\n\
\ SELECT foosubid\n\
\ FROM getfoo(foo.fooid) z\n\
\ WHERE z.fooid = foo.fooid\n\
\ );"
{-,"SELECT *\n\
{-,t "SELECT *\n\
\ FROM dblink('dbname=mydb', 'SELECT proname, prosrc FROM pg_proc')\n\
\ AS t1(proname name, prosrc text)\n\
\ WHERE proname LIKE 'bytea%';"-} -- types in the alias??
,"SELECT * FROM foo, LATERAL (SELECT * FROM bar WHERE bar.id = foo.bar_id) ss;"
,"SELECT * FROM foo, bar WHERE bar.id = foo.bar_id;"
,t "SELECT * FROM foo, LATERAL (SELECT * FROM bar WHERE bar.id = foo.bar_id) ss;"
,t "SELECT * FROM foo, bar WHERE bar.id = foo.bar_id;"
{-,"SELECT p1.id, p2.id, v1, v2\n\
{-,t "SELECT p1.id, p2.id, v1, v2\n\
\FROM polygons p1, polygons p2,\n\
\ LATERAL vertices(p1.poly) v1,\n\
\ LATERAL vertices(p2.poly) v2\n\
\WHERE (v1 <-> v2) < 10 AND p1.id != p2.id;"-} -- <-> operator?
{-,"SELECT p1.id, p2.id, v1, v2\n\
{-,t "SELECT p1.id, p2.id, v1, v2\n\
\FROM polygons p1 CROSS JOIN LATERAL vertices(p1.poly) v1,\n\
\ polygons p2 CROSS JOIN LATERAL vertices(p2.poly) v2\n\
\WHERE (v1 <-> v2) < 10 AND p1.id != p2.id;"-}
,"SELECT m.name\n\
,t "SELECT m.name\n\
\FROM manufacturers m LEFT JOIN LATERAL get_product_names(m.id) pname ON true\n\
\WHERE pname IS NULL;"
,"SELECT * FROM fdt WHERE c1 > 5"
,t "SELECT * FROM fdt WHERE c1 > 5"
,"SELECT * FROM fdt WHERE c1 IN (1, 2, 3)"
,t "SELECT * FROM fdt WHERE c1 IN (1, 2, 3)"
,"SELECT * FROM fdt WHERE c1 IN (SELECT c1 FROM t2)"
,t "SELECT * FROM fdt WHERE c1 IN (SELECT c1 FROM t2)"
,"SELECT * FROM fdt WHERE c1 IN (SELECT c3 FROM t2 WHERE c2 = fdt.c1 + 10)"
,t "SELECT * FROM fdt WHERE c1 IN (SELECT c3 FROM t2 WHERE c2 = fdt.c1 + 10)"
,"SELECT * FROM fdt WHERE c1 BETWEEN \n\
,t "SELECT * FROM fdt WHERE c1 BETWEEN \n\
\ (SELECT c3 FROM t2 WHERE c2 = fdt.c1 + 10) AND 100"
,"SELECT * FROM fdt WHERE EXISTS (SELECT c1 FROM t2 WHERE c2 > fdt.c1)"
,t "SELECT * FROM fdt WHERE EXISTS (SELECT c1 FROM t2 WHERE c2 > fdt.c1)"
,"SELECT * FROM test1;"
,t "SELECT * FROM test1;"
,"SELECT x FROM test1 GROUP BY x;"
,"SELECT x, sum(y) FROM test1 GROUP BY x;"
,t "SELECT x FROM test1 GROUP BY x;"
,t "SELECT x, sum(y) FROM test1 GROUP BY x;"
-- s.date changed to s.datex because of reserved keyword
-- handling, not sure if this is correct or not for ansi sql
,"SELECT product_id, p.name, (sum(s.units) * p.price) AS sales\n\
,t "SELECT product_id, p.name, (sum(s.units) * p.price) AS sales\n\
\ FROM products p LEFT JOIN sales s USING (product_id)\n\
\ GROUP BY product_id, p.name, p.price;"
,"SELECT x, sum(y) FROM test1 GROUP BY x HAVING sum(y) > 3;"
,"SELECT x, sum(y) FROM test1 GROUP BY x HAVING x < 'c';"
,"SELECT product_id, p.name, (sum(s.units) * (p.price - p.cost)) AS profit\n\
,t "SELECT x, sum(y) FROM test1 GROUP BY x HAVING sum(y) > 3;"
,t "SELECT x, sum(y) FROM test1 GROUP BY x HAVING x < 'c';"
,t "SELECT product_id, p.name, (sum(s.units) * (p.price - p.cost)) AS profit\n\
\ FROM products p LEFT JOIN sales s USING (product_id)\n\
\ WHERE s.datex > CURRENT_DATE - INTERVAL '4 weeks'\n\
\ GROUP BY product_id, p.name, p.price, p.cost\n\
\ HAVING sum(p.price * s.units) > 5000;"
,"SELECT a, b, c FROM t"
,t "SELECT a, b, c FROM t"
,"SELECT tbl1.a, tbl2.a, tbl1.b FROM t"
,t "SELECT tbl1.a, tbl2.a, tbl1.b FROM t"
,"SELECT tbl1.*, tbl2.a FROM t"
,t "SELECT tbl1.*, tbl2.a FROM t"
,"SELECT a AS value, b + c AS sum FROM t"
,t "SELECT a AS value, b + c AS sum FROM t"
,"SELECT a \"value\", b + c AS sum FROM t"
,t "SELECT a \"value\", b + c AS sum FROM t"
,"SELECT DISTINCT select_list t"
,t "SELECT DISTINCT select_list t"
,"VALUES (1, 'one'), (2, 'two'), (3, 'three');"
,t "VALUES (1, 'one'), (2, 'two'), (3, 'three');"
,"SELECT 1 AS column1, 'one' AS column2\n\
,t "SELECT 1 AS column1, 'one' AS column2\n\
\UNION ALL\n\
\SELECT 2, 'two'\n\
\UNION ALL\n\
\SELECT 3, 'three';"
,"SELECT * FROM (VALUES (1, 'one'), (2, 'two'), (3, 'three')) AS t (num,letter);"
,t "SELECT * FROM (VALUES (1, 'one'), (2, 'two'), (3, 'three')) AS t (num,letter);"
,"WITH regional_sales AS (\n\
,t "WITH regional_sales AS (\n\
\ SELECT region, SUM(amount) AS total_sales\n\
\ FROM orders\n\
\ GROUP BY region\n\
@ -161,14 +163,14 @@ TODO: get all the commented out tests working
\WHERE region IN (SELECT region FROM top_regions)\n\
\GROUP BY region, product;"
,"WITH RECURSIVE t(n) AS (\n\
,t "WITH RECURSIVE t(n) AS (\n\
\ VALUES (1)\n\
\ UNION ALL\n\
\ SELECT n+1 FROM t WHERE n < 100\n\
\)\n\
\SELECT sum(n) FROM t"
,"WITH RECURSIVE included_parts(sub_part, part, quantity) AS (\n\
,t "WITH RECURSIVE included_parts(sub_part, part, quantity) AS (\n\
\ SELECT sub_part, part, quantity FROM parts WHERE part = 'our_product'\n\
\ UNION ALL\n\
\ SELECT p.sub_part, p.part, p.quantity\n\
@ -179,7 +181,7 @@ TODO: get all the commented out tests working
\FROM included_parts\n\
\GROUP BY sub_part"
,"WITH RECURSIVE search_graph(id, link, data, depth) AS (\n\
,t "WITH RECURSIVE search_graph(id, link, data, depth) AS (\n\
\ SELECT g.id, g.link, g.data, 1\n\
\ FROM graph g\n\
\ UNION ALL\n\
@ -189,7 +191,7 @@ TODO: get all the commented out tests working
\)\n\
\SELECT * FROM search_graph;"
{-,"WITH RECURSIVE search_graph(id, link, data, depth, path, cycle) AS (\n\
{-,t "WITH RECURSIVE search_graph(id, link, data, depth, path, cycle) AS (\n\
\ SELECT g.id, g.link, g.data, 1,\n\
\ ARRAY[g.id],\n\
\ false\n\
@ -203,7 +205,7 @@ TODO: get all the commented out tests working
\)\n\
\SELECT * FROM search_graph;"-} -- ARRAY
{-,"WITH RECURSIVE search_graph(id, link, data, depth, path, cycle) AS (\n\
{-,t "WITH RECURSIVE search_graph(id, link, data, depth, path, cycle) AS (\n\
\ SELECT g.id, g.link, g.data, 1,\n\
\ ARRAY[ROW(g.f1, g.f2)],\n\
\ false\n\
@ -217,7 +219,7 @@ TODO: get all the commented out tests working
\)\n\
\SELECT * FROM search_graph;"-} -- ARRAY
,"WITH RECURSIVE t(n) AS (\n\
,t "WITH RECURSIVE t(n) AS (\n\
\ SELECT 1\n\
\ UNION ALL\n\
\ SELECT n+1 FROM t\n\
@ -226,19 +228,19 @@ TODO: get all the commented out tests working
-- select page reference
,"SELECT f.title, f.did, d.name, f.date_prod, f.kind\n\
,t "SELECT f.title, f.did, d.name, f.date_prod, f.kind\n\
\ FROM distributors d, films f\n\
\ WHERE f.did = d.did"
,"SELECT kind, sum(len) AS total\n\
,t "SELECT kind, sum(len) AS total\n\
\ FROM films\n\
\ GROUP BY kind\n\
\ HAVING sum(len) < interval '5 hours';"
,"SELECT * FROM distributors ORDER BY name;"
,"SELECT * FROM distributors ORDER BY 2;"
,t "SELECT * FROM distributors ORDER BY name;"
,t "SELECT * FROM distributors ORDER BY 2;"
,"SELECT distributors.name\n\
,t "SELECT distributors.name\n\
\ FROM distributors\n\
\ WHERE distributors.name LIKE 'W%'\n\
\UNION\n\
@ -246,14 +248,14 @@ TODO: get all the commented out tests working
\ FROM actors\n\
\ WHERE actors.name LIKE 'W%';"
,"WITH t AS (\n\
,t "WITH t AS (\n\
\ SELECT random() as x FROM generate_series(1, 3)\n\
\ )\n\
\SELECT * FROM t\n\
\UNION ALL\n\
\SELECT * FROM t"
,"WITH RECURSIVE employee_recursive(distance, employee_name, manager_name) AS (\n\
,t "WITH RECURSIVE employee_recursive(distance, employee_name, manager_name) AS (\n\
\ SELECT 1, employee_name, manager_name\n\
\ FROM employee\n\
\ WHERE manager_name = 'Mary'\n\
@ -264,16 +266,19 @@ TODO: get all the commented out tests working
\ )\n\
\SELECT distance, employee_name FROM employee_recursive;"
,"SELECT m.name AS mname, pname\n\
,t "SELECT m.name AS mname, pname\n\
\FROM manufacturers m, LATERAL get_product_names(m.id) pname;"
,"SELECT m.name AS mname, pname\n\
,t "SELECT m.name AS mname, pname\n\
\FROM manufacturers m LEFT JOIN LATERAL get_product_names(m.id) pname ON true;"
,"SELECT 2+2;"
,t "SELECT 2+2;"
-- simple-sql-parser doesn't support where without from
-- this can be added for the postgres dialect when it is written
--,"SELECT distributors.* WHERE distributors.name = 'Westward';"
--,t "SELECT distributors.* WHERE distributors.name = 'Westward';"
]
where
t :: HasCallStack => Text -> TestItem
t src = testParseQueryExpr postgres src

View file

@ -12,7 +12,8 @@ module Language.SQL.SimpleSQL.QueryExprComponents (queryExprComponentTests) wher
import Language.SQL.SimpleSQL.TestTypes
import Language.SQL.SimpleSQL.Syntax
import Language.SQL.SimpleSQL.TestRunners
import Data.Text (Text)
queryExprComponentTests :: TestItem
queryExprComponentTests = Group "queryExprComponentTests"
@ -31,10 +32,10 @@ queryExprComponentTests = Group "queryExprComponentTests"
duplicates :: TestItem
duplicates = Group "duplicates" $ map (uncurry (TestQueryExpr ansi2011))
[("select a from t" ,ms SQDefault)
,("select all a from t" ,ms All)
,("select distinct a from t", ms Distinct)
duplicates = Group "duplicates"
[q "select a from t" $ ms SQDefault
,q "select all a from t" $ ms All
,q "select distinct a from t" $ ms Distinct
]
where
ms d = toQueryExpr $ makeSelect
@ -43,77 +44,77 @@ duplicates = Group "duplicates" $ map (uncurry (TestQueryExpr ansi2011))
,msFrom = [TRSimple [Name Nothing "t"]]}
selectLists :: TestItem
selectLists = Group "selectLists" $ map (uncurry (TestQueryExpr ansi2011))
[("select 1",
toQueryExpr $ makeSelect {msSelectList = [(NumLit "1",Nothing)]})
selectLists = Group "selectLists"
[q "select 1"
$ toQueryExpr $ makeSelect {msSelectList = [(NumLit "1",Nothing)]}
,("select a"
,toQueryExpr $ makeSelect {msSelectList = [(Iden [Name Nothing "a"],Nothing)]})
,q "select a"
$ toQueryExpr $ makeSelect {msSelectList = [(Iden [Name Nothing "a"],Nothing)]}
,("select a,b"
,toQueryExpr $ makeSelect {msSelectList = [(Iden [Name Nothing "a"],Nothing)
,(Iden [Name Nothing "b"],Nothing)]})
,q "select a,b"
$ toQueryExpr $ makeSelect {msSelectList = [(Iden [Name Nothing "a"],Nothing)
,(Iden [Name Nothing "b"],Nothing)]}
,("select 1+2,3+4"
,toQueryExpr $ makeSelect {msSelectList =
,q "select 1+2,3+4"
$ toQueryExpr $ makeSelect {msSelectList =
[(BinOp (NumLit "1") [Name Nothing "+"] (NumLit "2"),Nothing)
,(BinOp (NumLit "3") [Name Nothing "+"] (NumLit "4"),Nothing)]})
,(BinOp (NumLit "3") [Name Nothing "+"] (NumLit "4"),Nothing)]}
,("select a as a, /*comment*/ b as b"
,toQueryExpr $ makeSelect {msSelectList = [(Iden [Name Nothing "a"], Just $ Name Nothing "a")
,(Iden [Name Nothing "b"], Just $ Name Nothing "b")]})
,q "select a as a, /*comment*/ b as b"
$ toQueryExpr $ makeSelect {msSelectList = [(Iden [Name Nothing "a"], Just $ Name Nothing "a")
,(Iden [Name Nothing "b"], Just $ Name Nothing "b")]}
,("select a a, b b"
,toQueryExpr $ makeSelect {msSelectList = [(Iden [Name Nothing "a"], Just $ Name Nothing "a")
,(Iden [Name Nothing "b"], Just $ Name Nothing "b")]})
,q "select a a, b b"
$ toQueryExpr $ makeSelect {msSelectList = [(Iden [Name Nothing "a"], Just $ Name Nothing "a")
,(Iden [Name Nothing "b"], Just $ Name Nothing "b")]}
,("select a + b * c"
,toQueryExpr $ makeSelect {msSelectList =
,q "select a + b * c"
$ toQueryExpr $ makeSelect {msSelectList =
[(BinOp (Iden [Name Nothing "a"]) [Name Nothing "+"]
(BinOp (Iden [Name Nothing "b"]) [Name Nothing "*"] (Iden [Name Nothing "c"]))
,Nothing)]})
,Nothing)]}
]
whereClause :: TestItem
whereClause = Group "whereClause" $ map (uncurry (TestQueryExpr ansi2011))
[("select a from t where a = 5"
,toQueryExpr $ makeSelect {msSelectList = [(Iden [Name Nothing "a"],Nothing)]
whereClause = Group "whereClause"
[q "select a from t where a = 5"
$ toQueryExpr $ makeSelect {msSelectList = [(Iden [Name Nothing "a"],Nothing)]
,msFrom = [TRSimple [Name Nothing "t"]]
,msWhere = Just $ BinOp (Iden [Name Nothing "a"]) [Name Nothing "="] (NumLit "5")})
,msWhere = Just $ BinOp (Iden [Name Nothing "a"]) [Name Nothing "="] (NumLit "5")}
]
having :: TestItem
having = Group "having" $ map (uncurry (TestQueryExpr ansi2011))
[("select a,sum(b) from t group by a having sum(b) > 5"
,toQueryExpr $ makeSelect {msSelectList = [(Iden [Name Nothing "a"],Nothing)
having = Group "having"
[q "select a,sum(b) from t group by a having sum(b) > 5"
$ toQueryExpr $ makeSelect {msSelectList = [(Iden [Name Nothing "a"],Nothing)
,(App [Name Nothing "sum"] [Iden [Name Nothing "b"]],Nothing)]
,msFrom = [TRSimple [Name Nothing "t"]]
,msGroupBy = [SimpleGroup $ Iden [Name Nothing "a"]]
,msHaving = Just $ BinOp (App [Name Nothing "sum"] [Iden [Name Nothing "b"]])
[Name Nothing ">"] (NumLit "5")
})
}
]
orderBy :: TestItem
orderBy = Group "orderBy" $ map (uncurry (TestQueryExpr ansi2011))
[("select a from t order by a"
,ms [SortSpec (Iden [Name Nothing "a"]) DirDefault NullsOrderDefault])
orderBy = Group "orderBy"
[q "select a from t order by a"
$ ms [SortSpec (Iden [Name Nothing "a"]) DirDefault NullsOrderDefault]
,("select a from t order by a, b"
,ms [SortSpec (Iden [Name Nothing "a"]) DirDefault NullsOrderDefault
,SortSpec (Iden [Name Nothing "b"]) DirDefault NullsOrderDefault])
,q "select a from t order by a, b"
$ ms [SortSpec (Iden [Name Nothing "a"]) DirDefault NullsOrderDefault
,SortSpec (Iden [Name Nothing "b"]) DirDefault NullsOrderDefault]
,("select a from t order by a asc"
,ms [SortSpec (Iden [Name Nothing "a"]) Asc NullsOrderDefault])
,q "select a from t order by a asc"
$ ms [SortSpec (Iden [Name Nothing "a"]) Asc NullsOrderDefault]
,("select a from t order by a desc, b desc"
,ms [SortSpec (Iden [Name Nothing "a"]) Desc NullsOrderDefault
,SortSpec (Iden [Name Nothing "b"]) Desc NullsOrderDefault])
,q "select a from t order by a desc, b desc"
$ ms [SortSpec (Iden [Name Nothing "a"]) Desc NullsOrderDefault
,SortSpec (Iden [Name Nothing "b"]) Desc NullsOrderDefault]
,("select a from t order by a desc nulls first, b desc nulls last"
,ms [SortSpec (Iden [Name Nothing "a"]) Desc NullsFirst
,SortSpec (Iden [Name Nothing "b"]) Desc NullsLast])
,q "select a from t order by a desc nulls first, b desc nulls last"
$ ms [SortSpec (Iden [Name Nothing "a"]) Desc NullsFirst
,SortSpec (Iden [Name Nothing "b"]) Desc NullsLast]
]
where
@ -122,20 +123,20 @@ orderBy = Group "orderBy" $ map (uncurry (TestQueryExpr ansi2011))
,msOrderBy = o}
offsetFetch :: TestItem
offsetFetch = Group "offsetFetch" $ map (uncurry (TestQueryExpr ansi2011))
offsetFetch = Group "offsetFetch"
[-- 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"))
q "select a from t offset 5 rows fetch next 10 rows only"
$ ms (Just $ NumLit "5") (Just $ NumLit "10")
,q "select a from t offset 5 rows;"
$ ms (Just $ NumLit "5") Nothing
,q "select a from t fetch next 10 row only;"
$ ms Nothing (Just $ NumLit "10")
,q "select a from t offset 5 row fetch first 10 row only"
$ ms (Just $ NumLit "5") (Just $ NumLit "10")
-- postgres: disabled, will add back when postgres
-- dialect is added
--,("select a from t limit 10 offset 5"
-- ,ms (Just $ NumLit "5") (Just $ NumLit "10"))
--,q "select a from t limit 10 offset 5"
-- $ ms (Just $ NumLit "5") (Just $ NumLit "10"))
]
where
ms o l = toQueryExpr $ makeSelect
@ -145,23 +146,23 @@ offsetFetch = Group "offsetFetch" $ map (uncurry (TestQueryExpr ansi2011))
,msFetchFirst = l}
combos :: TestItem
combos = Group "combos" $ map (uncurry (TestQueryExpr ansi2011))
[("select a from t union select b from u"
,QueryExprSetOp mst Union SQDefault Respectively msu)
combos = Group "combos"
[q "select a from t union select b from u"
$ QueryExprSetOp mst Union SQDefault Respectively msu
,("select a from t intersect select b from u"
,QueryExprSetOp mst Intersect SQDefault Respectively msu)
,q "select a from t intersect select b from u"
$ QueryExprSetOp mst Intersect SQDefault Respectively msu
,("select a from t except all select b from u"
,QueryExprSetOp mst Except All Respectively msu)
,q "select a from t except all select b from u"
$ QueryExprSetOp mst Except All Respectively msu
,("select a from t union distinct corresponding \
,q "select a from t union distinct corresponding \
\select b from u"
,QueryExprSetOp mst Union Distinct Corresponding msu)
$ QueryExprSetOp mst Union Distinct Corresponding msu
,("select a from t union select a from t union select a from t"
,QueryExprSetOp (QueryExprSetOp mst Union SQDefault Respectively mst)
Union SQDefault Respectively mst)
,q "select a from t union select a from t union select a from t"
$ QueryExprSetOp (QueryExprSetOp mst Union SQDefault Respectively mst)
Union SQDefault Respectively mst
]
where
mst = toQueryExpr $ makeSelect
@ -173,20 +174,20 @@ combos = Group "combos" $ map (uncurry (TestQueryExpr ansi2011))
withQueries :: TestItem
withQueries = Group "with queries" $ map (uncurry (TestQueryExpr ansi2011))
[("with u as (select a from t) select a from u"
,With False [(Alias (Name Nothing "u") Nothing, ms1)] ms2)
withQueries = Group "with queries"
[q "with u as (select a from t) select a from u"
$ With False [(Alias (Name Nothing "u") Nothing, ms1)] ms2
,("with u(b) as (select a from t) select a from u"
,With False [(Alias (Name Nothing "u") (Just [Name Nothing "b"]), ms1)] ms2)
,q "with u(b) as (select a from t) select a from u"
$ With False [(Alias (Name Nothing "u") (Just [Name Nothing "b"]), ms1)] ms2
,("with x as (select a from t),\n\
,q "with x as (select a from t),\n\
\ u as (select a from x)\n\
\select a from u"
,With False [(Alias (Name Nothing "x") Nothing, ms1), (Alias (Name Nothing "u") Nothing,ms3)] ms2)
$ With False [(Alias (Name Nothing "x") Nothing, ms1), (Alias (Name Nothing "u") Nothing,ms3)] ms2
,("with recursive u as (select a from t) select a from u"
,With True [(Alias (Name Nothing "u") Nothing, ms1)] ms2)
,q "with recursive u as (select a from t) select a from u"
$ With True [(Alias (Name Nothing "u") Nothing, ms1)] ms2
]
where
ms c t = toQueryExpr $ makeSelect
@ -197,13 +198,16 @@ withQueries = Group "with queries" $ map (uncurry (TestQueryExpr ansi2011))
ms3 = ms "a" "x"
values :: TestItem
values = Group "values" $ map (uncurry (TestQueryExpr ansi2011))
[("values (1,2),(3,4)"
,Values [[NumLit "1", NumLit "2"]
,[NumLit "3", NumLit "4"]])
values = Group "values"
[q "values (1,2),(3,4)"
$ Values [[NumLit "1", NumLit "2"]
,[NumLit "3", NumLit "4"]]
]
tables :: TestItem
tables = Group "tables" $ map (uncurry (TestQueryExpr ansi2011))
[("table tbl", Table [Name Nothing "tbl"])
tables = Group "tables"
[q "table tbl" $ Table [Name Nothing "tbl"]
]
q :: HasCallStack => Text -> QueryExpr -> TestItem
q src ast = testQueryExpr ansi2011 src ast

View file

@ -9,19 +9,23 @@ module Language.SQL.SimpleSQL.QueryExprs (queryExprsTests) where
import Language.SQL.SimpleSQL.TestTypes
import Language.SQL.SimpleSQL.Syntax
import Language.SQL.SimpleSQL.TestRunners
import Data.Text (Text)
queryExprsTests :: TestItem
queryExprsTests = Group "query exprs" $ map (uncurry (TestStatements ansi2011))
[("select 1",[ms])
,("select 1;",[ms])
,("select 1;select 1",[ms,ms])
,(" select 1;select 1; ",[ms,ms])
,("SELECT CURRENT_TIMESTAMP;"
,[SelectStatement $ toQueryExpr $ makeSelect
{msSelectList = [(Iden [Name Nothing "CURRENT_TIMESTAMP"],Nothing)]}])
,("SELECT \"CURRENT_TIMESTAMP\";"
,[SelectStatement $ toQueryExpr $ makeSelect
{msSelectList = [(Iden [Name (Just ("\"","\"")) "CURRENT_TIMESTAMP"],Nothing)]}])
queryExprsTests = Group "query exprs"
[q "select 1" [ms]
,q "select 1;" [ms]
,q "select 1;select 1" [ms,ms]
,q " select 1;select 1; " [ms,ms]
,q "SELECT CURRENT_TIMESTAMP;"
[SelectStatement $ toQueryExpr $ makeSelect
{msSelectList = [(Iden [Name Nothing "CURRENT_TIMESTAMP"],Nothing)]}]
,q "SELECT \"CURRENT_TIMESTAMP\";"
[SelectStatement $ toQueryExpr $ makeSelect
{msSelectList = [(Iden [Name (Just ("\"","\"")) "CURRENT_TIMESTAMP"],Nothing)]}]
]
where
ms = SelectStatement $ toQueryExpr $ makeSelect {msSelectList = [(NumLit "1",Nothing)]}
q :: HasCallStack => Text -> [Statement] -> TestItem
q src ast = testStatements ansi2011 src ast

View file

@ -11,6 +11,8 @@ module Language.SQL.SimpleSQL.SQL2011AccessControl (sql2011AccessControlTests) w
import Language.SQL.SimpleSQL.TestTypes
import Language.SQL.SimpleSQL.Syntax
import Language.SQL.SimpleSQL.TestRunners
import Data.Text (Text)
sql2011AccessControlTests :: TestItem
sql2011AccessControlTests = Group "sql 2011 access control tests" [
@ -78,128 +80,107 @@ sql2011AccessControlTests = Group "sql 2011 access control tests" [
| CURRENT_ROLE
-}
(TestStatement ansi2011
"grant all privileges on tbl1 to role1"
s "grant all privileges on tbl1 to role1"
$ GrantPrivilege [PrivAll]
(PrivTable [Name Nothing "tbl1"])
[Name Nothing "role1"] WithoutGrantOption)
[Name Nothing "role1"] WithoutGrantOption
,(TestStatement ansi2011
"grant all privileges on tbl1 to role1,role2"
,s "grant all privileges on tbl1 to role1,role2"
$ GrantPrivilege [PrivAll]
(PrivTable [Name Nothing "tbl1"])
[Name Nothing "role1",Name Nothing "role2"] WithoutGrantOption)
[Name Nothing "role1",Name Nothing "role2"] WithoutGrantOption
,(TestStatement ansi2011
"grant all privileges on tbl1 to role1 with grant option"
,s "grant all privileges on tbl1 to role1 with grant option"
$ GrantPrivilege [PrivAll]
(PrivTable [Name Nothing "tbl1"])
[Name Nothing "role1"] WithGrantOption)
[Name Nothing "role1"] WithGrantOption
,(TestStatement ansi2011
"grant all privileges on table tbl1 to role1"
,s "grant all privileges on table tbl1 to role1"
$ GrantPrivilege [PrivAll]
(PrivTable [Name Nothing "tbl1"])
[Name Nothing "role1"] WithoutGrantOption)
[Name Nothing "role1"] WithoutGrantOption
,(TestStatement ansi2011
"grant all privileges on domain mydom to role1"
,s "grant all privileges on domain mydom to role1"
$ GrantPrivilege [PrivAll]
(PrivDomain [Name Nothing "mydom"])
[Name Nothing "role1"] WithoutGrantOption)
[Name Nothing "role1"] WithoutGrantOption
,(TestStatement ansi2011
"grant all privileges on type t1 to role1"
,s "grant all privileges on type t1 to role1"
$ GrantPrivilege [PrivAll]
(PrivType [Name Nothing "t1"])
[Name Nothing "role1"] WithoutGrantOption)
[Name Nothing "role1"] WithoutGrantOption
,(TestStatement ansi2011
"grant all privileges on sequence s1 to role1"
,s "grant all privileges on sequence s1 to role1"
$ GrantPrivilege [PrivAll]
(PrivSequence [Name Nothing "s1"])
[Name Nothing "role1"] WithoutGrantOption)
[Name Nothing "role1"] WithoutGrantOption
,(TestStatement ansi2011
"grant select on table t1 to role1"
,s "grant select on table t1 to role1"
$ GrantPrivilege [PrivSelect []]
(PrivTable [Name Nothing "t1"])
[Name Nothing "role1"] WithoutGrantOption)
[Name Nothing "role1"] WithoutGrantOption
,(TestStatement ansi2011
"grant select(a,b) on table t1 to role1"
,s "grant select(a,b) on table t1 to role1"
$ GrantPrivilege [PrivSelect [Name Nothing "a", Name Nothing "b"]]
(PrivTable [Name Nothing "t1"])
[Name Nothing "role1"] WithoutGrantOption)
[Name Nothing "role1"] WithoutGrantOption
,(TestStatement ansi2011
"grant delete on table t1 to role1"
,s "grant delete on table t1 to role1"
$ GrantPrivilege [PrivDelete]
(PrivTable [Name Nothing "t1"])
[Name Nothing "role1"] WithoutGrantOption)
[Name Nothing "role1"] WithoutGrantOption
,(TestStatement ansi2011
"grant insert on table t1 to role1"
,s "grant insert on table t1 to role1"
$ GrantPrivilege [PrivInsert []]
(PrivTable [Name Nothing "t1"])
[Name Nothing "role1"] WithoutGrantOption)
[Name Nothing "role1"] WithoutGrantOption
,(TestStatement ansi2011
"grant insert(a,b) on table t1 to role1"
,s "grant insert(a,b) on table t1 to role1"
$ GrantPrivilege [PrivInsert [Name Nothing "a", Name Nothing "b"]]
(PrivTable [Name Nothing "t1"])
[Name Nothing "role1"] WithoutGrantOption)
[Name Nothing "role1"] WithoutGrantOption
,(TestStatement ansi2011
"grant update on table t1 to role1"
,s "grant update on table t1 to role1"
$ GrantPrivilege [PrivUpdate []]
(PrivTable [Name Nothing "t1"])
[Name Nothing "role1"] WithoutGrantOption)
[Name Nothing "role1"] WithoutGrantOption
,(TestStatement ansi2011
"grant update(a,b) on table t1 to role1"
,s "grant update(a,b) on table t1 to role1"
$ GrantPrivilege [PrivUpdate [Name Nothing "a", Name Nothing "b"]]
(PrivTable [Name Nothing "t1"])
[Name Nothing "role1"] WithoutGrantOption)
[Name Nothing "role1"] WithoutGrantOption
,(TestStatement ansi2011
"grant references on table t1 to role1"
,s "grant references on table t1 to role1"
$ GrantPrivilege [PrivReferences []]
(PrivTable [Name Nothing "t1"])
[Name Nothing "role1"] WithoutGrantOption)
[Name Nothing "role1"] WithoutGrantOption
,(TestStatement ansi2011
"grant references(a,b) on table t1 to role1"
,s "grant references(a,b) on table t1 to role1"
$ GrantPrivilege [PrivReferences [Name Nothing "a", Name Nothing "b"]]
(PrivTable [Name Nothing "t1"])
[Name Nothing "role1"] WithoutGrantOption)
[Name Nothing "role1"] WithoutGrantOption
,(TestStatement ansi2011
"grant usage on table t1 to role1"
,s "grant usage on table t1 to role1"
$ GrantPrivilege [PrivUsage]
(PrivTable [Name Nothing "t1"])
[Name Nothing "role1"] WithoutGrantOption)
[Name Nothing "role1"] WithoutGrantOption
,(TestStatement ansi2011
"grant trigger on table t1 to role1"
,s "grant trigger on table t1 to role1"
$ GrantPrivilege [PrivTrigger]
(PrivTable [Name Nothing "t1"])
[Name Nothing "role1"] WithoutGrantOption)
[Name Nothing "role1"] WithoutGrantOption
,(TestStatement ansi2011
"grant execute on specific function f to role1"
,s "grant execute on specific function f to role1"
$ GrantPrivilege [PrivExecute]
(PrivFunction [Name Nothing "f"])
[Name Nothing "role1"] WithoutGrantOption)
[Name Nothing "role1"] WithoutGrantOption
,(TestStatement ansi2011
"grant select,delete on table t1 to role1"
,s "grant select,delete on table t1 to role1"
$ GrantPrivilege [PrivSelect [], PrivDelete]
(PrivTable [Name Nothing "t1"])
[Name Nothing "role1"] WithoutGrantOption)
[Name Nothing "role1"] WithoutGrantOption
{-
skipping for now:
@ -224,9 +205,8 @@ functions, etc., by argument types since they can be overloaded
CREATE ROLE <role name> [ WITH ADMIN <grantor> ]
-}
,(TestStatement ansi2011
"create role rolee"
$ CreateRole (Name Nothing "rolee"))
,s "create role rolee"
$ CreateRole (Name Nothing "rolee")
{-
@ -242,18 +222,15 @@ functions, etc., by argument types since they can be overloaded
<role name>
-}
,(TestStatement ansi2011
"grant role1 to public"
$ GrantRole [Name Nothing "role1"] [Name Nothing "public"] WithoutAdminOption)
,s "grant role1 to public"
$ GrantRole [Name Nothing "role1"] [Name Nothing "public"] WithoutAdminOption
,(TestStatement ansi2011
"grant role1,role2 to role3,role4"
,s "grant role1,role2 to role3,role4"
$ GrantRole [Name Nothing "role1",Name Nothing "role2"]
[Name Nothing "role3", Name Nothing "role4"] WithoutAdminOption)
[Name Nothing "role3", Name Nothing "role4"] WithoutAdminOption
,(TestStatement ansi2011
"grant role1 to role3 with admin option"
$ GrantRole [Name Nothing "role1"] [Name Nothing "role3"] WithAdminOption)
,s "grant role1 to role3 with admin option"
$ GrantRole [Name Nothing "role1"] [Name Nothing "role3"] WithAdminOption
{-
@ -263,9 +240,8 @@ functions, etc., by argument types since they can be overloaded
DROP ROLE <role name>
-}
,(TestStatement ansi2011
"drop role rolee"
$ DropRole (Name Nothing "rolee"))
,s "drop role rolee"
$ DropRole (Name Nothing "rolee")
{-
@ -287,17 +263,16 @@ functions, etc., by argument types since they can be overloaded
-}
,(TestStatement ansi2011
"revoke select on t1 from role1"
,s "revoke select on t1 from role1"
$ RevokePrivilege NoGrantOptionFor [PrivSelect []]
(PrivTable [Name Nothing "t1"])
[Name Nothing "role1"] DefaultDropBehaviour)
[Name Nothing "role1"] DefaultDropBehaviour
,(TestStatement ansi2011
,s
"revoke grant option for select on t1 from role1,role2 cascade"
$ RevokePrivilege GrantOptionFor [PrivSelect []]
(PrivTable [Name Nothing "t1"])
[Name Nothing "role1",Name Nothing "role2"] Cascade)
[Name Nothing "role1",Name Nothing "role2"] Cascade
{-
@ -311,20 +286,19 @@ functions, etc., by argument types since they can be overloaded
<role name>
-}
,(TestStatement ansi2011
"revoke role1 from role2"
,s "revoke role1 from role2"
$ RevokeRole NoAdminOptionFor [Name Nothing "role1"]
[Name Nothing "role2"] DefaultDropBehaviour)
[Name Nothing "role2"] DefaultDropBehaviour
,(TestStatement ansi2011
"revoke role1,role2 from role3,role4"
,s "revoke role1,role2 from role3,role4"
$ RevokeRole NoAdminOptionFor [Name Nothing "role1",Name Nothing "role2"]
[Name Nothing "role3",Name Nothing "role4"] DefaultDropBehaviour)
[Name Nothing "role3",Name Nothing "role4"] DefaultDropBehaviour
,(TestStatement ansi2011
"revoke admin option for role1 from role2 cascade"
$ RevokeRole AdminOptionFor [Name Nothing "role1"] [Name Nothing "role2"] Cascade)
,s "revoke admin option for role1 from role2 cascade"
$ RevokeRole AdminOptionFor [Name Nothing "role1"] [Name Nothing "role2"] Cascade
]
s :: HasCallStack => Text -> Statement -> TestItem
s src ast = testStatement ansi2011 src ast

View file

@ -12,6 +12,8 @@ module Language.SQL.SimpleSQL.SQL2011Bits (sql2011BitsTests) where
import Language.SQL.SimpleSQL.TestTypes
import Language.SQL.SimpleSQL.Syntax
import Language.SQL.SimpleSQL.TestRunners
import Data.Text (Text)
sql2011BitsTests :: TestItem
sql2011BitsTests = Group "sql 2011 bits tests" [
@ -27,10 +29,8 @@ sql2011BitsTests = Group "sql 2011 bits tests" [
BEGIN is not in the standard!
-}
(TestStatement ansi2011
"start transaction"
$ StartTransaction)
s "start transaction" StartTransaction
{-
17.2 <set transaction statement>
@ -84,9 +84,8 @@ BEGIN is not in the standard!
<savepoint name>
-}
,(TestStatement ansi2011
"savepoint difficult_bit"
$ Savepoint $ Name Nothing "difficult_bit")
,s "savepoint difficult_bit"
$ Savepoint $ Name Nothing "difficult_bit"
{-
@ -96,9 +95,8 @@ BEGIN is not in the standard!
RELEASE SAVEPOINT <savepoint specifier>
-}
,(TestStatement ansi2011
"release savepoint difficult_bit"
$ ReleaseSavepoint $ Name Nothing "difficult_bit")
,s "release savepoint difficult_bit"
$ ReleaseSavepoint $ Name Nothing "difficult_bit"
{-
@ -108,13 +106,9 @@ BEGIN is not in the standard!
COMMIT [ WORK ] [ AND [ NO ] CHAIN ]
-}
,(TestStatement ansi2011
"commit"
$ Commit)
,s "commit" Commit
,(TestStatement ansi2011
"commit work"
$ Commit)
,s "commit work" Commit
{-
@ -127,17 +121,12 @@ BEGIN is not in the standard!
TO SAVEPOINT <savepoint specifier>
-}
,(TestStatement ansi2011
"rollback"
$ Rollback Nothing)
,s "rollback" $ Rollback Nothing
,(TestStatement ansi2011
"rollback work"
$ Rollback Nothing)
,s "rollback work" $ Rollback Nothing
,(TestStatement ansi2011
"rollback to savepoint difficult_bit"
$ Rollback $ Just $ Name Nothing "difficult_bit")
,s "rollback to savepoint difficult_bit"
$ Rollback $ Just $ Name Nothing "difficult_bit"
{-
@ -232,3 +221,6 @@ BEGIN is not in the standard!
-}
]
s :: HasCallStack => Text -> Statement -> TestItem
s src ast = testStatement ansi2011 src ast

View file

@ -7,6 +7,8 @@ module Language.SQL.SimpleSQL.SQL2011DataManipulation (sql2011DataManipulationTe
import Language.SQL.SimpleSQL.TestTypes
import Language.SQL.SimpleSQL.Syntax
import Language.SQL.SimpleSQL.TestRunners
import Data.Text (Text)
sql2011DataManipulationTests :: TestItem
sql2011DataManipulationTests = Group "sql 2011 data manipulation tests"
@ -111,20 +113,20 @@ sql2011DataManipulationTests = Group "sql 2011 data manipulation tests"
[ WHERE <search condition> ]
-}
(TestStatement ansi2011 "delete from t"
$ Delete [Name Nothing "t"] Nothing Nothing)
s "delete from t"
$ Delete [Name Nothing "t"] Nothing Nothing
,(TestStatement ansi2011 "delete from t as u"
$ Delete [Name Nothing "t"] (Just (Name Nothing "u")) Nothing)
,s "delete from t as u"
$ Delete [Name Nothing "t"] (Just (Name Nothing "u")) Nothing
,(TestStatement ansi2011 "delete from t where x = 5"
,s "delete from t where x = 5"
$ Delete [Name Nothing "t"] Nothing
(Just $ BinOp (Iden [Name Nothing "x"]) [Name Nothing "="] (NumLit "5")))
(Just $ BinOp (Iden [Name Nothing "x"]) [Name Nothing "="] (NumLit "5"))
,(TestStatement ansi2011 "delete from t as u where u.x = 5"
,s "delete from t as u where u.x = 5"
$ Delete [Name Nothing "t"] (Just (Name Nothing "u"))
(Just $ BinOp (Iden [Name Nothing "u", Name Nothing "x"]) [Name Nothing "="] (NumLit "5")))
(Just $ BinOp (Iden [Name Nothing "u", Name Nothing "x"]) [Name Nothing "="] (NumLit "5"))
{-
14.10 <truncate table statement>
@ -137,14 +139,14 @@ sql2011DataManipulationTests = Group "sql 2011 data manipulation tests"
| RESTART IDENTITY
-}
,(TestStatement ansi2011 "truncate table t"
$ Truncate [Name Nothing "t"] DefaultIdentityRestart)
,s "truncate table t"
$ Truncate [Name Nothing "t"] DefaultIdentityRestart
,(TestStatement ansi2011 "truncate table t continue identity"
$ Truncate [Name Nothing "t"] ContinueIdentity)
,s "truncate table t continue identity"
$ Truncate [Name Nothing "t"] ContinueIdentity
,(TestStatement ansi2011 "truncate table t restart identity"
$ Truncate [Name Nothing "t"] RestartIdentity)
,s "truncate table t restart identity"
$ Truncate [Name Nothing "t"] RestartIdentity
{-
@ -182,37 +184,37 @@ sql2011DataManipulationTests = Group "sql 2011 data manipulation tests"
<column name list>
-}
,(TestStatement ansi2011 "insert into t select * from u"
,s "insert into t select * from u"
$ Insert [Name Nothing "t"] Nothing
$ InsertQuery $ toQueryExpr $ makeSelect
{msSelectList = [(Star, Nothing)]
,msFrom = [TRSimple [Name Nothing "u"]]})
,msFrom = [TRSimple [Name Nothing "u"]]}
,(TestStatement ansi2011 "insert into t(a,b,c) select * from u"
,s "insert into t(a,b,c) select * from u"
$ Insert [Name Nothing "t"] (Just [Name Nothing "a", Name Nothing "b", Name Nothing "c"])
$ InsertQuery $ toQueryExpr $ makeSelect
{msSelectList = [(Star, Nothing)]
,msFrom = [TRSimple [Name Nothing "u"]]})
,msFrom = [TRSimple [Name Nothing "u"]]}
,(TestStatement ansi2011 "insert into t default values"
$ Insert [Name Nothing "t"] Nothing DefaultInsertValues)
,s "insert into t default values"
$ Insert [Name Nothing "t"] Nothing DefaultInsertValues
,(TestStatement ansi2011 "insert into t values(1,2)"
,s "insert into t values(1,2)"
$ Insert [Name Nothing "t"] Nothing
$ InsertQuery $ Values [[NumLit "1", NumLit "2"]])
$ InsertQuery $ Values [[NumLit "1", NumLit "2"]]
,(TestStatement ansi2011 "insert into t values (1,2),(3,4)"
,s "insert into t values (1,2),(3,4)"
$ Insert [Name Nothing "t"] Nothing
$ InsertQuery $ Values [[NumLit "1", NumLit "2"]
,[NumLit "3", NumLit "4"]])
,[NumLit "3", NumLit "4"]]
,(TestStatement ansi2011
,s
"insert into t values (default,null,array[],multiset[])"
$ Insert [Name Nothing "t"] Nothing
$ InsertQuery $ Values [[Iden [Name Nothing "default"]
,Iden [Name Nothing "null"]
,Array (Iden [Name Nothing "array"]) []
,MultisetCtor []]])
,MultisetCtor []]]
{-
@ -456,32 +458,32 @@ FROM CentralOfficeAccounts;
-}
,(TestStatement ansi2011 "update t set a=b"
,s "update t set a=b"
$ Update [Name Nothing "t"] Nothing
[Set [Name Nothing "a"] (Iden [Name Nothing "b"])] Nothing)
[Set [Name Nothing "a"] (Iden [Name Nothing "b"])] Nothing
,(TestStatement ansi2011 "update t set a=b, c=5"
,s "update t set a=b, c=5"
$ Update [Name Nothing "t"] Nothing
[Set [Name Nothing "a"] (Iden [Name Nothing "b"])
,Set [Name Nothing "c"] (NumLit "5")] Nothing)
,Set [Name Nothing "c"] (NumLit "5")] Nothing
,(TestStatement ansi2011 "update t set a=b where a>5"
,s "update t set a=b where a>5"
$ Update [Name Nothing "t"] Nothing
[Set [Name Nothing "a"] (Iden [Name Nothing "b"])]
$ Just $ BinOp (Iden [Name Nothing "a"]) [Name Nothing ">"] (NumLit "5"))
$ Just $ BinOp (Iden [Name Nothing "a"]) [Name Nothing ">"] (NumLit "5")
,(TestStatement ansi2011 "update t as u set a=b where u.a>5"
,s "update t as u set a=b where u.a>5"
$ Update [Name Nothing "t"] (Just $ Name Nothing "u")
[Set [Name Nothing "a"] (Iden [Name Nothing "b"])]
$ Just $ BinOp (Iden [Name Nothing "u",Name Nothing "a"])
[Name Nothing ">"] (NumLit "5"))
[Name Nothing ">"] (NumLit "5")
,(TestStatement ansi2011 "update t set (a,b)=(3,5)"
,s "update t set (a,b)=(3,5)"
$ Update [Name Nothing "t"] Nothing
[SetMultiple [[Name Nothing "a"],[Name Nothing "b"]]
[NumLit "3", NumLit "5"]] Nothing)
[NumLit "3", NumLit "5"]] Nothing
@ -553,3 +555,6 @@ declare local temporary table t (a int) [on commit {preserve | delete} rows]
]
s :: HasCallStack => Text -> Statement -> TestItem
s src ast = testStatement ansi2011 src ast

View file

@ -37,6 +37,7 @@ import Language.SQL.SimpleSQL.TestTypes
import Language.SQL.SimpleSQL.Syntax
import Data.Text (Text)
import Language.SQL.SimpleSQL.TestRunners
sql2011QueryTests :: TestItem
sql2011QueryTests = Group "sql 2011 query tests"
@ -515,19 +516,19 @@ generalLiterals = Group "general literals"
characterStringLiterals :: TestItem
characterStringLiterals = Group "character string literals"
$ map (uncurry (TestScalarExpr ansi2011))
[("'a regular string literal'"
,StringLit "'" "'" "a regular string literal")
,("'something' ' some more' 'and more'"
,StringLit "'" "'" "something some moreand more")
,("'something' \n ' some more' \t 'and more'"
,StringLit "'" "'" "something some moreand more")
,("'something' -- a comment\n ' some more' /*another comment*/ 'and more'"
,StringLit "'" "'" "something some moreand more")
,("'a quote: '', stuff'"
,StringLit "'" "'" "a quote: '', stuff")
,("''"
,StringLit "'" "'" "")
$
[e "'a regular string literal'"
$ StringLit "'" "'" "a regular string literal"
,e "'something' ' some more' 'and more'"
$ StringLit "'" "'" "something some moreand more"
,e "'something' \n ' some more' \t 'and more'"
$ StringLit "'" "'" "something some moreand more"
,e "'something' -- a comment\n ' some more' /*another comment*/ 'and more'"
$ StringLit "'" "'" "something some moreand more"
,e "'a quote: '', stuff'"
$ StringLit "'" "'" "a quote: '', stuff"
,e "''"
$ StringLit "'" "'" ""
{-
I'm not sure how this should work. Maybe the parser should reject non
@ -535,8 +536,8 @@ ascii characters in strings and identifiers unless the current SQL
character set allows them.
-}
,("_francais 'français'"
,TypedLit (TypeName [Name Nothing "_francais"]) "français")
,e "_francais 'français'"
$ TypedLit (TypeName [Name Nothing "_francais"]) "français"
]
{-
@ -547,9 +548,9 @@ character set allows them.
nationalCharacterStringLiterals :: TestItem
nationalCharacterStringLiterals = Group "national character string literals"
$ map (uncurry (TestScalarExpr ansi2011))
[("N'something'", StringLit "N'" "'" "something")
,("n'something'", StringLit "n'" "'" "something")
$
[e "N'something'" $ StringLit "N'" "'" "something"
,e "n'something'" $ StringLit "n'" "'" "something"
]
{-
@ -566,8 +567,8 @@ nationalCharacterStringLiterals = Group "national character string literals"
unicodeCharacterStringLiterals :: TestItem
unicodeCharacterStringLiterals = Group "unicode character string literals"
$ map (uncurry (TestScalarExpr ansi2011))
[("U&'something'", StringLit "U&'" "'" "something")
$
[e "U&'something'" $ StringLit "U&'" "'" "something"
{-,("u&'something' escape ="
,Escape (StringLit "u&'" "'" "something") '=')
,("u&'something' uescape ="
@ -587,9 +588,9 @@ TODO: unicode escape
binaryStringLiterals :: TestItem
binaryStringLiterals = Group "binary string literals"
$ map (uncurry (TestScalarExpr ansi2011))
$
[--("B'101010'", CSStringLit "B" "101010")
("X'7f7f7f'", StringLit "X'" "'" "7f7f7f")
e "X'7f7f7f'" $ StringLit "X'" "'" "7f7f7f"
--,("X'7f7f7f' escape z", Escape (StringLit "X'" "'" "7f7f7f") 'z')
]
@ -619,33 +620,32 @@ binaryStringLiterals = Group "binary string literals"
numericLiterals :: TestItem
numericLiterals = Group "numeric literals"
$ map (uncurry (TestScalarExpr ansi2011))
[("11", NumLit "11")
,("11.11", NumLit "11.11")
[e "11" $ NumLit "11"
,e "11.11" $ NumLit "11.11"
,("11E23", NumLit "11E23")
,("11E+23", NumLit "11E+23")
,("11E-23", NumLit "11E-23")
,e "11E23" $ NumLit "11E23"
,e "11E+23" $ NumLit "11E+23"
,e "11E-23" $ NumLit "11E-23"
,("11.11E23", NumLit "11.11E23")
,("11.11E+23", NumLit "11.11E+23")
,("11.11E-23", NumLit "11.11E-23")
,e "11.11E23" $ NumLit "11.11E23"
,e "11.11E+23" $ NumLit "11.11E+23"
,e "11.11E-23" $ NumLit "11.11E-23"
,("+11E23", PrefixOp [Name Nothing "+"] $ NumLit "11E23")
,("+11E+23", PrefixOp [Name Nothing "+"] $ NumLit "11E+23")
,("+11E-23", PrefixOp [Name Nothing "+"] $ NumLit "11E-23")
,("+11.11E23", PrefixOp [Name Nothing "+"] $ NumLit "11.11E23")
,("+11.11E+23", PrefixOp [Name Nothing "+"] $ NumLit "11.11E+23")
,("+11.11E-23", PrefixOp [Name Nothing "+"] $ NumLit "11.11E-23")
,e "+11E23" $ PrefixOp [Name Nothing "+"] $ NumLit "11E23"
,e "+11E+23" $ PrefixOp [Name Nothing "+"] $ NumLit "11E+23"
,e "+11E-23" $ PrefixOp [Name Nothing "+"] $ NumLit "11E-23"
,e "+11.11E23" $ PrefixOp [Name Nothing "+"] $ NumLit "11.11E23"
,e "+11.11E+23" $ PrefixOp [Name Nothing "+"] $ NumLit "11.11E+23"
,e "+11.11E-23" $ PrefixOp [Name Nothing "+"] $ NumLit "11.11E-23"
,("-11E23", PrefixOp [Name Nothing "-"] $ NumLit "11E23")
,("-11E+23", PrefixOp [Name Nothing "-"] $ NumLit "11E+23")
,("-11E-23", PrefixOp [Name Nothing "-"] $ NumLit "11E-23")
,("-11.11E23", PrefixOp [Name Nothing "-"] $ NumLit "11.11E23")
,("-11.11E+23", PrefixOp [Name Nothing "-"] $ NumLit "11.11E+23")
,("-11.11E-23", PrefixOp [Name Nothing "-"] $ NumLit "11.11E-23")
,e "-11E23" $ PrefixOp [Name Nothing "-"] $ NumLit "11E23"
,e "-11E+23" $ PrefixOp [Name Nothing "-"] $ NumLit "11E+23"
,e "-11E-23" $ PrefixOp [Name Nothing "-"] $ NumLit "11E-23"
,e "-11.11E23" $ PrefixOp [Name Nothing "-"] $ NumLit "11.11E23"
,e "-11.11E+23" $ PrefixOp [Name Nothing "-"] $ NumLit "11.11E+23"
,e "-11.11E-23" $ PrefixOp [Name Nothing "-"] $ NumLit "11.11E-23"
,("11.11e23", NumLit "11.11e23")
,e "11.11e23" $ NumLit "11.11e23"
]
@ -729,33 +729,30 @@ dateTimeLiterals = Group "datetime literals"
intervalLiterals :: TestItem
intervalLiterals = Group "intervalLiterals literals"
$ map (uncurry (TestScalarExpr ansi2011))
[("interval '1'", TypedLit (TypeName [Name Nothing "interval"]) "1")
,("interval '1' day"
,IntervalLit Nothing "1" (Itf "day" Nothing) Nothing)
,("interval '1' day(3)"
,IntervalLit Nothing "1" (Itf "day" $ Just (3,Nothing)) Nothing)
,("interval + '1' day(3)"
,IntervalLit (Just Plus) "1" (Itf "day" $ Just (3,Nothing)) Nothing)
,("interval - '1' second(2,2)"
,IntervalLit (Just Minus) "1" (Itf "second" $ Just (2,Just 2)) Nothing)
,("interval '1' year to month"
,IntervalLit Nothing "1" (Itf "year" Nothing)
(Just $ Itf "month" Nothing))
,("interval '1' year(4) to second(2,3) "
,IntervalLit Nothing "1" (Itf "year" $ Just (4,Nothing))
(Just $ Itf "second" $ Just (2, Just 3)))
[e "interval '1'" $ TypedLit (TypeName [Name Nothing "interval"]) "1"
,e "interval '1' day"
$ IntervalLit Nothing "1" (Itf "day" Nothing) Nothing
,e "interval '1' day(3)"
$ IntervalLit Nothing "1" (Itf "day" $ Just (3,Nothing)) Nothing
,e "interval + '1' day(3)"
$ IntervalLit (Just Plus) "1" (Itf "day" $ Just (3,Nothing)) Nothing
,e "interval - '1' second(2,2)"
$ IntervalLit (Just Minus) "1" (Itf "second" $ Just (2,Just 2)) Nothing
,e "interval '1' year to month"
$ IntervalLit Nothing "1" (Itf "year" Nothing)
(Just $ Itf "month" Nothing)
,e "interval '1' year(4) to second(2,3) "
$ IntervalLit Nothing "1" (Itf "year" $ Just (4,Nothing))
(Just $ Itf "second" $ Just (2, Just 3))
]
-- <boolean literal> ::= TRUE | FALSE | UNKNOWN
booleanLiterals :: TestItem
booleanLiterals = Group "boolean literals"
$ map (uncurry (TestScalarExpr ansi2011))
[("true", Iden [Name Nothing "true"])
,("false", Iden [Name Nothing "false"])
,("unknown", Iden [Name Nothing "unknown"])
[e "true" $ Iden [Name Nothing "true"]
,e "false" $ Iden [Name Nothing "false"]
,e "unknown" $ Iden [Name Nothing "unknown"]
]
{-
@ -774,16 +771,15 @@ Specify names.
identifiers :: TestItem
identifiers = Group "identifiers"
$ map (uncurry (TestScalarExpr ansi2011))
[("test",Iden [Name Nothing "test"])
,("_test",Iden [Name Nothing "_test"])
,("t1",Iden [Name Nothing "t1"])
,("a.b",Iden [Name Nothing "a", Name Nothing "b"])
,("a.b.c",Iden [Name Nothing "a", Name Nothing "b", Name Nothing "c"])
,("\"quoted iden\"", Iden [Name (Just ("\"","\"")) "quoted iden"])
,("\"quoted \"\" iden\"", Iden [Name (Just ("\"","\"")) "quoted \"\" iden"])
,("U&\"quoted iden\"", Iden [Name (Just ("U&\"","\"")) "quoted iden"])
,("U&\"quoted \"\" iden\"", Iden [Name (Just ("U&\"","\"")) "quoted \"\" iden"])
[e "test" $ Iden [Name Nothing "test"]
,e "_test" $ Iden [Name Nothing "_test"]
,e "t1" $ Iden [Name Nothing "t1"]
,e "a.b" $ Iden [Name Nothing "a", Name Nothing "b"]
,e "a.b.c" $ Iden [Name Nothing "a", Name Nothing "b", Name Nothing "c"]
,e "\"quoted iden\"" $ Iden [Name (Just ("\"", "\"")) "quoted iden"]
,e "\"quoted \"\" iden\"" $ Iden [Name (Just ("\"", "\"")) "quoted \"\" iden"]
,e "U&\"quoted iden\"" $ Iden [Name (Just ("U&\"", "\"")) "quoted iden"]
,e "U&\"quoted \"\" iden\"" $ Iden [Name (Just ("U&\"", "\"")) "quoted \"\" iden"]
]
{-
@ -1220,11 +1216,11 @@ expression
typeNameTests :: TestItem
typeNameTests = Group "type names"
[Group "type names" $ map (uncurry (TestScalarExpr ansi2011))
[Group "type names" $ map (uncurry (testScalarExpr ansi2011))
$ concatMap makeSimpleTests $ fst typeNames
,Group "generated casts" $ map (uncurry (TestScalarExpr ansi2011))
,Group "generated casts" $ map (uncurry (testScalarExpr ansi2011))
$ concatMap makeCastTests $ fst typeNames
,Group "generated typename" $ map (uncurry (TestScalarExpr ansi2011))
,Group "generated typename" $ map (uncurry (testScalarExpr ansi2011))
$ concatMap makeTests $ snd typeNames]
where
makeSimpleTests (ctn, stn) =
@ -1247,12 +1243,10 @@ Define a field of a row type.
fieldDefinition :: TestItem
fieldDefinition = Group "field definition"
$ map (uncurry (TestScalarExpr ansi2011))
[("cast('(1,2)' as row(a int,b char))"
,Cast (StringLit "'" "'" "(1,2)")
[e "cast('(1,2)' as row(a int,b char))"
$ Cast (StringLit "'" "'" "(1,2)")
$ RowTypeName [(Name Nothing "a", TypeName [Name Nothing "int"])
,(Name Nothing "b", TypeName [Name Nothing "char"])])]
,(Name Nothing "b", TypeName [Name Nothing "char"])]]
{-
== 6.3 <value expression primary>
@ -1329,9 +1323,8 @@ valueExpressions = Group "value expressions"
parenthesizedScalarExpression :: TestItem
parenthesizedScalarExpression = Group "parenthesized value expression"
$ map (uncurry (TestScalarExpr ansi2011))
[("(3)", Parens (NumLit "3"))
,("((3))", Parens $ Parens (NumLit "3"))
[e "(3)" $ Parens (NumLit "3")
,e "((3))" $ Parens $ Parens (NumLit "3")
]
{-
@ -1367,8 +1360,7 @@ Specify one or more values, host parameters, SQL parameters, dynamic parameters,
generalValueSpecification :: TestItem
generalValueSpecification = Group "general value specification"
$ map (uncurry (TestScalarExpr ansi2011)) $
map mkIden ["CURRENT_DEFAULT_TRANSFORM_GROUP"
$ map mkIden ["CURRENT_DEFAULT_TRANSFORM_GROUP"
,"CURRENT_PATH"
,"CURRENT_ROLE"
,"CURRENT_USER"
@ -1377,7 +1369,7 @@ generalValueSpecification = Group "general value specification"
,"USER"
,"VALUE"]
where
mkIden nm = (nm,Iden [Name Nothing nm])
mkIden nm = e nm $ Iden [Name Nothing nm]
{-
TODO: add the missing bits
@ -1423,12 +1415,11 @@ TODO: add the missing bits
parameterSpecification :: TestItem
parameterSpecification = Group "parameter specification"
$ map (uncurry (TestScalarExpr ansi2011))
[(":hostparam", HostParameter ":hostparam" Nothing)
,(":hostparam indicator :another_host_param"
,HostParameter ":hostparam" $ Just ":another_host_param")
,("?", Parameter)
,(":h[3]", Array (HostParameter ":h" Nothing) [NumLit "3"])
[e ":hostparam" $ HostParameter ":hostparam" Nothing
,e ":hostparam indicator :another_host_param"
$ HostParameter ":hostparam" $ Just ":another_host_param"
,e "?" $ Parameter
,e ":h[3]" $ Array (HostParameter ":h" Nothing) [NumLit "3"]
]
{-
@ -1462,11 +1453,10 @@ Specify a value whose data type is to be inferred from its context.
contextuallyTypedValueSpecification :: TestItem
contextuallyTypedValueSpecification =
Group "contextually typed value specification"
$ map (uncurry (TestScalarExpr ansi2011))
[("null", Iden [Name Nothing "null"])
,("array[]", Array (Iden [Name Nothing "array"]) [])
,("multiset[]", MultisetCtor [])
,("default", Iden [Name Nothing "default"])
[e "null" $ Iden [Name Nothing "null"]
,e "array[]" $ Array (Iden [Name Nothing "array"]) []
,e "multiset[]" $ MultisetCtor []
,e "default" $ Iden [Name Nothing "default"]
]
{-
@ -1482,8 +1472,7 @@ Disambiguate a <period>-separated chain of identifiers.
identifierChain :: TestItem
identifierChain = Group "identifier chain"
$ map (uncurry (TestScalarExpr ansi2011))
[("a.b", Iden [Name Nothing "a",Name Nothing "b"])]
[e "a.b" $ Iden [Name Nothing "a",Name Nothing "b"]]
{-
== 6.7 <column reference>
@ -1498,8 +1487,7 @@ Reference a column.
columnReference :: TestItem
columnReference = Group "column reference"
$ map (uncurry (TestScalarExpr ansi2011))
[("module.a.b", Iden [Name Nothing "module",Name Nothing "a",Name Nothing "b"])]
[e "module.a.b" $ Iden [Name Nothing "module",Name Nothing "a",Name Nothing "b"]]
{-
== 6.8 <SQL parameter reference>
@ -1523,19 +1511,19 @@ Specify a value derived by the application of a function to an argument.
setFunctionSpecification :: TestItem
setFunctionSpecification = Group "set function specification"
$ map (uncurry (TestQueryExpr ansi2011))
[("SELECT SalesQuota, SUM(SalesYTD) TotalSalesYTD,\n\
$
[q "SELECT SalesQuota, SUM(SalesYTD) TotalSalesYTD,\n\
\ GROUPING(SalesQuota) AS Grouping\n\
\FROM Sales.SalesPerson\n\
\GROUP BY ROLLUP(SalesQuota);"
,toQueryExpr $ makeSelect
$ toQueryExpr $ makeSelect
{msSelectList = [(Iden [Name Nothing "SalesQuota"],Nothing)
,(App [Name Nothing "SUM"] [Iden [Name Nothing "SalesYTD"]]
,Just (Name Nothing "TotalSalesYTD"))
,(App [Name Nothing "GROUPING"] [Iden [Name Nothing "SalesQuota"]]
,Just (Name Nothing "Grouping"))]
,msFrom = [TRSimple [Name Nothing "Sales",Name Nothing "SalesPerson"]]
,msGroupBy = [Rollup [SimpleGroup (Iden [Name Nothing "SalesQuota"])]]})
,msGroupBy = [Rollup [SimpleGroup (Iden [Name Nothing "SalesQuota"])]]}
]
{-
@ -1732,9 +1720,8 @@ Specify a data conversion.
castSpecification :: TestItem
castSpecification = Group "cast specification"
$ map (uncurry (TestScalarExpr ansi2011))
[("cast(a as int)"
,Cast (Iden [Name Nothing "a"]) (TypeName [Name Nothing "int"]))
[e "cast(a as int)"
$ Cast (Iden [Name Nothing "a"]) (TypeName [Name Nothing "int"])
]
{-
@ -1748,8 +1735,7 @@ Return the next value of a sequence generator.
nextScalarExpression :: TestItem
nextScalarExpression = Group "next value expression"
$ map (uncurry (TestScalarExpr ansi2011))
[("next value for a.b", NextValueFor [Name Nothing "a", Name Nothing "b"])
[e "next value for a.b" $ NextValueFor [Name Nothing "a", Name Nothing "b"]
]
{-
@ -1763,11 +1749,10 @@ Reference a field of a row value.
fieldReference :: TestItem
fieldReference = Group "field reference"
$ map (uncurry (TestScalarExpr ansi2011))
[("f(something).a"
,BinOp (App [Name Nothing "f"] [Iden [Name Nothing "something"]])
[e "f(something).a"
$ BinOp (App [Name Nothing "f"] [Iden [Name Nothing "something"]])
[Name Nothing "."]
(Iden [Name Nothing "a"]))
(Iden [Name Nothing "a"])
]
{-
@ -1889,17 +1874,16 @@ Return an element of an array.
arrayElementReference :: TestItem
arrayElementReference = Group "array element reference"
$ map (uncurry (TestScalarExpr ansi2011))
[("something[3]"
,Array (Iden [Name Nothing "something"]) [NumLit "3"])
,("(something(a))[x]"
,Array (Parens (App [Name Nothing "something"] [Iden [Name Nothing "a"]]))
[Iden [Name Nothing "x"]])
,("(something(a))[x][y] "
,Array (
[e "something[3]"
$ Array (Iden [Name Nothing "something"]) [NumLit "3"]
,e "(something(a))[x]"
$ Array (Parens (App [Name Nothing "something"] [Iden [Name Nothing "a"]]))
[Iden [Name Nothing "x"]]
,e "(something(a))[x][y] "
$ Array (
Array (Parens (App [Name Nothing "something"] [Iden [Name Nothing "a"]]))
[Iden [Name Nothing "x"]])
[Iden [Name Nothing "y"]])
[Iden [Name Nothing "y"]]
]
{-
@ -1914,9 +1898,8 @@ Return the sole element of a multiset of one element.
multisetElementReference :: TestItem
multisetElementReference = Group "multisetElementReference"
$ map (uncurry (TestScalarExpr ansi2011))
[("element(something)"
,App [Name Nothing "element"] [Iden [Name Nothing "something"]])
[e "element(something)"
$ App [Name Nothing "element"] [Iden [Name Nothing "something"]]
]
{-
@ -1966,13 +1949,12 @@ Specify a numeric value.
numericScalarExpression :: TestItem
numericScalarExpression = Group "numeric value expression"
$ map (uncurry (TestScalarExpr ansi2011))
[("a + b", binOp "+")
,("a - b", binOp "-")
,("a * b", binOp "*")
,("a / b", binOp "/")
,("+a", prefOp "+")
,("-a", prefOp "-")
[e "a + b" $ binOp "+"
,e "a - b" $ binOp "-"
,e "a * b" $ binOp "*"
,e "a / b" $ binOp "/"
,e "+a" $ prefOp "+"
,e "-a" $ prefOp "-"
]
where
binOp o = BinOp (Iden [Name Nothing "a"]) [Name Nothing o] (Iden [Name Nothing "b"])
@ -2439,17 +2421,16 @@ Specify a boolean value.
booleanScalarExpression :: TestItem
booleanScalarExpression = Group "booleab value expression"
$ map (uncurry (TestScalarExpr ansi2011))
[("a or b", BinOp a [Name Nothing "or"] b)
,("a and b", BinOp a [Name Nothing "and"] b)
,("not a", PrefixOp [Name Nothing "not"] a)
,("a is true", postfixOp "is true")
,("a is false", postfixOp "is false")
,("a is unknown", postfixOp "is unknown")
,("a is not true", postfixOp "is not true")
,("a is not false", postfixOp "is not false")
,("a is not unknown", postfixOp "is not unknown")
,("(a or b)", Parens $ BinOp a [Name Nothing "or"] b)
[e "a or b" $ BinOp a [Name Nothing "or"] b
,e "a and b" $ BinOp a [Name Nothing "and"] b
,e "not a" $ PrefixOp [Name Nothing "not"] a
,e "a is true" $ postfixOp "is true"
,e "a is false" $ postfixOp "is false"
,e "a is unknown" $ postfixOp "is unknown"
,e "a is not true" $ postfixOp "is not true"
,e "a is not false" $ postfixOp "is not false"
,e "a is not unknown" $ postfixOp "is not unknown"
,e "(a or b)" $ Parens $ BinOp a [Name Nothing "or"] b
]
where
a = Iden [Name Nothing "a"]
@ -2520,23 +2501,22 @@ Specify construction of an array.
arrayValueConstructor :: TestItem
arrayValueConstructor = Group "array value constructor"
$ map (uncurry (TestScalarExpr ansi2011))
[("array[1,2,3]"
,Array (Iden [Name Nothing "array"])
[NumLit "1", NumLit "2", NumLit "3"])
,("array[a,b,c]"
,Array (Iden [Name Nothing "array"])
[Iden [Name Nothing "a"], Iden [Name Nothing "b"], Iden [Name Nothing "c"]])
,("array(select * from t)"
,ArrayCtor (toQueryExpr $ makeSelect
[e "array[1,2,3]"
$ Array (Iden [Name Nothing "array"])
[NumLit "1", NumLit "2", NumLit "3"]
,e "array[a,b,c]"
$ Array (Iden [Name Nothing "array"])
[Iden [Name Nothing "a"], Iden [Name Nothing "b"], Iden [Name Nothing "c"]]
,e "array(select * from t)"
$ ArrayCtor (toQueryExpr $ makeSelect
{msSelectList = [(Star,Nothing)]
,msFrom = [TRSimple [Name Nothing "t"]]}))
,("array(select * from t order by a)"
,ArrayCtor (toQueryExpr $ makeSelect
,msFrom = [TRSimple [Name Nothing "t"]]})
,e "array(select * from t order by a)"
$ ArrayCtor (toQueryExpr $ makeSelect
{msSelectList = [(Star,Nothing)]
,msFrom = [TRSimple [Name Nothing "t"]]
,msOrderBy = [SortSpec (Iden [Name Nothing "a"])
DirDefault NullsOrderDefault]}))
DirDefault NullsOrderDefault]})
]
@ -2560,7 +2540,7 @@ Specify a multiset value.
multisetScalarExpression :: TestItem
multisetScalarExpression = Group "multiset value expression"
$ map (uncurry (TestScalarExpr ansi2011))
$ map (uncurry (testScalarExpr ansi2011))
[("a multiset union b"
,MultisetBinOp (Iden [Name Nothing "a"]) Union SQDefault (Iden [Name Nothing "b"]))
,("a multiset union all b"
@ -2592,7 +2572,7 @@ special case term.
multisetValueFunction :: TestItem
multisetValueFunction = Group "multiset value function"
$ map (uncurry (TestScalarExpr ansi2011))
$ map (uncurry (testScalarExpr ansi2011))
[("set(a)", App [Name Nothing "set"] [Iden [Name Nothing "a"]])
]
@ -2622,7 +2602,7 @@ Specify construction of a multiset.
multisetValueConstructor :: TestItem
multisetValueConstructor = Group "multiset value constructor"
$ map (uncurry (TestScalarExpr ansi2011))
$ map (uncurry (testScalarExpr ansi2011))
[("multiset[a,b,c]", MultisetCtor[Iden [Name Nothing "a"]
,Iden [Name Nothing "b"], Iden [Name Nothing "c"]])
,("multiset(select * from t)", MultisetQueryCtor ms)
@ -2702,7 +2682,7 @@ Specify a value or list of values to be constructed into a row.
rowValueConstructor :: TestItem
rowValueConstructor = Group "row value constructor"
$ map (uncurry (TestScalarExpr ansi2011))
$ map (uncurry (testScalarExpr ansi2011))
[("(a,b)"
,SpecialOp [Name Nothing "rowctor"] [Iden [Name Nothing "a"], Iden [Name Nothing "b"]])
,("row(1)",App [Name Nothing "row"] [NumLit "1"])
@ -2755,7 +2735,7 @@ Specify a set of <row value expression>s to be constructed into a table.
tableValueConstructor :: TestItem
tableValueConstructor = Group "table value constructor"
$ map (uncurry (TestQueryExpr ansi2011))
$ map (uncurry (testQueryExpr ansi2011))
[("values (1,2), (a+b,(select count(*) from t));"
,Values [[NumLit "1", NumLit "2"]
,[BinOp (Iden [Name Nothing "a"]) [Name Nothing "+"]
@ -2792,7 +2772,7 @@ Specify a table derived from one or more tables.
fromClause :: TestItem
fromClause = Group "fromClause"
$ map (uncurry (TestQueryExpr ansi2011))
$ map (uncurry (testQueryExpr ansi2011))
[("select * from tbl1,tbl2"
,toQueryExpr $ makeSelect
{msSelectList = [(Star, Nothing)]
@ -2809,7 +2789,7 @@ Reference a table.
tableReference :: TestItem
tableReference = Group "table reference"
$ map (uncurry (TestQueryExpr ansi2011))
$ map (uncurry (testQueryExpr ansi2011))
[("select * from t", toQueryExpr sel)
{-
@ -2994,7 +2974,7 @@ Specify a table derived from a Cartesian product, inner join, or outer join.
joinedTable :: TestItem
joinedTable = Group "joined table"
$ map (uncurry (TestQueryExpr ansi2011))
$ map (uncurry (testQueryExpr ansi2011))
[("select * from a cross join b"
,sel $ TRJoin a False JCross b Nothing)
,("select * from a join b on true"
@ -3053,7 +3033,7 @@ the result of the preceding <from clause>.
whereClause :: TestItem
whereClause = Group "where clause"
$ map (uncurry (TestQueryExpr ansi2011))
$ map (uncurry (testQueryExpr ansi2011))
[("select * from t where a = 5"
,toQueryExpr $ makeSelect
{msSelectList = [(Star,Nothing)]
@ -3115,7 +3095,7 @@ clause> to the result of the previously specified clause.
groupByClause :: TestItem
groupByClause = Group "group by clause"
$ map (uncurry (TestQueryExpr ansi2011))
$ map (uncurry (testQueryExpr ansi2011))
[("select a,sum(x) from t group by a"
,toQueryExpr $ ms [SimpleGroup $ Iden [Name Nothing "a"]])
,("select a,sum(x) from t group by a collate c"
@ -3170,7 +3150,7 @@ not satisfy a <search condition>.
havingClause :: TestItem
havingClause = Group "having clause"
$ map (uncurry (TestQueryExpr ansi2011))
$ map (uncurry (testQueryExpr ansi2011))
[("select a,sum(x) from t group by a having sum(x) > 1000"
,toQueryExpr $ makeSelect
{msSelectList = [(Iden [Name Nothing "a"], Nothing)
@ -3297,7 +3277,7 @@ Specify a table derived from the result of a <table expression>.
querySpecification :: TestItem
querySpecification = Group "query specification"
$ map (uncurry (TestQueryExpr ansi2011))
$ map (uncurry (testQueryExpr ansi2011))
[("select a from t",toQueryExpr ms)
,("select all a from t",toQueryExpr $ ms {msSetQuantifier = All})
,("select distinct a from t",toQueryExpr $ ms {msSetQuantifier = Distinct})
@ -3369,7 +3349,7 @@ withQueryExpression= Group "with query expression"
setOpQueryExpression :: TestItem
setOpQueryExpression= Group "set operation query expression"
$ map (uncurry (TestQueryExpr ansi2011))
$ map (uncurry (testQueryExpr ansi2011))
-- todo: complete setop query expression tests
[{-("select * from t union select * from t"
,undefined)
@ -3408,7 +3388,7 @@ everywhere
explicitTableQueryExpression :: TestItem
explicitTableQueryExpression= Group "explicit table query expression"
$ map (uncurry (TestQueryExpr ansi2011))
$ map (uncurry (testQueryExpr ansi2011))
[("table t", Table [Name Nothing "t"])
]
@ -3432,7 +3412,7 @@ explicitTableQueryExpression= Group "explicit table query expression"
orderOffsetFetchQueryExpression :: TestItem
orderOffsetFetchQueryExpression = Group "order, offset, fetch query expression"
$ map (uncurry (TestQueryExpr ansi2011))
$ map (uncurry (testQueryExpr ansi2011))
[-- todo: finish tests for order offset and fetch
("select a from t order by a"
,toQueryExpr $ ms {msOrderBy = [SortSpec (Iden [Name Nothing "a"])
@ -3597,7 +3577,7 @@ Specify a comparison of two row values.
comparisonPredicates :: TestItem
comparisonPredicates = Group "comparison predicates"
$ map (uncurry (TestScalarExpr ansi2011))
$ map (uncurry (testScalarExpr ansi2011))
$ map mkOp ["=", "<>", "<", ">", "<=", ">="]
<> [("ROW(a) = ROW(b)"
,BinOp (App [Name Nothing "ROW"] [a])
@ -3815,7 +3795,7 @@ Specify a quantified comparison.
quantifiedComparisonPredicate :: TestItem
quantifiedComparisonPredicate = Group "quantified comparison predicate"
$ map (uncurry (TestScalarExpr ansi2011))
$ map (uncurry (testScalarExpr ansi2011))
[("a = any (select * from t)"
,QuantifiedComparison (Iden [Name Nothing "a"]) [Name Nothing "="] CPAny ms)
@ -3844,7 +3824,7 @@ Specify a test for a non-empty set.
existsPredicate :: TestItem
existsPredicate = Group "exists predicate"
$ map (uncurry (TestScalarExpr ansi2011))
$ map (uncurry (testScalarExpr ansi2011))
[("exists(select * from t where a = 4)"
,SubQueryExpr SqExists
$ toQueryExpr $ makeSelect
@ -3865,7 +3845,7 @@ Specify a test for the absence of duplicate rows.
uniquePredicate :: TestItem
uniquePredicate = Group "unique predicate"
$ map (uncurry (TestScalarExpr ansi2011))
$ map (uncurry (testScalarExpr ansi2011))
[("unique(select * from t where a = 4)"
,SubQueryExpr SqUnique
$ toQueryExpr $ makeSelect
@ -3905,7 +3885,7 @@ Specify a test for matching rows.
matchPredicate :: TestItem
matchPredicate = Group "match predicate"
$ map (uncurry (TestScalarExpr ansi2011))
$ map (uncurry (testScalarExpr ansi2011))
[("a match (select a from t)"
,Match (Iden [Name Nothing "a"]) False $ toQueryExpr ms)
,("(a,b) match (select a,b from t)"
@ -4273,7 +4253,7 @@ Specify a default collation.
collateClause :: TestItem
collateClause = Group "collate clause"
$ map (uncurry (TestScalarExpr ansi2011))
$ map (uncurry (testScalarExpr ansi2011))
[("a collate my_collation"
,Collate (Iden [Name Nothing "a"]) [Name Nothing "my_collation"])]
@ -4386,7 +4366,7 @@ Specify a value computed from a collection of rows.
aggregateFunction :: TestItem
aggregateFunction = Group "aggregate function"
$ map (uncurry (TestScalarExpr ansi2011)) $
$ map (uncurry (testScalarExpr ansi2011)) $
[("count(*)",App [Name Nothing "count"] [Star])
,("count(*) filter (where something > 5)"
,AggregateApp [Name Nothing "count"] SQDefault [Star] [] fil)
@ -4483,7 +4463,7 @@ Specify a sort order.
sortSpecificationList :: TestItem
sortSpecificationList = Group "sort specification list"
$ map (uncurry (TestQueryExpr ansi2011))
$ map (uncurry (testQueryExpr ansi2011))
[("select * from t order by a"
,toQueryExpr $ ms {msOrderBy = [SortSpec (Iden [Name Nothing "a"])
DirDefault NullsOrderDefault]})
@ -4518,3 +4498,10 @@ sortSpecificationList = Group "sort specification list"
ms = makeSelect
{msSelectList = [(Star,Nothing)]
,msFrom = [TRSimple [Name Nothing "t"]]}
q :: HasCallStack => Text -> QueryExpr -> TestItem
q src ast = testQueryExpr ansi2011 src ast
e :: HasCallStack => Text -> ScalarExpr -> TestItem
e src ast = testScalarExpr ansi2011 src ast

View file

@ -10,6 +10,8 @@ module Language.SQL.SimpleSQL.SQL2011Schema (sql2011SchemaTests) where
import Language.SQL.SimpleSQL.TestTypes
import Language.SQL.SimpleSQL.Syntax
import Language.SQL.SimpleSQL.TestRunners
import Data.Text (Text)
sql2011SchemaTests :: TestItem
sql2011SchemaTests = Group "sql 2011 schema tests"
@ -25,8 +27,8 @@ sql2011SchemaTests = Group "sql 2011 schema tests"
[ <schema element>... ]
-}
(TestStatement ansi2011 "create schema my_schema"
$ CreateSchema [Name Nothing "my_schema"])
s "create schema my_schema"
$ CreateSchema [Name Nothing "my_schema"]
{-
todo: schema name can have .
@ -86,12 +88,12 @@ add schema element support:
-}
,(TestStatement ansi2011 "drop schema my_schema"
$ DropSchema [Name Nothing "my_schema"] DefaultDropBehaviour)
,(TestStatement ansi2011 "drop schema my_schema cascade"
$ DropSchema [Name Nothing "my_schema"] Cascade)
,(TestStatement ansi2011 "drop schema my_schema restrict"
$ DropSchema [Name Nothing "my_schema"] Restrict)
,s "drop schema my_schema"
$ DropSchema [Name Nothing "my_schema"] DefaultDropBehaviour
,s "drop schema my_schema cascade"
$ DropSchema [Name Nothing "my_schema"] Cascade
,s "drop schema my_schema restrict"
$ DropSchema [Name Nothing "my_schema"] Restrict
{-
11.3 <table definition>
@ -103,10 +105,10 @@ add schema element support:
[ ON COMMIT <table commit action> ROWS ]
-}
,(TestStatement ansi2011 "create table t (a int, b int);"
,s "create table t (a int, b int);"
$ CreateTable [Name Nothing "t"]
[TableColumnDef $ ColumnDef (Name Nothing "a") (TypeName [Name Nothing "int"]) Nothing []
,TableColumnDef $ ColumnDef (Name Nothing "b") (TypeName [Name Nothing "int"]) Nothing []])
,TableColumnDef $ ColumnDef (Name Nothing "b") (TypeName [Name Nothing "int"]) Nothing []]
{-
@ -321,35 +323,35 @@ todo: constraint characteristics
-}
,(TestStatement ansi2011
,s
"create table t (a int not null);"
$ CreateTable [Name Nothing "t"]
[TableColumnDef $ ColumnDef (Name Nothing "a") (TypeName [Name Nothing "int"]) Nothing
[ColConstraintDef Nothing ColNotNullConstraint]])
[ColConstraintDef Nothing ColNotNullConstraint]]
,(TestStatement ansi2011
,s
"create table t (a int constraint a_not_null not null);"
$ CreateTable [Name Nothing "t"]
[TableColumnDef $ ColumnDef (Name Nothing "a") (TypeName [Name Nothing "int"]) Nothing
[ColConstraintDef (Just [Name Nothing "a_not_null"]) ColNotNullConstraint]])
[ColConstraintDef (Just [Name Nothing "a_not_null"]) ColNotNullConstraint]]
,(TestStatement ansi2011
,s
"create table t (a int unique);"
$ CreateTable [Name Nothing "t"]
[TableColumnDef $ ColumnDef (Name Nothing "a") (TypeName [Name Nothing "int"]) Nothing
[ColConstraintDef Nothing ColUniqueConstraint]])
[ColConstraintDef Nothing ColUniqueConstraint]]
,(TestStatement ansi2011
,s
"create table t (a int primary key);"
$ CreateTable [Name Nothing "t"]
[TableColumnDef $ ColumnDef (Name Nothing "a") (TypeName [Name Nothing "int"]) Nothing
[ColConstraintDef Nothing (ColPrimaryKeyConstraint False)]])
[ColConstraintDef Nothing (ColPrimaryKeyConstraint False)]]
,(TestStatement ansi2011 { diAutoincrement = True }
,testStatement ansi2011{ diAutoincrement = True }
"create table t (a int primary key autoincrement);"
$ CreateTable [Name Nothing "t"]
[TableColumnDef $ ColumnDef (Name Nothing "a") (TypeName [Name Nothing "int"]) Nothing
[ColConstraintDef Nothing (ColPrimaryKeyConstraint True)]])
[ColConstraintDef Nothing (ColPrimaryKeyConstraint True)]]
{-
references t(a,b)
@ -358,102 +360,102 @@ references t(a,b)
on delete ""
-}
,(TestStatement ansi2011
,s
"create table t (a int references u);"
$ CreateTable [Name Nothing "t"]
[TableColumnDef $ ColumnDef (Name Nothing "a") (TypeName [Name Nothing "int"]) Nothing
[ColConstraintDef Nothing $ ColReferencesConstraint
[Name Nothing "u"] Nothing DefaultReferenceMatch
DefaultReferentialAction DefaultReferentialAction]])
DefaultReferentialAction DefaultReferentialAction]]
,(TestStatement ansi2011
,s
"create table t (a int references u(a));"
$ CreateTable [Name Nothing "t"]
[TableColumnDef $ ColumnDef (Name Nothing "a") (TypeName [Name Nothing "int"]) Nothing
[ColConstraintDef Nothing $ ColReferencesConstraint
[Name Nothing "u"] (Just $ Name Nothing "a") DefaultReferenceMatch
DefaultReferentialAction DefaultReferentialAction]])
DefaultReferentialAction DefaultReferentialAction]]
,(TestStatement ansi2011
,s
"create table t (a int references u match full);"
$ CreateTable [Name Nothing "t"]
[TableColumnDef $ ColumnDef (Name Nothing "a") (TypeName [Name Nothing "int"]) Nothing
[ColConstraintDef Nothing $ ColReferencesConstraint
[Name Nothing "u"] Nothing MatchFull
DefaultReferentialAction DefaultReferentialAction]])
DefaultReferentialAction DefaultReferentialAction]]
,(TestStatement ansi2011
,s
"create table t (a int references u match partial);"
$ CreateTable [Name Nothing "t"]
[TableColumnDef $ ColumnDef (Name Nothing "a") (TypeName [Name Nothing "int"]) Nothing
[ColConstraintDef Nothing $ ColReferencesConstraint
[Name Nothing "u"] Nothing MatchPartial
DefaultReferentialAction DefaultReferentialAction]])
DefaultReferentialAction DefaultReferentialAction]]
,(TestStatement ansi2011
,s
"create table t (a int references u match simple);"
$ CreateTable [Name Nothing "t"]
[TableColumnDef $ ColumnDef (Name Nothing "a") (TypeName [Name Nothing "int"]) Nothing
[ColConstraintDef Nothing $ ColReferencesConstraint
[Name Nothing "u"] Nothing MatchSimple
DefaultReferentialAction DefaultReferentialAction]])
DefaultReferentialAction DefaultReferentialAction]]
,(TestStatement ansi2011
,s
"create table t (a int references u on update cascade );"
$ CreateTable [Name Nothing "t"]
[TableColumnDef $ ColumnDef (Name Nothing "a") (TypeName [Name Nothing "int"]) Nothing
[ColConstraintDef Nothing $ ColReferencesConstraint
[Name Nothing "u"] Nothing DefaultReferenceMatch
RefCascade DefaultReferentialAction]])
RefCascade DefaultReferentialAction]]
,(TestStatement ansi2011
,s
"create table t (a int references u on update set null );"
$ CreateTable [Name Nothing "t"]
[TableColumnDef $ ColumnDef (Name Nothing "a") (TypeName [Name Nothing "int"]) Nothing
[ColConstraintDef Nothing $ ColReferencesConstraint
[Name Nothing "u"] Nothing DefaultReferenceMatch
RefSetNull DefaultReferentialAction]])
RefSetNull DefaultReferentialAction]]
,(TestStatement ansi2011
,s
"create table t (a int references u on update set default );"
$ CreateTable [Name Nothing "t"]
[TableColumnDef $ ColumnDef (Name Nothing "a") (TypeName [Name Nothing "int"]) Nothing
[ColConstraintDef Nothing $ ColReferencesConstraint
[Name Nothing "u"] Nothing DefaultReferenceMatch
RefSetDefault DefaultReferentialAction]])
RefSetDefault DefaultReferentialAction]]
,(TestStatement ansi2011
,s
"create table t (a int references u on update no action );"
$ CreateTable [Name Nothing "t"]
[TableColumnDef $ ColumnDef (Name Nothing "a") (TypeName [Name Nothing "int"]) Nothing
[ColConstraintDef Nothing $ ColReferencesConstraint
[Name Nothing "u"] Nothing DefaultReferenceMatch
RefNoAction DefaultReferentialAction]])
RefNoAction DefaultReferentialAction]]
,(TestStatement ansi2011
,s
"create table t (a int references u on delete cascade );"
$ CreateTable [Name Nothing "t"]
[TableColumnDef $ ColumnDef (Name Nothing "a") (TypeName [Name Nothing "int"]) Nothing
[ColConstraintDef Nothing $ ColReferencesConstraint
[Name Nothing "u"] Nothing DefaultReferenceMatch
DefaultReferentialAction RefCascade]])
DefaultReferentialAction RefCascade]]
,(TestStatement ansi2011
,s
"create table t (a int references u on update cascade on delete restrict );"
$ CreateTable [Name Nothing "t"]
[TableColumnDef $ ColumnDef (Name Nothing "a") (TypeName [Name Nothing "int"]) Nothing
[ColConstraintDef Nothing $ ColReferencesConstraint
[Name Nothing "u"] Nothing DefaultReferenceMatch
RefCascade RefRestrict]])
RefCascade RefRestrict]]
,(TestStatement ansi2011
,s
"create table t (a int references u on delete restrict on update cascade );"
$ CreateTable [Name Nothing "t"]
[TableColumnDef $ ColumnDef (Name Nothing "a") (TypeName [Name Nothing "int"]) Nothing
[ColConstraintDef Nothing $ ColReferencesConstraint
[Name Nothing "u"] Nothing DefaultReferenceMatch
RefCascade RefRestrict]])
RefCascade RefRestrict]]
{-
TODO: try combinations and permutations of column constraints and
@ -461,12 +463,12 @@ options
-}
,(TestStatement ansi2011
,s
"create table t (a int check (a>5));"
$ CreateTable [Name Nothing "t"]
[TableColumnDef $ ColumnDef (Name Nothing "a") (TypeName [Name Nothing "int"]) Nothing
[ColConstraintDef Nothing
(ColCheckConstraint $ BinOp (Iden [Name Nothing "a"]) [Name Nothing ">"] (NumLit "5"))]])
(ColCheckConstraint $ BinOp (Iden [Name Nothing "a"]) [Name Nothing ">"] (NumLit "5"))]]
@ -478,18 +480,18 @@ options
[ <left paren> <common sequence generator options> <right paren> ]
-}
,(TestStatement ansi2011 "create table t (a int generated always as identity);"
,s "create table t (a int generated always as identity);"
$ CreateTable [Name Nothing "t"]
[TableColumnDef $ ColumnDef (Name Nothing "a") (TypeName [Name Nothing "int"])
(Just $ IdentityColumnSpec GeneratedAlways []) []])
(Just $ IdentityColumnSpec GeneratedAlways []) []]
,(TestStatement ansi2011 "create table t (a int generated by default as identity);"
,s "create table t (a int generated by default as identity);"
$ CreateTable [Name Nothing "t"]
[TableColumnDef $ ColumnDef (Name Nothing "a") (TypeName [Name Nothing "int"])
(Just $ IdentityColumnSpec GeneratedByDefault []) []])
(Just $ IdentityColumnSpec GeneratedByDefault []) []]
,(TestStatement ansi2011
,s
"create table t (a int generated always as identity\n\
\ ( start with 5 increment by 5 maxvalue 500 minvalue 5 cycle ));"
$ CreateTable [Name Nothing "t"]
@ -499,9 +501,9 @@ options
,SGOIncrementBy 5
,SGOMaxValue 500
,SGOMinValue 5
,SGOCycle]) []])
,SGOCycle]) []]
,(TestStatement ansi2011
,s
"create table t (a int generated always as identity\n\
\ ( start with -4 no maxvalue no minvalue no cycle ));"
$ CreateTable [Name Nothing "t"]
@ -510,7 +512,7 @@ options
[SGOStartWith (-4)
,SGONoMaxValue
,SGONoMinValue
,SGONoCycle]) []])
,SGONoCycle]) []]
{-
I think <common sequence generator options> is supposed to just
@ -531,14 +533,14 @@ generated always (valueexpr)
<left paren> <value expression> <right paren>
-}
,(TestStatement ansi2011
,s
"create table t (a int, \n\
\ a2 int generated always as (a * 2));"
$ CreateTable [Name Nothing "t"]
[TableColumnDef $ ColumnDef (Name Nothing "a") (TypeName [Name Nothing "int"]) Nothing []
,TableColumnDef $ ColumnDef (Name Nothing "a2") (TypeName [Name Nothing "int"])
(Just $ GenerationClause
(BinOp (Iden [Name Nothing "a"]) [Name Nothing "*"] (NumLit "2"))) []])
(BinOp (Iden [Name Nothing "a"]) [Name Nothing "*"] (NumLit "2"))) []]
@ -563,10 +565,10 @@ generated always (valueexpr)
-}
,(TestStatement ansi2011 "create table t (a int default 0);"
,s "create table t (a int default 0);"
$ CreateTable [Name Nothing "t"]
[TableColumnDef $ ColumnDef (Name Nothing "a") (TypeName [Name Nothing "int"])
(Just $ DefaultClause $ NumLit "0") []])
(Just $ DefaultClause $ NumLit "0") []]
@ -597,40 +599,40 @@ generated always (valueexpr)
<column name list>
-}
,(TestStatement ansi2011
,s
"create table t (a int, unique (a));"
$ CreateTable [Name Nothing "t"]
[TableColumnDef $ ColumnDef (Name Nothing "a") (TypeName [Name Nothing "int"]) Nothing []
,TableConstraintDef Nothing $ TableUniqueConstraint [Name Nothing "a"]
])
]
,(TestStatement ansi2011
,s
"create table t (a int, constraint a_unique unique (a));"
$ CreateTable [Name Nothing "t"]
[TableColumnDef $ ColumnDef (Name Nothing "a") (TypeName [Name Nothing "int"]) Nothing []
,TableConstraintDef (Just [Name Nothing "a_unique"]) $
TableUniqueConstraint [Name Nothing "a"]
])
]
-- todo: test permutations of column defs and table constraints
,(TestStatement ansi2011
,s
"create table t (a int, b int, unique (a,b));"
$ CreateTable [Name Nothing "t"]
[TableColumnDef $ ColumnDef (Name Nothing "a") (TypeName [Name Nothing "int"]) Nothing []
,TableColumnDef $ ColumnDef (Name Nothing "b") (TypeName [Name Nothing "int"]) Nothing []
,TableConstraintDef Nothing $
TableUniqueConstraint [Name Nothing "a", Name Nothing "b"]
])
]
,(TestStatement ansi2011
,s
"create table t (a int, b int, primary key (a,b));"
$ CreateTable [Name Nothing "t"]
[TableColumnDef $ ColumnDef (Name Nothing "a") (TypeName [Name Nothing "int"]) Nothing []
,TableColumnDef $ ColumnDef (Name Nothing "b") (TypeName [Name Nothing "int"]) Nothing []
,TableConstraintDef Nothing $
TablePrimaryKeyConstraint [Name Nothing "a", Name Nothing "b"]
])
]
{-
@ -649,7 +651,7 @@ defintely skip
-}
,(TestStatement ansi2011
,s
"create table t (a int, b int,\n\
\ foreign key (a,b) references u(c,d) match full on update cascade on delete restrict );"
$ CreateTable [Name Nothing "t"]
@ -661,9 +663,9 @@ defintely skip
[Name Nothing "u"]
(Just [Name Nothing "c", Name Nothing "d"])
MatchFull RefCascade RefRestrict
])
]
,(TestStatement ansi2011
,s
"create table t (a int,\n\
\ constraint tfku1 foreign key (a) references u);"
$ CreateTable [Name Nothing "t"]
@ -674,9 +676,9 @@ defintely skip
[Name Nothing "u"]
Nothing DefaultReferenceMatch
DefaultReferentialAction DefaultReferentialAction
])
]
,(TestStatement ansi2011 { diNonCommaSeparatedConstraints = True }
,testStatement ansi2011{ diNonCommaSeparatedConstraints = True }
"create table t (a int, b int,\n\
\ foreign key (a) references u(c)\n\
\ foreign key (b) references v(d));"
@ -697,7 +699,7 @@ defintely skip
(Just [Name Nothing "d"])
DefaultReferenceMatch
DefaultReferentialAction DefaultReferentialAction
])
]
{-
@ -755,7 +757,7 @@ defintely skip
CHECK <left paren> <search condition> <right paren>
-}
,(TestStatement ansi2011
,s
"create table t (a int, b int, \n\
\ check (a > b));"
$ CreateTable [Name Nothing "t"]
@ -764,10 +766,10 @@ defintely skip
,TableConstraintDef Nothing $
TableCheckConstraint
(BinOp (Iden [Name Nothing "a"]) [Name Nothing ">"] (Iden [Name Nothing "b"]))
])
]
,(TestStatement ansi2011
,s
"create table t (a int, b int, \n\
\ constraint agtb check (a > b));"
$ CreateTable [Name Nothing "t"]
@ -776,7 +778,7 @@ defintely skip
,TableConstraintDef (Just [Name Nothing "agtb"]) $
TableCheckConstraint
(BinOp (Iden [Name Nothing "a"]) [Name Nothing ">"] (Iden [Name Nothing "b"]))
])
]
{-
@ -810,11 +812,10 @@ alter table t add a int
alter table t add a int unique not null check (a>0)
-}
,(TestStatement ansi2011
,s
"alter table t add column a int"
$ AlterTable [Name Nothing "t"] $ AddColumnDef
$ ColumnDef (Name Nothing "a") (TypeName [Name Nothing "int"]) Nothing []
)
{-
todo: more add column
@ -844,10 +845,10 @@ todo: more add column
-}
,(TestStatement ansi2011
,s
"alter table t alter column c set default 0"
$ AlterTable [Name Nothing "t"] $ AlterColumnSetDefault (Name Nothing "c")
$ NumLit "0")
$ NumLit "0"
{-
11.14 <drop column default clause>
@ -856,9 +857,9 @@ todo: more add column
DROP DEFAULT
-}
,(TestStatement ansi2011
,s
"alter table t alter column c drop default"
$ AlterTable [Name Nothing "t"] $ AlterColumnDropDefault (Name Nothing "c"))
$ AlterTable [Name Nothing "t"] $ AlterColumnDropDefault (Name Nothing "c")
{-
@ -868,9 +869,9 @@ todo: more add column
SET NOT NULL
-}
,(TestStatement ansi2011
,s
"alter table t alter column c set not null"
$ AlterTable [Name Nothing "t"] $ AlterColumnSetNotNull (Name Nothing "c"))
$ AlterTable [Name Nothing "t"] $ AlterColumnSetNotNull (Name Nothing "c")
{-
11.16 <drop column not null clause>
@ -879,9 +880,9 @@ todo: more add column
DROP NOT NULL
-}
,(TestStatement ansi2011
,s
"alter table t alter column c drop not null"
$ AlterTable [Name Nothing "t"] $ AlterColumnDropNotNull (Name Nothing "c"))
$ AlterTable [Name Nothing "t"] $ AlterColumnDropNotNull (Name Nothing "c")
{-
11.17 <add column scope clause>
@ -900,10 +901,10 @@ todo: more add column
SET DATA TYPE <data type>
-}
,(TestStatement ansi2011
,s
"alter table t alter column c set data type int;"
$ AlterTable [Name Nothing "t"] $
AlterColumnSetDataType (Name Nothing "c") (TypeName [Name Nothing "int"]))
AlterColumnSetDataType (Name Nothing "c") (TypeName [Name Nothing "int"])
@ -1001,20 +1002,20 @@ included in the generated plan above
DROP [ COLUMN ] <column name> <drop behavior>
-}
,(TestStatement ansi2011
,s
"alter table t drop column c"
$ AlterTable [Name Nothing "t"] $
DropColumn (Name Nothing "c") DefaultDropBehaviour)
DropColumn (Name Nothing "c") DefaultDropBehaviour
,(TestStatement ansi2011
,s
"alter table t drop c cascade"
$ AlterTable [Name Nothing "t"] $
DropColumn (Name Nothing "c") Cascade)
DropColumn (Name Nothing "c") Cascade
,(TestStatement ansi2011
,s
"alter table t drop c restrict"
$ AlterTable [Name Nothing "t"] $
DropColumn (Name Nothing "c") Restrict)
DropColumn (Name Nothing "c") Restrict
@ -1025,17 +1026,17 @@ included in the generated plan above
ADD <table constraint definition>
-}
,(TestStatement ansi2011
,s
"alter table t add constraint c unique (a,b)"
$ AlterTable [Name Nothing "t"] $
AddTableConstraintDef (Just [Name Nothing "c"])
$ TableUniqueConstraint [Name Nothing "a", Name Nothing "b"])
$ TableUniqueConstraint [Name Nothing "a", Name Nothing "b"]
,(TestStatement ansi2011
,s
"alter table t add unique (a,b)"
$ AlterTable [Name Nothing "t"] $
AddTableConstraintDef Nothing
$ TableUniqueConstraint [Name Nothing "a", Name Nothing "b"])
$ TableUniqueConstraint [Name Nothing "a", Name Nothing "b"]
{-
@ -1051,15 +1052,15 @@ todo
DROP CONSTRAINT <constraint name> <drop behavior>
-}
,(TestStatement ansi2011
,s
"alter table t drop constraint c"
$ AlterTable [Name Nothing "t"] $
DropTableConstraintDef [Name Nothing "c"] DefaultDropBehaviour)
DropTableConstraintDef [Name Nothing "c"] DefaultDropBehaviour
,(TestStatement ansi2011
,s
"alter table t drop constraint c restrict"
$ AlterTable [Name Nothing "t"] $
DropTableConstraintDef [Name Nothing "c"] Restrict)
DropTableConstraintDef [Name Nothing "c"] Restrict
{-
11.27 <add table period definition>
@ -1111,13 +1112,13 @@ defintely skip
DROP TABLE <table name> <drop behavior>
-}
,(TestStatement ansi2011
,s
"drop table t"
$ DropTable [Name Nothing "t"] DefaultDropBehaviour)
$ DropTable [Name Nothing "t"] DefaultDropBehaviour
,(TestStatement ansi2011
,s
"drop table t restrict"
$ DropTable [Name Nothing "t"] Restrict)
$ DropTable [Name Nothing "t"] Restrict
{-
@ -1159,51 +1160,51 @@ defintely skip
<column name list>
-}
,(TestStatement ansi2011
,s
"create view v as select * from t"
$ CreateView False [Name Nothing "v"] Nothing (toQueryExpr $ makeSelect
{msSelectList = [(Star, Nothing)]
,msFrom = [TRSimple [Name Nothing "t"]]
}) Nothing)
}) Nothing
,(TestStatement ansi2011
,s
"create recursive view v as select * from t"
$ CreateView True [Name Nothing "v"] Nothing (toQueryExpr $ makeSelect
{msSelectList = [(Star, Nothing)]
,msFrom = [TRSimple [Name Nothing "t"]]
}) Nothing)
}) Nothing
,(TestStatement ansi2011
,s
"create view v(a,b) as select * from t"
$ CreateView False [Name Nothing "v"] (Just [Name Nothing "a", Name Nothing "b"])
(toQueryExpr $ makeSelect
{msSelectList = [(Star, Nothing)]
,msFrom = [TRSimple [Name Nothing "t"]]
}) Nothing)
}) Nothing
,(TestStatement ansi2011
,s
"create view v as select * from t with check option"
$ CreateView False [Name Nothing "v"] Nothing (toQueryExpr $ makeSelect
{msSelectList = [(Star, Nothing)]
,msFrom = [TRSimple [Name Nothing "t"]]
}) (Just DefaultCheckOption))
}) (Just DefaultCheckOption)
,(TestStatement ansi2011
,s
"create view v as select * from t with cascaded check option"
$ CreateView False [Name Nothing "v"] Nothing (toQueryExpr $ makeSelect
{msSelectList = [(Star, Nothing)]
,msFrom = [TRSimple [Name Nothing "t"]]
}) (Just CascadedCheckOption))
}) (Just CascadedCheckOption)
,(TestStatement ansi2011
,s
"create view v as select * from t with local check option"
$ CreateView False [Name Nothing "v"] Nothing
(toQueryExpr $ makeSelect
{msSelectList = [(Star, Nothing)]
,msFrom = [TRSimple [Name Nothing "t"]]
}) (Just LocalCheckOption))
}) (Just LocalCheckOption)
{-
@ -1214,13 +1215,13 @@ defintely skip
-}
,(TestStatement ansi2011
,s
"drop view v"
$ DropView [Name Nothing "v"] DefaultDropBehaviour)
$ DropView [Name Nothing "v"] DefaultDropBehaviour
,(TestStatement ansi2011
,s
"drop view v cascade"
$ DropView [Name Nothing "v"] Cascade)
$ DropView [Name Nothing "v"] Cascade
{-
@ -1237,37 +1238,37 @@ defintely skip
<constraint characteristics> ]
-}
,(TestStatement ansi2011
,s
"create domain my_int int"
$ CreateDomain [Name Nothing "my_int"]
(TypeName [Name Nothing "int"])
Nothing [])
Nothing []
,(TestStatement ansi2011
,s
"create domain my_int as int"
$ CreateDomain [Name Nothing "my_int"]
(TypeName [Name Nothing "int"])
Nothing [])
Nothing []
,(TestStatement ansi2011
,s
"create domain my_int int default 0"
$ CreateDomain [Name Nothing "my_int"]
(TypeName [Name Nothing "int"])
(Just (NumLit "0")) [])
(Just (NumLit "0")) []
,(TestStatement ansi2011
,s
"create domain my_int int check (value > 5)"
$ CreateDomain [Name Nothing "my_int"]
(TypeName [Name Nothing "int"])
Nothing [(Nothing
,BinOp (Iden [Name Nothing "value"]) [Name Nothing ">"] (NumLit "5"))])
,BinOp (Iden [Name Nothing "value"]) [Name Nothing ">"] (NumLit "5"))]
,(TestStatement ansi2011
,s
"create domain my_int int constraint gt5 check (value > 5)"
$ CreateDomain [Name Nothing "my_int"]
(TypeName [Name Nothing "int"])
Nothing [(Just [Name Nothing "gt5"]
,BinOp (Iden [Name Nothing "value"]) [Name Nothing ">"] (NumLit "5"))])
,BinOp (Iden [Name Nothing "value"]) [Name Nothing ">"] (NumLit "5"))]
@ -1289,10 +1290,10 @@ defintely skip
SET <default clause>
-}
,(TestStatement ansi2011
,s
"alter domain my_int set default 0"
$ AlterDomain [Name Nothing "my_int"]
$ ADSetDefault $ NumLit "0")
$ ADSetDefault $ NumLit "0"
{-
@ -1302,10 +1303,10 @@ defintely skip
DROP DEFAULT
-}
,(TestStatement ansi2011
,s
"alter domain my_int drop default"
$ AlterDomain [Name Nothing "my_int"]
$ ADDropDefault)
$ ADDropDefault
{-
@ -1315,17 +1316,17 @@ defintely skip
ADD <domain constraint>
-}
,(TestStatement ansi2011
,s
"alter domain my_int add check (value > 6)"
$ AlterDomain [Name Nothing "my_int"]
$ ADAddConstraint Nothing
$ BinOp (Iden [Name Nothing "value"]) [Name Nothing ">"] (NumLit "6"))
$ BinOp (Iden [Name Nothing "value"]) [Name Nothing ">"] (NumLit "6")
,(TestStatement ansi2011
,s
"alter domain my_int add constraint gt6 check (value > 6)"
$ AlterDomain [Name Nothing "my_int"]
$ ADAddConstraint (Just [Name Nothing "gt6"])
$ BinOp (Iden [Name Nothing "value"]) [Name Nothing ">"] (NumLit "6"))
$ BinOp (Iden [Name Nothing "value"]) [Name Nothing ">"] (NumLit "6")
{-
@ -1335,10 +1336,10 @@ defintely skip
DROP CONSTRAINT <constraint name>
-}
,(TestStatement ansi2011
,s
"alter domain my_int drop constraint gt6"
$ AlterDomain [Name Nothing "my_int"]
$ ADDropConstraint [Name Nothing "gt6"])
$ ADDropConstraint [Name Nothing "gt6"]
{-
11.40 <drop domain statement>
@ -1347,13 +1348,13 @@ defintely skip
DROP DOMAIN <domain name> <drop behavior>
-}
,(TestStatement ansi2011
,s
"drop domain my_int"
$ DropDomain [Name Nothing "my_int"] DefaultDropBehaviour)
$ DropDomain [Name Nothing "my_int"] DefaultDropBehaviour
,(TestStatement ansi2011
,s
"drop domain my_int cascade"
$ DropDomain [Name Nothing "my_int"] Cascade)
$ DropDomain [Name Nothing "my_int"] Cascade
@ -1425,7 +1426,7 @@ defintely skip
[ <constraint characteristics> ]
-}
,(TestStatement ansi2011
,s
"create assertion t1_not_empty CHECK ((select count(*) from t1) > 0);"
$ CreateAssertion [Name Nothing "t1_not_empty"]
$ BinOp (SubQueryExpr SqSq $
@ -1433,7 +1434,7 @@ defintely skip
{msSelectList = [(App [Name Nothing "count"] [Star],Nothing)]
,msFrom = [TRSimple [Name Nothing "t1"]]
})
[Name Nothing ">"] (NumLit "0"))
[Name Nothing ">"] (NumLit "0")
{-
11.48 <drop assertion statement>
@ -1442,13 +1443,13 @@ defintely skip
DROP ASSERTION <constraint name> [ <drop behavior> ]
-}
,(TestStatement ansi2011
,s
"drop assertion t1_not_empty;"
$ DropAssertion [Name Nothing "t1_not_empty"] DefaultDropBehaviour)
$ DropAssertion [Name Nothing "t1_not_empty"] DefaultDropBehaviour
,(TestStatement ansi2011
,s
"drop assertion t1_not_empty cascade;"
$ DropAssertion [Name Nothing "t1_not_empty"] Cascade)
$ DropAssertion [Name Nothing "t1_not_empty"] Cascade
{-
@ -2085,21 +2086,21 @@ defintely skip
| NO CYCLE
-}
,(TestStatement ansi2011
,s
"create sequence seq"
$ CreateSequence [Name Nothing "seq"] [])
$ CreateSequence [Name Nothing "seq"] []
,(TestStatement ansi2011
,s
"create sequence seq as bigint"
$ CreateSequence [Name Nothing "seq"]
[SGODataType $ TypeName [Name Nothing "bigint"]])
[SGODataType $ TypeName [Name Nothing "bigint"]]
,(TestStatement ansi2011
,s
"create sequence seq as bigint start with 5"
$ CreateSequence [Name Nothing "seq"]
[SGOStartWith 5
,SGODataType $ TypeName [Name Nothing "bigint"]
])
]
{-
@ -2122,21 +2123,21 @@ defintely skip
<signed numeric literal>
-}
,(TestStatement ansi2011
,s
"alter sequence seq restart"
$ AlterSequence [Name Nothing "seq"]
[SGORestart Nothing])
[SGORestart Nothing]
,(TestStatement ansi2011
,s
"alter sequence seq restart with 5"
$ AlterSequence [Name Nothing "seq"]
[SGORestart $ Just 5])
[SGORestart $ Just 5]
,(TestStatement ansi2011
,s
"alter sequence seq restart with 5 increment by 5"
$ AlterSequence [Name Nothing "seq"]
[SGORestart $ Just 5
,SGOIncrementBy 5])
,SGOIncrementBy 5]
{-
@ -2146,13 +2147,16 @@ defintely skip
DROP SEQUENCE <sequence generator name> <drop behavior>
-}
,(TestStatement ansi2011
,s
"drop sequence seq"
$ DropSequence [Name Nothing "seq"] DefaultDropBehaviour)
$ DropSequence [Name Nothing "seq"] DefaultDropBehaviour
,(TestStatement ansi2011
,s
"drop sequence seq restrict"
$ DropSequence [Name Nothing "seq"] Restrict)
$ DropSequence [Name Nothing "seq"] Restrict
]
s :: HasCallStack => Text -> Statement -> TestItem
s src ast = testStatement ansi2011 src ast

View file

@ -6,6 +6,9 @@ module Language.SQL.SimpleSQL.ScalarExprs (scalarExprTests) where
import Language.SQL.SimpleSQL.TestTypes
import Language.SQL.SimpleSQL.Syntax
import Language.SQL.SimpleSQL.TestRunners
import Data.Text (Text)
scalarExprTests :: TestItem
scalarExprTests = Group "scalarExprTests"
@ -25,101 +28,108 @@ scalarExprTests = Group "scalarExprTests"
,functionsWithReservedNames
]
literals :: TestItem
literals = Group "literals" $ map (uncurry (TestScalarExpr ansi2011))
[("3", NumLit "3")
,("3.", NumLit "3.")
,("3.3", NumLit "3.3")
,(".3", NumLit ".3")
,("3.e3", NumLit "3.e3")
,("3.3e3", NumLit "3.3e3")
,(".3e3", NumLit ".3e3")
,("3e3", NumLit "3e3")
,("3e+3", NumLit "3e+3")
,("3e-3", NumLit "3e-3")
,("'string'", StringLit "'" "'" "string")
,("'string with a '' quote'", StringLit "'" "'" "string with a '' quote")
,("'1'", StringLit "'" "'" "1")
,("interval '3' day"
,IntervalLit Nothing "3" (Itf "day" Nothing) Nothing)
,("interval '3' day (3)"
,IntervalLit Nothing "3" (Itf "day" $ Just (3,Nothing)) Nothing)
,("interval '3 weeks'", TypedLit (TypeName [Name Nothing "interval"]) "3 weeks")
]
t :: HasCallStack => Text -> ScalarExpr -> TestItem
t src ast = testScalarExpr ansi2011 src ast
td :: HasCallStack => Dialect -> Text -> ScalarExpr -> TestItem
td d src ast = testScalarExpr d src ast
literals :: TestItem
literals = Group "literals"
[t "3" $ NumLit "3"
,t "3." $ NumLit "3."
,t "3.3" $ NumLit "3.3"
,t ".3" $ NumLit ".3"
,t "3.e3" $ NumLit "3.e3"
,t "3.3e3" $ NumLit "3.3e3"
,t ".3e3" $ NumLit ".3e3"
,t "3e3" $ NumLit "3e3"
,t "3e+3" $ NumLit "3e+3"
,t "3e-3" $ NumLit "3e-3"
,t "'string'" $ StringLit "'" "'" "string"
,t "'string with a '' quote'" $ StringLit "'" "'" "string with a '' quote"
,t "'1'" $ StringLit "'" "'" "1"
,t "interval '3' day"
$ IntervalLit Nothing "3" (Itf "day" Nothing) Nothing
,t "interval '3' day (3)"
$ IntervalLit Nothing "3" (Itf "day" $ Just (3,Nothing)) Nothing
,t "interval '3 weeks'" $ TypedLit (TypeName [Name Nothing "interval"]) "3 weeks"
]
identifiers :: TestItem
identifiers = Group "identifiers" $ map (uncurry (TestScalarExpr ansi2011))
[("iden1", Iden [Name Nothing "iden1"])
identifiers = Group "identifiers"
[t "iden1" $ Iden [Name Nothing "iden1"]
--,("t.a", Iden2 "t" "a")
,("\"quoted identifier\"", Iden [Name (Just ("\"","\"")) "quoted identifier"])
,("\"from\"", Iden [Name (Just ("\"","\"")) "from"])
,t "\"quoted identifier\"" $ Iden [Name (Just ("\"","\"")) "quoted identifier"]
,t "\"from\"" $ Iden [Name (Just ("\"","\"")) "from"]
]
star :: TestItem
star = Group "star" $ map (uncurry (TestScalarExpr ansi2011))
[("*", Star)
star = Group "star"
[t "*" Star
--,("t.*", Star2 "t")
--,("ROW(t.*,42)", App "ROW" [Star2 "t", NumLit "42"])
]
parameter :: TestItem
parameter = Group "parameter"
[TestScalarExpr ansi2011 "?" Parameter
,TestScalarExpr postgres "$13" $ PositionalArg 13]
[td ansi2011 "?" Parameter
,td postgres "$13" $ PositionalArg 13]
dots :: TestItem
dots = Group "dot" $ map (uncurry (TestScalarExpr ansi2011))
[("t.a", Iden [Name Nothing "t",Name Nothing "a"])
,("t.*", BinOp (Iden [Name Nothing "t"]) [Name Nothing "."] Star)
,("a.b.c", Iden [Name Nothing "a",Name Nothing "b",Name Nothing "c"])
,("ROW(t.*,42)", App [Name Nothing "ROW"] [BinOp (Iden [Name Nothing "t"]) [Name Nothing "."] Star, NumLit "42"])
dots = Group "dot"
[t "t.a" $ Iden [Name Nothing "t",Name Nothing "a"]
,t "t.*" $ BinOp (Iden [Name Nothing "t"]) [Name Nothing "."] Star
,t "a.b.c" $ Iden [Name Nothing "a",Name Nothing "b",Name Nothing "c"]
,t "ROW(t.*,42)"
$ App [Name Nothing "ROW"] [BinOp (Iden [Name Nothing "t"]) [Name Nothing "."] Star, NumLit "42"]
]
app :: TestItem
app = Group "app" $ map (uncurry (TestScalarExpr ansi2011))
[("f()", App [Name Nothing "f"] [])
,("f(a)", App [Name Nothing "f"] [Iden [Name Nothing "a"]])
,("f(a,b)", App [Name Nothing "f"] [Iden [Name Nothing "a"], Iden [Name Nothing "b"]])
app = Group "app"
[t "f()" $ App [Name Nothing "f"] []
,t "f(a)" $ App [Name Nothing "f"] [Iden [Name Nothing "a"]]
,t "f(a,b)" $ App [Name Nothing "f"] [Iden [Name Nothing "a"], Iden [Name Nothing "b"]]
]
caseexp :: TestItem
caseexp = Group "caseexp" $ map (uncurry (TestScalarExpr ansi2011))
[("case a when 1 then 2 end"
,Case (Just $ Iden [Name Nothing "a"]) [([NumLit "1"]
,NumLit "2")] Nothing)
caseexp = Group "caseexp"
[t "case a when 1 then 2 end"
$ Case (Just $ Iden [Name Nothing "a"]) [([NumLit "1"]
,NumLit "2")] Nothing
,("case a when 1 then 2 when 3 then 4 end"
,Case (Just $ Iden [Name Nothing "a"]) [([NumLit "1"], NumLit "2")
,([NumLit "3"], NumLit "4")] Nothing)
,t "case a when 1 then 2 when 3 then 4 end"
$ Case (Just $ Iden [Name Nothing "a"]) [([NumLit "1"], NumLit "2")
,([NumLit "3"], NumLit "4")] Nothing
,("case a when 1 then 2 when 3 then 4 else 5 end"
,Case (Just $ Iden [Name Nothing "a"]) [([NumLit "1"], NumLit "2")
,t "case a when 1 then 2 when 3 then 4 else 5 end"
$ Case (Just $ Iden [Name Nothing "a"]) [([NumLit "1"], NumLit "2")
,([NumLit "3"], NumLit "4")]
(Just $ NumLit "5"))
(Just $ NumLit "5")
,("case when a=1 then 2 when a=3 then 4 else 5 end"
,Case Nothing [([BinOp (Iden [Name Nothing "a"]) [Name Nothing "="] (NumLit "1")], NumLit "2")
,t "case when a=1 then 2 when a=3 then 4 else 5 end"
$ Case Nothing [([BinOp (Iden [Name Nothing "a"]) [Name Nothing "="] (NumLit "1")], NumLit "2")
,([BinOp (Iden [Name Nothing "a"]) [Name Nothing "="] (NumLit "3")], NumLit "4")]
(Just $ NumLit "5"))
(Just $ NumLit "5")
,("case a when 1,2 then 10 when 3,4 then 20 end"
,Case (Just $ Iden [Name Nothing "a"]) [([NumLit "1",NumLit "2"]
,t "case a when 1,2 then 10 when 3,4 then 20 end"
$ Case (Just $ Iden [Name Nothing "a"]) [([NumLit "1",NumLit "2"]
,NumLit "10")
,([NumLit "3",NumLit "4"]
,NumLit "20")]
Nothing)
Nothing
]
convertfun :: TestItem
convertfun = Group "convert" $ map (uncurry (TestScalarExpr sqlserver))
[("CONVERT(varchar, 25.65)"
,Convert (TypeName [Name Nothing "varchar"]) (NumLit "25.65") Nothing)
,("CONVERT(datetime, '2017-08-25')"
,Convert (TypeName [Name Nothing "datetime"]) (StringLit "'" "'" "2017-08-25") Nothing)
,("CONVERT(varchar, '2017-08-25', 101)"
,Convert (TypeName [Name Nothing "varchar"]) (StringLit "'" "'" "2017-08-25") (Just 101))
convertfun = Group "convert"
[td sqlserver "CONVERT(varchar, 25.65)"
$ Convert (TypeName [Name Nothing "varchar"]) (NumLit "25.65") Nothing
,td sqlserver "CONVERT(datetime, '2017-08-25')"
$ Convert (TypeName [Name Nothing "datetime"]) (StringLit "'" "'" "2017-08-25") Nothing
,td sqlserver "CONVERT(varchar, '2017-08-25', 101)"
$ Convert (TypeName [Name Nothing "varchar"]) (StringLit "'" "'" "2017-08-25") (Just 101)
]
operators :: TestItem
@ -130,70 +140,69 @@ operators = Group "operators"
,miscOps]
binaryOperators :: TestItem
binaryOperators = Group "binaryOperators" $ map (uncurry (TestScalarExpr ansi2011))
[("a + b", BinOp (Iden [Name Nothing "a"]) [Name Nothing "+"] (Iden [Name Nothing "b"]))
binaryOperators = Group "binaryOperators"
[t "a + b" $ BinOp (Iden [Name Nothing "a"]) [Name Nothing "+"] (Iden [Name Nothing "b"])
-- sanity check fixities
-- todo: add more fixity checking
,("a + b * c"
,BinOp (Iden [Name Nothing "a"]) [Name Nothing "+"]
(BinOp (Iden [Name Nothing "b"]) [Name Nothing "*"] (Iden [Name Nothing "c"])))
,t "a + b * c"
$ BinOp (Iden [Name Nothing "a"]) [Name Nothing "+"]
(BinOp (Iden [Name Nothing "b"]) [Name Nothing "*"] (Iden [Name Nothing "c"]))
,("a * b + c"
,BinOp (BinOp (Iden [Name Nothing "a"]) [Name Nothing "*"] (Iden [Name Nothing "b"]))
[Name Nothing "+"] (Iden [Name Nothing "c"]))
,t "a * b + c"
$ BinOp (BinOp (Iden [Name Nothing "a"]) [Name Nothing "*"] (Iden [Name Nothing "b"]))
[Name Nothing "+"] (Iden [Name Nothing "c"])
]
unaryOperators :: TestItem
unaryOperators = Group "unaryOperators" $ map (uncurry (TestScalarExpr ansi2011))
[("not a", PrefixOp [Name Nothing "not"] $ Iden [Name Nothing "a"])
,("not not a", PrefixOp [Name Nothing "not"] $ PrefixOp [Name Nothing "not"] $ Iden [Name Nothing "a"])
,("+a", PrefixOp [Name Nothing "+"] $ Iden [Name Nothing "a"])
,("-a", PrefixOp [Name Nothing "-"] $ Iden [Name Nothing "a"])
unaryOperators = Group "unaryOperators"
[t "not a" $ PrefixOp [Name Nothing "not"] $ Iden [Name Nothing "a"]
,t "not not a" $ PrefixOp [Name Nothing "not"] $ PrefixOp [Name Nothing "not"] $ Iden [Name Nothing "a"]
,t "+a" $ PrefixOp [Name Nothing "+"] $ Iden [Name Nothing "a"]
,t "-a" $ PrefixOp [Name Nothing "-"] $ Iden [Name Nothing "a"]
]
casts :: TestItem
casts = Group "operators" $ map (uncurry (TestScalarExpr ansi2011))
[("cast('1' as int)"
,Cast (StringLit "'" "'" "1") $ TypeName [Name Nothing "int"])
casts = Group "operators"
[t "cast('1' as int)"
$ Cast (StringLit "'" "'" "1") $ TypeName [Name Nothing "int"]
,("int '3'"
,TypedLit (TypeName [Name Nothing "int"]) "3")
,t "int '3'"
$ TypedLit (TypeName [Name Nothing "int"]) "3"
,("cast('1' as double precision)"
,Cast (StringLit "'" "'" "1") $ TypeName [Name Nothing "double precision"])
,t "cast('1' as double precision)"
$ Cast (StringLit "'" "'" "1") $ TypeName [Name Nothing "double precision"]
,("cast('1' as float(8))"
,Cast (StringLit "'" "'" "1") $ PrecTypeName [Name Nothing "float"] 8)
,t "cast('1' as float(8))"
$ Cast (StringLit "'" "'" "1") $ PrecTypeName [Name Nothing "float"] 8
,("cast('1' as decimal(15,2))"
,Cast (StringLit "'" "'" "1") $ PrecScaleTypeName [Name Nothing "decimal"] 15 2)
,t "cast('1' as decimal(15,2))"
$ Cast (StringLit "'" "'" "1") $ PrecScaleTypeName [Name Nothing "decimal"] 15 2
,("double precision '3'"
,TypedLit (TypeName [Name Nothing "double precision"]) "3")
,t "double precision '3'"
$ TypedLit (TypeName [Name Nothing "double precision"]) "3"
]
subqueries :: TestItem
subqueries = Group "unaryOperators" $ map (uncurry (TestScalarExpr ansi2011))
[("exists (select a from t)", SubQueryExpr SqExists ms)
,("(select a from t)", SubQueryExpr SqSq ms)
subqueries = Group "unaryOperators"
[t "exists (select a from t)" $ SubQueryExpr SqExists ms
,t "(select a from t)" $ SubQueryExpr SqSq ms
,("a in (select a from t)"
,In True (Iden [Name Nothing "a"]) (InQueryExpr ms))
,t "a in (select a from t)"
$ In True (Iden [Name Nothing "a"]) (InQueryExpr ms)
,("a not in (select a from t)"
,In False (Iden [Name Nothing "a"]) (InQueryExpr ms))
,t "a not in (select a from t)"
$ In False (Iden [Name Nothing "a"]) (InQueryExpr ms)
,("a > all (select a from t)"
,QuantifiedComparison (Iden [Name Nothing "a"]) [Name Nothing ">"] CPAll ms)
,t "a > all (select a from t)"
$ QuantifiedComparison (Iden [Name Nothing "a"]) [Name Nothing ">"] CPAll ms
,("a = some (select a from t)"
,QuantifiedComparison (Iden [Name Nothing "a"]) [Name Nothing "="] CPSome ms)
,t "a = some (select a from t)"
$ QuantifiedComparison (Iden [Name Nothing "a"]) [Name Nothing "="] CPSome ms
,("a <= any (select a from t)"
,QuantifiedComparison (Iden [Name Nothing "a"]) [Name Nothing "<="] CPAny ms)
,t "a <= any (select a from t)"
$ QuantifiedComparison (Iden [Name Nothing "a"]) [Name Nothing "<="] CPAny ms
]
where
ms = toQueryExpr $ makeSelect
@ -202,94 +211,93 @@ subqueries = Group "unaryOperators" $ map (uncurry (TestScalarExpr ansi2011))
}
miscOps :: TestItem
miscOps = Group "unaryOperators" $ map (uncurry (TestScalarExpr ansi2011))
[("a in (1,2,3)"
,In True (Iden [Name Nothing "a"]) $ InList $ map NumLit ["1","2","3"])
miscOps = Group "unaryOperators"
[t "a in (1,2,3)"
$ In True (Iden [Name Nothing "a"]) $ InList $ map NumLit ["1","2","3"]
,("a is null", PostfixOp [Name Nothing "is null"] (Iden [Name Nothing "a"]))
,("a is not null", PostfixOp [Name Nothing "is not null"] (Iden [Name Nothing "a"]))
,("a is true", PostfixOp [Name Nothing "is true"] (Iden [Name Nothing "a"]))
,("a is not true", PostfixOp [Name Nothing "is not true"] (Iden [Name Nothing "a"]))
,("a is false", PostfixOp [Name Nothing "is false"] (Iden [Name Nothing "a"]))
,("a is not false", PostfixOp [Name Nothing "is not false"] (Iden [Name Nothing "a"]))
,("a is unknown", PostfixOp [Name Nothing "is unknown"] (Iden [Name Nothing "a"]))
,("a is not unknown", PostfixOp [Name Nothing "is not unknown"] (Iden [Name Nothing "a"]))
,("a is distinct from b", BinOp (Iden [Name Nothing "a"]) [Name Nothing "is distinct from"] (Iden [Name Nothing "b"]))
,t "a is null" $ PostfixOp [Name Nothing "is null"] (Iden [Name Nothing "a"])
,t "a is not null" $ PostfixOp [Name Nothing "is not null"] (Iden [Name Nothing "a"])
,t "a is true" $ PostfixOp [Name Nothing "is true"] (Iden [Name Nothing "a"])
,t "a is not true" $ PostfixOp [Name Nothing "is not true"] (Iden [Name Nothing "a"])
,t "a is false" $ PostfixOp [Name Nothing "is false"] (Iden [Name Nothing "a"])
,t "a is not false" $ PostfixOp [Name Nothing "is not false"] (Iden [Name Nothing "a"])
,t "a is unknown" $ PostfixOp [Name Nothing "is unknown"] (Iden [Name Nothing "a"])
,t "a is not unknown" $ PostfixOp [Name Nothing "is not unknown"] (Iden [Name Nothing "a"])
,t "a is distinct from b" $ BinOp (Iden [Name Nothing "a"]) [Name Nothing "is distinct from"] (Iden [Name Nothing "b"])
,("a is not distinct from b"
,BinOp (Iden [Name Nothing "a"]) [Name Nothing "is not distinct from"] (Iden [Name Nothing "b"]))
,t "a is not distinct from b"
$ BinOp (Iden [Name Nothing "a"]) [Name Nothing "is not distinct from"] (Iden [Name Nothing "b"])
,("a like b", BinOp (Iden [Name Nothing "a"]) [Name Nothing "like"] (Iden [Name Nothing "b"]))
,("a not like b", BinOp (Iden [Name Nothing "a"]) [Name Nothing "not like"] (Iden [Name Nothing "b"]))
,("a is similar to b", BinOp (Iden [Name Nothing "a"]) [Name Nothing "is similar to"] (Iden [Name Nothing "b"]))
,t "a like b" $ BinOp (Iden [Name Nothing "a"]) [Name Nothing "like"] (Iden [Name Nothing "b"])
,t "a not like b" $ BinOp (Iden [Name Nothing "a"]) [Name Nothing "not like"] (Iden [Name Nothing "b"])
,t "a is similar to b"$ BinOp (Iden [Name Nothing "a"]) [Name Nothing "is similar to"] (Iden [Name Nothing "b"])
,("a is not similar to b"
,BinOp (Iden [Name Nothing "a"]) [Name Nothing "is not similar to"] (Iden [Name Nothing "b"]))
,("a overlaps b", BinOp (Iden [Name Nothing "a"]) [Name Nothing "overlaps"] (Iden [Name Nothing "b"]))
,t "a is not similar to b"
$ BinOp (Iden [Name Nothing "a"]) [Name Nothing "is not similar to"] (Iden [Name Nothing "b"])
,t "a overlaps b" $ BinOp (Iden [Name Nothing "a"]) [Name Nothing "overlaps"] (Iden [Name Nothing "b"])
-- special operators
,("a between b and c", SpecialOp [Name Nothing "between"] [Iden [Name Nothing "a"]
,t "a between b and c" $ SpecialOp [Name Nothing "between"] [Iden [Name Nothing "a"]
,Iden [Name Nothing "b"]
,Iden [Name Nothing "c"]])
,Iden [Name Nothing "c"]]
,("a not between b and c", SpecialOp [Name Nothing "not between"] [Iden [Name Nothing "a"]
,t "a not between b and c" $ SpecialOp [Name Nothing "not between"] [Iden [Name Nothing "a"]
,Iden [Name Nothing "b"]
,Iden [Name Nothing "c"]])
,("(1,2)"
,SpecialOp [Name Nothing "rowctor"] [NumLit "1", NumLit "2"])
,Iden [Name Nothing "c"]]
,t "(1,2)"
$ SpecialOp [Name Nothing "rowctor"] [NumLit "1", NumLit "2"]
-- keyword special operators
,("extract(day from t)"
, SpecialOpK [Name Nothing "extract"] (Just $ Iden [Name Nothing "day"]) [("from", Iden [Name Nothing "t"])])
,t "extract(day from t)"
$ SpecialOpK [Name Nothing "extract"] (Just $ Iden [Name Nothing "day"]) [("from", Iden [Name Nothing "t"])]
,("substring(x from 1 for 2)"
,SpecialOpK [Name Nothing "substring"] (Just $ Iden [Name Nothing "x"]) [("from", NumLit "1")
,("for", NumLit "2")])
,t "substring(x from 1 for 2)"
$ SpecialOpK [Name Nothing "substring"] (Just $ Iden [Name Nothing "x"]) [("from", NumLit "1")
,("for", NumLit "2")]
,("substring(x from 1)"
,SpecialOpK [Name Nothing "substring"] (Just $ Iden [Name Nothing "x"]) [("from", NumLit "1")])
,t "substring(x from 1)"
$ SpecialOpK [Name Nothing "substring"] (Just $ Iden [Name Nothing "x"]) [("from", NumLit "1")]
,("substring(x for 2)"
,SpecialOpK [Name Nothing "substring"] (Just $ Iden [Name Nothing "x"]) [("for", NumLit "2")])
,t "substring(x for 2)"
$ SpecialOpK [Name Nothing "substring"] (Just $ Iden [Name Nothing "x"]) [("for", NumLit "2")]
,("substring(x from 1 for 2 collate C)"
,SpecialOpK [Name Nothing "substring"] (Just $ Iden [Name Nothing "x"])
,t "substring(x from 1 for 2 collate C)"
$ SpecialOpK [Name Nothing "substring"] (Just $ Iden [Name Nothing "x"])
[("from", NumLit "1")
,("for", Collate (NumLit "2") [Name Nothing "C"])])
,("for", Collate (NumLit "2") [Name Nothing "C"])]
-- this doesn't work because of a overlap in the 'in' parser
,("POSITION( string1 IN string2 )"
,SpecialOpK [Name Nothing "position"] (Just $ Iden [Name Nothing "string1"]) [("in", Iden [Name Nothing "string2"])])
,t "POSITION( string1 IN string2 )"
$ SpecialOpK [Name Nothing "position"] (Just $ Iden [Name Nothing "string1"]) [("in", Iden [Name Nothing "string2"])]
,("CONVERT(char_value USING conversion_char_name)"
,SpecialOpK [Name Nothing "convert"] (Just $ Iden [Name Nothing "char_value"])
[("using", Iden [Name Nothing "conversion_char_name"])])
,t "CONVERT(char_value USING conversion_char_name)"
$ SpecialOpK [Name Nothing "convert"] (Just $ Iden [Name Nothing "char_value"])
[("using", Iden [Name Nothing "conversion_char_name"])]
,("TRANSLATE(char_value USING translation_name)"
,SpecialOpK [Name Nothing "translate"] (Just $ Iden [Name Nothing "char_value"])
[("using", Iden [Name Nothing "translation_name"])])
,t "TRANSLATE(char_value USING translation_name)"
$ SpecialOpK [Name Nothing "translate"] (Just $ Iden [Name Nothing "char_value"])
[("using", Iden [Name Nothing "translation_name"])]
{-
OVERLAY(string PLACING embedded_string FROM start
[FOR length])
-}
,("OVERLAY(string PLACING embedded_string FROM start)"
,SpecialOpK [Name Nothing "overlay"] (Just $ Iden [Name Nothing "string"])
,t "OVERLAY(string PLACING embedded_string FROM start)"
$ SpecialOpK [Name Nothing "overlay"] (Just $ Iden [Name Nothing "string"])
[("placing", Iden [Name Nothing "embedded_string"])
,("from", Iden [Name Nothing "start"])])
,("from", Iden [Name Nothing "start"])]
,("OVERLAY(string PLACING embedded_string FROM start FOR length)"
,SpecialOpK [Name Nothing "overlay"] (Just $ Iden [Name Nothing "string"])
,t "OVERLAY(string PLACING embedded_string FROM start FOR length)"
$ SpecialOpK [Name Nothing "overlay"] (Just $ Iden [Name Nothing "string"])
[("placing", Iden [Name Nothing "embedded_string"])
,("from", Iden [Name Nothing "start"])
,("for", Iden [Name Nothing "length"])])
,("for", Iden [Name Nothing "length"])]
{-
TRIM( [ [{LEADING | TRAILING | BOTH}] [removal_char] FROM ]
@ -299,135 +307,133 @@ target_string
,("trim(from target_string)"
,SpecialOpK [Name Nothing "trim"] Nothing
,t "trim(from target_string)"
$ SpecialOpK [Name Nothing "trim"] Nothing
[("both", StringLit "'" "'" " ")
,("from", Iden [Name Nothing "target_string"])])
,("from", Iden [Name Nothing "target_string"])]
,("trim(leading from target_string)"
,SpecialOpK [Name Nothing "trim"] Nothing
,t "trim(leading from target_string)"
$ SpecialOpK [Name Nothing "trim"] Nothing
[("leading", StringLit "'" "'" " ")
,("from", Iden [Name Nothing "target_string"])])
,("from", Iden [Name Nothing "target_string"])]
,("trim(trailing from target_string)"
,SpecialOpK [Name Nothing "trim"] Nothing
,t "trim(trailing from target_string)"
$ SpecialOpK [Name Nothing "trim"] Nothing
[("trailing", StringLit "'" "'" " ")
,("from", Iden [Name Nothing "target_string"])])
,("from", Iden [Name Nothing "target_string"])]
,("trim(both from target_string)"
,SpecialOpK [Name Nothing "trim"] Nothing
,t "trim(both from target_string)"
$ SpecialOpK [Name Nothing "trim"] Nothing
[("both", StringLit "'" "'" " ")
,("from", Iden [Name Nothing "target_string"])])
,("from", Iden [Name Nothing "target_string"])]
,("trim(leading 'x' from target_string)"
,SpecialOpK [Name Nothing "trim"] Nothing
,t "trim(leading 'x' from target_string)"
$ SpecialOpK [Name Nothing "trim"] Nothing
[("leading", StringLit "'" "'" "x")
,("from", Iden [Name Nothing "target_string"])])
,("from", Iden [Name Nothing "target_string"])]
,("trim(trailing 'y' from target_string)"
,SpecialOpK [Name Nothing "trim"] Nothing
,t "trim(trailing 'y' from target_string)"
$ SpecialOpK [Name Nothing "trim"] Nothing
[("trailing", StringLit "'" "'" "y")
,("from", Iden [Name Nothing "target_string"])])
,("from", Iden [Name Nothing "target_string"])]
,("trim(both 'z' from target_string collate C)"
,SpecialOpK [Name Nothing "trim"] Nothing
,t "trim(both 'z' from target_string collate C)"
$ SpecialOpK [Name Nothing "trim"] Nothing
[("both", StringLit "'" "'" "z")
,("from", Collate (Iden [Name Nothing "target_string"]) [Name Nothing "C"])])
,("from", Collate (Iden [Name Nothing "target_string"]) [Name Nothing "C"])]
,("trim(leading from target_string)"
,SpecialOpK [Name Nothing "trim"] Nothing
,t "trim(leading from target_string)"
$ SpecialOpK [Name Nothing "trim"] Nothing
[("leading", StringLit "'" "'" " ")
,("from", Iden [Name Nothing "target_string"])])
,("from", Iden [Name Nothing "target_string"])]
]
aggregates :: TestItem
aggregates = Group "aggregates" $ map (uncurry (TestScalarExpr ansi2011))
[("count(*)",App [Name Nothing "count"] [Star])
aggregates = Group "aggregates"
[t "count(*)" $ App [Name Nothing "count"] [Star]
,("sum(a order by a)"
,AggregateApp [Name Nothing "sum"] SQDefault [Iden [Name Nothing "a"]]
[SortSpec (Iden [Name Nothing "a"]) DirDefault NullsOrderDefault] Nothing)
,t "sum(a order by a)"
$ AggregateApp [Name Nothing "sum"] SQDefault [Iden [Name Nothing "a"]]
[SortSpec (Iden [Name Nothing "a"]) DirDefault NullsOrderDefault] Nothing
,("sum(all a)"
,AggregateApp [Name Nothing "sum"] All [Iden [Name Nothing "a"]] [] Nothing)
,t "sum(all a)"
$ AggregateApp [Name Nothing "sum"] All [Iden [Name Nothing "a"]] [] Nothing
,("count(distinct a)"
,AggregateApp [Name Nothing "count"] Distinct [Iden [Name Nothing "a"]] [] Nothing)
,t "count(distinct a)"
$ AggregateApp [Name Nothing "count"] Distinct [Iden [Name Nothing "a"]] [] Nothing
]
windowFunctions :: TestItem
windowFunctions = Group "windowFunctions" $ map (uncurry (TestScalarExpr ansi2011))
[("max(a) over ()", WindowApp [Name Nothing "max"] [Iden [Name Nothing "a"]] [] [] Nothing)
,("count(*) over ()", WindowApp [Name Nothing "count"] [Star] [] [] Nothing)
windowFunctions = Group "windowFunctions"
[t "max(a) over ()" $ WindowApp [Name Nothing "max"] [Iden [Name Nothing "a"]] [] [] Nothing
,t "count(*) over ()" $ WindowApp [Name Nothing "count"] [Star] [] [] Nothing
,("max(a) over (partition by b)"
,WindowApp [Name Nothing "max"] [Iden [Name Nothing "a"]] [Iden [Name Nothing "b"]] [] Nothing)
,t "max(a) over (partition by b)"
$ WindowApp [Name Nothing "max"] [Iden [Name Nothing "a"]] [Iden [Name Nothing "b"]] [] Nothing
,("max(a) over (partition by b,c)"
,WindowApp [Name Nothing "max"] [Iden [Name Nothing "a"]] [Iden [Name Nothing "b"],Iden [Name Nothing "c"]] [] Nothing)
,t "max(a) over (partition by b,c)"
$ WindowApp [Name Nothing "max"] [Iden [Name Nothing "a"]] [Iden [Name Nothing "b"],Iden [Name Nothing "c"]] [] Nothing
,("sum(a) over (order by b)"
,WindowApp [Name Nothing "sum"] [Iden [Name Nothing "a"]] []
[SortSpec (Iden [Name Nothing "b"]) DirDefault NullsOrderDefault] Nothing)
,t "sum(a) over (order by b)"
$ WindowApp [Name Nothing "sum"] [Iden [Name Nothing "a"]] []
[SortSpec (Iden [Name Nothing "b"]) DirDefault NullsOrderDefault] Nothing
,("sum(a) over (order by b desc,c)"
,WindowApp [Name Nothing "sum"] [Iden [Name Nothing "a"]] []
,t "sum(a) over (order by b desc,c)"
$ WindowApp [Name Nothing "sum"] [Iden [Name Nothing "a"]] []
[SortSpec (Iden [Name Nothing "b"]) Desc NullsOrderDefault
,SortSpec (Iden [Name Nothing "c"]) DirDefault NullsOrderDefault] Nothing)
,SortSpec (Iden [Name Nothing "c"]) DirDefault NullsOrderDefault] Nothing
,("sum(a) over (partition by b order by c)"
,WindowApp [Name Nothing "sum"] [Iden [Name Nothing "a"]] [Iden [Name Nothing "b"]]
[SortSpec (Iden [Name Nothing "c"]) DirDefault NullsOrderDefault] Nothing)
,t "sum(a) over (partition by b order by c)"
$ WindowApp [Name Nothing "sum"] [Iden [Name Nothing "a"]] [Iden [Name Nothing "b"]]
[SortSpec (Iden [Name Nothing "c"]) DirDefault NullsOrderDefault] Nothing
,("sum(a) over (partition by b order by c range unbounded preceding)"
,WindowApp [Name Nothing "sum"] [Iden [Name Nothing "a"]] [Iden [Name Nothing "b"]]
,t "sum(a) over (partition by b order by c range unbounded preceding)"
$ WindowApp [Name Nothing "sum"] [Iden [Name Nothing "a"]] [Iden [Name Nothing "b"]]
[SortSpec (Iden [Name Nothing "c"]) DirDefault NullsOrderDefault]
$ Just $ FrameFrom FrameRange UnboundedPreceding)
$ Just $ FrameFrom FrameRange UnboundedPreceding
,("sum(a) over (partition by b order by c range 5 preceding)"
,WindowApp [Name Nothing "sum"] [Iden [Name Nothing "a"]] [Iden [Name Nothing "b"]]
,t "sum(a) over (partition by b order by c range 5 preceding)"
$ WindowApp [Name Nothing "sum"] [Iden [Name Nothing "a"]] [Iden [Name Nothing "b"]]
[SortSpec (Iden [Name Nothing "c"]) DirDefault NullsOrderDefault]
$ Just $ FrameFrom FrameRange $ Preceding (NumLit "5"))
$ Just $ FrameFrom FrameRange $ Preceding (NumLit "5")
,("sum(a) over (partition by b order by c range current row)"
,WindowApp [Name Nothing "sum"] [Iden [Name Nothing "a"]] [Iden [Name Nothing "b"]]
,t "sum(a) over (partition by b order by c range current row)"
$ WindowApp [Name Nothing "sum"] [Iden [Name Nothing "a"]] [Iden [Name Nothing "b"]]
[SortSpec (Iden [Name Nothing "c"]) DirDefault NullsOrderDefault]
$ Just $ FrameFrom FrameRange Current)
$ Just $ FrameFrom FrameRange Current
,("sum(a) over (partition by b order by c rows 5 following)"
,WindowApp [Name Nothing "sum"] [Iden [Name Nothing "a"]] [Iden [Name Nothing "b"]]
,t "sum(a) over (partition by b order by c rows 5 following)"
$ WindowApp [Name Nothing "sum"] [Iden [Name Nothing "a"]] [Iden [Name Nothing "b"]]
[SortSpec (Iden [Name Nothing "c"]) DirDefault NullsOrderDefault]
$ Just $ FrameFrom FrameRows $ Following (NumLit "5"))
$ Just $ FrameFrom FrameRows $ Following (NumLit "5")
,("sum(a) over (partition by b order by c range unbounded following)"
,WindowApp [Name Nothing "sum"] [Iden [Name Nothing "a"]] [Iden [Name Nothing "b"]]
,t "sum(a) over (partition by b order by c range unbounded following)"
$ WindowApp [Name Nothing "sum"] [Iden [Name Nothing "a"]] [Iden [Name Nothing "b"]]
[SortSpec (Iden [Name Nothing "c"]) DirDefault NullsOrderDefault]
$ Just $ FrameFrom FrameRange UnboundedFollowing)
$ Just $ FrameFrom FrameRange UnboundedFollowing
,("sum(a) over (partition by b order by c \n\
,t "sum(a) over (partition by b order by c \n\
\range between 5 preceding and 5 following)"
,WindowApp [Name Nothing "sum"] [Iden [Name Nothing "a"]] [Iden [Name Nothing "b"]]
$ WindowApp [Name Nothing "sum"] [Iden [Name Nothing "a"]] [Iden [Name Nothing "b"]]
[SortSpec (Iden [Name Nothing "c"]) DirDefault NullsOrderDefault]
$ Just $ FrameBetween FrameRange
(Preceding (NumLit "5"))
(Following (NumLit "5")))
(Following (NumLit "5"))
]
parens :: TestItem
parens = Group "parens" $ map (uncurry (TestScalarExpr ansi2011))
[("(a)", Parens (Iden [Name Nothing "a"]))
,("(a + b)", Parens (BinOp (Iden [Name Nothing "a"]) [Name Nothing "+"] (Iden [Name Nothing "b"])))
parens = Group "parens"
[t "(a)" $ Parens (Iden [Name Nothing "a"])
,t "(a + b)" $ Parens (BinOp (Iden [Name Nothing "a"]) [Name Nothing "+"] (Iden [Name Nothing "b"]))
]
functionsWithReservedNames :: TestItem
functionsWithReservedNames = Group "functionsWithReservedNames" $ map t
functionsWithReservedNames = Group "functionsWithReservedNames" $ map f
["abs"
,"char_length"
]
where
t fn = TestScalarExpr ansi2011 (fn <> "(a)") $ App [Name Nothing fn] [Iden [Name Nothing "a"]]
f fn = t (fn <> "(a)") $ App [Name Nothing fn] [Iden [Name Nothing "a"]]

View file

@ -9,100 +9,103 @@ module Language.SQL.SimpleSQL.TableRefs (tableRefTests) where
import Language.SQL.SimpleSQL.TestTypes
import Language.SQL.SimpleSQL.Syntax
import Language.SQL.SimpleSQL.TestRunners
import Data.Text (Text)
tableRefTests :: TestItem
tableRefTests = Group "tableRefTests" $ map (uncurry (TestQueryExpr ansi2011))
[("select a from t"
,ms [TRSimple [Name Nothing "t"]])
tableRefTests = Group "tableRefTests"
[q "select a from t"
$ ms [TRSimple [Name Nothing "t"]]
,("select a from f(a)"
,ms [TRFunction [Name Nothing "f"] [Iden [Name Nothing "a"]]])
,q "select a from f(a)"
$ ms [TRFunction [Name Nothing "f"] [Iden [Name Nothing "a"]]]
,("select a from t,u"
,ms [TRSimple [Name Nothing "t"], TRSimple [Name Nothing "u"]])
,q "select a from t,u"
$ ms [TRSimple [Name Nothing "t"], TRSimple [Name Nothing "u"]]
,("select a from s.t"
,ms [TRSimple [Name Nothing "s", Name Nothing "t"]])
,q "select a from s.t"
$ ms [TRSimple [Name Nothing "s", Name Nothing "t"]]
-- these lateral queries make no sense but the syntax is valid
,("select a from lateral a"
,ms [TRLateral $ TRSimple [Name Nothing "a"]])
,q "select a from lateral a"
$ ms [TRLateral $ TRSimple [Name Nothing "a"]]
,("select a from lateral a,b"
,ms [TRLateral $ TRSimple [Name Nothing "a"], TRSimple [Name Nothing "b"]])
,q "select a from lateral a,b"
$ ms [TRLateral $ TRSimple [Name Nothing "a"], TRSimple [Name Nothing "b"]]
,("select a from a, lateral b"
,ms [TRSimple [Name Nothing "a"], TRLateral $ TRSimple [Name Nothing "b"]])
,q "select a from a, lateral b"
$ ms [TRSimple [Name Nothing "a"], TRLateral $ TRSimple [Name Nothing "b"]]
,("select a from a natural join lateral b"
,ms [TRJoin (TRSimple [Name Nothing "a"]) True JInner
,q "select a from a natural join lateral b"
$ ms [TRJoin (TRSimple [Name Nothing "a"]) True JInner
(TRLateral $ TRSimple [Name Nothing "b"])
Nothing])
Nothing]
,("select a from lateral a natural join lateral b"
,ms [TRJoin (TRLateral $ TRSimple [Name Nothing "a"]) True JInner
,q "select a from lateral a natural join lateral b"
$ ms [TRJoin (TRLateral $ TRSimple [Name Nothing "a"]) True JInner
(TRLateral $ TRSimple [Name Nothing "b"])
Nothing])
Nothing]
,("select a from t inner join u on expr"
,ms [TRJoin (TRSimple [Name Nothing "t"]) False JInner (TRSimple [Name Nothing "u"])
(Just $ JoinOn $ Iden [Name Nothing "expr"])])
,q "select a from t inner join u on expr"
$ ms [TRJoin (TRSimple [Name Nothing "t"]) False JInner (TRSimple [Name Nothing "u"])
(Just $ JoinOn $ Iden [Name Nothing "expr"])]
,("select a from t join u on expr"
,ms [TRJoin (TRSimple [Name Nothing "t"]) False JInner (TRSimple [Name Nothing "u"])
(Just $ JoinOn $ Iden [Name Nothing "expr"])])
,q "select a from t join u on expr"
$ ms [TRJoin (TRSimple [Name Nothing "t"]) False JInner (TRSimple [Name Nothing "u"])
(Just $ JoinOn $ Iden [Name Nothing "expr"])]
,("select a from t left join u on expr"
,ms [TRJoin (TRSimple [Name Nothing "t"]) False JLeft (TRSimple [Name Nothing "u"])
(Just $ JoinOn $ Iden [Name Nothing "expr"])])
,q "select a from t left join u on expr"
$ ms [TRJoin (TRSimple [Name Nothing "t"]) False JLeft (TRSimple [Name Nothing "u"])
(Just $ JoinOn $ Iden [Name Nothing "expr"])]
,("select a from t right join u on expr"
,ms [TRJoin (TRSimple [Name Nothing "t"]) False JRight (TRSimple [Name Nothing "u"])
(Just $ JoinOn $ Iden [Name Nothing "expr"])])
,q "select a from t right join u on expr"
$ ms [TRJoin (TRSimple [Name Nothing "t"]) False JRight (TRSimple [Name Nothing "u"])
(Just $ JoinOn $ Iden [Name Nothing "expr"])]
,("select a from t full join u on expr"
,ms [TRJoin (TRSimple [Name Nothing "t"]) False JFull (TRSimple [Name Nothing "u"])
(Just $ JoinOn $ Iden [Name Nothing "expr"])])
,q "select a from t full join u on expr"
$ ms [TRJoin (TRSimple [Name Nothing "t"]) False JFull (TRSimple [Name Nothing "u"])
(Just $ JoinOn $ Iden [Name Nothing "expr"])]
,("select a from t cross join u"
,ms [TRJoin (TRSimple [Name Nothing "t"]) False
JCross (TRSimple [Name Nothing "u"]) Nothing])
,q "select a from t cross join u"
$ ms [TRJoin (TRSimple [Name Nothing "t"]) False
JCross (TRSimple [Name Nothing "u"]) Nothing]
,("select a from t natural inner join u"
,ms [TRJoin (TRSimple [Name Nothing "t"]) True JInner (TRSimple [Name Nothing "u"])
Nothing])
,q "select a from t natural inner join u"
$ ms [TRJoin (TRSimple [Name Nothing "t"]) True JInner (TRSimple [Name Nothing "u"])
Nothing]
,("select a from t inner join u using(a,b)"
,ms [TRJoin (TRSimple [Name Nothing "t"]) False JInner (TRSimple [Name Nothing "u"])
(Just $ JoinUsing [Name Nothing "a", Name Nothing "b"])])
,q "select a from t inner join u using(a,b)"
$ ms [TRJoin (TRSimple [Name Nothing "t"]) False JInner (TRSimple [Name Nothing "u"])
(Just $ JoinUsing [Name Nothing "a", Name Nothing "b"])]
,("select a from (select a from t)"
,ms [TRQueryExpr $ ms [TRSimple [Name Nothing "t"]]])
,q "select a from (select a from t)"
$ ms [TRQueryExpr $ ms [TRSimple [Name Nothing "t"]]]
,("select a from t as u"
,ms [TRAlias (TRSimple [Name Nothing "t"]) (Alias (Name Nothing "u") Nothing)])
,q "select a from t as u"
$ ms [TRAlias (TRSimple [Name Nothing "t"]) (Alias (Name Nothing "u") Nothing)]
,("select a from t u"
,ms [TRAlias (TRSimple [Name Nothing "t"]) (Alias (Name Nothing "u") Nothing)])
,q "select a from t u"
$ ms [TRAlias (TRSimple [Name Nothing "t"]) (Alias (Name Nothing "u") Nothing)]
,("select a from t u(b)"
,ms [TRAlias (TRSimple [Name Nothing "t"]) (Alias (Name Nothing "u") $ Just [Name Nothing "b"])])
,q "select a from t u(b)"
$ ms [TRAlias (TRSimple [Name Nothing "t"]) (Alias (Name Nothing "u") $ Just [Name Nothing "b"])]
,("select a from (t cross join u) as u"
,ms [TRAlias (TRParens $
,q "select a from (t cross join u) as u"
$ ms [TRAlias (TRParens $
TRJoin (TRSimple [Name Nothing "t"]) False JCross (TRSimple [Name Nothing "u"]) Nothing)
(Alias (Name Nothing "u") Nothing)])
(Alias (Name Nothing "u") Nothing)]
-- todo: not sure if the associativity is correct
,("select a from t cross join u cross join v",
ms [TRJoin
,q "select a from t cross join u cross join v"
$ ms [TRJoin
(TRJoin (TRSimple [Name Nothing "t"]) False
JCross (TRSimple [Name Nothing "u"]) Nothing)
False JCross (TRSimple [Name Nothing "v"]) Nothing])
False JCross (TRSimple [Name Nothing "v"]) Nothing]
]
where
ms f = toQueryExpr $ makeSelect {msSelectList = [(Iden [Name Nothing "a"],Nothing)]
,msFrom = f}
q :: HasCallStack => Text -> QueryExpr -> TestItem
q src ast = testQueryExpr ansi2011 src ast

View file

@ -0,0 +1,92 @@
{-# LANGUAGE OverloadedStrings #-}
module Language.SQL.SimpleSQL.TestRunners
(testLex
,lexFails
,testScalarExpr
,testQueryExpr
,testStatement
,testStatements
,testParseQueryExpr
,testParseQueryExprFails
,testParseScalarExprFails
,HasCallStack
) where
import Language.SQL.SimpleSQL.Syntax
import Language.SQL.SimpleSQL.TestTypes
import Language.SQL.SimpleSQL.Pretty
import Language.SQL.SimpleSQL.Parse
import qualified Language.SQL.SimpleSQL.Lex as Lex
import Data.Text (Text)
import qualified Data.Text as T
import Language.SQL.SimpleSQL.Expectations
(shouldParseL
,shouldFail
,shouldParseA
,shouldSucceed
)
import Test.Hspec
(it
,HasCallStack
)
testLex :: HasCallStack => Dialect -> Text -> [Lex.Token] -> TestItem
testLex d input a =
LexTest d input a $ do
it (T.unpack input) $ Lex.lexSQL d False "" Nothing input `shouldParseL` a
it (T.unpack $ "pp: " <> input) $ Lex.lexSQL d False "" Nothing (Lex.prettyTokens d a) `shouldParseL` a
lexFails :: HasCallStack => Dialect -> Text -> TestItem
lexFails d input =
LexFails d input $
it (T.unpack input) $ shouldFail $ Lex.lexSQL d False "" Nothing input
testScalarExpr :: HasCallStack => Dialect -> Text -> ScalarExpr -> TestItem
testScalarExpr d input a =
TestScalarExpr d input a $ do
it (T.unpack input) $ parseScalarExpr d "" Nothing input `shouldParseA` a
it (T.unpack $ "pp: " <> input) $ parseScalarExpr d "" Nothing (prettyScalarExpr d a) `shouldParseA` a
testQueryExpr :: HasCallStack => Dialect -> Text -> QueryExpr -> TestItem
testQueryExpr d input a =
TestQueryExpr d input a $ do
it (T.unpack input) $ parseQueryExpr d "" Nothing input `shouldParseA` a
it (T.unpack $ "pp: " <> input) $ parseQueryExpr d "" Nothing (prettyQueryExpr d a) `shouldParseA` a
testParseQueryExpr :: HasCallStack => Dialect -> Text -> TestItem
testParseQueryExpr d input =
let a = parseQueryExpr d "" Nothing input
in ParseQueryExpr d input $ do
it (T.unpack input) $ shouldSucceed (T.unpack . prettyError) a
case a of
Left _ -> pure ()
Right a' ->
it (T.unpack $ "pp: " <> input) $
parseQueryExpr d "" Nothing (prettyQueryExpr d a') `shouldParseA` a'
testParseQueryExprFails :: HasCallStack => Dialect -> Text -> TestItem
testParseQueryExprFails d input =
ParseQueryExprFails d input $
it (T.unpack input) $ shouldFail $ parseQueryExpr d "" Nothing input
testParseScalarExprFails :: HasCallStack => Dialect -> Text -> TestItem
testParseScalarExprFails d input =
ParseScalarExprFails d input $
it (T.unpack input) $ shouldFail $ parseScalarExpr d "" Nothing input
testStatement :: HasCallStack => Dialect -> Text -> Statement -> TestItem
testStatement d input a =
TestStatement d input a $ do
it (T.unpack input) $ parseStatement d "" Nothing input `shouldParseA` a
it (T.unpack $ "pp: " <> input) $ parseStatement d "" Nothing (prettyStatement d a) `shouldParseA` a
testStatements :: HasCallStack => Dialect -> Text -> [Statement] -> TestItem
testStatements d input a =
TestStatements d input a $ do
it (T.unpack input) $ parseStatements d "" Nothing input `shouldParseA` a
it (T.unpack $ "pp: " <> input) $ parseStatements d "" Nothing (prettyStatements d a) `shouldParseA` a

View file

@ -13,6 +13,9 @@ import Language.SQL.SimpleSQL.Syntax
import Language.SQL.SimpleSQL.Lex (Token)
import Language.SQL.SimpleSQL.Dialect
import Test.Hspec (SpecWith)
import Data.Text (Text)
{-
@ -20,13 +23,19 @@ TODO: maybe make the dialect args into [dialect], then each test
checks all the dialects mentioned work, and all the dialects not
mentioned give a parse error. Not sure if this will be too awkward due
to lots of tricky exceptions/variationsx.
The test items are designed to allow code to grab all the examples
in easily usable data types, but since hspec has this neat feature
where it will give a source location for a test failure, each testitem
apart from group already has the SpecWith attached to run that test,
that way we can attach the source location to each test item
-}
data TestItem = Group Text [TestItem]
| TestScalarExpr Dialect Text ScalarExpr
| TestQueryExpr Dialect Text QueryExpr
| TestStatement Dialect Text Statement
| TestStatements Dialect Text [Statement]
| TestScalarExpr Dialect Text ScalarExpr (SpecWith ())
| TestQueryExpr Dialect Text QueryExpr (SpecWith ())
| TestStatement Dialect Text Statement (SpecWith ())
| TestStatements Dialect Text [Statement] (SpecWith ())
{-
this just checks the sql parses without error, mostly just a
@ -34,12 +43,13 @@ intermediate when I'm too lazy to write out the parsed AST. These
should all be TODO to convert to a testqueryexpr test.
-}
| ParseQueryExpr Dialect Text
| ParseQueryExpr Dialect Text (SpecWith ())
-- check that the string given fails to parse
| ParseQueryExprFails Dialect Text
| ParseScalarExprFails Dialect Text
| LexTest Dialect Text [Token]
| LexFails Dialect Text
deriving (Eq,Show)
| ParseQueryExprFails Dialect Text (SpecWith ())
| ParseScalarExprFails Dialect Text (SpecWith ())
| LexTest Dialect Text [Token] (SpecWith ())
| LexFails Dialect Text (SpecWith ())
| GeneralParseFailTest Text Text (SpecWith ())

View file

@ -12,13 +12,11 @@ module Language.SQL.SimpleSQL.Tests
,TestItem(..)
) where
import qualified Test.Tasty as T
import qualified Test.Tasty.HUnit as H
--import Language.SQL.SimpleSQL.Syntax
import Language.SQL.SimpleSQL.Pretty
import Language.SQL.SimpleSQL.Parse
import qualified Language.SQL.SimpleSQL.Lex as Lex
import Test.Hspec
(SpecWith
,describe
,parallel
)
import Language.SQL.SimpleSQL.TestTypes
@ -44,11 +42,10 @@ import Language.SQL.SimpleSQL.SQL2011Schema
import Language.SQL.SimpleSQL.MySQL
import Language.SQL.SimpleSQL.Oracle
import Language.SQL.SimpleSQL.CustomDialect
import Language.SQL.SimpleSQL.ErrorMessages
import Data.Text (Text)
import qualified Data.Text as T
{-
Order the tests to start from the simplest first. This is also the
order on the generated documentation.
@ -77,104 +74,22 @@ testData =
,customDialectTests
,emptyStatementTests
,createIndexTests
,errorMessageTests
]
tests :: T.TestTree
tests = itemToTest testData
tests :: SpecWith ()
tests = parallel $ itemToTest testData
--runTests :: IO ()
--runTests = void $ H.runTestTT $ itemToTest testData
itemToTest :: TestItem -> T.TestTree
itemToTest :: TestItem -> SpecWith ()
itemToTest (Group nm ts) =
T.testGroup (T.unpack nm) $ map itemToTest ts
itemToTest (TestScalarExpr d str expected) =
toTest parseScalarExpr prettyScalarExpr d str expected
itemToTest (TestQueryExpr d str expected) =
toTest parseQueryExpr prettyQueryExpr d str expected
itemToTest (TestStatement d str expected) =
toTest parseStatement prettyStatement d str expected
itemToTest (TestStatements d str expected) =
toTest parseStatements prettyStatements d str expected
itemToTest (ParseQueryExpr d str) =
toPTest parseQueryExpr prettyQueryExpr d str
itemToTest (ParseQueryExprFails d str) =
toFTest parseQueryExpr prettyQueryExpr d str
itemToTest (ParseScalarExprFails d str) =
toFTest parseScalarExpr prettyScalarExpr d str
itemToTest (LexTest d s ts) = makeLexerTest d s ts
itemToTest (LexFails d s) = makeLexingFailsTest d s
makeLexerTest :: Dialect -> Text -> [Lex.Token] -> T.TestTree
makeLexerTest d s ts = H.testCase (T.unpack s) $ do
let ts1 = either (error . T.unpack . Lex.prettyError) id $ Lex.lexSQL d "" Nothing s
H.assertEqual "" ts ts1
let s' = Lex.prettyTokens d $ ts1
H.assertEqual "pretty print" s s'
makeLexingFailsTest :: Dialect -> Text -> T.TestTree
makeLexingFailsTest d s = H.testCase (T.unpack s) $ do
case Lex.lexSQL d "" Nothing s of
Right x -> H.assertFailure $ "lexing should have failed: " ++ T.unpack s ++ "\ngot: " ++ show x
Left _ -> pure ()
toTest :: (Eq a, Show a) =>
(Dialect -> Text -> Maybe (Int,Int) -> Text -> Either ParseError a)
-> (Dialect -> a -> Text)
-> Dialect
-> Text
-> a
-> T.TestTree
toTest parser pp d str expected = H.testCase (T.unpack str) $ do
let egot = parser d "" Nothing str
case egot of
Left e -> H.assertFailure $ T.unpack $ prettyError e
Right got -> H.assertEqual "" expected got
let str' = pp d expected
egot' = parser d "" Nothing str'
case egot' of
Left e' ->
H.assertFailure $ "pp roundtrip"
++ "\n" ++ (T.unpack str')
++ (T.unpack $ prettyError e')
Right got' ->
H.assertEqual
("pp roundtrip" ++ "\n" ++ T.unpack str')
expected got'
toPTest :: (Eq a, Show a) =>
(Dialect -> Text -> Maybe (Int,Int) -> Text -> Either ParseError a)
-> (Dialect -> a -> Text)
-> Dialect
-> Text
-> T.TestTree
toPTest parser pp d str = H.testCase (T.unpack str) $ do
let egot = parser d "" Nothing str
case egot of
Left e -> H.assertFailure $ T.unpack $ prettyError e
Right got -> do
let str' = pp d got
let egot' = parser d "" Nothing str'
case egot' of
Left e' -> H.assertFailure $ "pp roundtrip "
++ "\n" ++ T.unpack str' ++ "\n"
++ T.unpack (prettyError e')
Right _got' -> return ()
toFTest :: (Eq a, Show a) =>
(Dialect -> Text -> Maybe (Int,Int) -> Text -> Either ParseError a)
-> (Dialect -> a -> Text)
-> Dialect
-> Text
-> T.TestTree
toFTest parser _pp d str = H.testCase (T.unpack str) $ do
let egot = parser d "" Nothing str
case egot of
Left _e -> return ()
Right _got ->
H.assertFailure $ "parse didn't fail: " ++ show d ++ "\n" ++ T.unpack str
describe (T.unpack nm) $ mapM_ itemToTest ts
itemToTest (TestScalarExpr _ _ _ t) = t
itemToTest (TestQueryExpr _ _ _ t) = t
itemToTest (TestStatement _ _ _ t) = t
itemToTest (TestStatements _ _ _ t) = t
itemToTest (ParseQueryExpr _ _ t) = t
itemToTest (ParseQueryExprFails _ _ t) = t
itemToTest (ParseScalarExprFails _ _ t) = t
itemToTest (LexTest _ _ _ t) = t
itemToTest (LexFails _ _ t) = t
itemToTest (GeneralParseFailTest _ _ t) = t

View file

@ -14,15 +14,14 @@ module Language.SQL.SimpleSQL.Tpch (tpchTests,tpchQueries) where
import Language.SQL.SimpleSQL.TestTypes
import Data.Text (Text)
import Language.SQL.SimpleSQL.TestRunners
tpchTests :: TestItem
tpchTests =
Group "parse tpch"
$ map (ParseQueryExpr ansi2011 . snd) tpchQueries
tpchTests = Group "parse tpch" tpchQueries
tpchQueries :: [(String,Text)]
tpchQueries :: [TestItem]
tpchQueries =
[("Q1","\n\
[q "Q1" "\n\
\select\n\
\ l_returnflag,\n\
\ l_linestatus,\n\
@ -43,8 +42,8 @@ tpchQueries =
\ l_linestatus\n\
\order by\n\
\ l_returnflag,\n\
\ l_linestatus")
,("Q2","\n\
\ l_linestatus"
,q "Q2" "\n\
\select\n\
\ s_acctbal,\n\
\ s_name,\n\
@ -88,8 +87,8 @@ tpchQueries =
\ n_name,\n\
\ s_name,\n\
\ p_partkey\n\
\fetch first 100 rows only")
,("Q3","\n\
\fetch first 100 rows only"
,q "Q3" "\n\
\ select\n\
\ l_orderkey,\n\
\ sum(l_extendedprice * (1 - l_discount)) as revenue,\n\
@ -112,8 +111,8 @@ tpchQueries =
\ order by\n\
\ revenue desc,\n\
\ o_orderdate\n\
\ fetch first 10 rows only")
,("Q4","\n\
\ fetch first 10 rows only"
,q "Q4" "\n\
\ select\n\
\ o_orderpriority,\n\
\ count(*) as order_count\n\
@ -134,8 +133,8 @@ tpchQueries =
\ group by\n\
\ o_orderpriority\n\
\ order by\n\
\ o_orderpriority")
,("Q5","\n\
\ o_orderpriority"
,q "Q5" "\n\
\ select\n\
\ n_name,\n\
\ sum(l_extendedprice * (1 - l_discount)) as revenue\n\
@ -159,8 +158,8 @@ tpchQueries =
\ group by\n\
\ n_name\n\
\ order by\n\
\ revenue desc")
,("Q6","\n\
\ revenue desc"
,q "Q6" "\n\
\ select\n\
\ sum(l_extendedprice * l_discount) as revenue\n\
\ from\n\
@ -169,8 +168,8 @@ tpchQueries =
\ l_shipdate >= date '1997-01-01'\n\
\ and l_shipdate < date '1997-01-01' + interval '1' year\n\
\ and l_discount between 0.07 - 0.01 and 0.07 + 0.01\n\
\ and l_quantity < 24")
,("Q7","\n\
\ and l_quantity < 24"
,q "Q7" "\n\
\ select\n\
\ supp_nation,\n\
\ cust_nation,\n\
@ -209,8 +208,8 @@ tpchQueries =
\ order by\n\
\ supp_nation,\n\
\ cust_nation,\n\
\ l_year")
,("Q8","\n\
\ l_year"
,q "Q8" "\n\
\ select\n\
\ o_year,\n\
\ sum(case\n\
@ -247,8 +246,8 @@ tpchQueries =
\ group by\n\
\ o_year\n\
\ order by\n\
\ o_year")
,("Q9","\n\
\ o_year"
,q "Q9" "\n\
\ select\n\
\ nation,\n\
\ o_year,\n\
@ -280,8 +279,8 @@ tpchQueries =
\ o_year\n\
\ order by\n\
\ nation,\n\
\ o_year desc")
,("Q10","\n\
\ o_year desc"
,q "Q10" "\n\
\ select\n\
\ c_custkey,\n\
\ c_name,\n\
@ -313,8 +312,8 @@ tpchQueries =
\ c_comment\n\
\ order by\n\
\ revenue desc\n\
\ fetch first 20 rows only")
,("Q11","\n\
\ fetch first 20 rows only"
,q "Q11" "\n\
\ select\n\
\ ps_partkey,\n\
\ sum(ps_supplycost * ps_availqty) as value\n\
@ -341,8 +340,8 @@ tpchQueries =
\ and n_name = 'CHINA'\n\
\ )\n\
\ order by\n\
\ value desc")
,("Q12","\n\
\ value desc"
,q "Q12" "\n\
\ select\n\
\ l_shipmode,\n\
\ sum(case\n\
@ -370,8 +369,8 @@ tpchQueries =
\ group by\n\
\ l_shipmode\n\
\ order by\n\
\ l_shipmode")
,("Q13","\n\
\ l_shipmode"
,q "Q13" "\n\
\ select\n\
\ c_count,\n\
\ count(*) as custdist\n\
@ -391,8 +390,8 @@ tpchQueries =
\ c_count\n\
\ order by\n\
\ custdist desc,\n\
\ c_count desc")
,("Q14","\n\
\ c_count desc"
,q "Q14" "\n\
\ select\n\
\ 100.00 * sum(case\n\
\ when p_type like 'PROMO%'\n\
@ -405,8 +404,8 @@ tpchQueries =
\ where\n\
\ l_partkey = p_partkey\n\
\ and l_shipdate >= date '1994-12-01'\n\
\ and l_shipdate < date '1994-12-01' + interval '1' month")
,("Q15","\n\
\ and l_shipdate < date '1994-12-01' + interval '1' month"
,q "Q15" "\n\
\ /*create view revenue0 (supplier_no, total_revenue) as\n\
\ select\n\
\ l_suppkey,\n\
@ -448,8 +447,8 @@ tpchQueries =
\ revenue0\n\
\ )\n\
\ order by\n\
\ s_suppkey")
,("Q16","\n\
\ s_suppkey"
,q "Q16" "\n\
\ select\n\
\ p_brand,\n\
\ p_type,\n\
@ -479,8 +478,8 @@ tpchQueries =
\ supplier_cnt desc,\n\
\ p_brand,\n\
\ p_type,\n\
\ p_size")
,("Q17","\n\
\ p_size"
,q "Q17" "\n\
\ select\n\
\ sum(l_extendedprice) / 7.0 as avg_yearly\n\
\ from\n\
@ -497,8 +496,8 @@ tpchQueries =
\ lineitem\n\
\ where\n\
\ l_partkey = p_partkey\n\
\ )")
,("Q18","\n\
\ )"
,q "Q18" "\n\
\ select\n\
\ c_name,\n\
\ c_custkey,\n\
@ -531,8 +530,8 @@ tpchQueries =
\ order by\n\
\ o_totalprice desc,\n\
\ o_orderdate\n\
\ fetch first 100 rows only")
,("Q19","\n\
\ fetch first 100 rows only"
,q "Q19" "\n\
\ select\n\
\ sum(l_extendedprice* (1 - l_discount)) as revenue\n\
\ from\n\
@ -567,8 +566,8 @@ tpchQueries =
\ and p_size between 1 and 15\n\
\ and l_shipmode in ('AIR', 'AIR REG')\n\
\ and l_shipinstruct = 'DELIVER IN PERSON'\n\
\ )")
,("Q20","\n\
\ )"
,q "Q20" "\n\
\ select\n\
\ s_name,\n\
\ s_address\n\
@ -605,8 +604,8 @@ tpchQueries =
\ and s_nationkey = n_nationkey\n\
\ and n_name = 'VIETNAM'\n\
\ order by\n\
\ s_name")
,("Q21","\n\
\ s_name"
,q "Q21" "\n\
\ select\n\
\ s_name,\n\
\ count(*) as numwait\n\
@ -646,8 +645,8 @@ tpchQueries =
\ order by\n\
\ numwait desc,\n\
\ s_name\n\
\ fetch first 100 rows only")
,("Q22","\n\
\ fetch first 100 rows only"
,q "Q22" "\n\
\ select\n\
\ cntrycode,\n\
\ count(*) as numcust,\n\
@ -684,5 +683,8 @@ tpchQueries =
\ group by\n\
\ cntrycode\n\
\ order by\n\
\ cntrycode")
\ cntrycode"
]
where
q :: HasCallStack => Text -> Text -> TestItem
q _ src = testParseQueryExpr ansi2011 src