postgresql-syntax 0.4.1 → 0.4.1.1
raw patch · 13 files changed
+434/−392 lines, 13 filesdep −QuickCheckdep −quickcheck-instancesdep −tasty-quickcheckdep ~bytestring
Dependencies removed: QuickCheck, quickcheck-instances, tasty-quickcheck
Dependency ranges changed: bytestring
Files
- hedgehog-test/Main.hs +18/−19
- hedgehog-test/Main/Gen.hs +21/−16
- library/PostgresqlSyntax/Ast.hs +8/−10
- library/PostgresqlSyntax/Extras/HeadedMegaparsec.hs +6/−4
- library/PostgresqlSyntax/Extras/NonEmpty.hs +3/−1
- library/PostgresqlSyntax/KeywordSet.hs +5/−2
- library/PostgresqlSyntax/Parsing.hs +208/−209
- library/PostgresqlSyntax/Predicate.hs +7/−5
- library/PostgresqlSyntax/Prelude.hs +14/−10
- library/PostgresqlSyntax/Rendering.hs +4/−5
- library/PostgresqlSyntax/Validation.hs +3/−4
- postgresql-syntax.cabal +88/−48
- tasty-test/Main.hs +49/−59
hedgehog-test/Main.hs view
@@ -2,33 +2,32 @@ import qualified Data.Text as Text import Hedgehog-import qualified Hedgehog.Gen as Gen import Hedgehog.Main-import qualified Hedgehog.Range as Range import qualified Main.Gen as Gen-import qualified PostgresqlSyntax.Ast as Ast import qualified PostgresqlSyntax.Parsing as Parsing import qualified PostgresqlSyntax.Rendering as Rendering import Prelude +main :: IO () main = defaultMain- [ checkParallel $- Group "Parsing a rendered AST produces the same AST" $- let p _name _amount _gen _parser _renderer =- (,) _name $- withDiscards (fromIntegral _amount * 200) $- withTests _amount $- property $ do- ast <- forAll _gen- let sql = Rendering.toText (_renderer ast)- in do- footnote ("SQL: " <> Text.unpack sql)- case Parsing.run _parser sql of- Left err -> do- footnote err- failure- Right ast' -> ast === ast'+ [ checkParallel+ $ Group "Parsing a rendered AST produces the same AST"+ $ let p name amount gen parser renderer =+ (,) name+ $ withDiscards (fromIntegral amount * 200)+ $ withTests amount+ $ property+ $ do+ ast <- forAll gen+ let sql = Rendering.toText (renderer ast)+ in do+ footnote ("SQL: " <> Text.unpack sql)+ case Parsing.run parser sql of+ Left err -> do+ footnote err+ failure+ Right ast' -> ast === ast' in [ p "typename" 10000 Gen.typename Parsing.typename Rendering.typename, p "tableRef" 10000 Gen.tableRef Parsing.tableRef Rendering.tableRef, p "aExpr" 60000 Gen.aExpr Parsing.aExpr Rendering.aExpr,
hedgehog-test/Main/Gen.hs view
@@ -1,9 +1,11 @@+{-# OPTIONS_GHC -Wno-missing-signatures #-}+ module Main.Gen where import qualified Data.HashSet as HashSet import qualified Data.List as List import qualified Data.Text as Text-import Hedgehog (Gen, MonadGen)+import Hedgehog (Gen) import Hedgehog.Gen import qualified Hedgehog.Range as Range import PostgresqlSyntax.Ast@@ -13,9 +15,9 @@ -- * Generic -inSet _set = filter (flip HashSet.member _set)+inSet set = filter (flip HashSet.member set) -notInSet _set = filter (not . flip HashSet.member _set)+notInSet set = filter (not . flip HashSet.member set) -- * Statements @@ -105,8 +107,8 @@ -- ** selectWithParens -selectWithParens = sized $ \_size ->- if _size <= 1+selectWithParens = sized $ \size ->+ if size <= 1 then discard else frequency@@ -144,8 +146,8 @@ valuesSimpleSelect = ValuesSimpleSelect <$> valuesClause -binSimpleSelect _leftSelect =- BinSimpleSelect <$> selectBinOp <*> pure _leftSelect <*> maybe allOrDistinct <*> small selectClause+binSimpleSelect leftSelect =+ BinSimpleSelect <$> selectBinOp <*> pure leftSelect <*> maybe allOrDistinct <*> small selectClause terminalSimpleSelect = pure (NormalSimpleSelect Nothing Nothing Nothing Nothing Nothing Nothing Nothing) @@ -523,8 +525,6 @@ GroupingCExpr <$> exprList ] --- **- caseExpr = CaseExpr <$> maybe aExpr <*> whenClauseList <*> maybe aExpr whenClauseList = nonEmpty (Range.exponential 1 7) whenClause@@ -538,8 +538,8 @@ ] arrayExpr =- small $- choice+ small+ $ choice [ ExprListArrayExpr <$> exprList, ArrayExprListArrayExpr <$> arrayExprList, pure EmptyArrayExpr@@ -678,7 +678,7 @@ ] op = do- a <- text (Range.exponential 1 7) (element "+-*/<>=~!@#%^&|`?")+ a <- text (Range.exponential 1 7) (listElement "+-*/<>=~!@#%^&|`?") case Validation.op a of Nothing -> return a _ -> discard@@ -741,8 +741,8 @@ [ IAexprConst <$> iconst, FAexprConst <$> fconst, SAexprConst <$> sconst,- BAexprConst <$> text (Range.exponential 1 100) (element "01"),- XAexprConst <$> text (Range.exponential 1 100) (element "0123456789abcdefABCDEF"),+ BAexprConst <$> text (Range.exponential 1 100) (listElement "01"),+ XAexprConst <$> text (Range.exponential 1 100) (listElement "0123456789abcdefABCDEF"), FuncAexprConst <$> funcName <*> maybe funcConstArgs <*> sconst, ConstTypenameAexprConst <$> constTypename <*> sconst, StringIntervalAexprConst <$> sconst <*> maybe interval,@@ -822,8 +822,8 @@ iconstOrFconst = choice [Left <$> iconst <|> Right <$> fconst] fconst =- filter (\a -> fromIntegral (round a) /= a) $- realFrac_ (Range.exponentialFloat 0 309457394857984375983475943)+ filter (\a -> fromIntegral (round a) /= a)+ $ realFrac_ (Range.exponentialFloat 0 309457394857984375983475943) iconst = integral (Range.exponential 0 maxBound) @@ -945,3 +945,8 @@ ascDesc = enumBounded nullsOrder = enumBounded++-- * Helpers++listElement :: [a] -> Gen a+listElement = element
library/PostgresqlSyntax/Ast.hs view
@@ -5,7 +5,7 @@ -- For reasoning see the docs of the parsing module of this project. module PostgresqlSyntax.Ast where -import PostgresqlSyntax.Prelude hiding (Op, Order)+import PostgresqlSyntax.Prelude -- * Statement @@ -773,15 +773,15 @@ -- @ data RelationExpr = SimpleRelationExpr+ -- | Name. QualifiedName- -- ^ Name.+ -- | Is asterisk present? Bool- -- ^ Is asterisk present? | OnlyRelationExpr+ -- | Name. QualifiedName- -- ^ Name.+ -- | Are parentheses present? Bool- -- ^ Are parentheses present? deriving (Show, Generic, Eq, Ord) -- |@@ -1162,8 +1162,6 @@ | GroupingCExpr ExprList deriving (Show, Generic, Eq, Ord) --- **- -- | -- ==== References -- @@@ -1983,13 +1981,13 @@ -- @ data Typename = Typename+ -- | SETOF Bool- -- ^ SETOF SimpleTypename+ -- | Question mark Bool- -- ^ Question mark+ -- | Array dimensions possibly followed by a question mark (Maybe (TypenameArrayDimensions, Bool))- -- ^ Array dimensions possibly followed by a question mark deriving (Show, Generic, Eq, Ord) -- |
library/PostgresqlSyntax/Extras/HeadedMegaparsec.hs view
@@ -1,3 +1,5 @@+{-# OPTIONS_GHC -Wno-redundant-constraints -Wno-dodgy-imports -Wno-unused-imports #-}+ -- | -- Generic helpers for HeadedMegaparsec. module PostgresqlSyntax.Extras.HeadedMegaparsec where@@ -79,11 +81,11 @@ -- * Combinators sep1 :: (Ord err, Stream strm, Megaparsec.Token strm ~ Char) => HeadedParsec err strm separtor -> HeadedParsec err strm a -> HeadedParsec err strm (NonEmpty a)-sep1 _separator _parser = do- _head <- _parser+sep1 separator parser = do+ head <- parser endHead- _tail <- many $ _separator *> _parser- return (_head :| _tail)+ tail <- many $ separator *> parser+ return (head :| tail) sepEnd1 :: (Ord err, Stream strm, Megaparsec.Token strm ~ Char) => HeadedParsec err strm separator -> HeadedParsec err strm end -> HeadedParsec err strm el -> HeadedParsec err strm (NonEmpty el, end) sepEnd1 sepP endP elP = do
library/PostgresqlSyntax/Extras/NonEmpty.hs view
@@ -1,3 +1,5 @@+{-# OPTIONS_GHC -Wno-dodgy-imports #-}+ module PostgresqlSyntax.Extras.NonEmpty where import Data.List.NonEmpty@@ -9,7 +11,7 @@ -- -- >>> intersperseFoldMap ", " id (fromList ["a", "b", "c"]) -- "a, b, c"-intersperseFoldMap :: Monoid m => m -> (a -> m) -> NonEmpty a -> m+intersperseFoldMap :: (Monoid m) => m -> (a -> m) -> NonEmpty a -> m intersperseFoldMap a b (c :| d) = b c <> foldMap (mappend a . b) d unsnoc :: NonEmpty a -> (Maybe (NonEmpty a), a)
library/PostgresqlSyntax/KeywordSet.hs view
@@ -1,8 +1,7 @@ module PostgresqlSyntax.KeywordSet where import Data.HashSet-import qualified Data.Text as Text-import PostgresqlSyntax.Prelude hiding (expression, fromList, toList)+import PostgresqlSyntax.Prelude hiding (fromList, toList) {-# NOINLINE keyword #-} {-@@ -36,6 +35,7 @@ lexicalBinOp = fromList ["and", "or"] {-# NOINLINE colId #-}+colId :: HashSet Text colId = unions [unreservedKeyword, colNameKeyword] {-@@ -45,6 +45,7 @@ | type_func_name_keyword -} {-# NOINLINE typeFunctionName #-}+typeFunctionName :: HashSet Text typeFunctionName = unions [unreservedKeyword, typeFuncNameKeyword] -- |@@ -57,7 +58,9 @@ -- * rather than the generic Op. -- */ {-# NOINLINE nonOp #-}+nonOp :: HashSet Text nonOp = fromList [">=", "<=", "=>", "<>", "!="] <> mathOp {-# NOINLINE mathOp #-}+mathOp :: HashSet Text mathOp = fromList ["<>", ">=", "!=", "<=", "+", "-", "*", "/", "%", "^", "<", ">", "="]
library/PostgresqlSyntax/Parsing.hs view
@@ -1,3 +1,5 @@+{-# OPTIONS_GHC -Wno-redundant-constraints -Wno-missing-signatures -Wno-dodgy-imports #-}+ -- | -- -- Our parsing strategy is to port the original Postgres parser as closely as possible.@@ -28,7 +30,6 @@ import Control.Applicative.Combinators hiding (some) import Control.Applicative.Combinators.NonEmpty import qualified Data.HashSet as HashSet-import qualified Data.List.NonEmpty as NonEmpty import qualified Data.Text as Text import HeadedMegaparsec hiding (string) import PostgresqlSyntax.Ast@@ -40,10 +41,8 @@ import PostgresqlSyntax.Prelude hiding (bit, expr, filter, fromList, head, many, option, some, sortBy, tail, try) import qualified PostgresqlSyntax.Validation as Validation import qualified Text.Builder as TextBuilder-import Text.Megaparsec (Parsec, Stream) import qualified Text.Megaparsec as Megaparsec import qualified Text.Megaparsec.Char as MegaparsecChar-import qualified Text.Megaparsec.Char.Lexer as MegaparsecLexer -- $setup -- >>> testParser parser = either putStr print . run parser@@ -76,16 +75,16 @@ inParensCont p = char '(' *> endHead *> pure (space *> p <* endHead <* space <* char ')') inParensWithLabel :: (label -> content -> result) -> Parser label -> Parser content -> Parser result-inParensWithLabel _result _labelParser _contentParser = do- _label <- wrapToHead _labelParser+inParensWithLabel result labelParser contentParser = do+ label <- wrapToHead labelParser space char '(' endHead space- _content <- _contentParser+ content <- contentParser space char ')'- pure (_result _label _content)+ pure (result label content) inParensWithClause :: Parser clause -> Parser content -> Parser content inParensWithClause = inParensWithLabel (const id)@@ -100,21 +99,21 @@ quotedString q = do char q endHead- _tail <-- parse $- let collectChunks !bdr = do- chunk <- Megaparsec.takeWhileP Nothing (/= q)- let bdr' = bdr <> TextBuilder.text chunk- Megaparsec.try (consumeEscapedQuote bdr') <|> finish bdr'- consumeEscapedQuote bdr = do- MegaparsecChar.char q- MegaparsecChar.char q- collectChunks (bdr <> TextBuilder.char q)- finish bdr = do- MegaparsecChar.char q- return (TextBuilder.run bdr)- in collectChunks mempty- return _tail+ tail <-+ parse+ $ let collectChunks !bdr = do+ chunk <- Megaparsec.takeWhileP Nothing (/= q)+ let bdr' = bdr <> TextBuilder.text chunk+ Megaparsec.try (consumeEscapedQuote bdr') <|> finish bdr'+ consumeEscapedQuote bdr = do+ MegaparsecChar.char q+ MegaparsecChar.char q+ collectChunks (bdr <> TextBuilder.char q)+ finish bdr = do+ MegaparsecChar.char q+ return (TextBuilder.run bdr)+ in collectChunks mempty+ return tail atEnd :: Parser a -> Parser a atEnd p = space *> p <* endHead <* space <* eof@@ -311,12 +310,12 @@ selectNoParens = withSelectNoParens <|> simpleSelectNoParens -sharedSelectNoParens _with = do- _select <- selectClause- _sort <- optional (space1 *> sortClause)- _limit <- optional (space1 *> selectLimit)- _forLocking <- optional (space1 *> forLockingClause)- return (SelectNoParens _with _select _sort _limit _forLocking)+sharedSelectNoParens with = do+ select <- selectClause+ sort <- optional (space1 *> sortClause)+ limit <- optional (space1 *> selectLimit)+ forLocking <- optional (space1 *> forLockingClause)+ return (SelectNoParens with select sort limit forLocking) -- | -- The one that doesn't start with \"WITH\".@@ -331,9 +330,9 @@ simpleSelectNoParens = sharedSelectNoParens Nothing withSelectNoParens = do- _with <- wrapToHead withClause+ with <- wrapToHead withClause space1- sharedSelectNoParens (Just _with)+ sharedSelectNoParens (Just with) selectClause = suffixRec base suffix where@@ -350,14 +349,14 @@ keyword "select" notFollowedBy $ satisfy $ isAlphaNum endHead- _targeting <- optional (space1 *> targeting)- _intoClause <- optional (space1 *> keyword "into" *> endHead *> space1 *> optTempTableName)- _fromClause <- optional (space1 *> fromClause)- _whereClause <- optional (space1 *> whereClause)- _groupClause <- optional (space1 *> keyphrase "group by" *> endHead *> space1 *> sep1 commaSeparator groupByItem)- _havingClause <- optional (space1 *> keyword "having" *> endHead *> space1 *> aExpr)- _windowClause <- optional (space1 *> keyword "window" *> endHead *> space1 *> sep1 commaSeparator windowDefinition)- return (NormalSimpleSelect _targeting _intoClause _fromClause _whereClause _groupClause _havingClause _windowClause),+ targeting <- optional (space1 *> targeting)+ intoClause <- optional (space1 *> keyword "into" *> endHead *> space1 *> optTempTableName)+ fromClause <- optional (space1 *> fromClause)+ whereClause <- optional (space1 *> whereClause)+ groupClause <- optional (space1 *> keyphrase "group by" *> endHead *> space1 *> sep1 commaSeparator groupByItem)+ havingClause <- optional (space1 *> keyword "having" *> endHead *> space1 *> aExpr)+ windowClause <- optional (space1 *> keyword "window" *> endHead *> space1 *> sep1 commaSeparator windowDefinition)+ return (NormalSimpleSelect targeting intoClause fromClause whereClause groupClause havingClause windowClause), do keyword "table" space1@@ -366,12 +365,12 @@ ValuesSimpleSelect <$> valuesClause ] -extensionSimpleSelect _headSelectClause = do- _op <- space1 *> selectBinOp <* space1+extensionSimpleSelect headSelectClause = do+ op <- space1 *> selectBinOp <* space1 endHead- _allOrDistinct <- optional (allOrDistinct <* space1)- _selectClause <- selectClause- return (BinSimpleSelect _op _headSelectClause _allOrDistinct _selectClause)+ allOrDistinct <- optional (allOrDistinct <* space1)+ selectClause <- selectClause+ return (BinSimpleSelect op headSelectClause allOrDistinct selectClause) allOrDistinct = keyword "all" $> False <|> keyword "distinct" $> True @@ -389,27 +388,27 @@ char '(' endHead space- _a <- sep1 commaSeparator aExpr+ a <- sep1 commaSeparator aExpr space char ')'- return _a+ return a withClause = label "with clause" $ do keyword "with" space1 endHead- _recursive <- option False (True <$ keyword "recursive" <* space1)- _cteList <- sep1 commaSeparator commonTableExpr- return (WithClause _recursive _cteList)+ recursive <- option False (True <$ keyword "recursive" <* space1)+ cteList <- sep1 commaSeparator commonTableExpr+ return (WithClause recursive cteList) commonTableExpr = label "common table expression" $ do- _name <- colId <* space <* endHead- _nameList <- optional (inParens (sep1 commaSeparator colId) <* space1)+ name <- colId <* space <* endHead+ nameList <- optional (inParens (sep1 commaSeparator colId) <* space1) keyword "as" space1- _materialized <- optional (materialized <* space1)- _stmt <- inParens preparableStmt- return (CommonTableExpr _name _nameList _materialized _stmt)+ materialized <- optional (materialized <* space1)+ stmt <- inParens preparableStmt+ return (CommonTableExpr name nameList materialized stmt) materialized = True <$ keyword "materialized"@@ -427,9 +426,9 @@ keyword "distinct" space1 endHead- _optOn <- optional (onExpressionsClause <* space1)- _targetList <- targetList- return (DistinctTargeting _optOn _targetList)+ optOn <- optional (onExpressionsClause <* space1)+ targetList <- targetList+ return (DistinctTargeting optOn targetList) targetList = sep1 commaSeparator targetEl @@ -437,18 +436,18 @@ -- >>> testParser targetEl "a.b as c" -- AliasedExprTargetEl (CExprAExpr (ColumnrefCExpr (Columnref (UnquotedIdent "a") (Just (AttrNameIndirectionEl (UnquotedIdent "b") :| []))))) (UnquotedIdent "c") targetEl =- label "target" $- asum+ label "target"+ $ asum [ do- _expr <- aExpr+ expr <- aExpr asum [ do space1 asum- [ AliasedExprTargetEl _expr <$> (keyword "as" *> space1 *> endHead *> colLabel),- ImplicitlyAliasedExprTargetEl _expr <$> ident+ [ AliasedExprTargetEl expr <$> (keyword "as" *> space1 *> endHead *> colLabel),+ ImplicitlyAliasedExprTargetEl expr <$> ident ],- pure (ExprTargetEl _expr)+ pure (ExprTargetEl expr) ], AsteriskTargetEl <$ char '*' ]@@ -522,8 +521,8 @@ -- opt_sort_clause opt_frame_clause ')' -- @ windowSpecification =- inParens $- asum+ inParens+ $ asum [ do a <- frameClause return (WindowSpecification Nothing Nothing Nothing (Just a)),@@ -607,18 +606,18 @@ -- >>> testParser tableRef "a left join b on (a.i = b.i)" -- JoinTableRef (MethJoinedTable (QualJoinMeth... tableRef =- label "table reference" $- do- _tr <- nonTrailingTableRef- recur _tr+ label "table reference"+ $ do+ tr <- nonTrailingTableRef+ recur tr where- recur _tr =+ recur tr = asum [ do- _tr2 <- wrapToHead (space1 *> trailingTableRef _tr)+ tr2 <- wrapToHead (space1 *> trailingTableRef tr) endHead- recur _tr2,- pure _tr+ recur tr2,+ pure tr ] nonTrailingTableRef =@@ -631,11 +630,11 @@ ] where relationExprTableRef = do- _relationExpr <- relationExpr+ relationExpr <- relationExpr endHead- _optAliasClause <- optional (space1 *> aliasClause)- _optTablesampleClause <- optional (space1 *> tablesampleClause)- return (RelationExprTableRef _relationExpr _optAliasClause _optTablesampleClause)+ optAliasClause <- optional (space1 *> aliasClause)+ optTablesampleClause <- optional (space1 *> tablesampleClause)+ return (RelationExprTableRef relationExpr optAliasClause optTablesampleClause) lateralTableRef = do keyword "lateral"@@ -645,46 +644,46 @@ nonLateralTableRef = lateralableTableRef False - lateralableTableRef _lateral =+ lateralableTableRef lateral = asum [ do a <- funcTable b <- optional (space1 *> funcAliasClause)- return (FuncTableRef _lateral a b),+ return (FuncTableRef lateral a b), do- _select <- selectWithParens- _optAliasClause <- optional $ space1 *> aliasClause- return (SelectTableRef _lateral _select _optAliasClause)+ select <- selectWithParens+ optAliasClause <- optional $ space1 *> aliasClause+ return (SelectTableRef lateral select optAliasClause) ] inParensJoinedTableTableRef = JoinTableRef <$> inParensJoinedTable <*> pure Nothing joinedTableWithAliasTableRef = do- _joinedTable <- wrapToHead (inParens joinedTable)+ joinedTable <- wrapToHead (inParens joinedTable) space1- _alias <- aliasClause- return (JoinTableRef _joinedTable (Just _alias))+ alias <- aliasClause+ return (JoinTableRef joinedTable (Just alias)) -trailingTableRef _tableRef =- JoinTableRef <$> trailingJoinedTable _tableRef <*> pure Nothing+trailingTableRef tableRef =+ JoinTableRef <$> trailingJoinedTable tableRef <*> pure Nothing relationExpr =- label "relation expression" $- asum+ label "relation expression"+ $ asum [ do keyword "only" space1- _name <- qualifiedName- return (OnlyRelationExpr _name False),+ name <- qualifiedName+ return (OnlyRelationExpr name False), inParensWithClause (keyword "only") qualifiedName <&> \a -> OnlyRelationExpr a True, do- _name <- qualifiedName- _asterisk <-+ name <- qualifiedName+ asterisk <- asum [ True <$ (space1 *> char '*'), pure False ]- return (SimpleRelationExpr _name _asterisk)+ return (SimpleRelationExpr name asterisk) ] relationExprOptAlias reservedKeywords = do@@ -796,18 +795,18 @@ head = asum [ do- _tr <- wrapToHead nonTrailingTableRef+ tr <- wrapToHead nonTrailingTableRef space1- trailingJoinedTable _tr,+ trailingJoinedTable tr, inParensJoinedTable ]- tail _jt =+ tail jt = asum [ do- _jt2 <- wrapToHead (space1 *> trailingJoinedTable (JoinTableRef _jt Nothing))+ jt2 <- wrapToHead (space1 *> trailingJoinedTable (JoinTableRef jt Nothing)) endHead- tail _jt2,- pure _jt+ tail jt2,+ pure jt ] -- |@@ -826,30 +825,30 @@ -- | table_ref NATURAL join_type JOIN table_ref -- | table_ref NATURAL JOIN table_ref -- @-trailingJoinedTable _tr1 =+trailingJoinedTable tr1 = asum [ do keyphrase "cross join" endHead space1- _tr2 <- nonTrailingTableRef- return (MethJoinedTable CrossJoinMeth _tr1 _tr2),+ tr2 <- nonTrailingTableRef+ return (MethJoinedTable CrossJoinMeth tr1 tr2), do- _jt <- joinTypedJoin+ jt <- joinTypedJoin endHead space1- _tr2 <- tableRef+ tr2 <- tableRef space1- _jq <- joinQual- return (MethJoinedTable (QualJoinMeth _jt _jq) _tr1 _tr2),+ jq <- joinQual+ return (MethJoinedTable (QualJoinMeth jt jq) tr1 tr2), do keyword "natural" endHead space1- _jt <- joinTypedJoin+ jt <- joinTypedJoin space1- _tr2 <- nonTrailingTableRef- return (MethJoinedTable (NaturalJoinMeth _jt) _tr1 _tr2)+ tr2 <- nonTrailingTableRef+ return (MethJoinedTable (NaturalJoinMeth jt) tr1 tr2) ] where joinTypedJoin =@@ -861,18 +860,18 @@ [ do keyword "full" endHead- _outer <- outerAfterSpace- return (FullJoinType _outer),+ outer <- outerAfterSpace+ return (FullJoinType outer), do keyword "left" endHead- _outer <- outerAfterSpace- return (LeftJoinType _outer),+ outer <- outerAfterSpace+ return (LeftJoinType outer), do keyword "right" endHead- _outer <- outerAfterSpace- return (RightJoinType _outer),+ outer <- outerAfterSpace+ return (RightJoinType outer), keyword "inner" $> InnerJoinType ] where@@ -885,9 +884,9 @@ ] aliasClause = do- (_as, _alias) <- (True,) <$> (keyword "as" *> space1 *> endHead *> colId) <|> (False,) <$> colId- _columnAliases <- optional (space1 *> inParens (sep1 commaSeparator colId))- return (AliasClause _as _alias _columnAliases)+ (as, alias) <- (True,) <$> (keyword "as" *> space1 *> endHead *> colId) <|> (False,) <$> colId+ columnAliases <- optional (space1 *> inParens (sep1 commaSeparator colId))+ return (AliasClause as alias columnAliases) -- * Where @@ -1055,7 +1054,6 @@ customizedBExpr cExpr = suffixRec base suffix where- aExpr = customizedAExpr cExpr bExpr = customizedBExpr cExpr base = asum@@ -1096,8 +1094,8 @@ do keyword "array" space- join $- asum+ join+ $ asum [ fmap (fmap (ArrayCExpr . Right)) arrayExprCont, fmap (fmap (ArrayCExpr . Left) . pure) selectWithParens ],@@ -1112,8 +1110,6 @@ ColumnrefCExpr <$> columnref ] --- *- subqueryOp = asum [ AnySubqueryOp <$> (keyword "operator" *> space *> endHead *> inParens anyOperator),@@ -1132,19 +1128,19 @@ inExpr = SelectInExpr <$> wrapToHead selectWithParens <|> ExprListInExpr <$> inParens exprList -symbolicBinOpExpr _a _bParser _constr = do- _binOp <- label "binary operator" (space *> wrapToHead symbolicExprBinOp <* space)- _b <- _bParser- return (_constr _a _binOp _b)+symbolicBinOpExpr a bParser constr = do+ binOp <- label "binary operator" (space *> wrapToHead symbolicExprBinOp <* space)+ b <- bParser+ return (constr a binOp b) typecastExpr :: a -> (a -> Typename -> a) -> HeadedParsec Void Text a-typecastExpr _prefix _constr = do+typecastExpr prefix constr = do space string "::" endHead space- _type <- typename- return (_constr _prefix _type)+ type' <- typename+ return (constr prefix type') plusedExpr expr = char '+' *> space *> expr @@ -1164,8 +1160,8 @@ (c, d) -> ImplicitRow c d arrayExprCont =- inBracketsCont $- asum+ inBracketsCont+ $ asum [ ArrayExprListArrayExpr <$> sep1 commaSeparator (join arrayExprCont), ExprListArrayExpr <$> exprList, pure EmptyArrayExpr@@ -1175,23 +1171,23 @@ keyword "case" space1 endHead- _arg <- optional (aExpr <* space1)- _whenClauses <- sep1 space1 whenClause+ arg <- optional (aExpr <* space1)+ whenClauses <- sep1 space1 whenClause space1- _default <- optional elseClause+ default' <- optional elseClause keyword "end"- pure $ CaseExpr _arg _whenClauses _default+ pure $ CaseExpr arg whenClauses default' whenClause = do keyword "when" space1 endHead- _a <- aExpr+ a <- aExpr space1 keyword "then" space1- _b <- aExpr- return (WhenClause _a _b)+ b <- aExpr+ return (WhenClause a b) elseClause = do keyword "else"@@ -1267,7 +1263,7 @@ inParensWithClause (keyword "least") (LeastFuncExprCommonSubexpr <$> exprList) ] where- labeledIconst _label = keyword _label *> endHead *> optional (space *> inParens iconst)+ labeledIconst label = keyword label *> endHead *> optional (space *> inParens iconst) extractList = ExtractList <$> extractArg <*> (space1 *> keyword "from" *> space1 *> aExpr) @@ -1349,26 +1345,26 @@ ] normalFuncApplicationParams = do- _optAllOrDistinct <- optional (allOrDistinct <* space1)- _argList <- sep1 commaSeparator funcArgExpr+ optAllOrDistinct <- optional (allOrDistinct <* space1)+ argList <- sep1 commaSeparator funcArgExpr endHead- _optSortClause <- optional (space1 *> sortClause)- return (NormalFuncApplicationParams _optAllOrDistinct _argList _optSortClause)+ optSortClause <- optional (space1 *> sortClause)+ return (NormalFuncApplicationParams optAllOrDistinct argList optSortClause) singleVariadicFuncApplicationParams = do keyword "variadic" space1 endHead- _arg <- funcArgExpr- _optSortClause <- optional (space1 *> sortClause)- return (VariadicFuncApplicationParams Nothing _arg _optSortClause)+ arg <- funcArgExpr+ optSortClause <- optional (space1 *> sortClause)+ return (VariadicFuncApplicationParams Nothing arg optSortClause) listVariadicFuncApplicationParams = do- (_argList, _) <- wrapToHead $ sepEnd1 commaSeparator (keyword "variadic" <* space1) funcArgExpr+ (argList, _) <- wrapToHead $ sepEnd1 commaSeparator (keyword "variadic" <* space1) funcArgExpr endHead- _arg <- funcArgExpr- _optSortClause <- optional (space1 *> sortClause)- return (VariadicFuncApplicationParams (Just _argList) _arg _optSortClause)+ arg <- funcArgExpr+ optSortClause <- optional (space1 *> sortClause)+ return (VariadicFuncApplicationParams (Just argList) arg optSortClause) starFuncApplicationParams = space *> char '*' *> endHead *> space $> StarFuncApplicationParams @@ -1668,11 +1664,11 @@ selectLimit = asum [ do- _a <- limitClause- LimitOffsetSelectLimit _a <$> (space1 *> offsetClause) <|> pure (LimitSelectLimit _a),+ a <- limitClause+ LimitOffsetSelectLimit a <$> (space1 *> offsetClause) <|> pure (LimitSelectLimit a), do- _a <- offsetClause- OffsetLimitSelectLimit _a <$> (space1 *> limitClause) <|> pure (OffsetSelectLimit _a)+ a <- offsetClause+ OffsetLimitSelectLimit a <$> (space1 *> limitClause) <|> pure (OffsetSelectLimit a) ] -- |@@ -1689,31 +1685,31 @@ keyword "limit" endHead space1- _a <- selectLimitValue- _b <- optional $ do+ a <- selectLimitValue+ b <- optional $ do commaSeparator aExpr- return (LimitLimitClause _a _b)+ return (LimitLimitClause a b) ) <|> ( do keyword "fetch" endHead space1- _a <- firstOrNext+ a <- firstOrNext space1 asum [ do- _b <- rowOrRows+ b <- rowOrRows space1 keyword "only"- return (FetchOnlyLimitClause _a Nothing _b),+ return (FetchOnlyLimitClause a Nothing b), do- _b <- selectFetchFirstValue+ b <- selectFetchFirstValue space1- _c <- rowOrRows+ c <- rowOrRows space1 keyword "only"- return (FetchOnlyLimitClause _a (Just _b) _c)+ return (FetchOnlyLimitClause a (Just b) c) ] ) @@ -1783,10 +1779,10 @@ -- | EMPTY -- @ forLockingItem = do- _strength <- forLockingStrength- _rels <- optional $ space1 *> keyword "of" *> space1 *> endHead *> sep1 commaSeparator qualifiedName- _nowaitOrSkip <- optional (space1 *> nowaitOrSkip)- return (ForLockingItem _strength _rels _nowaitOrSkip)+ strength <- forLockingStrength+ rels <- optional $ space1 *> keyword "of" *> space1 *> endHead *> sep1 commaSeparator qualifiedName+ nowaitOrSkip <- optional (space1 *> nowaitOrSkip)+ return (ForLockingItem strength rels nowaitOrSkip) -- | -- ==== References@@ -1828,14 +1824,15 @@ -- @ {-# NOINLINE colId #-} colId =- label "identifier" $- ident <|> keywordNameFromSet (KeywordSet.unreservedKeyword <> KeywordSet.colNameKeyword)+ label "identifier"+ $ ident+ <|> keywordNameFromSet (KeywordSet.unreservedKeyword <> KeywordSet.colNameKeyword) {-# NOINLINE filteredColId #-} filteredColId =- let _originalSet = KeywordSet.unreservedKeyword <> KeywordSet.colNameKeyword- _filteredSet = foldr HashSet.delete _originalSet- in \_reservedKeywords -> label "identifier" $ ident <|> keywordNameFromSet (_filteredSet _reservedKeywords)+ let originalSet = KeywordSet.unreservedKeyword <> KeywordSet.colNameKeyword+ filteredSet = foldr HashSet.delete originalSet+ in \reservedKeywords -> label "identifier" $ ident <|> keywordNameFromSet (filteredSet reservedKeywords) -- | -- ==== References@@ -1848,8 +1845,9 @@ -- | reserved_keyword -- @ colLabel =- label "column label" $- keywordNameFromSet KeywordSet.keyword <|> ident+ label "column label"+ $ keywordNameFromSet KeywordSet.keyword+ <|> ident -- | -- >>> testParser qualifiedName "a.b"@@ -1871,7 +1869,7 @@ columnref = customizedColumnref colId -filteredColumnref _keywords = customizedColumnref (filteredColId _keywords)+filteredColumnref keywords = customizedColumnref (filteredColId keywords) customizedColumnref colId = do a <- wrapToHead colId@@ -1881,7 +1879,7 @@ anyName = customizedAnyName colId -filteredAnyName _keywords = customizedAnyName (filteredColId _keywords)+filteredAnyName keywords = customizedAnyName (filteredColId keywords) customizedAnyName colId = do a <- wrapToHead colId@@ -1950,29 +1948,29 @@ char '[' endHead space- _a <-+ a <- asum [ do char ':' endHead space- _b <- optional aExpr- return (SliceIndirectionEl Nothing _b),+ b <- optional aExpr+ return (SliceIndirectionEl Nothing b), do- _a <- aExpr+ a <- aExpr asum [ do space char ':' space- _b <- optional aExpr- return (SliceIndirectionEl (Just _a) _b),- return (ExprIndirectionEl _a)+ b <- optional aExpr+ return (SliceIndirectionEl (Just a) b),+ return (ExprIndirectionEl a) ] ] space char ']'- return _a+ return a ] -- |@@ -1983,20 +1981,21 @@ -- @ attrName = colLabel -keywordNameFromSet _set = keywordNameByPredicate (Predicate.inSet _set)+keywordNameFromSet set = keywordNameByPredicate (Predicate.inSet set) -keywordNameByPredicate _predicate =- fmap UnquotedIdent $- filter+keywordNameByPredicate predicate =+ fmap UnquotedIdent+ $ filter (\a -> "Reserved keyword " <> show a <> " used as an identifier. If that's what you intend, you have to wrap it in double quotes.")- _predicate+ predicate anyKeyword -anyKeyword = parse $- Megaparsec.label "keyword" $ do- _firstChar <- Megaparsec.satisfy Predicate.firstIdentifierChar- _remainder <- Megaparsec.takeWhileP Nothing Predicate.notFirstIdentifierChar- return (Text.toLower (Text.cons _firstChar _remainder))+anyKeyword = parse+ $ Megaparsec.label "keyword"+ $ do+ firstChar <- Megaparsec.satisfy Predicate.firstIdentifierChar+ remainder <- Megaparsec.takeWhileP Nothing Predicate.notFirstIdentifierChar+ return (Text.toLower (Text.cons firstChar remainder)) -- | Expected keyword keyword a = mfilter (a ==) anyKeyword@@ -2044,20 +2043,20 @@ arrayBounds = sep1 space (inBrackets (optional iconst)) simpleTypename =- asum $- [ do- keyword "interval"- endHead- asum- [ ConstIntervalSimpleTypename <$> Right <$> (space *> inParens iconst),- ConstIntervalSimpleTypename <$> Left <$> optional (space *> interval)- ],- ConstDatetimeSimpleTypename <$> constDatetime,- NumericSimpleTypename <$> numeric,- BitSimpleTypename <$> bit,- CharacterSimpleTypename <$> character,- GenericTypeSimpleTypename <$> genericType- ]+ asum+ $ [ do+ keyword "interval"+ endHead+ asum+ [ ConstIntervalSimpleTypename <$> Right <$> (space *> inParens iconst),+ ConstIntervalSimpleTypename <$> Left <$> optional (space *> interval)+ ],+ ConstDatetimeSimpleTypename <$> constDatetime,+ NumericSimpleTypename <$> numeric,+ BitSimpleTypename <$> bit,+ CharacterSimpleTypename <$> character,+ GenericTypeSimpleTypename <$> genericType+ ] genericType = do a <- typeFunctionName
library/PostgresqlSyntax/Predicate.hs view
@@ -1,9 +1,11 @@+{-# OPTIONS_GHC -Wno-redundant-constraints #-}+ module PostgresqlSyntax.Predicate where import qualified Data.HashSet as HashSet import qualified PostgresqlSyntax.CharSet as CharSet import qualified PostgresqlSyntax.KeywordSet as KeywordSet-import PostgresqlSyntax.Prelude hiding (expression)+import PostgresqlSyntax.Prelude -- * Generic @@ -23,12 +25,9 @@ inSet :: (Eq a, Hashable a) => HashSet a -> a -> Bool inSet = flip HashSet.member --- *-+hexDigit :: Char -> Bool hexDigit = inSet CharSet.hexDigit --- *- {- ident_start [A-Za-z\200-\377_] -}@@ -62,8 +61,11 @@ -- ** Op chars +opChar :: Char -> Bool opChar = inSet CharSet.op +prohibitedOpChar :: Char -> Bool prohibitedOpChar a = a == '+' || a == '-' +prohibitionLiftingOpChar :: Char -> Bool prohibitionLiftingOpChar = inSet CharSet.prohibitionLiftingOp
library/PostgresqlSyntax/Prelude.hs view
@@ -29,7 +29,7 @@ import Data.Fixed as Exports import Data.Foldable as Exports import Data.Function as Exports hiding (id, (.))-import Data.Functor as Exports+import Data.Functor as Exports hiding (unzip) import Data.Functor.Identity as Exports import Data.HashMap.Strict as Exports (HashMap) import Data.HashSet as Exports (HashSet)@@ -37,7 +37,7 @@ import Data.IORef as Exports import Data.Int as Exports import Data.Ix as Exports-import Data.List as Exports hiding (all, and, any, concat, concatMap, elem, find, foldl, foldl', foldl1, foldr, foldr1, isSubsequenceOf, mapAccumL, mapAccumR, maximum, maximumBy, minimum, minimumBy, notElem, or, product, sortOn, sum, uncons)+import Data.List as Exports hiding (all, and, any, concat, concatMap, elem, find, foldl, foldl', foldl1, foldr, foldr1, isSubsequenceOf, mapAccumL, mapAccumR, maximum, maximumBy, minimum, minimumBy, notElem, or, product, sortOn, sum, uncons, unsnoc) import Data.List.NonEmpty as Exports (NonEmpty (..)) import Data.Maybe as Exports import Data.Monoid as Exports hiding (First (..), Last (..), (<>))@@ -72,20 +72,24 @@ import System.Mem as Exports import System.Mem.StableName as Exports import System.Timeout as Exports-import Text.ParserCombinators.ReadP as Exports (ReadP, ReadS, readP_to_S, readS_to_P)-import Text.ParserCombinators.ReadPrec as Exports (ReadPrec, readP_to_Prec, readPrec_to_P, readPrec_to_S, readS_to_Prec) import Text.Printf as Exports (hPrintf, printf) import Text.Read as Exports (Read (..), readEither, readMaybe) import Unsafe.Coerce as Exports import Prelude as Exports hiding (all, and, any, concat, concatMap, elem, fail, foldl, foldl1, foldr, foldr1, id, mapM, mapM_, maximum, minimum, notElem, or, product, sequence, sequence_, sum, (.)) -showAsText :: Show a => a -> Text+showAsText :: (Show a) => a -> Text showAsText = show >>> fromString -- | -- Compose a monad, which attempts to extend a value, based on the following input.--- It does that recursively until the suffix alternative fails.-suffixRec :: (Monad m, Alternative m) => m a -> (a -> m a) -> m a-suffixRec base suffix = do- _base <- base- suffixRec (suffix _base) suffix <|> pure _base+-- It does so recursively until the suffix alternative fails.+suffixRec :: (MonadPlus m) => m a -> (a -> m a) -> m a+suffixRec base suffix = base >>= extendMany suffix++extendMany :: (MonadPlus m) => (a -> m a) -> a -> m a+extendMany attempt = loop+ where+ loop !state =+ optional (attempt state) >>= \case+ Nothing -> pure state+ Just newState -> loop newState
library/PostgresqlSyntax/Rendering.hs view
@@ -1,6 +1,7 @@+{-# OPTIONS_GHC -Wno-missing-signatures -Wno-dodgy-imports #-}+ module PostgresqlSyntax.Rendering where -import qualified Data.List.NonEmpty as NonEmpty import qualified Data.Text as Text import qualified Data.Text.Encoding as Text import PostgresqlSyntax.Ast@@ -398,8 +399,8 @@ windowDefinition (WindowDefinition a b) = ident a <> " AS " <> windowSpecification b windowSpecification (WindowSpecification a b c d) =- inParens $- optLexemes+ inParens+ $ optLexemes [ fmap ident a, fmap partitionClause b, fmap sortClause c,@@ -566,8 +567,6 @@ GreaterEqualsMathOp -> ">=" ArrowLeftArrowRightMathOp -> "<>" ExclamationEqualsMathOp -> "!="---- * inExpr = \case SelectInExpr a -> selectWithParens a
library/PostgresqlSyntax/Validation.hs view
@@ -1,10 +1,9 @@ module PostgresqlSyntax.Validation where -import qualified Data.HashSet as HashSet import qualified Data.Text as Text-import qualified PostgresqlSyntax.KeywordSet as HashSet+import qualified PostgresqlSyntax.KeywordSet as KeywordSet import qualified PostgresqlSyntax.Predicate as Predicate-import PostgresqlSyntax.Prelude hiding (expression)+import PostgresqlSyntax.Prelude {- The operator name is a sequence of up to NAMEDATALEN-1 (63 by default)@@ -41,7 +40,7 @@ if Text.isInfixOf "/*" a then Just ("Operator contains a prohibited \"/*\" sequence: " <> a) else- if Predicate.inSet HashSet.nonOp a+ if Predicate.inSet KeywordSet.nonOp a then Just ("Operator is not generic: " <> a) else if Text.find Predicate.prohibitionLiftingOpChar a & isJust
postgresql-syntax.cabal view
@@ -1,78 +1,118 @@-name: postgresql-syntax-version: 0.4.1-category: Database, PostgreSQL, Parsing-synopsis: PostgreSQL AST parsing and rendering+cabal-version: 3.0+name: postgresql-syntax+version: 0.4.1.1+category: Database, PostgreSQL, Parsing+synopsis: PostgreSQL AST parsing and rendering description: Postgres syntax tree and related utils extracted from the \"hasql-th\" package. The API is in a rather raw \"guts out\" state with most documentation lacking, but the codebase is well tested.-homepage: https://github.com/nikita-volkov/postgresql-syntax-bug-reports: https://github.com/nikita-volkov/postgresql-syntax/issues-author: Nikita Volkov <nikita.y.volkov@mail.ru>-maintainer: Nikita Volkov <nikita.y.volkov@mail.ru>-copyright: (c) 2020, Nikita Volkov-license: MIT-license-file: LICENSE-build-type: Simple-cabal-version: >=1.10 +homepage: https://github.com/nikita-volkov/postgresql-syntax+bug-reports: https://github.com/nikita-volkov/postgresql-syntax/issues+author: Nikita Volkov <nikita.y.volkov@mail.ru>+maintainer: Nikita Volkov <nikita.y.volkov@mail.ru>+copyright: (c) 2020, Nikita Volkov+license: MIT+license-file: LICENSE+ source-repository head- type: git+ type: git location: git://github.com/nikita-volkov/postgresql-syntax.git +common base-settings+ default-language: Haskell2010+ default-extensions:+ NoImplicitPrelude+ NoMonomorphismRestriction+ ApplicativeDo+ Arrows+ BangPatterns+ ConstraintKinds+ DataKinds+ DefaultSignatures+ DeriveDataTypeable+ DeriveFoldable+ DeriveFunctor+ DeriveGeneric+ DeriveTraversable+ DuplicateRecordFields+ EmptyDataDecls+ FlexibleContexts+ FlexibleInstances+ FunctionalDependencies+ GADTs+ GeneralizedNewtypeDeriving+ LambdaCase+ LiberalTypeSynonyms+ MagicHash+ MultiParamTypeClasses+ MultiWayIf+ OverloadedStrings+ ParallelListComp+ PatternGuards+ QuasiQuotes+ RankNTypes+ RecordWildCards+ ScopedTypeVariables+ StandaloneDeriving+ TemplateHaskell+ TupleSections+ TypeApplications+ TypeFamilies+ TypeOperators+ UnboxedTuples+ library- hs-source-dirs: library- default-extensions: ApplicativeDo, Arrows, BangPatterns, ConstraintKinds, DataKinds, DefaultSignatures, DeriveDataTypeable, DeriveFoldable, DeriveFunctor, DeriveGeneric, DeriveTraversable, DuplicateRecordFields, EmptyDataDecls, FlexibleContexts, FlexibleInstances, FunctionalDependencies, GADTs, GeneralizedNewtypeDeriving, LambdaCase, LiberalTypeSynonyms, MagicHash, MultiParamTypeClasses, MultiWayIf, NoImplicitPrelude, NoMonomorphismRestriction, OverloadedStrings, PatternGuards, ParallelListComp, QuasiQuotes, RankNTypes, RecordWildCards, ScopedTypeVariables, StandaloneDeriving, TemplateHaskell, TupleSections, TypeFamilies, TypeOperators, UnboxedTuples- default-language: Haskell2010+ import: base-settings+ hs-source-dirs: library exposed-modules: PostgresqlSyntax.Ast PostgresqlSyntax.KeywordSet PostgresqlSyntax.Parsing PostgresqlSyntax.Rendering PostgresqlSyntax.Validation+ other-modules: PostgresqlSyntax.CharSet- PostgresqlSyntax.Extras.TextBuilder PostgresqlSyntax.Extras.HeadedMegaparsec PostgresqlSyntax.Extras.NonEmpty+ PostgresqlSyntax.Extras.TextBuilder PostgresqlSyntax.Predicate PostgresqlSyntax.Prelude+ build-depends:- base >=4.12 && <5,- bytestring >=0.10 && <0.12,- case-insensitive >=1.2.1 && <2,- hashable >=1.3.5 && <2,- headed-megaparsec >=0.2.0.1 && <0.3,- megaparsec >=9.2 && <10,- parser-combinators >=1.3 && <1.4,- text >=1 && <3,- text-builder >=0.6.6.3 && <0.7,- unordered-containers >=0.2.16 && <0.3+ , base >=4.12 && <5+ , bytestring >=0.10 && <0.13+ , case-insensitive >=1.2.1 && <2+ , hashable >=1.3.5 && <2+ , headed-megaparsec >=0.2.0.1 && <0.3+ , megaparsec >=9.2 && <10+ , parser-combinators >=1.3 && <1.4+ , text >=1 && <3+ , text-builder >=0.6.6.3 && <0.7+ , unordered-containers >=0.2.16 && <0.3 test-suite tasty-test- type: exitcode-stdio-1.0+ import: base-settings+ type: exitcode-stdio-1.0 hs-source-dirs: tasty-test- main-is: Main.hs- default-extensions: ApplicativeDo, Arrows, BangPatterns, ConstraintKinds, DataKinds, DefaultSignatures, DeriveDataTypeable, DeriveFoldable, DeriveFunctor, DeriveGeneric, DeriveTraversable, DuplicateRecordFields, EmptyDataDecls, FlexibleContexts, FlexibleInstances, FunctionalDependencies, GADTs, GeneralizedNewtypeDeriving, LambdaCase, LiberalTypeSynonyms, MagicHash, MultiParamTypeClasses, MultiWayIf, NoImplicitPrelude, NoMonomorphismRestriction, OverloadedStrings, PatternGuards, ParallelListComp, QuasiQuotes, RankNTypes, RecordWildCards, ScopedTypeVariables, StandaloneDeriving, TemplateHaskell, TupleSections, TypeFamilies, TypeOperators, UnboxedTuples- default-language: Haskell2010+ main-is: Main.hs+ ghc-options: -threaded build-depends:- postgresql-syntax,- QuickCheck >=2.10 && <3,- quickcheck-instances >=0.3.22 && <0.4,- rerebase <2,- tasty >=1.2.3 && <2,- tasty-hunit >=0.10 && <0.11,- tasty-quickcheck >=0.10 && <0.11+ , postgresql-syntax+ , rerebase <2+ , tasty >=1.2.3 && <2+ , tasty-hunit >=0.10 && <0.11 test-suite hedgehog-test- type: exitcode-stdio-1.0+ import: base-settings+ type: exitcode-stdio-1.0 hs-source-dirs: hedgehog-test- default-extensions: ApplicativeDo, Arrows, BangPatterns, ConstraintKinds, DataKinds, DefaultSignatures, DeriveDataTypeable, DeriveFoldable, DeriveFunctor, DeriveGeneric, DeriveTraversable, DuplicateRecordFields, EmptyDataDecls, FlexibleContexts, FlexibleInstances, FunctionalDependencies, GADTs, GeneralizedNewtypeDeriving, LambdaCase, LiberalTypeSynonyms, MagicHash, MultiParamTypeClasses, MultiWayIf, NoImplicitPrelude, NoMonomorphismRestriction, OverloadedStrings, PatternGuards, ParallelListComp, QuasiQuotes, RankNTypes, RecordWildCards, ScopedTypeVariables, StandaloneDeriving, TemplateHaskell, TupleSections, TypeFamilies, TypeOperators, UnboxedTuples- default-language: Haskell2010- main-is: Main.hs- other-modules:- Main.Gen+ main-is: Main.hs+ ghc-options: -threaded+ other-modules: Main.Gen build-depends:- hedgehog >=1.0.1 && <2,- postgresql-syntax,- rerebase >=1.6.1 && <2+ , hedgehog >=1.0.1 && <2+ , postgresql-syntax+ , rerebase >=1.6.1 && <2
tasty-test/Main.hs view
@@ -1,71 +1,61 @@ module Main where import qualified Data.Text as Text-import qualified PostgresqlSyntax.Ast as Ast import qualified PostgresqlSyntax.Parsing as Parsing-import qualified PostgresqlSyntax.Rendering as Rendering-import qualified Test.QuickCheck as QuickCheck-import Test.QuickCheck.Instances import Test.Tasty import Test.Tasty.HUnit-import Test.Tasty.QuickCheck-import Test.Tasty.Runners import Prelude hiding (assert) +main :: IO () main =- defaultMain $- testGroup+ defaultMain+ $ testGroup ""- [ testGroup "Parsers" $- let testParserOnAllInputs parserName parser inputs =- testCase parserName $- forM_ inputs $ \input -> case Parsing.run parser input of- Left err -> assertFailure (err <> "\ninput: " <> Text.unpack input)- Right _ -> return ()- testParserOnEachInput parserName parser inputs =- testGroup parserName $- flip fmap inputs $ \input ->- testCase (Text.unpack input) $ case Parsing.run parser input of- Left err -> assertFailure err+ [ testGroup "Parsers"+ $ let testParserOnAllInputs parserName parser inputs =+ testCase parserName+ $ forM_ inputs+ $ \input -> case Parsing.run parser input of+ Left err -> assertFailure (err <> "\ninput: " <> Text.unpack input) Right _ -> return ()- in [ testParserOnAllInputs- "preparableStmt"- Parsing.preparableStmt- [ "select i :: int8 from auth.user as u\n\- \inner join edgenode.usere_provider as p\n\- \on u.id = p.user_id\n\- \inner join edgenode.provider_branch as b\n\- \on b.provider_fk = p.provider_id"- ],- testParserOnAllInputs- "typename"- Parsing.typename- [ "int4[]",- "int4[][]",- "int4?[]",- "int4?[]?",- "aa array",- "DOUBLE PRECISION",- "bool",- "int2",- "int4",- "int8",- "float4",- "float8",- "numeric",- "char",- "text",- "bytea",- "date",- "timestamp",- "timestamptz",- "time",- "timetz",- "interval",- "uuid",- "inet",- "json",- "jsonb"- ]- ]+ in [ testParserOnAllInputs+ "preparableStmt"+ Parsing.preparableStmt+ [ "select i :: int8 from auth.user as u\n\+ \inner join edgenode.usere_provider as p\n\+ \on u.id = p.user_id\n\+ \inner join edgenode.provider_branch as b\n\+ \on b.provider_fk = p.provider_id"+ ],+ testParserOnAllInputs+ "typename"+ Parsing.typename+ [ "int4[]",+ "int4[][]",+ "int4?[]",+ "int4?[]?",+ "aa array",+ "DOUBLE PRECISION",+ "bool",+ "int2",+ "int4",+ "int8",+ "float4",+ "float8",+ "numeric",+ "char",+ "text",+ "bytea",+ "date",+ "timestamp",+ "timestamptz",+ "time",+ "timetz",+ "interval",+ "uuid",+ "inet",+ "json",+ "jsonb"+ ]+ ] ]