packages feed

postgresql-syntax 0.4 → 0.4.0.1

raw patch · 16 files changed

+5753/−5594 lines, 16 filesdep ~case-insensitivedep ~hashabledep ~megaparsecsetup-changed

Dependency ranges changed: case-insensitive, hashable, megaparsec, parser-combinators, text, text-builder, unordered-containers

Files

− Setup.hs
@@ -1,2 +0,0 @@-import Distribution.Simple-main = defaultMain
hedgehog-test/Main.hs view
@@ -1,38 +1,37 @@ module Main where -import Prelude+import qualified Data.Text as Text import Hedgehog-import Hedgehog.Main-import qualified Main.Gen as Gen 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 qualified Data.Text as Text-+import Prelude -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'-      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-          ,-          p "preparableStmt" 30000 Gen.preparableStmt Parsing.preparableStmt Rendering.preparableStmt-        ]-  ]+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'+           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,+                p "preparableStmt" 30000 Gen.preparableStmt Parsing.preparableStmt Rendering.preparableStmt+              ]+    ]
hedgehog-test/Main/Gen.hs view
@@ -1,923 +1,937 @@ module Main.Gen where -import Prelude hiding (maybe, bool, sortBy, filter, bit, fromList)-import PostgresqlSyntax.Ast-import Hedgehog (Gen, MonadGen)-import Hedgehog.Gen-import qualified Hedgehog.Range as Range-import qualified Data.Text as Text-import qualified Data.HashSet as HashSet-import qualified Data.List as List-import qualified PostgresqlSyntax.KeywordSet as KeywordSet-import qualified PostgresqlSyntax.Validation as Validation------ * Generic----------------------------inSet _set = filter (flip HashSet.member _set)--notInSet _set = filter (not . flip HashSet.member _set)----- * Statements----------------------------preparableStmt = choice [-    SelectPreparableStmt <$> selectStmt,-    InsertPreparableStmt <$> insertStmt,-    UpdatePreparableStmt <$> updateStmt,-    DeletePreparableStmt <$> deleteStmt-  ]----- * Insert----------------------------insertStmt = InsertStmt <$> maybe withClause <*> insertTarget <*> insertRest <*> maybe onConflict <*> maybe returningClause--insertTarget = InsertTarget <$> qualifiedName <*> maybe colId--insertRest = choice [-    SelectInsertRest <$> maybe insertColumnList <*> maybe overrideKind <*> selectStmt,-    pure DefaultValuesInsertRest-  ]--overrideKind = enumBounded--insertColumnList = nonEmpty (Range.exponential 1 7) insertColumnItem--insertColumnItem = InsertColumnItem <$> colId <*> maybe indirection--onConflict = OnConflict <$> maybe confExpr <*> onConflictDo--onConflictDo = choice [-    UpdateOnConflictDo <$> setClauseList <*> maybe whereClause,-    pure NothingOnConflictDo-  ]--confExpr = choice [-    WhereConfExpr <$> indexParams <*> maybe whereClause,-    ConstraintConfExpr <$> name-  ]--returningClause = targetList----- * Update----------------------------updateStmt = UpdateStmt <$> maybe withClause <*> relationExprOptAlias <*> setClauseList <*> maybe fromClause <*> maybe whereOrCurrentClause <*> maybe returningClause--setClauseList = nonEmpty (Range.exponential 1 10) setClause--setClause = choice [-    TargetSetClause <$> setTarget <*> aExpr,-    TargetListSetClause <$> setTargetList <*> aExpr-  ]--setTarget = SetTarget <$> colId <*> maybe indirection--setTargetList = nonEmpty (Range.exponential 1 10) setTarget----- * Delete----------------------------deleteStmt = DeleteStmt <$> maybe withClause <*> relationExprOptAlias <*> maybe usingClause <*> maybe whereOrCurrentClause <*> maybe returningClause--usingClause = fromList----- * Select----------------------------selectStmt = Left <$> selectNoParens---- ** selectNoParens----------------------------selectNoParens = frequency [-    (90, SelectNoParens <$> maybe withClause <*> (Left <$> simpleSelect) <*> maybe sortClause <*> maybe selectLimit <*> maybe forLockingClause)-    ,-    (10, SelectNoParens <$> fmap Just withClause <*> selectClause <*> fmap Just sortClause <*> fmap Just selectLimit <*> fmap Just forLockingClause)-  ]--terminalSelectNoParens = -  SelectNoParens <$> pure Nothing <*> (Left <$> terminalSimpleSelect) <*> pure Nothing <*> pure Nothing <*> pure Nothing---- ** selectWithParens----------------------------selectWithParens = sized $ \ _size -> if _size <= 1-  then discard-  else frequency [-    (95, NoParensSelectWithParens <$> selectNoParens)-    ,-    (5, WithParensSelectWithParens <$> selectWithParens)-  ]--terminalSelectWithParens = NoParensSelectWithParens <$> terminalSelectNoParens---- ** selectClause----------------------------selectClause = choice [-    Left <$> simpleSelect,-    Right <$> small selectWithParens-  ]--nonTrailingSelectClause = Left <$> nonTrailingSimpleSelect---- ** simpleSelect----------------------------simpleSelect = choice [-    normalSimpleSelect,-    tableSimpleSelect,-    valuesSimpleSelect,-    small nonTrailingSelectClause >>= binSimpleSelect-  ]--nonTrailingSimpleSelect = choice [normalSimpleSelect, valuesSimpleSelect, tableSimpleSelect]--normalSimpleSelect = NormalSimpleSelect <$> maybe targeting <*> maybe intoClause <*> maybe fromClause <*> maybe whereClause <*> maybe groupClause <*> maybe havingClause <*> maybe windowClause--tableSimpleSelect = TableSimpleSelect <$> relationExpr--valuesSimpleSelect = ValuesSimpleSelect <$> valuesClause--binSimpleSelect _leftSelect = -  BinSimpleSelect <$> selectBinOp <*> pure _leftSelect <*> maybe allOrDistinct <*> small selectClause--terminalSimpleSelect = pure (NormalSimpleSelect Nothing Nothing Nothing Nothing Nothing Nothing Nothing)----- * Targeting----------------------------targeting = choice [-    NormalTargeting <$> targetList,-    AllTargeting <$> maybe targetList,-    DistinctTargeting <$> maybe (nonEmpty (Range.exponential 1 8) aExpr) <*> targetList-  ]--targetList = nonEmpty (Range.exponential 1 8) targetEl--targetEl = choice [-    pure AsteriskTargetEl,-    AliasedExprTargetEl <$> aExpr <*> colLabel,-    ImplicitlyAliasedExprTargetEl <$> prefixAExpr <*> ident,-    ExprTargetEl <$> aExpr-  ]----- * BinSimpleSelect----------------------------selectBinOp = element [UnionSelectBinOp, IntersectSelectBinOp, ExceptSelectBinOp]----- * With Clause----------------------------withClause = WithClause <$> bool <*> nonEmpty (Range.exponential 1 7) commonTableExpr--commonTableExpr = CommonTableExpr <$> name <*> maybe (nonEmpty (Range.exponential 1 8) name) <*> maybe bool <*> small preparableStmt----- * Into Clause----------------------------intoClause = optTempTableName--optTempTableName = choice [-    TemporaryOptTempTableName <$> bool <*> qualifiedName,-    TempOptTempTableName <$> bool <*> qualifiedName,-    LocalTemporaryOptTempTableName <$> bool <*> qualifiedName,-    LocalTempOptTempTableName <$> bool <*> qualifiedName,-    GlobalTemporaryOptTempTableName <$> bool <*> qualifiedName,-    GlobalTempOptTempTableName <$> bool <*> qualifiedName,-    UnloggedOptTempTableName <$> bool <*> qualifiedName,-    TableOptTempTableName <$> qualifiedName,-    QualifedOptTempTableName <$> qualifiedName-  ]----- * From Clause----------------------------fromList = nonEmpty (Range.exponential 1 8) tableRef--fromClause = fromList--tableRef = choice [relationExprTableRef, selectTableRef, joinTableRef]--relationExprTableRef = RelationExprTableRef <$> relationExpr <*> maybe aliasClause <*> maybe tablesampleClause--funcTableRef = FuncTableRef <$> bool <*> funcTable <*> maybe funcAliasClause--selectTableRef = SelectTableRef <$> bool <*> small selectWithParens <*> maybe aliasClause--joinTableRef = JoinTableRef <$> joinedTable <*> maybe aliasClause--relationExpr = choice [-    SimpleRelationExpr <$> qualifiedName <*> bool,-    OnlyRelationExpr <$> qualifiedName <*> bool-  ]--relationExprOptAlias = RelationExprOptAlias <$> relationExpr <*> maybe ((,) <$> bool <*> colId)--tablesampleClause = TablesampleClause <$> funcName <*> exprList <*> maybe repeatableClause--repeatableClause = aExpr--funcTable = choice [-    FuncExprFuncTable <$> funcExprWindowless <*> optOrdinality,-    RowsFromFuncTable <$> rowsfromList <*> optOrdinality-  ]--rowsfromItem = RowsfromItem <$> funcExprWindowless <*> maybe colDefList--rowsfromList = nonEmpty (Range.exponential 1 8) rowsfromItem--colDefList = tableFuncElementList--optOrdinality = bool--tableFuncElementList = nonEmpty (Range.exponential 1 7) tableFuncElement--tableFuncElement = TableFuncElement <$> colId <*> typename <*> maybe collateClause--collateClause = anyName--aliasClause = AliasClause <$> bool <*> name <*> maybe (nonEmpty (Range.exponential 1 8) name)--funcAliasClause = choice [-    AliasFuncAliasClause <$> aliasClause,-    AsFuncAliasClause <$> tableFuncElementList,-    AsColIdFuncAliasClause <$> colId <*> tableFuncElementList,-    ColIdFuncAliasClause <$> colId <*> tableFuncElementList-  ]--joinedTable = frequency [-    (5,) $ InParensJoinedTable <$> joinedTable,-    (95,) $ MethJoinedTable <$> joinMeth <*> tableRef <*> choice [relationExprTableRef, selectTableRef, funcTableRef]-  ]--joinMeth = choice [-    pure CrossJoinMeth,-    QualJoinMeth <$> maybe joinType <*> joinQual,-    NaturalJoinMeth <$> maybe joinType-  ]--joinType = choice [-    FullJoinType <$> bool,-    LeftJoinType <$> bool,-    RightJoinType <$> bool,-    pure InnerJoinType-  ]--joinQual = choice [-    UsingJoinQual <$> nonEmpty (Range.exponential 1 8) name,-    OnJoinQual <$> aExpr-  ]----- * Group Clause----------------------------groupClause = nonEmpty (Range.exponential 1 8) groupByItem--groupByItem = choice [-    ExprGroupByItem <$> aExpr,-    pure EmptyGroupingSetGroupByItem,-    RollupGroupByItem <$> nonEmpty (Range.exponential 1 8) aExpr,-    CubeGroupByItem <$> nonEmpty (Range.exponential 1 8) aExpr,-    GroupingSetsGroupByItem <$> nonEmpty (Range.exponential 1 3) groupByItem-  ]----- * Having Clause----------------------------havingClause = aExpr----- * Where Clause----------------------------whereClause = aExpr--whereOrCurrentClause = choice [-    ExprWhereOrCurrentClause <$> aExpr,-    CursorWhereOrCurrentClause <$> cursorName-  ]----- * Window Clause----------------------------windowClause = nonEmpty (Range.exponential 1 8) windowDefinition--windowDefinition = WindowDefinition <$> name <*> windowSpecification--windowSpecification = WindowSpecification <$> maybe name <*> maybe (nonEmpty (Range.exponential 1 8) nonSuffixOpAExpr) <*> maybe sortClause <*> maybe frameClause--frameClause = FrameClause <$> frameClauseMode <*> frameExtent <*> maybe windowExclusionClause--frameClauseMode = element [RangeFrameClauseMode, RowsFrameClauseMode, GroupsFrameClauseMode]--frameExtent = choice [-    SingularFrameExtent <$> frameBound,-    BetweenFrameExtent <$> frameBound <*> frameBound-  ]--frameBound = choice [-    pure UnboundedPrecedingFrameBound,-    pure UnboundedFollowingFrameBound,-    pure CurrentRowFrameBound,-    PrecedingFrameBound <$> prefixAExpr,-    FollowingFrameBound <$> prefixAExpr-  ]--windowExclusionClause = element [CurrentRowWindowExclusionClause, GroupWindowExclusionClause, TiesWindowExclusionClause, NoOthersWindowExclusionClause]----- * Values Clause----------------------------valuesClause = nonEmpty (Range.exponential 1 8) (nonEmpty (Range.exponential 1 8) aExpr)----- * Sort Clause----------------------------sortClause = nonEmpty (Range.exponential 1 8) sortBy--sortBy = choice [-    UsingSortBy <$> nonSuffixOpAExpr <*> qualAllOp <*> maybe nullsOrder,-    AscDescSortBy <$> nonSuffixOpAExpr <*> maybe ascDesc <*> maybe nullsOrder-  ]----- * All or distinct----------------------------allOrDistinct = bool----- * Limit----------------------------selectLimit = choice [-    LimitOffsetSelectLimit <$> limitClause <*> offsetClause,-    OffsetLimitSelectLimit <$> offsetClause <*> limitClause,-    LimitSelectLimit <$> limitClause,-    OffsetSelectLimit <$> offsetClause-  ]--limitClause = choice [-    LimitLimitClause <$> selectLimitValue <*> maybe aExpr,-    FetchOnlyLimitClause <$> bool <*> maybe selectFetchFirstValue <*> bool-  ]--selectFetchFirstValue = choice [-    ExprSelectFetchFirstValue <$> cExpr,-    NumSelectFetchFirstValue <$> bool <*> iconstOrFconst-  ]--selectLimitValue = choice [-    ExprSelectLimitValue <$> aExpr,-    pure AllSelectLimitValue-  ]--offsetClause = choice [-    ExprOffsetClause <$> aExpr,-    FetchFirstOffsetClause <$> selectFetchFirstValue <*> bool-  ]----- * For Locking----------------------------forLockingClause = choice [-    ItemsForLockingClause <$> nonEmpty (Range.exponential 1 8) forLockingItem,-    pure ReadOnlyForLockingClause-  ]--forLockingItem = ForLockingItem <$> forLockingStrength <*> maybe (nonEmpty (Range.exponential 1 8) qualifiedName) <*> maybe bool--forLockingStrength = element [-    UpdateForLockingStrength,-    NoKeyUpdateForLockingStrength,-    ShareForLockingStrength,-    KeyForLockingStrength-  ]----- * Expressions----------------------------exprList = nonEmpty (Range.exponential 1 7) aExpr--aExpr = recursive choice [-    CExprAExpr <$> cExpr,-    pure DefaultAExpr-  ] [-    TypecastAExpr <$> prefixAExpr <*> typename,-    CollateAExpr <$> prefixAExpr <*> anyName,-    AtTimeZoneAExpr <$> prefixAExpr <*> aExpr,-    PlusAExpr <$> aExpr,-    MinusAExpr <$> aExpr,-    SymbolicBinOpAExpr <$> prefixAExpr <*> symbolicExprBinOp <*> aExpr,-    PrefixQualOpAExpr <$> qualOp <*> aExpr,-    SuffixQualOpAExpr <$> prefixAExpr <*> qualOp,-    AndAExpr <$> prefixAExpr <*> aExpr,-    OrAExpr <$> prefixAExpr <*> aExpr,-    NotAExpr <$> aExpr,-    VerbalExprBinOpAExpr <$> prefixAExpr <*> bool <*> verbalExprBinOp <*> prefixAExpr <*> maybe aExpr,-    ReversableOpAExpr <$> prefixAExpr <*> bool <*> aExprReversableOp,-    IsnullAExpr <$> prefixAExpr,-    NotnullAExpr <$> prefixAExpr,-    OverlapsAExpr <$> row <*> row,-    SubqueryAExpr <$> prefixAExpr <*> subqueryOp <*> subType <*> choice [Left <$> selectWithParens, Right <$> nonSelectAExpr],-    UniqueAExpr <$> selectWithParens-  ]--prefixAExpr = choice [-    CExprAExpr <$> cExpr,-    pure DefaultAExpr,-    UniqueAExpr <$> selectWithParens-  ]--nonSuffixOpAExpr = recursive choice [-    CExprAExpr <$> cExpr,-    pure DefaultAExpr-  ] [-    TypecastAExpr <$> prefixAExpr <*> typename,-    CollateAExpr <$> prefixAExpr <*> anyName,-    AtTimeZoneAExpr <$> prefixAExpr <*> nonSuffixOpAExpr,-    PlusAExpr <$> nonSuffixOpAExpr,-    MinusAExpr <$> nonSuffixOpAExpr,-    SymbolicBinOpAExpr <$> prefixAExpr <*> symbolicExprBinOp <*> nonSuffixOpAExpr,-    PrefixQualOpAExpr <$> qualOp <*> nonSuffixOpAExpr,-    AndAExpr <$> prefixAExpr <*> nonSuffixOpAExpr,-    OrAExpr <$> prefixAExpr <*> nonSuffixOpAExpr,-    NotAExpr <$> nonSuffixOpAExpr,-    VerbalExprBinOpAExpr <$> prefixAExpr <*> bool <*> verbalExprBinOp <*> prefixAExpr <*> maybe nonSuffixOpAExpr,-    IsnullAExpr <$> prefixAExpr,-    NotnullAExpr <$> prefixAExpr,-    UniqueAExpr <$> selectWithParens-  ]--nonSelectAExpr = choice [-    TypecastAExpr <$> prefixAExpr <*> typename,-    CollateAExpr <$> prefixAExpr <*> anyName,-    AtTimeZoneAExpr <$> prefixAExpr <*> aExpr,-    PlusAExpr <$> aExpr,-    MinusAExpr <$> aExpr,-    SymbolicBinOpAExpr <$> prefixAExpr <*> symbolicExprBinOp <*> aExpr,-    PrefixQualOpAExpr <$> qualOp <*> aExpr,-    SuffixQualOpAExpr <$> prefixAExpr <*> qualOp,-    AndAExpr <$> prefixAExpr <*> aExpr,-    OrAExpr <$> prefixAExpr <*> aExpr,-    NotAExpr <$> aExpr,-    VerbalExprBinOpAExpr <$> prefixAExpr <*> bool <*> verbalExprBinOp <*> prefixAExpr <*> maybe aExpr,-    ReversableOpAExpr <$> prefixAExpr <*> bool <*> aExprReversableOp,-    IsnullAExpr <$> prefixAExpr,-    NotnullAExpr <$> prefixAExpr,-    OverlapsAExpr <$> row <*> row,-    SubqueryAExpr <$> prefixAExpr <*> subqueryOp <*> subType <*> choice [Left <$> selectWithParens, Right <$> nonSelectAExpr],-    UniqueAExpr <$> selectWithParens-  ]--bExpr = recursive choice [-    CExprBExpr <$> cExpr-  ] [-    TypecastBExpr <$> prefixBExpr <*> typename,-    PlusBExpr <$> bExpr,-    MinusBExpr <$> bExpr,-    SymbolicBinOpBExpr <$> prefixBExpr <*> symbolicExprBinOp <*> bExpr,-    QualOpBExpr <$> qualOp <*> bExpr,-    IsOpBExpr <$> prefixBExpr <*> bool <*> bExprIsOp-  ]--prefixBExpr = choice [-    CExprBExpr <$> cExpr-  ]--cExpr = recursive choice [-    ColumnrefCExpr <$> columnref-  ] [-    AexprConstCExpr <$> aexprConst,-    ParamCExpr <$> integral (Range.linear 1 19) <*> maybe indirection,-    InParensCExpr <$> nonSelectAExpr <*> maybe indirection,-    CaseCExpr <$> caseExpr,-    FuncCExpr <$> funcExpr,-    SelectWithParensCExpr <$> selectWithParens <*> maybe indirection,-    ExistsCExpr <$> selectWithParens,-    ArrayCExpr <$> choice [Left <$> selectWithParens, Right <$> arrayExpr],-    ExplicitRowCExpr <$> explicitRow,-    ImplicitRowCExpr <$> implicitRow,-    GroupingCExpr <$> exprList-  ]---- **----------------------------caseExpr = CaseExpr <$> maybe aExpr <*> whenClauseList <*> maybe aExpr--whenClauseList = nonEmpty (Range.exponential 1 7) whenClause--whenClause = WhenClause <$> small aExpr <*> small aExpr--inExpr = choice [-    SelectInExpr <$> NoParensSelectWithParens <$> selectNoParens,-    ExprListInExpr <$> exprList-  ]--arrayExpr = small $ choice [-    ExprListArrayExpr <$> exprList,-    ArrayExprListArrayExpr <$> arrayExprList,-    pure EmptyArrayExpr-  ]--arrayExprList = nonEmpty (Range.exponential 1 4) arrayExpr--row = choice [-    ExplicitRowRow <$> explicitRow,-    ImplicitRowRow <$> implicitRow-  ]--explicitRow = maybe exprList--implicitRow = ImplicitRow <$> exprList <*> aExpr---- ** FuncExpr----------------------------funcExpr = choice [-    ApplicationFuncExpr <$> funcApplication <*> maybe withinGroupClause <*> maybe filterClause <*> maybe overClause,-    SubexprFuncExpr <$> funcExprCommonSubexpr-  ]--funcExprWindowless = choice [-    ApplicationFuncExprWindowless <$> funcApplication,-    CommonSubexprFuncExprWindowless <$> funcExprCommonSubexpr-  ]--funcApplication = FuncApplication <$> funcName <*> maybe funcApplicationParams--funcApplicationParams = choice [-    NormalFuncApplicationParams <$> maybe allOrDistinct <*> nonEmpty (Range.exponential 1 8) funcArgExpr <*> maybe sortClause,-    VariadicFuncApplicationParams <$> maybe (nonEmpty (Range.exponential 1 8) funcArgExpr) <*> funcArgExpr <*> maybe sortClause,-    pure StarFuncApplicationParams-  ]--funcArgExpr = choice [-    ExprFuncArgExpr <$> small aExpr,-    ColonEqualsFuncArgExpr <$> name <*> small aExpr,-    EqualsGreaterFuncArgExpr <$> name <*> small aExpr-  ]--withinGroupClause = sortClause--filterClause = aExpr--overClause = choice [WindowOverClause <$> windowSpecification, ColIdOverClause <$> colId]--funcExprCommonSubexpr = choice [-    CollationForFuncExprCommonSubexpr <$> aExpr,-    pure CurrentDateFuncExprCommonSubexpr,-    CurrentTimeFuncExprCommonSubexpr <$> maybe iconst,-    CurrentTimestampFuncExprCommonSubexpr <$> maybe iconst,-    LocalTimeFuncExprCommonSubexpr <$> maybe iconst,-    LocalTimestampFuncExprCommonSubexpr <$> maybe iconst,-    pure CurrentRoleFuncExprCommonSubexpr,-    pure CurrentUserFuncExprCommonSubexpr,-    pure SessionUserFuncExprCommonSubexpr,-    pure UserFuncExprCommonSubexpr,-    pure CurrentCatalogFuncExprCommonSubexpr,-    pure CurrentSchemaFuncExprCommonSubexpr,-    CastFuncExprCommonSubexpr <$> aExpr <*> typename,-    ExtractFuncExprCommonSubexpr <$> maybe extractList,-    OverlayFuncExprCommonSubexpr <$> overlayList,-    PositionFuncExprCommonSubexpr <$> maybe positionList,-    SubstringFuncExprCommonSubexpr <$> maybe substrList,-    TreatFuncExprCommonSubexpr <$> aExpr <*> typename,-    TrimFuncExprCommonSubexpr <$> maybe trimModifier <*> trimList,-    NullIfFuncExprCommonSubexpr <$> aExpr <*> aExpr,-    CoalesceFuncExprCommonSubexpr <$> exprList,-    GreatestFuncExprCommonSubexpr <$> exprList,-    LeastFuncExprCommonSubexpr <$> exprList-  ]--extractList = ExtractList <$> extractArg <*> aExpr--extractArg = choice [-    IdentExtractArg <$> ident,-    pure YearExtractArg,-    pure MonthExtractArg,-    pure DayExtractArg,-    pure HourExtractArg,-    pure MinuteExtractArg,-    pure SecondExtractArg,-    SconstExtractArg <$> sconst-  ]--overlayList = OverlayList <$> aExpr <*> overlayPlacing <*> substrFrom <*> maybe substrFor--overlayPlacing = aExpr--positionList = PositionList <$> bExpr <*> bExpr--substrList = choice [-    ExprSubstrList <$> aExpr <*> substrListFromFor,-    ExprListSubstrList <$> exprList-  ]--substrListFromFor = choice [-    FromForSubstrListFromFor <$> substrFrom <*> substrFor,-    ForFromSubstrListFromFor <$> substrFor <*> substrFrom,-    FromSubstrListFromFor <$> substrFrom,-    ForSubstrListFromFor <$> substrFor-  ]--substrFrom = aExpr--substrFor = aExpr--trimModifier = enumBounded--trimList = choice [-    ExprFromExprListTrimList <$> aExpr <*> exprList,-    FromExprListTrimList <$> exprList,-    ExprListTrimList <$> exprList-  ]----- * Operators----------------------------qualOp = choice [OpQualOp <$> op, OperatorQualOp <$> anyOperator]--qualAllOp = choice [-    AllQualAllOp <$> allOp,-    AnyQualAllOp <$> anyOperator-  ]--op = do-  a <- text (Range.exponential 1 7) (element "+-*/<>=~!@#%^&|`?")-  case Validation.op a of-    Nothing -> return a-    _ -> discard--anyOperator = recursive choice [-    AllOpAnyOperator <$> allOp-  ] [-    QualifiedAnyOperator <$> colId <*> anyOperator-  ]--allOp = choice [OpAllOp <$> op, MathAllOp <$> mathOp]--mathOp = enumBounded--symbolicExprBinOp = choice [-    MathSymbolicExprBinOp <$> mathOp,-    QualSymbolicExprBinOp <$> qualOp-  ]--binOp = element (toList KeywordSet.symbolicBinOp <> ["AND", "OR", "IS DISTINCT FROM", "IS NOT DISTINCT FROM"])--verbalExprBinOp = enumBounded--aExprReversableOp = choice [-    pure NullAExprReversableOp,-    pure TrueAExprReversableOp,-    pure FalseAExprReversableOp,-    pure UnknownAExprReversableOp,-    DistinctFromAExprReversableOp <$> aExpr,-    OfAExprReversableOp <$> typeList,-    BetweenAExprReversableOp <$> bool <*> bExpr <*> aExpr,-    BetweenSymmetricAExprReversableOp <$> bExpr <*> aExpr,-    InAExprReversableOp <$> inExpr,-    pure DocumentAExprReversableOp-  ]--bExprIsOp = choice [-    DistinctFromBExprIsOp <$> bExpr,-    OfBExprIsOp <$> typeList,-    pure DocumentBExprIsOp-  ]--subqueryOp = choice [-    AllSubqueryOp <$> allOp,-    AnySubqueryOp <$> anyOperator,-    LikeSubqueryOp <$> bool,-    IlikeSubqueryOp <$> bool-  ]----- * Constants----------------------------aexprConst = choice [-    IAexprConst <$> iconst,-    FAexprConst <$> fconst,-    SAexprConst <$> sconst,-    BAexprConst <$> text (Range.exponential 1 100) (element "01"),-    XAexprConst <$> text (Range.exponential 1 100) (element "0123456789abcdefABCDEF"),-    FuncAexprConst <$> funcName <*> maybe funcConstArgs <*> sconst,-    ConstTypenameAexprConst <$> constTypename <*> sconst,-    StringIntervalAexprConst <$> sconst <*> maybe interval,-    IntIntervalAexprConst <$> integral (Range.exponential 0 2309482309483029) <*> sconst,-    BoolAexprConst <$> bool,-    pure NullAexprConst-  ]--funcConstArgs = FuncConstArgs <$> nonEmpty (Range.exponential 1 7) funcArgExpr <*> maybe sortClause--constTypename = choice [-    NumericConstTypename <$> numeric,-    ConstBitConstTypename <$> constBit,-    ConstCharacterConstTypename <$> constCharacter,-    ConstDatetimeConstTypename <$> constDatetime-  ]--numeric = choice [-    pure IntNumeric,-    pure IntegerNumeric,-    pure SmallintNumeric,-    pure BigintNumeric,-    pure RealNumeric,-    FloatNumeric <$> maybe iconst,-    pure DoublePrecisionNumeric,-    DecimalNumeric <$> maybe (nonEmpty (Range.exponential 1 7) (small aExpr)),-    DecNumeric <$> maybe (nonEmpty (Range.exponential 1 7) (small aExpr)),-    NumericNumeric <$> maybe (nonEmpty (Range.exponential 1 7) (small aExpr)),-    pure BooleanNumeric-  ]--bit = Bit <$> bool <*> maybe (nonEmpty (Range.exponential 1 7) (small aExpr))--constBit = bit--constCharacter = ConstCharacter <$> character <*> maybe iconst--character = choice [-    CharacterCharacter <$> bool,-    CharCharacter <$> bool,-    pure VarcharCharacter,-    NationalCharacterCharacter <$> bool,-    NationalCharCharacter <$> bool,-    NcharCharacter <$> bool-  ]--constDatetime = choice [-    TimestampConstDatetime <$> maybe iconst <*> maybe bool,-    TimeConstDatetime <$> maybe iconst <*> maybe bool-  ]--interval = choice [-    pure YearInterval,-    pure MonthInterval,-    pure DayInterval,-    pure HourInterval,-    pure MinuteInterval,-    SecondInterval <$> intervalSecond,-    pure YearToMonthInterval,-    pure DayToHourInterval,-    pure DayToMinuteInterval,-    DayToSecondInterval <$> intervalSecond,-    pure HourToMinuteInterval,-    HourToSecondInterval <$> intervalSecond,-    MinuteToSecondInterval <$> intervalSecond-  ]--intervalSecond = maybe iconst--sconst = text (Range.exponential 0 1000) unicode--iconstOrFconst = choice [Left <$> iconst <|> Right <$> fconst]--fconst =-  filter (\ a -> fromIntegral (round a) /= a) $-  realFrac_ (Range.exponentialFloat 0 309457394857984375983475943)--iconst = integral (Range.exponential 0 maxBound)----- * Types----------------------------nullable = pure False--arrayDimensionsAmount = int (Range.exponential 0 4)---- ** Typename----------------------------typename = Typename <$> bool <*> simpleTypename <*> pure False <*> maybe ((,) <$> typenameArrayDimensions <*> pure False)--typenameArrayDimensions = choice [-    BoundsTypenameArrayDimensions <$> arrayBounds,-    ExplicitTypenameArrayDimensions <$> maybe iconst-  ]--arrayBounds = nonEmpty (Range.exponential 1 4) (maybe iconst)--simpleTypename = choice [-    GenericTypeSimpleTypename <$> genericType,-    NumericSimpleTypename <$> numeric,-    BitSimpleTypename <$> bit,-    CharacterSimpleTypename <$> character,-    ConstDatetimeSimpleTypename <$> constDatetime,-    ConstIntervalSimpleTypename <$> choice [Left <$> maybe interval, Right <$> iconst]-  ]--genericType = GenericType <$> typeFunctionName <*> maybe attrs <*> maybe typeModifiers--attrs = nonEmpty (Range.exponential 1 10) attrName--typeModifiers = exprList--typeList = nonEmpty (Range.exponential 1 7) typename--subType = enumBounded----- * Names----------------------------columnref = Columnref <$> colId <*> maybe indirection--keywordNotInSet = \ set -> notInSet set $ do-  a <- element startList-  b <- text (Range.linear 1 29) (element contList)-  return (Text.cons a b)-  where-    startList = "abcdefghijklmnopqrstuvwxyz_" <> List.filter isLower (enumFromTo '\200' '\377')-    contList = startList <> "0123456789$"--ident = identWithSet mempty--typeName = identWithSet KeywordSet.typeFunctionName--name = identWithSet KeywordSet.colId--cursorName = name--identWithSet set = frequency [-    (95,) $ UnquotedIdent <$> (keywordNotInSet . HashSet.difference KeywordSet.keyword) set,-    (5,) $ QuotedIdent <$> text (Range.linear 1 30) quotedChar-  ]--qualifiedName = choice [-    SimpleQualifiedName <$> name,-    IndirectedQualifiedName <$> name <*> indirection-  ]--indirection = nonEmpty (Range.linear 1 3) indirectionEl--indirectionEl = choice [-    AttrNameIndirectionEl <$> name,-    pure AllIndirectionEl,-    ExprIndirectionEl <$> (small aExpr),-    SliceIndirectionEl <$> maybe (small aExpr) <*> maybe (small aExpr)-  ]--quotedChar = filter (not . isControl) unicode--colId = name--colLabel = name--attrName = colLabel--typeFunctionName = name--funcName = choice [-    TypeFuncName <$> typeFunctionName,-    IndirectedFuncName <$> colId <*> indirection-  ]--anyName = AnyName <$> colId <*> maybe attrs----- * Indexes----------------------------indexParams = nonEmpty (Range.exponential 1 5) indexElem--indexElem = IndexElem <$> indexElemDef <*> maybe collate <*> maybe class_ <*> maybe ascDesc <*> maybe nullsOrder--indexElemDef = choice [-    IdIndexElemDef <$> colId,-    FuncIndexElemDef <$> funcExprWindowless,-    ExprIndexElemDef <$> aExpr-  ]+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 qualified Hedgehog.Range as Range+import PostgresqlSyntax.Ast+import qualified PostgresqlSyntax.KeywordSet as KeywordSet+import qualified PostgresqlSyntax.Validation as Validation+import Prelude hiding (bit, bool, filter, fromList, maybe, sortBy)++-- * Generic++inSet _set = filter (flip HashSet.member _set)++notInSet _set = filter (not . flip HashSet.member _set)++-- * Statements++preparableStmt =+  choice+    [ SelectPreparableStmt <$> selectStmt,+      InsertPreparableStmt <$> insertStmt,+      UpdatePreparableStmt <$> updateStmt,+      DeletePreparableStmt <$> deleteStmt+    ]++-- * Insert++insertStmt = InsertStmt <$> maybe withClause <*> insertTarget <*> insertRest <*> maybe onConflict <*> maybe returningClause++insertTarget = InsertTarget <$> qualifiedName <*> maybe colId++insertRest =+  choice+    [ SelectInsertRest <$> maybe insertColumnList <*> maybe overrideKind <*> selectStmt,+      pure DefaultValuesInsertRest+    ]++overrideKind = enumBounded++insertColumnList = nonEmpty (Range.exponential 1 7) insertColumnItem++insertColumnItem = InsertColumnItem <$> colId <*> maybe indirection++onConflict = OnConflict <$> maybe confExpr <*> onConflictDo++onConflictDo =+  choice+    [ UpdateOnConflictDo <$> setClauseList <*> maybe whereClause,+      pure NothingOnConflictDo+    ]++confExpr =+  choice+    [ WhereConfExpr <$> indexParams <*> maybe whereClause,+      ConstraintConfExpr <$> name+    ]++returningClause = targetList++-- * Update++updateStmt = UpdateStmt <$> maybe withClause <*> relationExprOptAlias <*> setClauseList <*> maybe fromClause <*> maybe whereOrCurrentClause <*> maybe returningClause++setClauseList = nonEmpty (Range.exponential 1 10) setClause++setClause =+  choice+    [ TargetSetClause <$> setTarget <*> aExpr,+      TargetListSetClause <$> setTargetList <*> aExpr+    ]++setTarget = SetTarget <$> colId <*> maybe indirection++setTargetList = nonEmpty (Range.exponential 1 10) setTarget++-- * Delete++deleteStmt = DeleteStmt <$> maybe withClause <*> relationExprOptAlias <*> maybe usingClause <*> maybe whereOrCurrentClause <*> maybe returningClause++usingClause = fromList++-- * Select++selectStmt = Left <$> selectNoParens++-- ** selectNoParens++selectNoParens =+  frequency+    [ (90, SelectNoParens <$> maybe withClause <*> (Left <$> simpleSelect) <*> maybe sortClause <*> maybe selectLimit <*> maybe forLockingClause),+      (10, SelectNoParens <$> fmap Just withClause <*> selectClause <*> fmap Just sortClause <*> fmap Just selectLimit <*> fmap Just forLockingClause)+    ]++terminalSelectNoParens =+  SelectNoParens <$> pure Nothing <*> (Left <$> terminalSimpleSelect) <*> pure Nothing <*> pure Nothing <*> pure Nothing++-- ** selectWithParens++selectWithParens = sized $ \_size ->+  if _size <= 1+    then discard+    else+      frequency+        [ (95, NoParensSelectWithParens <$> selectNoParens),+          (5, WithParensSelectWithParens <$> selectWithParens)+        ]++terminalSelectWithParens = NoParensSelectWithParens <$> terminalSelectNoParens++-- ** selectClause++selectClause =+  choice+    [ Left <$> simpleSelect,+      Right <$> small selectWithParens+    ]++nonTrailingSelectClause = Left <$> nonTrailingSimpleSelect++-- ** simpleSelect++simpleSelect =+  choice+    [ normalSimpleSelect,+      tableSimpleSelect,+      valuesSimpleSelect,+      small nonTrailingSelectClause >>= binSimpleSelect+    ]++nonTrailingSimpleSelect = choice [normalSimpleSelect, valuesSimpleSelect, tableSimpleSelect]++normalSimpleSelect = NormalSimpleSelect <$> maybe targeting <*> maybe intoClause <*> maybe fromClause <*> maybe whereClause <*> maybe groupClause <*> maybe havingClause <*> maybe windowClause++tableSimpleSelect = TableSimpleSelect <$> relationExpr++valuesSimpleSelect = ValuesSimpleSelect <$> valuesClause++binSimpleSelect _leftSelect =+  BinSimpleSelect <$> selectBinOp <*> pure _leftSelect <*> maybe allOrDistinct <*> small selectClause++terminalSimpleSelect = pure (NormalSimpleSelect Nothing Nothing Nothing Nothing Nothing Nothing Nothing)++-- * Targeting++targeting =+  choice+    [ NormalTargeting <$> targetList,+      AllTargeting <$> maybe targetList,+      DistinctTargeting <$> maybe (nonEmpty (Range.exponential 1 8) aExpr) <*> targetList+    ]++targetList = nonEmpty (Range.exponential 1 8) targetEl++targetEl =+  choice+    [ pure AsteriskTargetEl,+      AliasedExprTargetEl <$> aExpr <*> colLabel,+      ImplicitlyAliasedExprTargetEl <$> prefixAExpr <*> ident,+      ExprTargetEl <$> aExpr+    ]++-- * BinSimpleSelect++selectBinOp = element [UnionSelectBinOp, IntersectSelectBinOp, ExceptSelectBinOp]++-- * With Clause++withClause = WithClause <$> bool <*> nonEmpty (Range.exponential 1 7) commonTableExpr++commonTableExpr = CommonTableExpr <$> name <*> maybe (nonEmpty (Range.exponential 1 8) name) <*> maybe bool <*> small preparableStmt++-- * Into Clause++intoClause = optTempTableName++optTempTableName =+  choice+    [ TemporaryOptTempTableName <$> bool <*> qualifiedName,+      TempOptTempTableName <$> bool <*> qualifiedName,+      LocalTemporaryOptTempTableName <$> bool <*> qualifiedName,+      LocalTempOptTempTableName <$> bool <*> qualifiedName,+      GlobalTemporaryOptTempTableName <$> bool <*> qualifiedName,+      GlobalTempOptTempTableName <$> bool <*> qualifiedName,+      UnloggedOptTempTableName <$> bool <*> qualifiedName,+      TableOptTempTableName <$> qualifiedName,+      QualifedOptTempTableName <$> qualifiedName+    ]++-- * From Clause++fromList = nonEmpty (Range.exponential 1 8) tableRef++fromClause = fromList++tableRef = choice [relationExprTableRef, selectTableRef, joinTableRef]++relationExprTableRef = RelationExprTableRef <$> relationExpr <*> maybe aliasClause <*> maybe tablesampleClause++funcTableRef = FuncTableRef <$> bool <*> funcTable <*> maybe funcAliasClause++selectTableRef = SelectTableRef <$> bool <*> small selectWithParens <*> maybe aliasClause++joinTableRef = JoinTableRef <$> joinedTable <*> maybe aliasClause++relationExpr =+  choice+    [ SimpleRelationExpr <$> qualifiedName <*> bool,+      OnlyRelationExpr <$> qualifiedName <*> bool+    ]++relationExprOptAlias = RelationExprOptAlias <$> relationExpr <*> maybe ((,) <$> bool <*> colId)++tablesampleClause = TablesampleClause <$> funcName <*> exprList <*> maybe repeatableClause++repeatableClause = aExpr++funcTable =+  choice+    [ FuncExprFuncTable <$> funcExprWindowless <*> optOrdinality,+      RowsFromFuncTable <$> rowsfromList <*> optOrdinality+    ]++rowsfromItem = RowsfromItem <$> funcExprWindowless <*> maybe colDefList++rowsfromList = nonEmpty (Range.exponential 1 8) rowsfromItem++colDefList = tableFuncElementList++optOrdinality = bool++tableFuncElementList = nonEmpty (Range.exponential 1 7) tableFuncElement++tableFuncElement = TableFuncElement <$> colId <*> typename <*> maybe collateClause++collateClause = anyName++aliasClause = AliasClause <$> bool <*> name <*> maybe (nonEmpty (Range.exponential 1 8) name)++funcAliasClause =+  choice+    [ AliasFuncAliasClause <$> aliasClause,+      AsFuncAliasClause <$> tableFuncElementList,+      AsColIdFuncAliasClause <$> colId <*> tableFuncElementList,+      ColIdFuncAliasClause <$> colId <*> tableFuncElementList+    ]++joinedTable =+  frequency+    [ (5,) $ InParensJoinedTable <$> joinedTable,+      (95,) $ MethJoinedTable <$> joinMeth <*> tableRef <*> choice [relationExprTableRef, selectTableRef, funcTableRef]+    ]++joinMeth =+  choice+    [ pure CrossJoinMeth,+      QualJoinMeth <$> maybe joinType <*> joinQual,+      NaturalJoinMeth <$> maybe joinType+    ]++joinType =+  choice+    [ FullJoinType <$> bool,+      LeftJoinType <$> bool,+      RightJoinType <$> bool,+      pure InnerJoinType+    ]++joinQual =+  choice+    [ UsingJoinQual <$> nonEmpty (Range.exponential 1 8) name,+      OnJoinQual <$> aExpr+    ]++-- * Group Clause++groupClause = nonEmpty (Range.exponential 1 8) groupByItem++groupByItem =+  choice+    [ ExprGroupByItem <$> aExpr,+      pure EmptyGroupingSetGroupByItem,+      RollupGroupByItem <$> nonEmpty (Range.exponential 1 8) aExpr,+      CubeGroupByItem <$> nonEmpty (Range.exponential 1 8) aExpr,+      GroupingSetsGroupByItem <$> nonEmpty (Range.exponential 1 3) groupByItem+    ]++-- * Having Clause++havingClause = aExpr++-- * Where Clause++whereClause = aExpr++whereOrCurrentClause =+  choice+    [ ExprWhereOrCurrentClause <$> aExpr,+      CursorWhereOrCurrentClause <$> cursorName+    ]++-- * Window Clause++windowClause = nonEmpty (Range.exponential 1 8) windowDefinition++windowDefinition = WindowDefinition <$> name <*> windowSpecification++windowSpecification = WindowSpecification <$> maybe name <*> maybe (nonEmpty (Range.exponential 1 8) nonSuffixOpAExpr) <*> maybe sortClause <*> maybe frameClause++frameClause = FrameClause <$> frameClauseMode <*> frameExtent <*> maybe windowExclusionClause++frameClauseMode = element [RangeFrameClauseMode, RowsFrameClauseMode, GroupsFrameClauseMode]++frameExtent =+  choice+    [ SingularFrameExtent <$> frameBound,+      BetweenFrameExtent <$> frameBound <*> frameBound+    ]++frameBound =+  choice+    [ pure UnboundedPrecedingFrameBound,+      pure UnboundedFollowingFrameBound,+      pure CurrentRowFrameBound,+      PrecedingFrameBound <$> prefixAExpr,+      FollowingFrameBound <$> prefixAExpr+    ]++windowExclusionClause = element [CurrentRowWindowExclusionClause, GroupWindowExclusionClause, TiesWindowExclusionClause, NoOthersWindowExclusionClause]++-- * Values Clause++valuesClause = nonEmpty (Range.exponential 1 8) (nonEmpty (Range.exponential 1 8) aExpr)++-- * Sort Clause++sortClause = nonEmpty (Range.exponential 1 8) sortBy++sortBy =+  choice+    [ UsingSortBy <$> nonSuffixOpAExpr <*> qualAllOp <*> maybe nullsOrder,+      AscDescSortBy <$> nonSuffixOpAExpr <*> maybe ascDesc <*> maybe nullsOrder+    ]++-- * All or distinct++allOrDistinct = bool++-- * Limit++selectLimit =+  choice+    [ LimitOffsetSelectLimit <$> limitClause <*> offsetClause,+      OffsetLimitSelectLimit <$> offsetClause <*> limitClause,+      LimitSelectLimit <$> limitClause,+      OffsetSelectLimit <$> offsetClause+    ]++limitClause =+  choice+    [ LimitLimitClause <$> selectLimitValue <*> maybe aExpr,+      FetchOnlyLimitClause <$> bool <*> maybe selectFetchFirstValue <*> bool+    ]++selectFetchFirstValue =+  choice+    [ ExprSelectFetchFirstValue <$> cExpr,+      NumSelectFetchFirstValue <$> bool <*> iconstOrFconst+    ]++selectLimitValue =+  choice+    [ ExprSelectLimitValue <$> aExpr,+      pure AllSelectLimitValue+    ]++offsetClause =+  choice+    [ ExprOffsetClause <$> aExpr,+      FetchFirstOffsetClause <$> selectFetchFirstValue <*> bool+    ]++-- * For Locking++forLockingClause =+  choice+    [ ItemsForLockingClause <$> nonEmpty (Range.exponential 1 8) forLockingItem,+      pure ReadOnlyForLockingClause+    ]++forLockingItem = ForLockingItem <$> forLockingStrength <*> maybe (nonEmpty (Range.exponential 1 8) qualifiedName) <*> maybe bool++forLockingStrength =+  element+    [ UpdateForLockingStrength,+      NoKeyUpdateForLockingStrength,+      ShareForLockingStrength,+      KeyForLockingStrength+    ]++-- * Expressions++exprList = nonEmpty (Range.exponential 1 7) aExpr++aExpr =+  recursive+    choice+    [ CExprAExpr <$> cExpr,+      pure DefaultAExpr+    ]+    [ TypecastAExpr <$> prefixAExpr <*> typename,+      CollateAExpr <$> prefixAExpr <*> anyName,+      AtTimeZoneAExpr <$> prefixAExpr <*> aExpr,+      PlusAExpr <$> aExpr,+      MinusAExpr <$> aExpr,+      SymbolicBinOpAExpr <$> prefixAExpr <*> symbolicExprBinOp <*> aExpr,+      PrefixQualOpAExpr <$> qualOp <*> aExpr,+      SuffixQualOpAExpr <$> prefixAExpr <*> qualOp,+      AndAExpr <$> prefixAExpr <*> aExpr,+      OrAExpr <$> prefixAExpr <*> aExpr,+      NotAExpr <$> aExpr,+      VerbalExprBinOpAExpr <$> prefixAExpr <*> bool <*> verbalExprBinOp <*> prefixAExpr <*> maybe aExpr,+      ReversableOpAExpr <$> prefixAExpr <*> bool <*> aExprReversableOp,+      IsnullAExpr <$> prefixAExpr,+      NotnullAExpr <$> prefixAExpr,+      OverlapsAExpr <$> row <*> row,+      SubqueryAExpr <$> prefixAExpr <*> subqueryOp <*> subType <*> choice [Left <$> selectWithParens, Right <$> nonSelectAExpr],+      UniqueAExpr <$> selectWithParens+    ]++prefixAExpr =+  choice+    [ CExprAExpr <$> cExpr,+      pure DefaultAExpr,+      UniqueAExpr <$> selectWithParens+    ]++nonSuffixOpAExpr =+  recursive+    choice+    [ CExprAExpr <$> cExpr,+      pure DefaultAExpr+    ]+    [ TypecastAExpr <$> prefixAExpr <*> typename,+      CollateAExpr <$> prefixAExpr <*> anyName,+      AtTimeZoneAExpr <$> prefixAExpr <*> nonSuffixOpAExpr,+      PlusAExpr <$> nonSuffixOpAExpr,+      MinusAExpr <$> nonSuffixOpAExpr,+      SymbolicBinOpAExpr <$> prefixAExpr <*> symbolicExprBinOp <*> nonSuffixOpAExpr,+      PrefixQualOpAExpr <$> qualOp <*> nonSuffixOpAExpr,+      AndAExpr <$> prefixAExpr <*> nonSuffixOpAExpr,+      OrAExpr <$> prefixAExpr <*> nonSuffixOpAExpr,+      NotAExpr <$> nonSuffixOpAExpr,+      VerbalExprBinOpAExpr <$> prefixAExpr <*> bool <*> verbalExprBinOp <*> prefixAExpr <*> maybe nonSuffixOpAExpr,+      IsnullAExpr <$> prefixAExpr,+      NotnullAExpr <$> prefixAExpr,+      UniqueAExpr <$> selectWithParens+    ]++nonSelectAExpr =+  choice+    [ TypecastAExpr <$> prefixAExpr <*> typename,+      CollateAExpr <$> prefixAExpr <*> anyName,+      AtTimeZoneAExpr <$> prefixAExpr <*> aExpr,+      PlusAExpr <$> aExpr,+      MinusAExpr <$> aExpr,+      SymbolicBinOpAExpr <$> prefixAExpr <*> symbolicExprBinOp <*> aExpr,+      PrefixQualOpAExpr <$> qualOp <*> aExpr,+      SuffixQualOpAExpr <$> prefixAExpr <*> qualOp,+      AndAExpr <$> prefixAExpr <*> aExpr,+      OrAExpr <$> prefixAExpr <*> aExpr,+      NotAExpr <$> aExpr,+      VerbalExprBinOpAExpr <$> prefixAExpr <*> bool <*> verbalExprBinOp <*> prefixAExpr <*> maybe aExpr,+      ReversableOpAExpr <$> prefixAExpr <*> bool <*> aExprReversableOp,+      IsnullAExpr <$> prefixAExpr,+      NotnullAExpr <$> prefixAExpr,+      OverlapsAExpr <$> row <*> row,+      SubqueryAExpr <$> prefixAExpr <*> subqueryOp <*> subType <*> choice [Left <$> selectWithParens, Right <$> nonSelectAExpr],+      UniqueAExpr <$> selectWithParens+    ]++bExpr =+  recursive+    choice+    [ CExprBExpr <$> cExpr+    ]+    [ TypecastBExpr <$> prefixBExpr <*> typename,+      PlusBExpr <$> bExpr,+      MinusBExpr <$> bExpr,+      SymbolicBinOpBExpr <$> prefixBExpr <*> symbolicExprBinOp <*> bExpr,+      QualOpBExpr <$> qualOp <*> bExpr,+      IsOpBExpr <$> prefixBExpr <*> bool <*> bExprIsOp+    ]++prefixBExpr =+  choice+    [ CExprBExpr <$> cExpr+    ]++cExpr =+  recursive+    choice+    [ ColumnrefCExpr <$> columnref+    ]+    [ AexprConstCExpr <$> aexprConst,+      ParamCExpr <$> integral (Range.linear 1 19) <*> maybe indirection,+      InParensCExpr <$> nonSelectAExpr <*> maybe indirection,+      CaseCExpr <$> caseExpr,+      FuncCExpr <$> funcExpr,+      SelectWithParensCExpr <$> selectWithParens <*> maybe indirection,+      ExistsCExpr <$> selectWithParens,+      ArrayCExpr <$> choice [Left <$> selectWithParens, Right <$> arrayExpr],+      ExplicitRowCExpr <$> explicitRow,+      ImplicitRowCExpr <$> implicitRow,+      GroupingCExpr <$> exprList+    ]++-- **++caseExpr = CaseExpr <$> maybe aExpr <*> whenClauseList <*> maybe aExpr++whenClauseList = nonEmpty (Range.exponential 1 7) whenClause++whenClause = WhenClause <$> small aExpr <*> small aExpr++inExpr =+  choice+    [ SelectInExpr <$> NoParensSelectWithParens <$> selectNoParens,+      ExprListInExpr <$> exprList+    ]++arrayExpr =+  small $+    choice+      [ ExprListArrayExpr <$> exprList,+        ArrayExprListArrayExpr <$> arrayExprList,+        pure EmptyArrayExpr+      ]++arrayExprList = nonEmpty (Range.exponential 1 4) arrayExpr++row =+  choice+    [ ExplicitRowRow <$> explicitRow,+      ImplicitRowRow <$> implicitRow+    ]++explicitRow = maybe exprList++implicitRow = ImplicitRow <$> exprList <*> aExpr++-- ** FuncExpr++funcExpr =+  choice+    [ ApplicationFuncExpr <$> funcApplication <*> maybe withinGroupClause <*> maybe filterClause <*> maybe overClause,+      SubexprFuncExpr <$> funcExprCommonSubexpr+    ]++funcExprWindowless =+  choice+    [ ApplicationFuncExprWindowless <$> funcApplication,+      CommonSubexprFuncExprWindowless <$> funcExprCommonSubexpr+    ]++funcApplication = FuncApplication <$> funcName <*> maybe funcApplicationParams++funcApplicationParams =+  choice+    [ NormalFuncApplicationParams <$> maybe allOrDistinct <*> nonEmpty (Range.exponential 1 8) funcArgExpr <*> maybe sortClause,+      VariadicFuncApplicationParams <$> maybe (nonEmpty (Range.exponential 1 8) funcArgExpr) <*> funcArgExpr <*> maybe sortClause,+      pure StarFuncApplicationParams+    ]++funcArgExpr =+  choice+    [ ExprFuncArgExpr <$> small aExpr,+      ColonEqualsFuncArgExpr <$> name <*> small aExpr,+      EqualsGreaterFuncArgExpr <$> name <*> small aExpr+    ]++withinGroupClause = sortClause++filterClause = aExpr++overClause = choice [WindowOverClause <$> windowSpecification, ColIdOverClause <$> colId]++funcExprCommonSubexpr =+  choice+    [ CollationForFuncExprCommonSubexpr <$> aExpr,+      pure CurrentDateFuncExprCommonSubexpr,+      CurrentTimeFuncExprCommonSubexpr <$> maybe iconst,+      CurrentTimestampFuncExprCommonSubexpr <$> maybe iconst,+      LocalTimeFuncExprCommonSubexpr <$> maybe iconst,+      LocalTimestampFuncExprCommonSubexpr <$> maybe iconst,+      pure CurrentRoleFuncExprCommonSubexpr,+      pure CurrentUserFuncExprCommonSubexpr,+      pure SessionUserFuncExprCommonSubexpr,+      pure UserFuncExprCommonSubexpr,+      pure CurrentCatalogFuncExprCommonSubexpr,+      pure CurrentSchemaFuncExprCommonSubexpr,+      CastFuncExprCommonSubexpr <$> aExpr <*> typename,+      ExtractFuncExprCommonSubexpr <$> maybe extractList,+      OverlayFuncExprCommonSubexpr <$> overlayList,+      PositionFuncExprCommonSubexpr <$> maybe positionList,+      SubstringFuncExprCommonSubexpr <$> maybe substrList,+      TreatFuncExprCommonSubexpr <$> aExpr <*> typename,+      TrimFuncExprCommonSubexpr <$> maybe trimModifier <*> trimList,+      NullIfFuncExprCommonSubexpr <$> aExpr <*> aExpr,+      CoalesceFuncExprCommonSubexpr <$> exprList,+      GreatestFuncExprCommonSubexpr <$> exprList,+      LeastFuncExprCommonSubexpr <$> exprList+    ]++extractList = ExtractList <$> extractArg <*> aExpr++extractArg =+  choice+    [ IdentExtractArg <$> ident,+      pure YearExtractArg,+      pure MonthExtractArg,+      pure DayExtractArg,+      pure HourExtractArg,+      pure MinuteExtractArg,+      pure SecondExtractArg,+      SconstExtractArg <$> sconst+    ]++overlayList = OverlayList <$> aExpr <*> overlayPlacing <*> substrFrom <*> maybe substrFor++overlayPlacing = aExpr++positionList = PositionList <$> bExpr <*> bExpr++substrList =+  choice+    [ ExprSubstrList <$> aExpr <*> substrListFromFor,+      ExprListSubstrList <$> exprList+    ]++substrListFromFor =+  choice+    [ FromForSubstrListFromFor <$> substrFrom <*> substrFor,+      ForFromSubstrListFromFor <$> substrFor <*> substrFrom,+      FromSubstrListFromFor <$> substrFrom,+      ForSubstrListFromFor <$> substrFor+    ]++substrFrom = aExpr++substrFor = aExpr++trimModifier = enumBounded++trimList =+  choice+    [ ExprFromExprListTrimList <$> aExpr <*> exprList,+      FromExprListTrimList <$> exprList,+      ExprListTrimList <$> exprList+    ]++-- * Operators++qualOp = choice [OpQualOp <$> op, OperatorQualOp <$> anyOperator]++qualAllOp =+  choice+    [ AllQualAllOp <$> allOp,+      AnyQualAllOp <$> anyOperator+    ]++op = do+  a <- text (Range.exponential 1 7) (element "+-*/<>=~!@#%^&|`?")+  case Validation.op a of+    Nothing -> return a+    _ -> discard++anyOperator =+  recursive+    choice+    [ AllOpAnyOperator <$> allOp+    ]+    [ QualifiedAnyOperator <$> colId <*> anyOperator+    ]++allOp = choice [OpAllOp <$> op, MathAllOp <$> mathOp]++mathOp = enumBounded++symbolicExprBinOp =+  choice+    [ MathSymbolicExprBinOp <$> mathOp,+      QualSymbolicExprBinOp <$> qualOp+    ]++binOp = element (toList KeywordSet.symbolicBinOp <> ["AND", "OR", "IS DISTINCT FROM", "IS NOT DISTINCT FROM"])++verbalExprBinOp = enumBounded++aExprReversableOp =+  choice+    [ pure NullAExprReversableOp,+      pure TrueAExprReversableOp,+      pure FalseAExprReversableOp,+      pure UnknownAExprReversableOp,+      DistinctFromAExprReversableOp <$> aExpr,+      OfAExprReversableOp <$> typeList,+      BetweenAExprReversableOp <$> bool <*> bExpr <*> aExpr,+      BetweenSymmetricAExprReversableOp <$> bExpr <*> aExpr,+      InAExprReversableOp <$> inExpr,+      pure DocumentAExprReversableOp+    ]++bExprIsOp =+  choice+    [ DistinctFromBExprIsOp <$> bExpr,+      OfBExprIsOp <$> typeList,+      pure DocumentBExprIsOp+    ]++subqueryOp =+  choice+    [ AllSubqueryOp <$> allOp,+      AnySubqueryOp <$> anyOperator,+      LikeSubqueryOp <$> bool,+      IlikeSubqueryOp <$> bool+    ]++-- * Constants++aexprConst =+  choice+    [ IAexprConst <$> iconst,+      FAexprConst <$> fconst,+      SAexprConst <$> sconst,+      BAexprConst <$> text (Range.exponential 1 100) (element "01"),+      XAexprConst <$> text (Range.exponential 1 100) (element "0123456789abcdefABCDEF"),+      FuncAexprConst <$> funcName <*> maybe funcConstArgs <*> sconst,+      ConstTypenameAexprConst <$> constTypename <*> sconst,+      StringIntervalAexprConst <$> sconst <*> maybe interval,+      IntIntervalAexprConst <$> integral (Range.exponential 0 2309482309483029) <*> sconst,+      BoolAexprConst <$> bool,+      pure NullAexprConst+    ]++funcConstArgs = FuncConstArgs <$> nonEmpty (Range.exponential 1 7) funcArgExpr <*> maybe sortClause++constTypename =+  choice+    [ NumericConstTypename <$> numeric,+      ConstBitConstTypename <$> constBit,+      ConstCharacterConstTypename <$> constCharacter,+      ConstDatetimeConstTypename <$> constDatetime+    ]++numeric =+  choice+    [ pure IntNumeric,+      pure IntegerNumeric,+      pure SmallintNumeric,+      pure BigintNumeric,+      pure RealNumeric,+      FloatNumeric <$> maybe iconst,+      pure DoublePrecisionNumeric,+      DecimalNumeric <$> maybe (nonEmpty (Range.exponential 1 7) (small aExpr)),+      DecNumeric <$> maybe (nonEmpty (Range.exponential 1 7) (small aExpr)),+      NumericNumeric <$> maybe (nonEmpty (Range.exponential 1 7) (small aExpr)),+      pure BooleanNumeric+    ]++bit = Bit <$> bool <*> maybe (nonEmpty (Range.exponential 1 7) (small aExpr))++constBit = bit++constCharacter = ConstCharacter <$> character <*> maybe iconst++character =+  choice+    [ CharacterCharacter <$> bool,+      CharCharacter <$> bool,+      pure VarcharCharacter,+      NationalCharacterCharacter <$> bool,+      NationalCharCharacter <$> bool,+      NcharCharacter <$> bool+    ]++constDatetime =+  choice+    [ TimestampConstDatetime <$> maybe iconst <*> maybe bool,+      TimeConstDatetime <$> maybe iconst <*> maybe bool+    ]++interval =+  choice+    [ pure YearInterval,+      pure MonthInterval,+      pure DayInterval,+      pure HourInterval,+      pure MinuteInterval,+      SecondInterval <$> intervalSecond,+      pure YearToMonthInterval,+      pure DayToHourInterval,+      pure DayToMinuteInterval,+      DayToSecondInterval <$> intervalSecond,+      pure HourToMinuteInterval,+      HourToSecondInterval <$> intervalSecond,+      MinuteToSecondInterval <$> intervalSecond+    ]++intervalSecond = maybe iconst++sconst = text (Range.exponential 0 1000) unicode++iconstOrFconst = choice [Left <$> iconst <|> Right <$> fconst]++fconst =+  filter (\a -> fromIntegral (round a) /= a) $+    realFrac_ (Range.exponentialFloat 0 309457394857984375983475943)++iconst = integral (Range.exponential 0 maxBound)++-- * Types++nullable = pure False++arrayDimensionsAmount = int (Range.exponential 0 4)++-- ** Typename++typename = Typename <$> bool <*> simpleTypename <*> pure False <*> maybe ((,) <$> typenameArrayDimensions <*> pure False)++typenameArrayDimensions =+  choice+    [ BoundsTypenameArrayDimensions <$> arrayBounds,+      ExplicitTypenameArrayDimensions <$> maybe iconst+    ]++arrayBounds = nonEmpty (Range.exponential 1 4) (maybe iconst)++simpleTypename =+  choice+    [ GenericTypeSimpleTypename <$> genericType,+      NumericSimpleTypename <$> numeric,+      BitSimpleTypename <$> bit,+      CharacterSimpleTypename <$> character,+      ConstDatetimeSimpleTypename <$> constDatetime,+      ConstIntervalSimpleTypename <$> choice [Left <$> maybe interval, Right <$> iconst]+    ]++genericType = GenericType <$> typeFunctionName <*> maybe attrs <*> maybe typeModifiers++attrs = nonEmpty (Range.exponential 1 10) attrName++typeModifiers = exprList++typeList = nonEmpty (Range.exponential 1 7) typename++subType = enumBounded++-- * Names++columnref = Columnref <$> colId <*> maybe indirection++keywordNotInSet = \set -> notInSet set $ do+  a <- element startList+  b <- text (Range.linear 1 29) (element contList)+  return (Text.cons a b)+  where+    startList = "abcdefghijklmnopqrstuvwxyz_" <> List.filter isLower (enumFromTo '\200' '\377')+    contList = startList <> "0123456789$"++ident = identWithSet mempty++typeName = identWithSet KeywordSet.typeFunctionName++name = identWithSet KeywordSet.colId++cursorName = name++identWithSet set =+  frequency+    [ (95,) $ UnquotedIdent <$> (keywordNotInSet . HashSet.difference KeywordSet.keyword) set,+      (5,) $ QuotedIdent <$> text (Range.linear 1 30) quotedChar+    ]++qualifiedName =+  choice+    [ SimpleQualifiedName <$> name,+      IndirectedQualifiedName <$> name <*> indirection+    ]++indirection = nonEmpty (Range.linear 1 3) indirectionEl++indirectionEl =+  choice+    [ AttrNameIndirectionEl <$> name,+      pure AllIndirectionEl,+      ExprIndirectionEl <$> (small aExpr),+      SliceIndirectionEl <$> maybe (small aExpr) <*> maybe (small aExpr)+    ]++quotedChar = filter (not . isControl) unicode++colId = name++colLabel = name++attrName = colLabel++typeFunctionName = name++funcName =+  choice+    [ TypeFuncName <$> typeFunctionName,+      IndirectedFuncName <$> colId <*> indirection+    ]++anyName = AnyName <$> colId <*> maybe attrs++-- * Indexes++indexParams = nonEmpty (Range.exponential 1 5) indexElem++indexElem = IndexElem <$> indexElemDef <*> maybe collate <*> maybe class_ <*> maybe ascDesc <*> maybe nullsOrder++indexElemDef =+  choice+    [ IdIndexElemDef <$> colId,+      FuncIndexElemDef <$> funcExprWindowless,+      ExprIndexElemDef <$> aExpr+    ]  collate = anyName 
library/PostgresqlSyntax/Ast.hs view
@@ -1,2057 +1,2326 @@-{-|-Names for nodes mostly resemble the according definitions in the @gram.y@-original Postgres parser file, except for the cases where we can optimize on that.--For reasoning see the docs of the parsing module of this project.--}-module PostgresqlSyntax.Ast where--import PostgresqlSyntax.Prelude hiding (Order, Op)----- * Statement----------------------------{--PreparableStmt:-  |  SelectStmt-  |  InsertStmt-  |  UpdateStmt-  |  DeleteStmt--}-data PreparableStmt = -  SelectPreparableStmt SelectStmt |-  InsertPreparableStmt InsertStmt |-  UpdatePreparableStmt UpdateStmt |-  DeletePreparableStmt DeleteStmt-  deriving (Show, Generic, Eq, Ord)----- * Insert----------------------------{--InsertStmt:-  | opt_with_clause INSERT INTO insert_target insert_rest-      opt_on_conflict returning_clause--}-data InsertStmt = InsertStmt (Maybe WithClause) InsertTarget InsertRest (Maybe OnConflict) (Maybe ReturningClause)-  deriving (Show, Generic, Eq, Ord)--{--insert_target:-  | qualified_name-  | qualified_name AS ColId--}-data InsertTarget = InsertTarget QualifiedName (Maybe ColId)-  deriving (Show, Generic, Eq, Ord)--{--insert_rest:-  | SelectStmt-  | OVERRIDING override_kind VALUE_P SelectStmt-  | '(' insert_column_list ')' SelectStmt-  | '(' insert_column_list ')' OVERRIDING override_kind VALUE_P SelectStmt-  | DEFAULT VALUES--}-data InsertRest =-  SelectInsertRest (Maybe InsertColumnList) (Maybe OverrideKind) SelectStmt |-  DefaultValuesInsertRest-  deriving (Show, Generic, Eq, Ord)--{--override_kind:-  | USER-  | SYSTEM_P--}-data OverrideKind = UserOverrideKind | SystemOverrideKind-  deriving (Show, Generic, Eq, Ord, Enum, Bounded)--{--insert_column_list:-  | insert_column_item-  | insert_column_list ',' insert_column_item--}-type InsertColumnList = NonEmpty InsertColumnItem--{--insert_column_item:-  | ColId opt_indirection--}-data InsertColumnItem = InsertColumnItem ColId (Maybe Indirection)-  deriving (Show, Generic, Eq, Ord)--{--opt_on_conflict:-  | ON CONFLICT opt_conf_expr DO UPDATE SET set_clause_list where_clause-  | ON CONFLICT opt_conf_expr DO NOTHING-  | EMPTY--}-data OnConflict = OnConflict (Maybe ConfExpr) OnConflictDo-  deriving (Show, Generic, Eq, Ord)--{--opt_on_conflict:-  | ON CONFLICT opt_conf_expr DO UPDATE SET set_clause_list where_clause-  | ON CONFLICT opt_conf_expr DO NOTHING-  | EMPTY--}-data OnConflictDo =-  UpdateOnConflictDo SetClauseList (Maybe WhereClause) |-  NothingOnConflictDo-  deriving (Show, Generic, Eq, Ord)--{--opt_conf_expr:-  | '(' index_params ')' where_clause-  | ON CONSTRAINT name-  | EMPTY--}-data ConfExpr =-  WhereConfExpr IndexParams (Maybe WhereClause) |-  ConstraintConfExpr Name-  deriving (Show, Generic, Eq, Ord)--{--returning_clause:-  | RETURNING target_list-  | EMPTY--}-type ReturningClause = TargetList----- * Update----------------------------{--UpdateStmt:-  | opt_with_clause UPDATE relation_expr_opt_alias-      SET set_clause_list-      from_clause-      where_or_current_clause-      returning_clause--}-data UpdateStmt = UpdateStmt (Maybe WithClause) RelationExprOptAlias SetClauseList (Maybe FromClause) (Maybe WhereOrCurrentClause) (Maybe ReturningClause)-  deriving (Show, Generic, Eq, Ord)--{--set_clause_list:-  | set_clause-  | set_clause_list ',' set_clause--}-type SetClauseList = NonEmpty SetClause--{--set_clause:-  | set_target '=' a_expr-  | '(' set_target_list ')' '=' a_expr--}-data SetClause =-  TargetSetClause SetTarget AExpr |-  TargetListSetClause SetTargetList AExpr-  deriving (Show, Generic, Eq, Ord)--{--set_target:-  | ColId opt_indirection--}-data SetTarget = SetTarget ColId (Maybe Indirection)-  deriving (Show, Generic, Eq, Ord)--{--set_target_list:-  | set_target-  | set_target_list ',' set_target--}-type SetTargetList = NonEmpty SetTarget----- * Delete----------------------------{--DeleteStmt:-  | opt_with_clause DELETE_P FROM relation_expr_opt_alias-      using_clause where_or_current_clause returning_clause--}-data DeleteStmt = DeleteStmt (Maybe WithClause) RelationExprOptAlias (Maybe UsingClause) (Maybe WhereOrCurrentClause) (Maybe ReturningClause)-  deriving (Show, Generic, Eq, Ord)--{--using_clause:-  | USING from_list-  | EMPTY--}-type UsingClause = FromList----- * Select----------------------------{--SelectStmt:-  |  select_no_parens-  |  select_with_parens--}-type SelectStmt = Either SelectNoParens SelectWithParens--{--select_with_parens:-  |  '(' select_no_parens ')'-  |  '(' select_with_parens ')'--}-data SelectWithParens =-  NoParensSelectWithParens SelectNoParens |-  WithParensSelectWithParens SelectWithParens-  deriving (Show, Generic, Eq, Ord)--{-|-Covers the following cases:--@-select_no_parens:-  |  simple_select-  |  select_clause sort_clause-  |  select_clause opt_sort_clause for_locking_clause opt_select_limit-  |  select_clause opt_sort_clause select_limit opt_for_locking_clause-  |  with_clause select_clause-  |  with_clause select_clause sort_clause-  |  with_clause select_clause opt_sort_clause for_locking_clause opt_select_limit-  |  with_clause select_clause opt_sort_clause select_limit opt_for_locking_clause-@--}-data SelectNoParens =-  SelectNoParens (Maybe WithClause) SelectClause (Maybe SortClause) (Maybe SelectLimit) (Maybe ForLockingClause)-  deriving (Show, Generic, Eq, Ord)--{-|-@-select_clause:-  |  simple_select-  |  select_with_parens-@--}-type SelectClause = Either SimpleSelect SelectWithParens--{--simple_select:-  |  SELECT opt_all_clause opt_target_list-      into_clause from_clause where_clause-      group_clause having_clause window_clause-  |  SELECT distinct_clause target_list-      into_clause from_clause where_clause-      group_clause having_clause window_clause-  |  values_clause-  |  TABLE relation_expr-  |  select_clause UNION all_or_distinct select_clause-  |  select_clause INTERSECT all_or_distinct select_clause-  |  select_clause EXCEPT all_or_distinct select_clause--}-data SimpleSelect =-  NormalSimpleSelect (Maybe Targeting) (Maybe IntoClause) (Maybe FromClause) (Maybe WhereClause) (Maybe GroupClause) (Maybe HavingClause) (Maybe WindowClause) |-  ValuesSimpleSelect ValuesClause |-  TableSimpleSelect RelationExpr |-  BinSimpleSelect SelectBinOp SelectClause (Maybe Bool) SelectClause-  deriving (Show, Generic, Eq, Ord)--{-|-Covers these parts of spec:--@-simple_select:-  |  SELECT opt_all_clause opt_target_list-      into_clause from_clause where_clause-      group_clause having_clause window_clause-  |  SELECT distinct_clause target_list-      into_clause from_clause where_clause-      group_clause having_clause window_clause--distinct_clause:-  |  DISTINCT-  |  DISTINCT ON '(' expr_list ')'-@--}-data Targeting =-  NormalTargeting TargetList |-  AllTargeting (Maybe TargetList) |-  DistinctTargeting (Maybe ExprList) TargetList-  deriving (Show, Generic, Eq, Ord)--{--target_list:-  | target_el-  | target_list ',' target_el--}-type TargetList = NonEmpty TargetEl--{--target_el:-  |  a_expr AS ColLabel-  |  a_expr IDENT-  |  a_expr-  |  '*'--}-data TargetEl =-  AliasedExprTargetEl AExpr Ident |-  ImplicitlyAliasedExprTargetEl AExpr Ident |-  ExprTargetEl AExpr |-  AsteriskTargetEl-  deriving (Show, Generic, Eq, Ord)--{--  |  select_clause UNION all_or_distinct select_clause-  |  select_clause INTERSECT all_or_distinct select_clause-  |  select_clause EXCEPT all_or_distinct select_clause--}-data SelectBinOp = UnionSelectBinOp | IntersectSelectBinOp | ExceptSelectBinOp-  deriving (Show, Generic, Eq, Ord)--{--with_clause:-  |  WITH cte_list-  |  WITH_LA cte_list-  |  WITH RECURSIVE cte_list--}-data WithClause = WithClause Bool (NonEmpty CommonTableExpr)-  deriving (Show, Generic, Eq, Ord)--{--common_table_expr:-  |  name opt_name_list AS opt_materialized '(' PreparableStmt ')'-opt_materialized:-  | MATERIALIZED-  | NOT MATERIALIZED-  | EMPTY--}-data CommonTableExpr = CommonTableExpr Ident (Maybe (NonEmpty Ident)) (Maybe Bool) PreparableStmt-  deriving (Show, Generic, Eq, Ord)--type IntoClause = OptTempTableName--{--OptTempTableName:-  |  TEMPORARY opt_table qualified_name-  |  TEMP opt_table qualified_name-  |  LOCAL TEMPORARY opt_table qualified_name-  |  LOCAL TEMP opt_table qualified_name-  |  GLOBAL TEMPORARY opt_table qualified_name-  |  GLOBAL TEMP opt_table qualified_name-  |  UNLOGGED opt_table qualified_name-  |  TABLE qualified_name-  |  qualified_name--}-data OptTempTableName =-  TemporaryOptTempTableName Bool QualifiedName |-  TempOptTempTableName Bool QualifiedName |-  LocalTemporaryOptTempTableName Bool QualifiedName |-  LocalTempOptTempTableName Bool QualifiedName |-  GlobalTemporaryOptTempTableName Bool QualifiedName |-  GlobalTempOptTempTableName Bool QualifiedName |-  UnloggedOptTempTableName Bool QualifiedName |-  TableOptTempTableName QualifiedName |-  QualifedOptTempTableName QualifiedName-  deriving (Show, Generic, Eq, Ord)--type FromClause = NonEmpty TableRef--type GroupClause = NonEmpty GroupByItem--{--group_by_item:-  |  a_expr-  |  empty_grouping_set-  |  cube_clause-  |  rollup_clause-  |  grouping_sets_clause-empty_grouping_set:-  |  '(' ')'-rollup_clause:-  |  ROLLUP '(' expr_list ')'-cube_clause:-  |  CUBE '(' expr_list ')'-grouping_sets_clause:-  |  GROUPING SETS '(' group_by_list ')'--}-data GroupByItem =-  ExprGroupByItem AExpr |-  EmptyGroupingSetGroupByItem |-  RollupGroupByItem ExprList |-  CubeGroupByItem ExprList |-  GroupingSetsGroupByItem (NonEmpty GroupByItem)-  deriving (Show, Generic, Eq, Ord)--{-|-@-having_clause:-  |  HAVING a_expr-  |  EMPTY-@--}-type HavingClause = AExpr--{-|-@-window_clause:-  |  WINDOW window_definition_list-  |  EMPTY--window_definition_list:-  |  window_definition-  |  window_definition_list ',' window_definition-@--}-type WindowClause = NonEmpty WindowDefinition--{-|-@-window_definition:-  |  ColId AS window_specification-@--}-data WindowDefinition = WindowDefinition Ident WindowSpecification-  deriving (Show, Generic, Eq, Ord)--{-|-@-window_specification:-  |  '(' opt_existing_window_name opt_partition_clause-            opt_sort_clause opt_frame_clause ')'--opt_existing_window_name:-  |  ColId-  |  EMPTY--opt_partition_clause:-  |  PARTITION BY expr_list-  |  EMPTY-@--}-data WindowSpecification = WindowSpecification (Maybe ExistingWindowName) (Maybe PartitionClause) (Maybe SortClause) (Maybe FrameClause)-  deriving (Show, Generic, Eq, Ord)--type ExistingWindowName = ColId--type PartitionClause = ExprList--{--opt_frame_clause:-  |  RANGE frame_extent opt_window_exclusion_clause-  |  ROWS frame_extent opt_window_exclusion_clause-  |  GROUPS frame_extent opt_window_exclusion_clause-  |  EMPTY--}-data FrameClause = FrameClause FrameClauseMode FrameExtent (Maybe WindowExclusionClause)-  deriving (Show, Generic, Eq, Ord)--{--opt_frame_clause:-  |  RANGE frame_extent opt_window_exclusion_clause-  |  ROWS frame_extent opt_window_exclusion_clause-  |  GROUPS frame_extent opt_window_exclusion_clause-  |  EMPTY--}-data FrameClauseMode = RangeFrameClauseMode | RowsFrameClauseMode | GroupsFrameClauseMode-  deriving (Show, Generic, Eq, Ord)--{--frame_extent:-  |  frame_bound-  |  BETWEEN frame_bound AND frame_bound--}-data FrameExtent = SingularFrameExtent FrameBound | BetweenFrameExtent FrameBound FrameBound-  deriving (Show, Generic, Eq, Ord)--{--frame_bound:-  |  UNBOUNDED PRECEDING-  |  UNBOUNDED FOLLOWING-  |  CURRENT_P ROW-  |  a_expr PRECEDING-  |  a_expr FOLLOWING--}-data FrameBound =-  UnboundedPrecedingFrameBound |-  UnboundedFollowingFrameBound |-  CurrentRowFrameBound |-  PrecedingFrameBound AExpr |-  FollowingFrameBound AExpr-  deriving (Show, Generic, Eq, Ord)--{--opt_window_exclusion_clause:-  |  EXCLUDE CURRENT_P ROW-  |  EXCLUDE GROUP_P-  |  EXCLUDE TIES-  |  EXCLUDE NO OTHERS-  |  EMPTY--}-data WindowExclusionClause =-  CurrentRowWindowExclusionClause |-  GroupWindowExclusionClause |-  TiesWindowExclusionClause |-  NoOthersWindowExclusionClause-  deriving (Show, Generic, Eq, Ord)--{--values_clause:-  |  VALUES '(' expr_list ')'-  |  values_clause ',' '(' expr_list ')'--}-type ValuesClause = NonEmpty ExprList--{-|--sort_clause:-  |  ORDER BY sortby_list--sortby_list:-  |  sortby-  |  sortby_list ',' sortby---}-type SortClause = NonEmpty SortBy--{--sortby:-  |  a_expr USING qual_all_Op opt_nulls_order-  |  a_expr opt_asc_desc opt_nulls_order--}-data SortBy =-  UsingSortBy AExpr QualAllOp (Maybe NullsOrder) |-  AscDescSortBy AExpr (Maybe AscDesc) (Maybe NullsOrder)-  deriving (Show, Generic, Eq, Ord)--{--select_limit:-  | limit_clause offset_clause-  | offset_clause limit_clause-  | limit_clause-  | offset_clause--}-data SelectLimit =-  LimitOffsetSelectLimit LimitClause OffsetClause |-  OffsetLimitSelectLimit OffsetClause LimitClause |-  LimitSelectLimit LimitClause |-  OffsetSelectLimit OffsetClause-  deriving (Show, Generic, Eq, Ord)--{--limit_clause:-  | LIMIT select_limit_value-  | LIMIT select_limit_value ',' select_offset_value-  | FETCH first_or_next select_fetch_first_value row_or_rows ONLY-  | FETCH first_or_next row_or_rows ONLY-select_offset_value:-  | a_expr-first_or_next:-  | FIRST_P-  | NEXT-row_or_rows:-  | ROW-  | ROWS--}-data LimitClause =-  LimitLimitClause SelectLimitValue (Maybe AExpr) |-  FetchOnlyLimitClause Bool (Maybe SelectFetchFirstValue) Bool-  deriving (Show, Generic, Eq, Ord)--{--select_fetch_first_value:-  | c_expr-  | '+' I_or_F_const-  | '-' I_or_F_const--}-data SelectFetchFirstValue =-  ExprSelectFetchFirstValue CExpr |-  NumSelectFetchFirstValue Bool (Either Int64 Double)-  deriving (Show, Generic, Eq, Ord)--{--select_limit_value:-  | a_expr-  | ALL--}-data SelectLimitValue =-  ExprSelectLimitValue AExpr |-  AllSelectLimitValue-  deriving (Show, Generic, Eq, Ord)--{--offset_clause:-  | OFFSET select_offset_value-  | OFFSET select_fetch_first_value row_or_rows-select_offset_value:-  | a_expr-row_or_rows:-  | ROW-  | ROWS--}-data OffsetClause =-  ExprOffsetClause AExpr |-  FetchFirstOffsetClause SelectFetchFirstValue Bool-  deriving (Show, Generic, Eq, Ord)----- * For Locking----------------------------{--for_locking_clause:-  | for_locking_items-  | FOR READ ONLY-for_locking_items:-  | for_locking_item-  | for_locking_items for_locking_item--}-data ForLockingClause =-  ItemsForLockingClause (NonEmpty ForLockingItem) |-  ReadOnlyForLockingClause-  deriving (Show, Generic, Eq, Ord)--{--for_locking_item:-  | for_locking_strength locked_rels_list opt_nowait_or_skip-locked_rels_list:-  | OF qualified_name_list-  | EMPTY-opt_nowait_or_skip:-  | NOWAIT-  | SKIP LOCKED-  | EMPTY--}-data ForLockingItem = ForLockingItem ForLockingStrength (Maybe (NonEmpty QualifiedName)) (Maybe Bool)-  deriving (Show, Generic, Eq, Ord)--{--for_locking_strength:-  | FOR UPDATE-  | FOR NO KEY UPDATE-  | FOR SHARE-  | FOR KEY SHARE--}-data ForLockingStrength =-  UpdateForLockingStrength |-  NoKeyUpdateForLockingStrength |-  ShareForLockingStrength |-  KeyForLockingStrength-  deriving (Show, Generic, Eq, Ord)----- * Table references and joining----------------------------{--from_list:-  | table_ref-  | from_list ',' table_ref--}-type FromList = NonEmpty TableRef--{--| relation_expr opt_alias_clause-| relation_expr opt_alias_clause tablesample_clause-| func_table func_alias_clause-| LATERAL_P func_table func_alias_clause-| xmltable opt_alias_clause-| LATERAL_P xmltable opt_alias_clause-| select_with_parens opt_alias_clause-| LATERAL_P select_with_parens opt_alias_clause-| joined_table-| '(' joined_table ')' alias_clause--TODO: Add xmltable--}-data TableRef =-  {--  | relation_expr opt_alias_clause-  | relation_expr opt_alias_clause tablesample_clause-  -}-  RelationExprTableRef RelationExpr (Maybe AliasClause) (Maybe TablesampleClause) |-  {--  | func_table func_alias_clause-  | LATERAL_P func_table func_alias_clause-  -}-  FuncTableRef Bool FuncTable (Maybe FuncAliasClause) |-  {--  | select_with_parens opt_alias_clause-  | LATERAL_P select_with_parens opt_alias_clause-  -}-  SelectTableRef Bool SelectWithParens (Maybe AliasClause) |-  {--  | joined_table-  | '(' joined_table ')' alias_clause-  -}-  JoinTableRef JoinedTable (Maybe AliasClause)-  deriving (Show, Generic, Eq, Ord)--{--| qualified_name-| qualified_name '*'-| ONLY qualified_name-| ONLY '(' qualified_name ')'--}-data RelationExpr =-  SimpleRelationExpr QualifiedName Bool |-  OnlyRelationExpr QualifiedName Bool-  deriving (Show, Generic, Eq, Ord)--{--relation_expr_opt_alias:-  | relation_expr-  | relation_expr ColId-  | relation_expr AS ColId--}-data RelationExprOptAlias = RelationExprOptAlias RelationExpr (Maybe (Bool, ColId))-  deriving (Show, Generic, Eq, Ord)--{--tablesample_clause:-  | TABLESAMPLE func_name '(' expr_list ')' opt_repeatable_clause--}-data TablesampleClause = TablesampleClause FuncName ExprList (Maybe RepeatableClause)-  deriving (Show, Generic, Eq, Ord)--{--opt_repeatable_clause:-  | REPEATABLE '(' a_expr ')'-  | EMPTY--}-type RepeatableClause = AExpr--{--func_table:-  | func_expr_windowless opt_ordinality-  | ROWS FROM '(' rowsfrom_list ')' opt_ordinality--}-data FuncTable =-  FuncExprFuncTable FuncExprWindowless OptOrdinality |-  RowsFromFuncTable RowsfromList OptOrdinality-  deriving (Show, Generic, Eq, Ord)--{--rowsfrom_item:-  | func_expr_windowless opt_col_def_list--}-data RowsfromItem = RowsfromItem FuncExprWindowless (Maybe ColDefList)-  deriving (Show, Generic, Eq, Ord)--{--rowsfrom_list:-  | rowsfrom_item-  | rowsfrom_list ',' rowsfrom_item--}-type RowsfromList = NonEmpty RowsfromItem--{--opt_col_def_list:-  | AS '(' TableFuncElementList ')'-  | EMPTY--}-type ColDefList = TableFuncElementList--{--opt_ordinality:-  | WITH_LA ORDINALITY-  | EMPTY--}-type OptOrdinality = Bool--{--TableFuncElementList:-  | TableFuncElement-  | TableFuncElementList ',' TableFuncElement--}-type TableFuncElementList = NonEmpty TableFuncElement--{--TableFuncElement:-  | ColId Typename opt_collate_clause--}-data TableFuncElement = TableFuncElement ColId Typename (Maybe CollateClause)-  deriving (Show, Generic, Eq, Ord)--{--opt_collate_clause:-  | COLLATE any_name-  | EMPTY--}-type CollateClause = AnyName--{--alias_clause:-  |  AS ColId '(' name_list ')'-  |  AS ColId-  |  ColId '(' name_list ')'-  |  ColId--}-data AliasClause = AliasClause Bool ColId (Maybe NameList)-  deriving (Show, Generic, Eq, Ord)--{--func_alias_clause:-  | alias_clause-  | AS '(' TableFuncElementList ')'-  | AS ColId '(' TableFuncElementList ')'-  | ColId '(' TableFuncElementList ')'-  | EMPTY--}-data FuncAliasClause =-  AliasFuncAliasClause AliasClause |-  AsFuncAliasClause TableFuncElementList |-  AsColIdFuncAliasClause ColId TableFuncElementList |-  ColIdFuncAliasClause ColId TableFuncElementList-  deriving (Show, Generic, Eq, Ord)--{--| '(' joined_table ')'-| table_ref CROSS JOIN table_ref-| table_ref join_type JOIN table_ref join_qual-| table_ref JOIN table_ref join_qual-| table_ref NATURAL join_type JOIN table_ref-| table_ref NATURAL JOIN table_ref--The options are covered by the `JoinMeth` type.--}-data JoinedTable =-  InParensJoinedTable JoinedTable |-  MethJoinedTable JoinMeth TableRef TableRef-  deriving (Show, Generic, Eq, Ord)--{--| table_ref CROSS JOIN table_ref-| table_ref join_type JOIN table_ref join_qual-| table_ref JOIN table_ref join_qual-| table_ref NATURAL join_type JOIN table_ref-| table_ref NATURAL JOIN table_ref--}-data JoinMeth =-  CrossJoinMeth |-  QualJoinMeth (Maybe JoinType) JoinQual |-  NaturalJoinMeth (Maybe JoinType)-  deriving (Show, Generic, Eq, Ord)--{--| FULL join_outer-| LEFT join_outer-| RIGHT join_outer-| INNER_P--}-data JoinType =-  FullJoinType Bool |-  LeftJoinType Bool |-  RightJoinType Bool |-  InnerJoinType-  deriving (Show, Generic, Eq, Ord)--{--join_qual:-  |  USING '(' name_list ')'-  |  ON a_expr--}-data JoinQual =-  UsingJoinQual (NonEmpty Ident) |-  OnJoinQual AExpr-  deriving (Show, Generic, Eq, Ord)----- * Where----------------------------type WhereClause = AExpr--{--| WHERE a_expr-| WHERE CURRENT_P OF cursor_name-| /*EMPTY*/--}-data WhereOrCurrentClause = -  ExprWhereOrCurrentClause AExpr |-  CursorWhereOrCurrentClause CursorName-  deriving (Show, Generic, Eq, Ord)----- * Expression----------------------------type ExprList = NonEmpty AExpr--{--a_expr:-  | c_expr-  | a_expr TYPECAST Typename-  | a_expr COLLATE any_name-  | a_expr AT TIME ZONE a_expr-  | '+' a_expr-  | '-' a_expr-  | a_expr '+' a_expr-  | a_expr '-' a_expr-  | a_expr '*' a_expr-  | a_expr '/' a_expr-  | a_expr '%' a_expr-  | a_expr '^' a_expr-  | a_expr '<' a_expr-  | a_expr '>' a_expr-  | a_expr '=' a_expr-  | a_expr LESS_EQUALS a_expr-  | a_expr GREATER_EQUALS a_expr-  | a_expr NOT_EQUALS a_expr-  | a_expr qual_Op a_expr-  | qual_Op a_expr-  | a_expr qual_Op-  | a_expr AND a_expr-  | a_expr OR a_expr-  | NOT a_expr-  | NOT_LA a_expr-  | a_expr LIKE a_expr-  | a_expr LIKE a_expr ESCAPE a_expr-  | a_expr NOT_LA LIKE a_expr-  | a_expr NOT_LA LIKE a_expr ESCAPE a_expr-  | a_expr ILIKE a_expr-  | a_expr ILIKE a_expr ESCAPE a_expr-  | a_expr NOT_LA ILIKE a_expr-  | a_expr NOT_LA ILIKE a_expr ESCAPE a_expr-  | a_expr SIMILAR TO a_expr-  | a_expr SIMILAR TO a_expr ESCAPE a_expr-  | a_expr NOT_LA SIMILAR TO a_expr-  | a_expr NOT_LA SIMILAR TO a_expr ESCAPE a_expr-  | a_expr IS NULL_P-  | a_expr ISNULL-  | a_expr IS NOT NULL_P-  | a_expr NOTNULL-  | row OVERLAPS row-  | a_expr IS TRUE_P-  | a_expr IS NOT TRUE_P-  | a_expr IS FALSE_P-  | a_expr IS NOT FALSE_P-  | a_expr IS UNKNOWN-  | a_expr IS NOT UNKNOWN-  | a_expr IS DISTINCT FROM a_expr-  | a_expr IS NOT DISTINCT FROM a_expr-  | a_expr IS OF '(' type_list ')'-  | a_expr IS NOT OF '(' type_list ')'-  | a_expr BETWEEN opt_asymmetric b_expr AND a_expr-  | a_expr NOT_LA BETWEEN opt_asymmetric b_expr AND a_expr-  | a_expr BETWEEN SYMMETRIC b_expr AND a_expr-  | a_expr NOT_LA BETWEEN SYMMETRIC b_expr AND a_expr-  | a_expr IN_P in_expr-  | a_expr NOT_LA IN_P in_expr-  | a_expr subquery_Op sub_type select_with_parens-  | a_expr subquery_Op sub_type '(' a_expr ')'-  | UNIQUE select_with_parens-  | a_expr IS DOCUMENT_P-  | a_expr IS NOT DOCUMENT_P-  | DEFAULT--}-data AExpr =-  CExprAExpr CExpr |-  TypecastAExpr AExpr Typename |-  CollateAExpr AExpr AnyName |-  AtTimeZoneAExpr AExpr AExpr |-  PlusAExpr AExpr |-  MinusAExpr AExpr |-  SymbolicBinOpAExpr AExpr SymbolicExprBinOp AExpr |-  PrefixQualOpAExpr QualOp AExpr |-  SuffixQualOpAExpr AExpr QualOp |-  AndAExpr AExpr AExpr |-  OrAExpr AExpr AExpr |-  NotAExpr AExpr |-  VerbalExprBinOpAExpr AExpr Bool VerbalExprBinOp AExpr (Maybe AExpr) |-  ReversableOpAExpr AExpr Bool AExprReversableOp |-  IsnullAExpr AExpr |-  NotnullAExpr AExpr |-  OverlapsAExpr Row Row |-  SubqueryAExpr AExpr SubqueryOp SubType (Either SelectWithParens AExpr) |-  UniqueAExpr SelectWithParens |-  DefaultAExpr-  deriving (Show, Generic, Eq, Ord)--{--b_expr:-  | c_expr-  | b_expr TYPECAST Typename-  | '+' b_expr-  | '-' b_expr-  | b_expr '+' b_expr-  | b_expr '-' b_expr-  | b_expr '*' b_expr-  | b_expr '/' b_expr-  | b_expr '%' b_expr-  | b_expr '^' b_expr-  | b_expr '<' b_expr-  | b_expr '>' b_expr-  | b_expr '=' b_expr-  | b_expr LESS_EQUALS b_expr-  | b_expr GREATER_EQUALS b_expr-  | b_expr NOT_EQUALS b_expr-  | b_expr qual_Op b_expr-  | qual_Op b_expr-  | b_expr qual_Op-  | b_expr IS DISTINCT FROM b_expr-  | b_expr IS NOT DISTINCT FROM b_expr-  | b_expr IS OF '(' type_list ')'-  | b_expr IS NOT OF '(' type_list ')'-  | b_expr IS DOCUMENT_P-  | b_expr IS NOT DOCUMENT_P--}-data BExpr =-  CExprBExpr CExpr |-  TypecastBExpr BExpr Typename |-  PlusBExpr BExpr |-  MinusBExpr BExpr |-  SymbolicBinOpBExpr BExpr SymbolicExprBinOp BExpr |-  QualOpBExpr QualOp BExpr |-  IsOpBExpr BExpr Bool BExprIsOp-  deriving (Show, Generic, Eq, Ord)--{--c_expr:-  | columnref-  | AexprConst-  | PARAM opt_indirection-  | '(' a_expr ')' opt_indirection-  | case_expr-  | func_expr-  | select_with_parens-  | select_with_parens indirection-  | EXISTS select_with_parens-  | ARRAY select_with_parens-  | ARRAY array_expr-  | explicit_row-  | implicit_row-  | GROUPING '(' expr_list ')'--}-data CExpr =-  ColumnrefCExpr Columnref |-  AexprConstCExpr AexprConst |-  ParamCExpr Int (Maybe Indirection) |-  InParensCExpr AExpr (Maybe Indirection) |-  CaseCExpr CaseExpr |-  FuncCExpr FuncExpr |-  SelectWithParensCExpr SelectWithParens (Maybe Indirection) |-  ExistsCExpr SelectWithParens |-  ArrayCExpr (Either SelectWithParens ArrayExpr) |-  ExplicitRowCExpr ExplicitRow |-  ImplicitRowCExpr ImplicitRow |-  GroupingCExpr ExprList-  deriving (Show, Generic, Eq, Ord)---- **----------------------------{--in_expr:-  | select_with_parens-  | '(' expr_list ')'--}-data InExpr =-  SelectInExpr SelectWithParens |-  ExprListInExpr ExprList-  deriving (Show, Generic, Eq, Ord)--{--sub_type:-  | ANY-  | SOME-  | ALL--}-data SubType = AnySubType | SomeSubType | AllSubType-  deriving (Show, Generic, Eq, Ord, Enum, Bounded)--{--array_expr:-  | '[' expr_list ']'-  | '[' array_expr_list ']'-  | '[' ']'--}-data ArrayExpr =-  ExprListArrayExpr ExprList |-  ArrayExprListArrayExpr ArrayExprList |-  EmptyArrayExpr-  deriving (Show, Generic, Eq, Ord)--{--array_expr_list:-  | array_expr-  | array_expr_list ',' array_expr--}-type ArrayExprList = NonEmpty ArrayExpr--{--row:-  | ROW '(' expr_list ')'-  | ROW '(' ')'-  | '(' expr_list ',' a_expr ')'--}-data Row =-  ExplicitRowRow ExplicitRow |-  ImplicitRowRow ImplicitRow-  deriving (Show, Generic, Eq, Ord)--{--explicit_row:-  | ROW '(' expr_list ')'-  | ROW '(' ')'--}-type ExplicitRow = Maybe ExprList--{--implicit_row:-  | '(' expr_list ',' a_expr ')'--}-data ImplicitRow = ImplicitRow ExprList AExpr-  deriving (Show, Generic, Eq, Ord)--{--func_expr:-  | func_application within_group_clause filter_clause over_clause-  | func_expr_common_subexpr--}-data FuncExpr =-  ApplicationFuncExpr FuncApplication (Maybe WithinGroupClause) (Maybe FilterClause) (Maybe OverClause) |-  SubexprFuncExpr FuncExprCommonSubexpr-  deriving (Show, Generic, Eq, Ord)--{--func_expr_windowless:-  | func_application-  | func_expr_common_subexpr--}-data FuncExprWindowless =-  ApplicationFuncExprWindowless FuncApplication |-  CommonSubexprFuncExprWindowless FuncExprCommonSubexpr-  deriving (Show, Generic, Eq, Ord)--{--within_group_clause:-  | WITHIN GROUP_P '(' sort_clause ')'-  | EMPTY--}-type WithinGroupClause = SortClause--{--filter_clause:-  | FILTER '(' WHERE a_expr ')'-  | EMPTY--}-type FilterClause = AExpr--{--over_clause:-  | OVER window_specification-  | OVER ColId-  | EMPTY--}-data OverClause =-  WindowOverClause WindowSpecification |-  ColIdOverClause ColId-  deriving (Show, Generic, Eq, Ord)--{--func_expr_common_subexpr:-  | COLLATION FOR '(' a_expr ')'-  | CURRENT_DATE-  | CURRENT_TIME-  | CURRENT_TIME '(' Iconst ')'-  | CURRENT_TIMESTAMP-  | CURRENT_TIMESTAMP '(' Iconst ')'-  | LOCALTIME-  | LOCALTIME '(' Iconst ')'-  | LOCALTIMESTAMP-  | LOCALTIMESTAMP '(' Iconst ')'-  | CURRENT_ROLE-  | CURRENT_USER-  | SESSION_USER-  | USER-  | CURRENT_CATALOG-  | CURRENT_SCHEMA-  | CAST '(' a_expr AS Typename ')'-  | EXTRACT '(' extract_list ')'-  | OVERLAY '(' overlay_list ')'-  | POSITION '(' position_list ')'-  | SUBSTRING '(' substr_list ')'-  | TREAT '(' a_expr AS Typename ')'-  | TRIM '(' BOTH trim_list ')'-  | TRIM '(' LEADING trim_list ')'-  | TRIM '(' TRAILING trim_list ')'-  | TRIM '(' trim_list ')'-  | NULLIF '(' a_expr ',' a_expr ')'-  | COALESCE '(' expr_list ')'-  | GREATEST '(' expr_list ')'-  | LEAST '(' expr_list ')'-  | XMLCONCAT '(' expr_list ')'-  | XMLELEMENT '(' NAME_P ColLabel ')'-  | XMLELEMENT '(' NAME_P ColLabel ',' xml_attributes ')'-  | XMLELEMENT '(' NAME_P ColLabel ',' expr_list ')'-  | XMLELEMENT '(' NAME_P ColLabel ',' xml_attributes ',' expr_list ')'-  | XMLEXISTS '(' c_expr xmlexists_argument ')'-  | XMLFOREST '(' xml_attribute_list ')'-  | XMLPARSE '(' document_or_content a_expr xml_whitespace_option ')'-  | XMLPI '(' NAME_P ColLabel ')'-  | XMLPI '(' NAME_P ColLabel ',' a_expr ')'-  | XMLROOT '(' a_expr ',' xml_root_version opt_xml_root_standalone ')'-  | XMLSERIALIZE '(' document_or_content a_expr AS SimpleTypename ')'--TODO: Implement the XML cases--}-data FuncExprCommonSubexpr =-  CollationForFuncExprCommonSubexpr AExpr |-  CurrentDateFuncExprCommonSubexpr |-  CurrentTimeFuncExprCommonSubexpr (Maybe Int64) |-  CurrentTimestampFuncExprCommonSubexpr (Maybe Int64) |-  LocalTimeFuncExprCommonSubexpr (Maybe Int64) |-  LocalTimestampFuncExprCommonSubexpr (Maybe Int64) |-  CurrentRoleFuncExprCommonSubexpr |-  CurrentUserFuncExprCommonSubexpr |-  SessionUserFuncExprCommonSubexpr |-  UserFuncExprCommonSubexpr |-  CurrentCatalogFuncExprCommonSubexpr |-  CurrentSchemaFuncExprCommonSubexpr |-  CastFuncExprCommonSubexpr AExpr Typename |-  ExtractFuncExprCommonSubexpr (Maybe ExtractList) |-  OverlayFuncExprCommonSubexpr OverlayList |-  PositionFuncExprCommonSubexpr (Maybe PositionList) |-  SubstringFuncExprCommonSubexpr (Maybe SubstrList) |-  TreatFuncExprCommonSubexpr AExpr Typename |-  TrimFuncExprCommonSubexpr (Maybe TrimModifier) TrimList |-  NullIfFuncExprCommonSubexpr AExpr AExpr |-  CoalesceFuncExprCommonSubexpr ExprList |-  GreatestFuncExprCommonSubexpr ExprList |-  LeastFuncExprCommonSubexpr ExprList-  deriving (Show, Generic, Eq, Ord)--{--extract_list:-  | extract_arg FROM a_expr-  | EMPTY--}-data ExtractList = ExtractList ExtractArg AExpr-  deriving (Show, Generic, Eq, Ord)--{--extract_arg:-  | IDENT-  | YEAR_P-  | MONTH_P-  | DAY_P-  | HOUR_P-  | MINUTE_P-  | SECOND_P-  | Sconst--}-data ExtractArg =-  IdentExtractArg Ident |-  YearExtractArg |-  MonthExtractArg |-  DayExtractArg |-  HourExtractArg |-  MinuteExtractArg |-  SecondExtractArg |-  SconstExtractArg Sconst-  deriving (Show, Generic, Eq, Ord)--{--overlay_list:-  | a_expr overlay_placing substr_from substr_for-  | a_expr overlay_placing substr_from--}-data OverlayList = OverlayList AExpr OverlayPlacing SubstrFrom (Maybe SubstrFor)-  deriving (Show, Generic, Eq, Ord)--{--overlay_placing:-  | PLACING a_expr--}-type OverlayPlacing = AExpr--{--position_list:-  | b_expr IN_P b_expr-  | EMPTY--}-data PositionList = PositionList BExpr BExpr-  deriving (Show, Generic, Eq, Ord)--{--substr_list:-  | a_expr substr_from substr_for-  | a_expr substr_for substr_from-  | a_expr substr_from-  | a_expr substr_for-  | expr_list-  | EMPTY--}-data SubstrList =-  ExprSubstrList AExpr SubstrListFromFor |-  ExprListSubstrList ExprList-  deriving (Show, Generic, Eq, Ord)--{--  | a_expr substr_from substr_for-  | a_expr substr_for substr_from-  | a_expr substr_from-  | a_expr substr_for--}-data SubstrListFromFor =-  FromForSubstrListFromFor SubstrFrom SubstrFor |-  ForFromSubstrListFromFor SubstrFor SubstrFrom |-  FromSubstrListFromFor SubstrFrom |-  ForSubstrListFromFor SubstrFor-  deriving (Show, Generic, Eq, Ord)--{--substr_from:-  | FROM a_expr--}-type SubstrFrom = AExpr--{--substr_for:-  | FOR a_expr--}-type SubstrFor = AExpr--{--  | TRIM '(' BOTH trim_list ')'-  | TRIM '(' LEADING trim_list ')'-  | TRIM '(' TRAILING trim_list ')'--}-data TrimModifier = BothTrimModifier | LeadingTrimModifier | TrailingTrimModifier-  deriving (Show, Generic, Eq, Ord, Enum, Bounded)--{--trim_list:-  | a_expr FROM expr_list-  | FROM expr_list-  | expr_list--}-data TrimList =-  ExprFromExprListTrimList AExpr ExprList |-  FromExprListTrimList ExprList |-  ExprListTrimList ExprList-  deriving (Show, Generic, Eq, Ord)--{--case_expr:-  | CASE case_arg when_clause_list case_default END_P--}-data CaseExpr = CaseExpr (Maybe CaseArg) WhenClauseList (Maybe CaseDefault)-  deriving (Show, Generic, Eq, Ord)--{--case_arg:-  | a_expr-  | EMPTY--}-type CaseArg = AExpr--{--when_clause_list:-  | when_clause-  | when_clause_list when_clause--}-type WhenClauseList = NonEmpty WhenClause--{--case_default:-  | ELSE a_expr-  | EMPTY--}-type CaseDefault = AExpr--{--when_clause:-  |  WHEN a_expr THEN a_expr--}-data WhenClause = WhenClause AExpr AExpr-  deriving (Show, Generic, Eq, Ord)--{--func_application:-  |  func_name '(' ')'-  |  func_name '(' func_arg_list opt_sort_clause ')'-  |  func_name '(' VARIADIC func_arg_expr opt_sort_clause ')'-  |  func_name '(' func_arg_list ',' VARIADIC func_arg_expr opt_sort_clause ')'-  |  func_name '(' ALL func_arg_list opt_sort_clause ')'-  |  func_name '(' DISTINCT func_arg_list opt_sort_clause ')'-  |  func_name '(' '*' ')'--}-data FuncApplication = FuncApplication FuncName (Maybe FuncApplicationParams)-  deriving (Show, Generic, Eq, Ord)--{--func_application:-  |  func_name '(' ')'-  |  func_name '(' func_arg_list opt_sort_clause ')'-  |  func_name '(' VARIADIC func_arg_expr opt_sort_clause ')'-  |  func_name '(' func_arg_list ',' VARIADIC func_arg_expr opt_sort_clause ')'-  |  func_name '(' ALL func_arg_list opt_sort_clause ')'-  |  func_name '(' DISTINCT func_arg_list opt_sort_clause ')'-  |  func_name '(' '*' ')'--}-data FuncApplicationParams =-  NormalFuncApplicationParams (Maybe Bool) (NonEmpty FuncArgExpr) (Maybe SortClause) |-  VariadicFuncApplicationParams (Maybe (NonEmpty FuncArgExpr)) FuncArgExpr (Maybe SortClause) |-  StarFuncApplicationParams-  deriving (Show, Generic, Eq, Ord)--data FuncArgExpr =-  ExprFuncArgExpr AExpr |-  ColonEqualsFuncArgExpr Ident AExpr |-  EqualsGreaterFuncArgExpr Ident AExpr-  deriving (Show, Generic, Eq, Ord)----- * Constants----------------------------type Sconst = Text-type Iconst = Int64-type Fconst = Double-type Bconst = Text-type Xconst = Text--{-|-AexprConst:-  |  Iconst-  |  FCONST-  |  Sconst-  |  BCONST-  |  XCONST-  |  func_name Sconst-  |  func_name '(' func_arg_list opt_sort_clause ')' Sconst-  |  ConstTypename Sconst-  |  ConstInterval Sconst opt_interval-  |  ConstInterval '(' Iconst ')' Sconst-  |  TRUE_P-  |  FALSE_P-  |  NULL_P--}-data AexprConst =-  IAexprConst Iconst |-  FAexprConst Fconst |-  SAexprConst Sconst |-  BAexprConst Bconst |-  XAexprConst Xconst |-  FuncAexprConst FuncName (Maybe FuncConstArgs) Sconst |-  ConstTypenameAexprConst ConstTypename Sconst |-  StringIntervalAexprConst Sconst (Maybe Interval) |-  IntIntervalAexprConst Iconst Sconst |-  BoolAexprConst Bool |-  NullAexprConst-  deriving (Show, Generic, Eq, Ord)--{--  |  func_name '(' func_arg_list opt_sort_clause ')' Sconst--}-data FuncConstArgs = FuncConstArgs (NonEmpty FuncArgExpr) (Maybe SortClause)-  deriving (Show, Generic, Eq, Ord)--{--ConstTypename:-  | Numeric-  | ConstBit-  | ConstCharacter-  | ConstDatetime--}-data ConstTypename =-  NumericConstTypename Numeric |-  ConstBitConstTypename ConstBit |-  ConstCharacterConstTypename ConstCharacter |-  ConstDatetimeConstTypename ConstDatetime-  deriving (Show, Generic, Eq, Ord)--{--Numeric:-  | INT_P-  | INTEGER-  | SMALLINT-  | BIGINT-  | REAL-  | FLOAT_P opt_float-  | DOUBLE_P PRECISION-  | DECIMAL_P opt_type_modifiers-  | DEC opt_type_modifiers-  | NUMERIC opt_type_modifiers-  | BOOLEAN_P-opt_float:-  | '(' Iconst ')'-  | EMPTY-opt_type_modifiers:-  | '(' expr_list ')'-  | EMPTY--}-data Numeric =-  IntNumeric |-  IntegerNumeric |-  SmallintNumeric |-  BigintNumeric |-  RealNumeric |-  FloatNumeric (Maybe Int64) |-  DoublePrecisionNumeric |-  DecimalNumeric (Maybe TypeModifiers) |-  DecNumeric (Maybe TypeModifiers) |-  NumericNumeric (Maybe TypeModifiers) |-  BooleanNumeric-  deriving (Show, Generic, Eq, Ord)--{--Bit:-  | BitWithLength-  | BitWithoutLength-ConstBit:-  | BitWithLength-  | BitWithoutLength-BitWithLength:-  | BIT opt_varying '(' expr_list ')'-BitWithoutLength:-  | BIT opt_varying--}-data Bit = Bit OptVarying (Maybe ExprList)-  deriving (Show, Generic, Eq, Ord)--type ConstBit = Bit--{--opt_varying:-  | VARYING-  | EMPTY--}-type OptVarying = Bool--{--Character:-  | CharacterWithLength-  | CharacterWithoutLength-ConstCharacter:-  | CharacterWithLength-  | CharacterWithoutLength-CharacterWithLength:-  | character '(' Iconst ')'-CharacterWithoutLength:-  | character--}-data ConstCharacter = ConstCharacter Character (Maybe Int64)-  deriving (Show, Generic, Eq, Ord)--{--character:-  | CHARACTER opt_varying-  | CHAR_P opt_varying-  | VARCHAR-  | NATIONAL CHARACTER opt_varying-  | NATIONAL CHAR_P opt_varying-  | NCHAR opt_varying--}-data Character =-  CharacterCharacter OptVarying |-  CharCharacter OptVarying |-  VarcharCharacter |-  NationalCharacterCharacter OptVarying |-  NationalCharCharacter OptVarying |-  NcharCharacter OptVarying-  deriving (Show, Generic, Eq, Ord)--{--ConstDatetime:-  | TIMESTAMP '(' Iconst ')' opt_timezone-  | TIMESTAMP opt_timezone-  | TIME '(' Iconst ')' opt_timezone-  | TIME opt_timezone--}-data ConstDatetime =-  TimestampConstDatetime (Maybe Int64) (Maybe Timezone) |-  TimeConstDatetime (Maybe Int64) (Maybe Timezone)-  deriving (Show, Generic, Eq, Ord)--{--opt_timezone:-  | WITH_LA TIME ZONE-  | WITHOUT TIME ZONE-  | EMPTY--}-type Timezone = Bool--{--opt_interval:-  | YEAR_P-  | MONTH_P-  | DAY_P-  | HOUR_P-  | MINUTE_P-  | interval_second-  | YEAR_P TO MONTH_P-  | DAY_P TO HOUR_P-  | DAY_P TO MINUTE_P-  | DAY_P TO interval_second-  | HOUR_P TO MINUTE_P-  | HOUR_P TO interval_second-  | MINUTE_P TO interval_second-  | EMPTY--}-data Interval =-  YearInterval | MonthInterval | DayInterval | HourInterval | MinuteInterval |-  SecondInterval IntervalSecond |-  YearToMonthInterval |-  DayToHourInterval |-  DayToMinuteInterval |-  DayToSecondInterval IntervalSecond |-  HourToMinuteInterval |-  HourToSecondInterval IntervalSecond |-  MinuteToSecondInterval IntervalSecond-  deriving (Show, Generic, Eq, Ord)--{--interval_second:-  | SECOND_P-  | SECOND_P '(' Iconst ')'--}-type IntervalSecond = Maybe Int64----- * Names & References----------------------------{--IDENT--}-data Ident = QuotedIdent Text | UnquotedIdent Text-  deriving (Show, Generic, Eq, Ord)--{--ColId:-  | IDENT-  | unreserved_keyword-  | col_name_keyword--}-type ColId = Ident--{--ColLabel:-  | IDENT-  | unreserved_keyword-  | col_name_keyword-  | type_func_name_keyword-  | reserved_keyword--}-type ColLabel = Ident--{--name:-  | ColId--}-type Name = ColId--{--name_list:-  | name-  | name_list ',' name--}-type NameList = NonEmpty Name--{--cursor_name:-  | name--}-type CursorName = Name--{--columnref:-  | ColId-  | ColId indirection--}-data Columnref = Columnref ColId (Maybe Indirection)-  deriving (Show, Generic, Eq, Ord)--{--any_name:-  | ColId-  | ColId attrs--}-data AnyName = AnyName ColId (Maybe Attrs)-  deriving (Show, Generic, Eq, Ord)--{--func_name:-  | type_function_name-  | ColId indirection--}-data FuncName =-  TypeFuncName TypeFunctionName |-  IndirectedFuncName ColId Indirection-  deriving (Show, Generic, Eq, Ord)--{--type_function_name:-  | IDENT-  | unreserved_keyword-  | type_func_name_keyword--}-type TypeFunctionName = Ident--{--columnref:-  | ColId-  | ColId indirection-qualified_name:-  | ColId-  | ColId indirection--}-data QualifiedName =-  SimpleQualifiedName Ident |-  IndirectedQualifiedName Ident Indirection-  deriving (Show, Generic, Eq, Ord)--{--indirection:-  |  indirection_el-  |  indirection indirection_el--}-type Indirection = NonEmpty IndirectionEl--{--indirection_el:-  |  '.' attr_name-  |  '.' '*'-  |  '[' a_expr ']'-  |  '[' opt_slice_bound ':' opt_slice_bound ']'-opt_slice_bound:-  |  a_expr-  |  EMPTY--}-data IndirectionEl =-  AttrNameIndirectionEl Ident |-  AllIndirectionEl |-  ExprIndirectionEl AExpr |-  SliceIndirectionEl (Maybe AExpr) (Maybe AExpr)-  deriving (Show, Generic, Eq, Ord)----- * Types----------------------------{-|-Typename definition extended with custom question-marks for nullability specification.--To match the standard Postgres syntax simply interpret their presence as a parsing error.--}-{--Typename:-  | SimpleTypename opt_array_bounds-  | SETOF SimpleTypename opt_array_bounds-  | SimpleTypename ARRAY '[' Iconst ']'-  | SETOF SimpleTypename ARRAY '[' Iconst ']'-  | SimpleTypename ARRAY-  | SETOF SimpleTypename ARRAY--}-data Typename =-  Typename-    Bool {-^ SETOF -}-    SimpleTypename-    Bool {-^ Question mark -}-    (Maybe (TypenameArrayDimensions, Bool)) {-^ Array dimensions possibly followed by a question mark -}-  deriving (Show, Generic, Eq, Ord)--{--Part of the Typename specification responsible for the choice between the following:-  | opt_array_bounds-  | ARRAY '[' Iconst ']'-  | ARRAY--}-data TypenameArrayDimensions =-  BoundsTypenameArrayDimensions ArrayBounds |-  ExplicitTypenameArrayDimensions (Maybe Iconst)-  deriving (Show, Generic, Eq, Ord)--{--opt_array_bounds:-  | opt_array_bounds '[' ']'-  | opt_array_bounds '[' Iconst ']'-  | EMPTY--}-type ArrayBounds = NonEmpty (Maybe Iconst)--{--SimpleTypename:-  | GenericType-  | Numeric-  | Bit-  | Character-  | ConstDatetime-  | ConstInterval opt_interval-  | ConstInterval '(' Iconst ')'-ConstInterval:-  | INTERVAL--}-data SimpleTypename =-  GenericTypeSimpleTypename GenericType |-  NumericSimpleTypename Numeric |-  BitSimpleTypename Bit |-  CharacterSimpleTypename Character |-  ConstDatetimeSimpleTypename ConstDatetime |-  ConstIntervalSimpleTypename (Either (Maybe Interval) Iconst)-  deriving (Show, Generic, Eq, Ord)--{--GenericType:-  | type_function_name opt_type_modifiers-  | type_function_name attrs opt_type_modifiers--}-data GenericType = GenericType TypeFunctionName (Maybe Attrs) (Maybe TypeModifiers)-  deriving (Show, Generic, Eq, Ord)--{--attrs:-  | '.' attr_name-  | attrs '.' attr_name--}-type Attrs = NonEmpty AttrName--{--attr_name:-  | ColLabel--}-type AttrName = ColLabel--{--opt_type_modifiers:-  | '(' expr_list ')'-  | EMPTY--}-type TypeModifiers = ExprList--{--type_list:-  | Typename-  | type_list ',' Typename--}-type TypeList = NonEmpty Typename----- * Operators----------------------------{--qual_Op:-  | Op-  | OPERATOR '(' any_operator ')'--}-data QualOp =-  OpQualOp Op |-  OperatorQualOp AnyOperator-  deriving (Show, Generic, Eq, Ord)--{--qual_all_Op:-  | all_Op-  | OPERATOR '(' any_operator ')'--}-data QualAllOp =-  AllQualAllOp AllOp |-  AnyQualAllOp AnyOperator-  deriving (Show, Generic, Eq, Ord)--{--The operator name is a sequence of up to NAMEDATALEN-1 (63 by default) -characters from the following list:--+ - * / < > = ~ ! @ # % ^ & | ` ?--There are a few restrictions on your choice of name:--- and /* cannot appear anywhere in an operator name, -since they will be taken as the start of a comment.--A multicharacter operator name cannot end in + or -, -unless the name also contains at least one of these characters:--~ ! @ # % ^ & | ` ?--For example, @- is an allowed operator name, but *- is not. -This restriction allows PostgreSQL to parse SQL-compliant -commands without requiring spaces between tokens.-The use of => as an operator name is deprecated. -It may be disallowed altogether in a future release.--The operator != is mapped to <> on input, -so these two names are always equivalent.--}-type Op = Text--{--any_operator:-  | all_Op-  | ColId '.' any_operator--}-data AnyOperator =-  AllOpAnyOperator AllOp |-  QualifiedAnyOperator ColId AnyOperator-  deriving (Show, Generic, Eq, Ord)--{--all_Op:-  | Op-  | MathOp--}-data AllOp =-  OpAllOp Op |-  MathAllOp MathOp-  deriving (Show, Generic, Eq, Ord)--{--MathOp:-  | '+'-  | '-'-  | '*'-  | '/'-  | '%'-  | '^'-  | '<'-  | '>'-  | '='-  | LESS_EQUALS-  | GREATER_EQUALS-  | NOT_EQUALS--}-data MathOp =-  PlusMathOp |-  MinusMathOp |-  AsteriskMathOp |-  SlashMathOp |-  PercentMathOp |-  ArrowUpMathOp |-  ArrowLeftMathOp |-  ArrowRightMathOp |-  EqualsMathOp |-  LessEqualsMathOp |-  GreaterEqualsMathOp |-  ArrowLeftArrowRightMathOp |-  ExclamationEqualsMathOp-  deriving (Show, Generic, Eq, Ord, Enum, Bounded)--data SymbolicExprBinOp =-  MathSymbolicExprBinOp MathOp |-  QualSymbolicExprBinOp QualOp-  deriving (Show, Generic, Eq, Ord)--data VerbalExprBinOp =-  LikeVerbalExprBinOp |-  IlikeVerbalExprBinOp |-  SimilarToVerbalExprBinOp-  deriving (Show, Generic, Eq, Ord, Enum, Bounded)--{--  | a_expr IS NULL_P-  | a_expr IS TRUE_P-  | a_expr IS FALSE_P-  | a_expr IS UNKNOWN-  | a_expr IS DISTINCT FROM a_expr-  | a_expr IS OF '(' type_list ')'-  | a_expr BETWEEN opt_asymmetric b_expr AND a_expr-  | a_expr BETWEEN SYMMETRIC b_expr AND a_expr-  | a_expr IN_P in_expr-  | a_expr IS DOCUMENT_P--}-data AExprReversableOp =-  NullAExprReversableOp |-  TrueAExprReversableOp |-  FalseAExprReversableOp |-  UnknownAExprReversableOp |-  DistinctFromAExprReversableOp AExpr |-  OfAExprReversableOp TypeList |-  BetweenAExprReversableOp Bool BExpr AExpr |-  BetweenSymmetricAExprReversableOp BExpr AExpr |-  InAExprReversableOp InExpr |-  DocumentAExprReversableOp-  deriving (Show, Generic, Eq, Ord)--{--  | b_expr IS DISTINCT FROM b_expr-  | b_expr IS NOT DISTINCT FROM b_expr-  | b_expr IS OF '(' type_list ')'-  | b_expr IS NOT OF '(' type_list ')'-  | b_expr IS DOCUMENT_P-  | b_expr IS NOT DOCUMENT_P--}-data BExprIsOp =-  DistinctFromBExprIsOp BExpr |-  OfBExprIsOp TypeList |-  DocumentBExprIsOp-  deriving (Show, Generic, Eq, Ord)--{--subquery_Op:-  | all_Op-  | OPERATOR '(' any_operator ')'-  | LIKE-  | NOT_LA LIKE-  | ILIKE-  | NOT_LA ILIKE--}-data SubqueryOp =-  AllSubqueryOp AllOp |-  AnySubqueryOp AnyOperator |-  LikeSubqueryOp Bool |-  IlikeSubqueryOp Bool-  deriving (Show, Generic, Eq, Ord)----- * Indexes----------------------------{--index_params:-  | index_elem-  | index_params ',' index_elem--}-type IndexParams = NonEmpty IndexElem--{--index_elem:-  | ColId opt_collate opt_class opt_asc_desc opt_nulls_order-  | func_expr_windowless opt_collate opt_class opt_asc_desc opt_nulls_order-  | '(' a_expr ')' opt_collate opt_class opt_asc_desc opt_nulls_order--}-data IndexElem = IndexElem IndexElemDef (Maybe Collate) (Maybe Class) (Maybe AscDesc) (Maybe NullsOrder)-  deriving (Show, Generic, Eq, Ord)--{--  | ColId opt_collate opt_class opt_asc_desc opt_nulls_order-  | func_expr_windowless opt_collate opt_class opt_asc_desc opt_nulls_order-  | '(' a_expr ')' opt_collate opt_class opt_asc_desc opt_nulls_order--}-data IndexElemDef =-  IdIndexElemDef ColId |-  FuncIndexElemDef FuncExprWindowless |-  ExprIndexElemDef AExpr-  deriving (Show, Generic, Eq, Ord)--{--opt_collate:-  | COLLATE any_name-  | EMPTY--}-type Collate = AnyName--{--opt_class:-  | any_name-  | EMPTY--}-type Class = AnyName--{--opt_asc_desc:-  | ASC-  | DESC-  | EMPTY--}-data AscDesc = AscAscDesc | DescAscDesc-  deriving (Show, Generic, Eq, Ord, Enum, Bounded)--{--opt_nulls_order:-  | NULLS_LA FIRST_P-  | NULLS_LA LAST_P-  | EMPTY--}+-- |+-- Names for nodes mostly resemble the according definitions in the @gram.y@+-- original Postgres parser file, except for the cases where we can optimize on that.+--+-- For reasoning see the docs of the parsing module of this project.+module PostgresqlSyntax.Ast where++import PostgresqlSyntax.Prelude hiding (Op, Order)++-- * Statement++-- |+-- ==== References+-- @+-- PreparableStmt:+--   |  SelectStmt+--   |  InsertStmt+--   |  UpdateStmt+--   |  DeleteStmt+-- @+data PreparableStmt+  = SelectPreparableStmt SelectStmt+  | InsertPreparableStmt InsertStmt+  | UpdatePreparableStmt UpdateStmt+  | DeletePreparableStmt DeleteStmt+  deriving (Show, Generic, Eq, Ord)++-- * Insert++-- |+-- ==== References+-- @+-- InsertStmt:+--   | opt_with_clause INSERT INTO insert_target insert_rest+--       opt_on_conflict returning_clause+-- @+data InsertStmt = InsertStmt (Maybe WithClause) InsertTarget InsertRest (Maybe OnConflict) (Maybe ReturningClause)+  deriving (Show, Generic, Eq, Ord)++-- |+-- ==== References+-- @+-- insert_target:+--   | qualified_name+--   | qualified_name AS ColId+-- @+data InsertTarget = InsertTarget QualifiedName (Maybe ColId)+  deriving (Show, Generic, Eq, Ord)++-- |+-- ==== References+-- @+-- insert_rest:+--   | SelectStmt+--   | OVERRIDING override_kind VALUE_P SelectStmt+--   | '(' insert_column_list ')' SelectStmt+--   | '(' insert_column_list ')' OVERRIDING override_kind VALUE_P SelectStmt+--   | DEFAULT VALUES+-- @+data InsertRest+  = SelectInsertRest (Maybe InsertColumnList) (Maybe OverrideKind) SelectStmt+  | DefaultValuesInsertRest+  deriving (Show, Generic, Eq, Ord)++-- |+-- ==== References+-- @+-- override_kind:+--   | USER+--   | SYSTEM_P+-- @+data OverrideKind = UserOverrideKind | SystemOverrideKind+  deriving (Show, Generic, Eq, Ord, Enum, Bounded)++-- |+-- ==== References+-- @+-- insert_column_list:+--   | insert_column_item+--   | insert_column_list ',' insert_column_item+-- @+type InsertColumnList = NonEmpty InsertColumnItem++-- |+-- ==== References+-- @+-- insert_column_item:+--   | ColId opt_indirection+-- @+data InsertColumnItem = InsertColumnItem ColId (Maybe Indirection)+  deriving (Show, Generic, Eq, Ord)++-- |+-- ==== References+-- @+-- opt_on_conflict:+--   | ON CONFLICT opt_conf_expr DO UPDATE SET set_clause_list where_clause+--   | ON CONFLICT opt_conf_expr DO NOTHING+--   | EMPTY+-- @+data OnConflict = OnConflict (Maybe ConfExpr) OnConflictDo+  deriving (Show, Generic, Eq, Ord)++-- |+-- ==== References+-- @+-- opt_on_conflict:+--   | ON CONFLICT opt_conf_expr DO UPDATE SET set_clause_list where_clause+--   | ON CONFLICT opt_conf_expr DO NOTHING+--   | EMPTY+-- @+data OnConflictDo+  = UpdateOnConflictDo SetClauseList (Maybe WhereClause)+  | NothingOnConflictDo+  deriving (Show, Generic, Eq, Ord)++-- |+-- ==== References+-- @+-- opt_conf_expr:+--   | '(' index_params ')' where_clause+--   | ON CONSTRAINT name+--   | EMPTY+-- @+data ConfExpr+  = WhereConfExpr IndexParams (Maybe WhereClause)+  | ConstraintConfExpr Name+  deriving (Show, Generic, Eq, Ord)++-- |+-- ==== References+-- @+-- returning_clause:+--   | RETURNING target_list+--   | EMPTY+-- @+type ReturningClause = TargetList++-- * Update++-- |+-- ==== References+-- @+-- UpdateStmt:+--   | opt_with_clause UPDATE relation_expr_opt_alias+--       SET set_clause_list+--       from_clause+--       where_or_current_clause+--       returning_clause+-- @+data UpdateStmt = UpdateStmt (Maybe WithClause) RelationExprOptAlias SetClauseList (Maybe FromClause) (Maybe WhereOrCurrentClause) (Maybe ReturningClause)+  deriving (Show, Generic, Eq, Ord)++-- |+-- ==== References+-- @+-- set_clause_list:+--   | set_clause+--   | set_clause_list ',' set_clause+-- @+type SetClauseList = NonEmpty SetClause++-- |+-- ==== References+-- @+-- set_clause:+--   | set_target '=' a_expr+--   | '(' set_target_list ')' '=' a_expr+-- @+data SetClause+  = TargetSetClause SetTarget AExpr+  | TargetListSetClause SetTargetList AExpr+  deriving (Show, Generic, Eq, Ord)++-- |+-- ==== References+-- @+-- set_target:+--   | ColId opt_indirection+-- @+data SetTarget = SetTarget ColId (Maybe Indirection)+  deriving (Show, Generic, Eq, Ord)++-- |+-- ==== References+-- @+-- set_target_list:+--   | set_target+--   | set_target_list ',' set_target+-- @+type SetTargetList = NonEmpty SetTarget++-- * Delete++-- |+-- ==== References+-- @+-- DeleteStmt:+--   | opt_with_clause DELETE_P FROM relation_expr_opt_alias+--       using_clause where_or_current_clause returning_clause+-- @+data DeleteStmt = DeleteStmt (Maybe WithClause) RelationExprOptAlias (Maybe UsingClause) (Maybe WhereOrCurrentClause) (Maybe ReturningClause)+  deriving (Show, Generic, Eq, Ord)++-- |+-- ==== References+-- @+-- using_clause:+--   | USING from_list+--   | EMPTY+-- @+type UsingClause = FromList++-- * Select++-- |+-- ==== References+-- @+-- SelectStmt:+--   |  select_no_parens+--   |  select_with_parens+-- @+type SelectStmt = Either SelectNoParens SelectWithParens++-- |+-- ==== References+-- @+-- select_with_parens:+--   |  '(' select_no_parens ')'+--   |  '(' select_with_parens ')'+-- @+data SelectWithParens+  = NoParensSelectWithParens SelectNoParens+  | WithParensSelectWithParens SelectWithParens+  deriving (Show, Generic, Eq, Ord)++-- |+-- Covers the following cases:+--+-- @+-- select_no_parens:+--   |  simple_select+--   |  select_clause sort_clause+--   |  select_clause opt_sort_clause for_locking_clause opt_select_limit+--   |  select_clause opt_sort_clause select_limit opt_for_locking_clause+--   |  with_clause select_clause+--   |  with_clause select_clause sort_clause+--   |  with_clause select_clause opt_sort_clause for_locking_clause opt_select_limit+--   |  with_clause select_clause opt_sort_clause select_limit opt_for_locking_clause+-- @+data SelectNoParens+  = SelectNoParens (Maybe WithClause) SelectClause (Maybe SortClause) (Maybe SelectLimit) (Maybe ForLockingClause)+  deriving (Show, Generic, Eq, Ord)++-- |+-- @+-- select_clause:+--   |  simple_select+--   |  select_with_parens+-- @+type SelectClause = Either SimpleSelect SelectWithParens++-- |+-- ==== References+-- @+-- simple_select:+--   |  SELECT opt_all_clause opt_target_list+--       into_clause from_clause where_clause+--       group_clause having_clause window_clause+--   |  SELECT distinct_clause target_list+--       into_clause from_clause where_clause+--       group_clause having_clause window_clause+--   |  values_clause+--   |  TABLE relation_expr+--   |  select_clause UNION all_or_distinct select_clause+--   |  select_clause INTERSECT all_or_distinct select_clause+--   |  select_clause EXCEPT all_or_distinct select_clause+-- @+data SimpleSelect+  = NormalSimpleSelect (Maybe Targeting) (Maybe IntoClause) (Maybe FromClause) (Maybe WhereClause) (Maybe GroupClause) (Maybe HavingClause) (Maybe WindowClause)+  | ValuesSimpleSelect ValuesClause+  | TableSimpleSelect RelationExpr+  | BinSimpleSelect SelectBinOp SelectClause (Maybe Bool) SelectClause+  deriving (Show, Generic, Eq, Ord)++-- |+-- Covers these parts of spec:+--+-- ==== References+-- @+-- simple_select:+--   |  SELECT opt_all_clause opt_target_list+--       into_clause from_clause where_clause+--       group_clause having_clause window_clause+--   |  SELECT distinct_clause target_list+--       into_clause from_clause where_clause+--       group_clause having_clause window_clause+--+-- distinct_clause:+--   |  DISTINCT+--   |  DISTINCT ON '(' expr_list ')'+-- @+data Targeting+  = NormalTargeting TargetList+  | AllTargeting (Maybe TargetList)+  | DistinctTargeting (Maybe ExprList) TargetList+  deriving (Show, Generic, Eq, Ord)++-- |+-- ==== References+-- @+-- target_list:+--   | target_el+--   | target_list ',' target_el+-- @+type TargetList = NonEmpty TargetEl++-- |+-- ==== References+-- @+-- target_el:+--   |  a_expr AS ColLabel+--   |  a_expr IDENT+--   |  a_expr+--   |  '*'+-- @+data TargetEl+  = AliasedExprTargetEl AExpr Ident+  | ImplicitlyAliasedExprTargetEl AExpr Ident+  | ExprTargetEl AExpr+  | AsteriskTargetEl+  deriving (Show, Generic, Eq, Ord)++-- |+-- ==== References+-- @+--   |  select_clause UNION all_or_distinct select_clause+--   |  select_clause INTERSECT all_or_distinct select_clause+--   |  select_clause EXCEPT all_or_distinct select_clause+-- @+data SelectBinOp = UnionSelectBinOp | IntersectSelectBinOp | ExceptSelectBinOp+  deriving (Show, Generic, Eq, Ord)++-- |+-- ==== References+-- @+-- with_clause:+--   |  WITH cte_list+--   |  WITH_LA cte_list+--   |  WITH RECURSIVE cte_list+-- @+data WithClause = WithClause Bool (NonEmpty CommonTableExpr)+  deriving (Show, Generic, Eq, Ord)++-- |+-- ==== References+-- @+-- common_table_expr:+--   |  name opt_name_list AS opt_materialized '(' PreparableStmt ')'+-- opt_materialized:+--   | MATERIALIZED+--   | NOT MATERIALIZED+--   | EMPTY+-- @+data CommonTableExpr = CommonTableExpr Ident (Maybe (NonEmpty Ident)) (Maybe Bool) PreparableStmt+  deriving (Show, Generic, Eq, Ord)++type IntoClause = OptTempTableName++-- |+-- ==== References+-- @+-- OptTempTableName:+--   |  TEMPORARY opt_table qualified_name+--   |  TEMP opt_table qualified_name+--   |  LOCAL TEMPORARY opt_table qualified_name+--   |  LOCAL TEMP opt_table qualified_name+--   |  GLOBAL TEMPORARY opt_table qualified_name+--   |  GLOBAL TEMP opt_table qualified_name+--   |  UNLOGGED opt_table qualified_name+--   |  TABLE qualified_name+--   |  qualified_name+-- @+data OptTempTableName+  = TemporaryOptTempTableName Bool QualifiedName+  | TempOptTempTableName Bool QualifiedName+  | LocalTemporaryOptTempTableName Bool QualifiedName+  | LocalTempOptTempTableName Bool QualifiedName+  | GlobalTemporaryOptTempTableName Bool QualifiedName+  | GlobalTempOptTempTableName Bool QualifiedName+  | UnloggedOptTempTableName Bool QualifiedName+  | TableOptTempTableName QualifiedName+  | QualifedOptTempTableName QualifiedName+  deriving (Show, Generic, Eq, Ord)++type FromClause = NonEmpty TableRef++type GroupClause = NonEmpty GroupByItem++-- |+-- ==== References+-- @+-- group_by_item:+--   |  a_expr+--   |  empty_grouping_set+--   |  cube_clause+--   |  rollup_clause+--   |  grouping_sets_clause+-- empty_grouping_set:+--   |  '(' ')'+-- rollup_clause:+--   |  ROLLUP '(' expr_list ')'+-- cube_clause:+--   |  CUBE '(' expr_list ')'+-- grouping_sets_clause:+--   |  GROUPING SETS '(' group_by_list ')'+-- @+data GroupByItem+  = ExprGroupByItem AExpr+  | EmptyGroupingSetGroupByItem+  | RollupGroupByItem ExprList+  | CubeGroupByItem ExprList+  | GroupingSetsGroupByItem (NonEmpty GroupByItem)+  deriving (Show, Generic, Eq, Ord)++-- |+-- @+-- having_clause:+--   |  HAVING a_expr+--   |  EMPTY+-- @+type HavingClause = AExpr++-- |+-- @+-- window_clause:+--   |  WINDOW window_definition_list+--   |  EMPTY+--+-- window_definition_list:+--   |  window_definition+--   |  window_definition_list ',' window_definition+-- @+type WindowClause = NonEmpty WindowDefinition++-- |+-- @+-- window_definition:+--   |  ColId AS window_specification+-- @+data WindowDefinition = WindowDefinition Ident WindowSpecification+  deriving (Show, Generic, Eq, Ord)++-- |+-- @+-- window_specification:+--   |  '(' opt_existing_window_name opt_partition_clause+--             opt_sort_clause opt_frame_clause ')'+--+-- opt_existing_window_name:+--   |  ColId+--   |  EMPTY+--+-- opt_partition_clause:+--   |  PARTITION BY expr_list+--   |  EMPTY+-- @+data WindowSpecification = WindowSpecification (Maybe ExistingWindowName) (Maybe PartitionClause) (Maybe SortClause) (Maybe FrameClause)+  deriving (Show, Generic, Eq, Ord)++type ExistingWindowName = ColId++type PartitionClause = ExprList++-- |+-- ==== References+-- @+-- opt_frame_clause:+--   |  RANGE frame_extent opt_window_exclusion_clause+--   |  ROWS frame_extent opt_window_exclusion_clause+--   |  GROUPS frame_extent opt_window_exclusion_clause+--   |  EMPTY+-- @+data FrameClause = FrameClause FrameClauseMode FrameExtent (Maybe WindowExclusionClause)+  deriving (Show, Generic, Eq, Ord)++-- |+-- ==== References+-- @+-- opt_frame_clause:+--   |  RANGE frame_extent opt_window_exclusion_clause+--   |  ROWS frame_extent opt_window_exclusion_clause+--   |  GROUPS frame_extent opt_window_exclusion_clause+--   |  EMPTY+-- @+data FrameClauseMode = RangeFrameClauseMode | RowsFrameClauseMode | GroupsFrameClauseMode+  deriving (Show, Generic, Eq, Ord)++-- |+-- ==== References+-- @+-- frame_extent:+--   |  frame_bound+--   |  BETWEEN frame_bound AND frame_bound+-- @+data FrameExtent = SingularFrameExtent FrameBound | BetweenFrameExtent FrameBound FrameBound+  deriving (Show, Generic, Eq, Ord)++-- |+-- ==== References+-- @+-- frame_bound:+--   |  UNBOUNDED PRECEDING+--   |  UNBOUNDED FOLLOWING+--   |  CURRENT_P ROW+--   |  a_expr PRECEDING+--   |  a_expr FOLLOWING+-- @+data FrameBound+  = UnboundedPrecedingFrameBound+  | UnboundedFollowingFrameBound+  | CurrentRowFrameBound+  | PrecedingFrameBound AExpr+  | FollowingFrameBound AExpr+  deriving (Show, Generic, Eq, Ord)++-- |+-- ==== References+-- @+-- opt_window_exclusion_clause:+--   |  EXCLUDE CURRENT_P ROW+--   |  EXCLUDE GROUP_P+--   |  EXCLUDE TIES+--   |  EXCLUDE NO OTHERS+--   |  EMPTY+-- @+data WindowExclusionClause+  = CurrentRowWindowExclusionClause+  | GroupWindowExclusionClause+  | TiesWindowExclusionClause+  | NoOthersWindowExclusionClause+  deriving (Show, Generic, Eq, Ord)++-- |+-- ==== References+-- @+-- values_clause:+--   |  VALUES '(' expr_list ')'+--   |  values_clause ',' '(' expr_list ')'+-- @+type ValuesClause = NonEmpty ExprList++-- |+--+-- sort_clause:+--   |  ORDER BY sortby_list+--+-- sortby_list:+--   |  sortby+--   |  sortby_list ',' sortby+type SortClause = NonEmpty SortBy++-- |+-- ==== References+-- @+-- sortby:+--   |  a_expr USING qual_all_Op opt_nulls_order+--   |  a_expr opt_asc_desc opt_nulls_order+-- @+data SortBy+  = UsingSortBy AExpr QualAllOp (Maybe NullsOrder)+  | AscDescSortBy AExpr (Maybe AscDesc) (Maybe NullsOrder)+  deriving (Show, Generic, Eq, Ord)++-- |+-- ==== References+-- @+-- select_limit:+--   | limit_clause offset_clause+--   | offset_clause limit_clause+--   | limit_clause+--   | offset_clause+-- @+data SelectLimit+  = LimitOffsetSelectLimit LimitClause OffsetClause+  | OffsetLimitSelectLimit OffsetClause LimitClause+  | LimitSelectLimit LimitClause+  | OffsetSelectLimit OffsetClause+  deriving (Show, Generic, Eq, Ord)++-- |+-- ==== References+-- @+-- limit_clause:+--   | LIMIT select_limit_value+--   | LIMIT select_limit_value ',' select_offset_value+--   | FETCH first_or_next select_fetch_first_value row_or_rows ONLY+--   | FETCH first_or_next row_or_rows ONLY+-- select_offset_value:+--   | a_expr+-- first_or_next:+--   | FIRST_P+--   | NEXT+-- row_or_rows:+--   | ROW+--   | ROWS+-- @+data LimitClause+  = LimitLimitClause SelectLimitValue (Maybe AExpr)+  | FetchOnlyLimitClause Bool (Maybe SelectFetchFirstValue) Bool+  deriving (Show, Generic, Eq, Ord)++-- |+-- ==== References+-- @+-- select_fetch_first_value:+--   | c_expr+--   | '+' I_or_F_const+--   | '-' I_or_F_const+-- @+data SelectFetchFirstValue+  = ExprSelectFetchFirstValue CExpr+  | NumSelectFetchFirstValue Bool (Either Int64 Double)+  deriving (Show, Generic, Eq, Ord)++-- |+-- ==== References+-- @+-- select_limit_value:+--   | a_expr+--   | ALL+-- @+data SelectLimitValue+  = ExprSelectLimitValue AExpr+  | AllSelectLimitValue+  deriving (Show, Generic, Eq, Ord)++-- |+-- ==== References+-- @+-- offset_clause:+--   | OFFSET select_offset_value+--   | OFFSET select_fetch_first_value row_or_rows+-- select_offset_value:+--   | a_expr+-- row_or_rows:+--   | ROW+--   | ROWS+-- @+data OffsetClause+  = ExprOffsetClause AExpr+  | FetchFirstOffsetClause SelectFetchFirstValue Bool+  deriving (Show, Generic, Eq, Ord)++-- * For Locking++-- |+-- ==== References+-- @+-- for_locking_clause:+--   | for_locking_items+--   | FOR READ ONLY+-- for_locking_items:+--   | for_locking_item+--   | for_locking_items for_locking_item+-- @+data ForLockingClause+  = ItemsForLockingClause (NonEmpty ForLockingItem)+  | ReadOnlyForLockingClause+  deriving (Show, Generic, Eq, Ord)++-- |+-- ==== References+-- @+-- for_locking_item:+--   | for_locking_strength locked_rels_list opt_nowait_or_skip+-- locked_rels_list:+--   | OF qualified_name_list+--   | EMPTY+-- opt_nowait_or_skip:+--   | NOWAIT+--   | SKIP LOCKED+--   | EMPTY+-- @+data ForLockingItem = ForLockingItem ForLockingStrength (Maybe (NonEmpty QualifiedName)) (Maybe Bool)+  deriving (Show, Generic, Eq, Ord)++-- |+-- ==== References+-- @+-- for_locking_strength:+--   | FOR UPDATE+--   | FOR NO KEY UPDATE+--   | FOR SHARE+--   | FOR KEY SHARE+-- @+data ForLockingStrength+  = UpdateForLockingStrength+  | NoKeyUpdateForLockingStrength+  | ShareForLockingStrength+  | KeyForLockingStrength+  deriving (Show, Generic, Eq, Ord)++-- * Table references and joining++-- |+-- ==== References+-- @+-- from_list:+--   | table_ref+--   | from_list ',' table_ref+-- @+type FromList = NonEmpty TableRef++-- |+-- ==== References+-- @+-- | relation_expr opt_alias_clause+-- | relation_expr opt_alias_clause tablesample_clause+-- | func_table func_alias_clause+-- | LATERAL_P func_table func_alias_clause+-- | xmltable opt_alias_clause+-- | LATERAL_P xmltable opt_alias_clause+-- | select_with_parens opt_alias_clause+-- | LATERAL_P select_with_parens opt_alias_clause+-- | joined_table+-- | '(' joined_table ')' alias_clause+--+-- TODO: Add xmltable+-- @+data TableRef+  = -- |+    -- @+    --    | relation_expr opt_alias_clause+    --    | relation_expr opt_alias_clause tablesample_clause+    -- @+    RelationExprTableRef RelationExpr (Maybe AliasClause) (Maybe TablesampleClause)+  | -- |+    -- @+    --    | func_table func_alias_clause+    --    | LATERAL_P func_table func_alias_clause+    -- @+    FuncTableRef Bool FuncTable (Maybe FuncAliasClause)+  | -- |+    -- @+    --    | select_with_parens opt_alias_clause+    --    | LATERAL_P select_with_parens opt_alias_clause+    -- @+    SelectTableRef Bool SelectWithParens (Maybe AliasClause)+  | -- |+    -- @+    --    | joined_table+    --    | '(' joined_table ')' alias_clause+    -- @+    JoinTableRef JoinedTable (Maybe AliasClause)+  deriving (Show, Generic, Eq, Ord)++-- |+-- ==== References+-- @+-- | qualified_name+-- | qualified_name '*'+-- | ONLY qualified_name+-- | ONLY '(' qualified_name ')'+-- @+data RelationExpr+  = SimpleRelationExpr QualifiedName Bool+  | OnlyRelationExpr QualifiedName Bool+  deriving (Show, Generic, Eq, Ord)++-- |+-- ==== References+-- @+-- relation_expr_opt_alias:+--   | relation_expr+--   | relation_expr ColId+--   | relation_expr AS ColId+-- @+data RelationExprOptAlias = RelationExprOptAlias RelationExpr (Maybe (Bool, ColId))+  deriving (Show, Generic, Eq, Ord)++-- |+-- ==== References+-- @+-- tablesample_clause:+--   | TABLESAMPLE func_name '(' expr_list ')' opt_repeatable_clause+-- @+data TablesampleClause = TablesampleClause FuncName ExprList (Maybe RepeatableClause)+  deriving (Show, Generic, Eq, Ord)++-- |+-- ==== References+-- @+-- opt_repeatable_clause:+--   | REPEATABLE '(' a_expr ')'+--   | EMPTY+-- @+type RepeatableClause = AExpr++-- |+-- ==== References+-- @+-- func_table:+--   | func_expr_windowless opt_ordinality+--   | ROWS FROM '(' rowsfrom_list ')' opt_ordinality+-- @+data FuncTable+  = FuncExprFuncTable FuncExprWindowless OptOrdinality+  | RowsFromFuncTable RowsfromList OptOrdinality+  deriving (Show, Generic, Eq, Ord)++-- |+-- ==== References+-- @+-- rowsfrom_item:+--   | func_expr_windowless opt_col_def_list+-- @+data RowsfromItem = RowsfromItem FuncExprWindowless (Maybe ColDefList)+  deriving (Show, Generic, Eq, Ord)++-- |+-- ==== References+-- @+-- rowsfrom_list:+--   | rowsfrom_item+--   | rowsfrom_list ',' rowsfrom_item+-- @+type RowsfromList = NonEmpty RowsfromItem++-- |+-- ==== References+-- @+-- opt_col_def_list:+--   | AS '(' TableFuncElementList ')'+--   | EMPTY+-- @+type ColDefList = TableFuncElementList++-- |+-- ==== References+-- @+-- opt_ordinality:+--   | WITH_LA ORDINALITY+--   | EMPTY+-- @+type OptOrdinality = Bool++-- |+-- ==== References+-- @+-- TableFuncElementList:+--   | TableFuncElement+--   | TableFuncElementList ',' TableFuncElement+-- @+type TableFuncElementList = NonEmpty TableFuncElement++-- |+-- ==== References+-- @+-- TableFuncElement:+--   | ColId Typename opt_collate_clause+-- @+data TableFuncElement = TableFuncElement ColId Typename (Maybe CollateClause)+  deriving (Show, Generic, Eq, Ord)++-- |+-- ==== References+-- @+-- opt_collate_clause:+--   | COLLATE any_name+--   | EMPTY+-- @+type CollateClause = AnyName++-- |+-- ==== References+-- @+-- alias_clause:+--   |  AS ColId '(' name_list ')'+--   |  AS ColId+--   |  ColId '(' name_list ')'+--   |  ColId+-- @+data AliasClause = AliasClause Bool ColId (Maybe NameList)+  deriving (Show, Generic, Eq, Ord)++-- |+-- ==== References+-- @+-- func_alias_clause:+--   | alias_clause+--   | AS '(' TableFuncElementList ')'+--   | AS ColId '(' TableFuncElementList ')'+--   | ColId '(' TableFuncElementList ')'+--   | EMPTY+-- @+data FuncAliasClause+  = AliasFuncAliasClause AliasClause+  | AsFuncAliasClause TableFuncElementList+  | AsColIdFuncAliasClause ColId TableFuncElementList+  | ColIdFuncAliasClause ColId TableFuncElementList+  deriving (Show, Generic, Eq, Ord)++-- |+-- ==== References+-- @+-- | '(' joined_table ')'+-- | table_ref CROSS JOIN table_ref+-- | table_ref join_type JOIN table_ref join_qual+-- | table_ref JOIN table_ref join_qual+-- | table_ref NATURAL join_type JOIN table_ref+-- | table_ref NATURAL JOIN table_ref+--+-- The options are covered by the `JoinMeth` type.+-- @+data JoinedTable+  = InParensJoinedTable JoinedTable+  | MethJoinedTable JoinMeth TableRef TableRef+  deriving (Show, Generic, Eq, Ord)++-- |+-- ==== References+-- @+-- | table_ref CROSS JOIN table_ref+-- | table_ref join_type JOIN table_ref join_qual+-- | table_ref JOIN table_ref join_qual+-- | table_ref NATURAL join_type JOIN table_ref+-- | table_ref NATURAL JOIN table_ref+-- @+data JoinMeth+  = CrossJoinMeth+  | QualJoinMeth (Maybe JoinType) JoinQual+  | NaturalJoinMeth (Maybe JoinType)+  deriving (Show, Generic, Eq, Ord)++-- |+-- ==== References+-- @+-- | FULL join_outer+-- | LEFT join_outer+-- | RIGHT join_outer+-- | INNER_P+-- @+data JoinType+  = FullJoinType Bool+  | LeftJoinType Bool+  | RightJoinType Bool+  | InnerJoinType+  deriving (Show, Generic, Eq, Ord)++-- |+-- ==== References+-- @+-- join_qual:+--   |  USING '(' name_list ')'+--   |  ON a_expr+-- @+data JoinQual+  = UsingJoinQual (NonEmpty Ident)+  | OnJoinQual AExpr+  deriving (Show, Generic, Eq, Ord)++-- * Where++type WhereClause = AExpr++-- |+-- ==== References+-- @+-- | WHERE a_expr+-- | WHERE CURRENT_P OF cursor_name+-- | /*EMPTY*/+-- @+data WhereOrCurrentClause+  = ExprWhereOrCurrentClause AExpr+  | CursorWhereOrCurrentClause CursorName+  deriving (Show, Generic, Eq, Ord)++-- * Expression++type ExprList = NonEmpty AExpr++-- |+-- ==== References+-- @+-- a_expr:+--   | c_expr+--   | a_expr TYPECAST Typename+--   | a_expr COLLATE any_name+--   | a_expr AT TIME ZONE a_expr+--   | '+' a_expr+--   | '-' a_expr+--   | a_expr '+' a_expr+--   | a_expr '-' a_expr+--   | a_expr '*' a_expr+--   | a_expr '/' a_expr+--   | a_expr '%' a_expr+--   | a_expr '^' a_expr+--   | a_expr '<' a_expr+--   | a_expr '>' a_expr+--   | a_expr '=' a_expr+--   | a_expr LESS_EQUALS a_expr+--   | a_expr GREATER_EQUALS a_expr+--   | a_expr NOT_EQUALS a_expr+--   | a_expr qual_Op a_expr+--   | qual_Op a_expr+--   | a_expr qual_Op+--   | a_expr AND a_expr+--   | a_expr OR a_expr+--   | NOT a_expr+--   | NOT_LA a_expr+--   | a_expr LIKE a_expr+--   | a_expr LIKE a_expr ESCAPE a_expr+--   | a_expr NOT_LA LIKE a_expr+--   | a_expr NOT_LA LIKE a_expr ESCAPE a_expr+--   | a_expr ILIKE a_expr+--   | a_expr ILIKE a_expr ESCAPE a_expr+--   | a_expr NOT_LA ILIKE a_expr+--   | a_expr NOT_LA ILIKE a_expr ESCAPE a_expr+--   | a_expr SIMILAR TO a_expr+--   | a_expr SIMILAR TO a_expr ESCAPE a_expr+--   | a_expr NOT_LA SIMILAR TO a_expr+--   | a_expr NOT_LA SIMILAR TO a_expr ESCAPE a_expr+--   | a_expr IS NULL_P+--   | a_expr ISNULL+--   | a_expr IS NOT NULL_P+--   | a_expr NOTNULL+--   | row OVERLAPS row+--   | a_expr IS TRUE_P+--   | a_expr IS NOT TRUE_P+--   | a_expr IS FALSE_P+--   | a_expr IS NOT FALSE_P+--   | a_expr IS UNKNOWN+--   | a_expr IS NOT UNKNOWN+--   | a_expr IS DISTINCT FROM a_expr+--   | a_expr IS NOT DISTINCT FROM a_expr+--   | a_expr IS OF '(' type_list ')'+--   | a_expr IS NOT OF '(' type_list ')'+--   | a_expr BETWEEN opt_asymmetric b_expr AND a_expr+--   | a_expr NOT_LA BETWEEN opt_asymmetric b_expr AND a_expr+--   | a_expr BETWEEN SYMMETRIC b_expr AND a_expr+--   | a_expr NOT_LA BETWEEN SYMMETRIC b_expr AND a_expr+--   | a_expr IN_P in_expr+--   | a_expr NOT_LA IN_P in_expr+--   | a_expr subquery_Op sub_type select_with_parens+--   | a_expr subquery_Op sub_type '(' a_expr ')'+--   | UNIQUE select_with_parens+--   | a_expr IS DOCUMENT_P+--   | a_expr IS NOT DOCUMENT_P+--   | DEFAULT+-- @+data AExpr+  = CExprAExpr CExpr+  | TypecastAExpr AExpr Typename+  | CollateAExpr AExpr AnyName+  | AtTimeZoneAExpr AExpr AExpr+  | PlusAExpr AExpr+  | MinusAExpr AExpr+  | SymbolicBinOpAExpr AExpr SymbolicExprBinOp AExpr+  | PrefixQualOpAExpr QualOp AExpr+  | SuffixQualOpAExpr AExpr QualOp+  | AndAExpr AExpr AExpr+  | OrAExpr AExpr AExpr+  | NotAExpr AExpr+  | VerbalExprBinOpAExpr AExpr Bool VerbalExprBinOp AExpr (Maybe AExpr)+  | ReversableOpAExpr AExpr Bool AExprReversableOp+  | IsnullAExpr AExpr+  | NotnullAExpr AExpr+  | OverlapsAExpr Row Row+  | SubqueryAExpr AExpr SubqueryOp SubType (Either SelectWithParens AExpr)+  | UniqueAExpr SelectWithParens+  | DefaultAExpr+  deriving (Show, Generic, Eq, Ord)++-- |+-- ==== References+-- @+-- b_expr:+--   | c_expr+--   | b_expr TYPECAST Typename+--   | '+' b_expr+--   | '-' b_expr+--   | b_expr '+' b_expr+--   | b_expr '-' b_expr+--   | b_expr '*' b_expr+--   | b_expr '/' b_expr+--   | b_expr '%' b_expr+--   | b_expr '^' b_expr+--   | b_expr '<' b_expr+--   | b_expr '>' b_expr+--   | b_expr '=' b_expr+--   | b_expr LESS_EQUALS b_expr+--   | b_expr GREATER_EQUALS b_expr+--   | b_expr NOT_EQUALS b_expr+--   | b_expr qual_Op b_expr+--   | qual_Op b_expr+--   | b_expr qual_Op+--   | b_expr IS DISTINCT FROM b_expr+--   | b_expr IS NOT DISTINCT FROM b_expr+--   | b_expr IS OF '(' type_list ')'+--   | b_expr IS NOT OF '(' type_list ')'+--   | b_expr IS DOCUMENT_P+--   | b_expr IS NOT DOCUMENT_P+-- @+data BExpr+  = CExprBExpr CExpr+  | TypecastBExpr BExpr Typename+  | PlusBExpr BExpr+  | MinusBExpr BExpr+  | SymbolicBinOpBExpr BExpr SymbolicExprBinOp BExpr+  | QualOpBExpr QualOp BExpr+  | IsOpBExpr BExpr Bool BExprIsOp+  deriving (Show, Generic, Eq, Ord)++-- |+-- ==== References+-- @+-- c_expr:+--   | columnref+--   | AexprConst+--   | PARAM opt_indirection+--   | '(' a_expr ')' opt_indirection+--   | case_expr+--   | func_expr+--   | select_with_parens+--   | select_with_parens indirection+--   | EXISTS select_with_parens+--   | ARRAY select_with_parens+--   | ARRAY array_expr+--   | explicit_row+--   | implicit_row+--   | GROUPING '(' expr_list ')'+-- @+data CExpr+  = ColumnrefCExpr Columnref+  | AexprConstCExpr AexprConst+  | ParamCExpr Int (Maybe Indirection)+  | InParensCExpr AExpr (Maybe Indirection)+  | CaseCExpr CaseExpr+  | FuncCExpr FuncExpr+  | SelectWithParensCExpr SelectWithParens (Maybe Indirection)+  | ExistsCExpr SelectWithParens+  | ArrayCExpr (Either SelectWithParens ArrayExpr)+  | ExplicitRowCExpr ExplicitRow+  | ImplicitRowCExpr ImplicitRow+  | GroupingCExpr ExprList+  deriving (Show, Generic, Eq, Ord)++-- **++-- |+-- ==== References+-- @+-- in_expr:+--   | select_with_parens+--   | '(' expr_list ')'+-- @+data InExpr+  = SelectInExpr SelectWithParens+  | ExprListInExpr ExprList+  deriving (Show, Generic, Eq, Ord)++-- |+-- ==== References+-- @+-- sub_type:+--   | ANY+--   | SOME+--   | ALL+-- @+data SubType = AnySubType | SomeSubType | AllSubType+  deriving (Show, Generic, Eq, Ord, Enum, Bounded)++-- |+-- ==== References+-- @+-- array_expr:+--   | '[' expr_list ']'+--   | '[' array_expr_list ']'+--   | '[' ']'+-- @+data ArrayExpr+  = ExprListArrayExpr ExprList+  | ArrayExprListArrayExpr ArrayExprList+  | EmptyArrayExpr+  deriving (Show, Generic, Eq, Ord)++-- |+-- ==== References+-- @+-- array_expr_list:+--   | array_expr+--   | array_expr_list ',' array_expr+-- @+type ArrayExprList = NonEmpty ArrayExpr++-- |+-- ==== References+-- @+-- row:+--   | ROW '(' expr_list ')'+--   | ROW '(' ')'+--   | '(' expr_list ',' a_expr ')'+-- @+data Row+  = ExplicitRowRow ExplicitRow+  | ImplicitRowRow ImplicitRow+  deriving (Show, Generic, Eq, Ord)++-- |+-- ==== References+-- @+-- explicit_row:+--   | ROW '(' expr_list ')'+--   | ROW '(' ')'+-- @+type ExplicitRow = Maybe ExprList++-- |+-- ==== References+-- @+-- implicit_row:+--   | '(' expr_list ',' a_expr ')'+-- @+data ImplicitRow = ImplicitRow ExprList AExpr+  deriving (Show, Generic, Eq, Ord)++-- |+-- ==== References+-- @+-- func_expr:+--   | func_application within_group_clause filter_clause over_clause+--   | func_expr_common_subexpr+-- @+data FuncExpr+  = ApplicationFuncExpr FuncApplication (Maybe WithinGroupClause) (Maybe FilterClause) (Maybe OverClause)+  | SubexprFuncExpr FuncExprCommonSubexpr+  deriving (Show, Generic, Eq, Ord)++-- |+-- ==== References+-- @+-- func_expr_windowless:+--   | func_application+--   | func_expr_common_subexpr+-- @+data FuncExprWindowless+  = ApplicationFuncExprWindowless FuncApplication+  | CommonSubexprFuncExprWindowless FuncExprCommonSubexpr+  deriving (Show, Generic, Eq, Ord)++-- |+-- ==== References+-- @+-- within_group_clause:+--   | WITHIN GROUP_P '(' sort_clause ')'+--   | EMPTY+-- @+type WithinGroupClause = SortClause++-- |+-- ==== References+-- @+-- filter_clause:+--   | FILTER '(' WHERE a_expr ')'+--   | EMPTY+-- @+type FilterClause = AExpr++-- |+-- ==== References+-- @+-- over_clause:+--   | OVER window_specification+--   | OVER ColId+--   | EMPTY+-- @+data OverClause+  = WindowOverClause WindowSpecification+  | ColIdOverClause ColId+  deriving (Show, Generic, Eq, Ord)++-- |+-- ==== References+-- @+-- func_expr_common_subexpr:+--   | COLLATION FOR '(' a_expr ')'+--   | CURRENT_DATE+--   | CURRENT_TIME+--   | CURRENT_TIME '(' Iconst ')'+--   | CURRENT_TIMESTAMP+--   | CURRENT_TIMESTAMP '(' Iconst ')'+--   | LOCALTIME+--   | LOCALTIME '(' Iconst ')'+--   | LOCALTIMESTAMP+--   | LOCALTIMESTAMP '(' Iconst ')'+--   | CURRENT_ROLE+--   | CURRENT_USER+--   | SESSION_USER+--   | USER+--   | CURRENT_CATALOG+--   | CURRENT_SCHEMA+--   | CAST '(' a_expr AS Typename ')'+--   | EXTRACT '(' extract_list ')'+--   | OVERLAY '(' overlay_list ')'+--   | POSITION '(' position_list ')'+--   | SUBSTRING '(' substr_list ')'+--   | TREAT '(' a_expr AS Typename ')'+--   | TRIM '(' BOTH trim_list ')'+--   | TRIM '(' LEADING trim_list ')'+--   | TRIM '(' TRAILING trim_list ')'+--   | TRIM '(' trim_list ')'+--   | NULLIF '(' a_expr ',' a_expr ')'+--   | COALESCE '(' expr_list ')'+--   | GREATEST '(' expr_list ')'+--   | LEAST '(' expr_list ')'+--   | XMLCONCAT '(' expr_list ')'+--   | XMLELEMENT '(' NAME_P ColLabel ')'+--   | XMLELEMENT '(' NAME_P ColLabel ',' xml_attributes ')'+--   | XMLELEMENT '(' NAME_P ColLabel ',' expr_list ')'+--   | XMLELEMENT '(' NAME_P ColLabel ',' xml_attributes ',' expr_list ')'+--   | XMLEXISTS '(' c_expr xmlexists_argument ')'+--   | XMLFOREST '(' xml_attribute_list ')'+--   | XMLPARSE '(' document_or_content a_expr xml_whitespace_option ')'+--   | XMLPI '(' NAME_P ColLabel ')'+--   | XMLPI '(' NAME_P ColLabel ',' a_expr ')'+--   | XMLROOT '(' a_expr ',' xml_root_version opt_xml_root_standalone ')'+--   | XMLSERIALIZE '(' document_or_content a_expr AS SimpleTypename ')'+--+-- TODO: Implement the XML cases+-- @+data FuncExprCommonSubexpr+  = CollationForFuncExprCommonSubexpr AExpr+  | CurrentDateFuncExprCommonSubexpr+  | CurrentTimeFuncExprCommonSubexpr (Maybe Int64)+  | CurrentTimestampFuncExprCommonSubexpr (Maybe Int64)+  | LocalTimeFuncExprCommonSubexpr (Maybe Int64)+  | LocalTimestampFuncExprCommonSubexpr (Maybe Int64)+  | CurrentRoleFuncExprCommonSubexpr+  | CurrentUserFuncExprCommonSubexpr+  | SessionUserFuncExprCommonSubexpr+  | UserFuncExprCommonSubexpr+  | CurrentCatalogFuncExprCommonSubexpr+  | CurrentSchemaFuncExprCommonSubexpr+  | CastFuncExprCommonSubexpr AExpr Typename+  | ExtractFuncExprCommonSubexpr (Maybe ExtractList)+  | OverlayFuncExprCommonSubexpr OverlayList+  | PositionFuncExprCommonSubexpr (Maybe PositionList)+  | SubstringFuncExprCommonSubexpr (Maybe SubstrList)+  | TreatFuncExprCommonSubexpr AExpr Typename+  | TrimFuncExprCommonSubexpr (Maybe TrimModifier) TrimList+  | NullIfFuncExprCommonSubexpr AExpr AExpr+  | CoalesceFuncExprCommonSubexpr ExprList+  | GreatestFuncExprCommonSubexpr ExprList+  | LeastFuncExprCommonSubexpr ExprList+  deriving (Show, Generic, Eq, Ord)++-- |+-- ==== References+-- @+-- extract_list:+--   | extract_arg FROM a_expr+--   | EMPTY+-- @+data ExtractList = ExtractList ExtractArg AExpr+  deriving (Show, Generic, Eq, Ord)++-- |+-- ==== References+-- @+-- extract_arg:+--   | IDENT+--   | YEAR_P+--   | MONTH_P+--   | DAY_P+--   | HOUR_P+--   | MINUTE_P+--   | SECOND_P+--   | Sconst+-- @+data ExtractArg+  = IdentExtractArg Ident+  | YearExtractArg+  | MonthExtractArg+  | DayExtractArg+  | HourExtractArg+  | MinuteExtractArg+  | SecondExtractArg+  | SconstExtractArg Sconst+  deriving (Show, Generic, Eq, Ord)++-- |+-- ==== References+-- @+-- overlay_list:+--   | a_expr overlay_placing substr_from substr_for+--   | a_expr overlay_placing substr_from+-- @+data OverlayList = OverlayList AExpr OverlayPlacing SubstrFrom (Maybe SubstrFor)+  deriving (Show, Generic, Eq, Ord)++-- |+-- ==== References+-- @+-- overlay_placing:+--   | PLACING a_expr+-- @+type OverlayPlacing = AExpr++-- |+-- ==== References+-- @+-- position_list:+--   | b_expr IN_P b_expr+--   | EMPTY+-- @+data PositionList = PositionList BExpr BExpr+  deriving (Show, Generic, Eq, Ord)++-- |+-- ==== References+-- @+-- substr_list:+--   | a_expr substr_from substr_for+--   | a_expr substr_for substr_from+--   | a_expr substr_from+--   | a_expr substr_for+--   | expr_list+--   | EMPTY+-- @+data SubstrList+  = ExprSubstrList AExpr SubstrListFromFor+  | ExprListSubstrList ExprList+  deriving (Show, Generic, Eq, Ord)++-- |+-- ==== References+-- @+--   | a_expr substr_from substr_for+--   | a_expr substr_for substr_from+--   | a_expr substr_from+--   | a_expr substr_for+-- @+data SubstrListFromFor+  = FromForSubstrListFromFor SubstrFrom SubstrFor+  | ForFromSubstrListFromFor SubstrFor SubstrFrom+  | FromSubstrListFromFor SubstrFrom+  | ForSubstrListFromFor SubstrFor+  deriving (Show, Generic, Eq, Ord)++-- |+-- ==== References+-- @+-- substr_from:+--   | FROM a_expr+-- @+type SubstrFrom = AExpr++-- |+-- ==== References+-- @+-- substr_for:+--   | FOR a_expr+-- @+type SubstrFor = AExpr++-- |+-- ==== References+-- @+--   | TRIM '(' BOTH trim_list ')'+--   | TRIM '(' LEADING trim_list ')'+--   | TRIM '(' TRAILING trim_list ')'+-- @+data TrimModifier = BothTrimModifier | LeadingTrimModifier | TrailingTrimModifier+  deriving (Show, Generic, Eq, Ord, Enum, Bounded)++-- |+-- ==== References+-- @+-- trim_list:+--   | a_expr FROM expr_list+--   | FROM expr_list+--   | expr_list+-- @+data TrimList+  = ExprFromExprListTrimList AExpr ExprList+  | FromExprListTrimList ExprList+  | ExprListTrimList ExprList+  deriving (Show, Generic, Eq, Ord)++-- |+-- ==== References+-- @+-- case_expr:+--   | CASE case_arg when_clause_list case_default END_P+-- @+data CaseExpr = CaseExpr (Maybe CaseArg) WhenClauseList (Maybe CaseDefault)+  deriving (Show, Generic, Eq, Ord)++-- |+-- ==== References+-- @+-- case_arg:+--   | a_expr+--   | EMPTY+-- @+type CaseArg = AExpr++-- |+-- ==== References+-- @+-- when_clause_list:+--   | when_clause+--   | when_clause_list when_clause+-- @+type WhenClauseList = NonEmpty WhenClause++-- |+-- ==== References+-- @+-- case_default:+--   | ELSE a_expr+--   | EMPTY+-- @+type CaseDefault = AExpr++-- |+-- ==== References+-- @+-- when_clause:+--   |  WHEN a_expr THEN a_expr+-- @+data WhenClause = WhenClause AExpr AExpr+  deriving (Show, Generic, Eq, Ord)++-- |+-- ==== References+-- @+-- func_application:+--   |  func_name '(' ')'+--   |  func_name '(' func_arg_list opt_sort_clause ')'+--   |  func_name '(' VARIADIC func_arg_expr opt_sort_clause ')'+--   |  func_name '(' func_arg_list ',' VARIADIC func_arg_expr opt_sort_clause ')'+--   |  func_name '(' ALL func_arg_list opt_sort_clause ')'+--   |  func_name '(' DISTINCT func_arg_list opt_sort_clause ')'+--   |  func_name '(' '*' ')'+-- @+data FuncApplication = FuncApplication FuncName (Maybe FuncApplicationParams)+  deriving (Show, Generic, Eq, Ord)++-- |+-- ==== References+-- @+-- func_application:+--   |  func_name '(' ')'+--   |  func_name '(' func_arg_list opt_sort_clause ')'+--   |  func_name '(' VARIADIC func_arg_expr opt_sort_clause ')'+--   |  func_name '(' func_arg_list ',' VARIADIC func_arg_expr opt_sort_clause ')'+--   |  func_name '(' ALL func_arg_list opt_sort_clause ')'+--   |  func_name '(' DISTINCT func_arg_list opt_sort_clause ')'+--   |  func_name '(' '*' ')'+-- @+data FuncApplicationParams+  = NormalFuncApplicationParams (Maybe Bool) (NonEmpty FuncArgExpr) (Maybe SortClause)+  | VariadicFuncApplicationParams (Maybe (NonEmpty FuncArgExpr)) FuncArgExpr (Maybe SortClause)+  | StarFuncApplicationParams+  deriving (Show, Generic, Eq, Ord)++data FuncArgExpr+  = ExprFuncArgExpr AExpr+  | ColonEqualsFuncArgExpr Ident AExpr+  | EqualsGreaterFuncArgExpr Ident AExpr+  deriving (Show, Generic, Eq, Ord)++-- * Constants++type Sconst = Text++type Iconst = Int64++type Fconst = Double++type Bconst = Text++type Xconst = Text++-- |+-- AexprConst:+--   |  Iconst+--   |  FCONST+--   |  Sconst+--   |  BCONST+--   |  XCONST+--   |  func_name Sconst+--   |  func_name '(' func_arg_list opt_sort_clause ')' Sconst+--   |  ConstTypename Sconst+--   |  ConstInterval Sconst opt_interval+--   |  ConstInterval '(' Iconst ')' Sconst+--   |  TRUE_P+--   |  FALSE_P+--   |  NULL_P+data AexprConst+  = IAexprConst Iconst+  | FAexprConst Fconst+  | SAexprConst Sconst+  | BAexprConst Bconst+  | XAexprConst Xconst+  | FuncAexprConst FuncName (Maybe FuncConstArgs) Sconst+  | ConstTypenameAexprConst ConstTypename Sconst+  | StringIntervalAexprConst Sconst (Maybe Interval)+  | IntIntervalAexprConst Iconst Sconst+  | BoolAexprConst Bool+  | NullAexprConst+  deriving (Show, Generic, Eq, Ord)++-- |+-- ==== References+-- @+--   |  func_name '(' func_arg_list opt_sort_clause ')' Sconst+-- @+data FuncConstArgs = FuncConstArgs (NonEmpty FuncArgExpr) (Maybe SortClause)+  deriving (Show, Generic, Eq, Ord)++-- |+-- ==== References+-- @+-- ConstTypename:+--   | Numeric+--   | ConstBit+--   | ConstCharacter+--   | ConstDatetime+-- @+data ConstTypename+  = NumericConstTypename Numeric+  | ConstBitConstTypename ConstBit+  | ConstCharacterConstTypename ConstCharacter+  | ConstDatetimeConstTypename ConstDatetime+  deriving (Show, Generic, Eq, Ord)++-- |+-- ==== References+-- @+-- Numeric:+--   | INT_P+--   | INTEGER+--   | SMALLINT+--   | BIGINT+--   | REAL+--   | FLOAT_P opt_float+--   | DOUBLE_P PRECISION+--   | DECIMAL_P opt_type_modifiers+--   | DEC opt_type_modifiers+--   | NUMERIC opt_type_modifiers+--   | BOOLEAN_P+-- opt_float:+--   | '(' Iconst ')'+--   | EMPTY+-- opt_type_modifiers:+--   | '(' expr_list ')'+--   | EMPTY+-- @+data Numeric+  = IntNumeric+  | IntegerNumeric+  | SmallintNumeric+  | BigintNumeric+  | RealNumeric+  | FloatNumeric (Maybe Int64)+  | DoublePrecisionNumeric+  | DecimalNumeric (Maybe TypeModifiers)+  | DecNumeric (Maybe TypeModifiers)+  | NumericNumeric (Maybe TypeModifiers)+  | BooleanNumeric+  deriving (Show, Generic, Eq, Ord)++-- |+-- ==== References+-- @+-- Bit:+--   | BitWithLength+--   | BitWithoutLength+-- ConstBit:+--   | BitWithLength+--   | BitWithoutLength+-- BitWithLength:+--   | BIT opt_varying '(' expr_list ')'+-- BitWithoutLength:+--   | BIT opt_varying+-- @+data Bit = Bit OptVarying (Maybe ExprList)+  deriving (Show, Generic, Eq, Ord)++type ConstBit = Bit++-- |+-- ==== References+-- @+-- opt_varying:+--   | VARYING+--   | EMPTY+-- @+type OptVarying = Bool++-- |+-- ==== References+-- @+-- Character:+--   | CharacterWithLength+--   | CharacterWithoutLength+-- ConstCharacter:+--   | CharacterWithLength+--   | CharacterWithoutLength+-- CharacterWithLength:+--   | character '(' Iconst ')'+-- CharacterWithoutLength:+--   | character+-- @+data ConstCharacter = ConstCharacter Character (Maybe Int64)+  deriving (Show, Generic, Eq, Ord)++-- |+-- ==== References+-- @+-- character:+--   | CHARACTER opt_varying+--   | CHAR_P opt_varying+--   | VARCHAR+--   | NATIONAL CHARACTER opt_varying+--   | NATIONAL CHAR_P opt_varying+--   | NCHAR opt_varying+-- @+data Character+  = CharacterCharacter OptVarying+  | CharCharacter OptVarying+  | VarcharCharacter+  | NationalCharacterCharacter OptVarying+  | NationalCharCharacter OptVarying+  | NcharCharacter OptVarying+  deriving (Show, Generic, Eq, Ord)++-- |+-- ==== References+-- @+-- ConstDatetime:+--   | TIMESTAMP '(' Iconst ')' opt_timezone+--   | TIMESTAMP opt_timezone+--   | TIME '(' Iconst ')' opt_timezone+--   | TIME opt_timezone+-- @+data ConstDatetime+  = TimestampConstDatetime (Maybe Int64) (Maybe Timezone)+  | TimeConstDatetime (Maybe Int64) (Maybe Timezone)+  deriving (Show, Generic, Eq, Ord)++-- |+-- ==== References+-- @+-- opt_timezone:+--   | WITH_LA TIME ZONE+--   | WITHOUT TIME ZONE+--   | EMPTY+-- @+type Timezone = Bool++-- |+-- ==== References+-- @+-- opt_interval:+--   | YEAR_P+--   | MONTH_P+--   | DAY_P+--   | HOUR_P+--   | MINUTE_P+--   | interval_second+--   | YEAR_P TO MONTH_P+--   | DAY_P TO HOUR_P+--   | DAY_P TO MINUTE_P+--   | DAY_P TO interval_second+--   | HOUR_P TO MINUTE_P+--   | HOUR_P TO interval_second+--   | MINUTE_P TO interval_second+--   | EMPTY+-- @+data Interval+  = YearInterval+  | MonthInterval+  | DayInterval+  | HourInterval+  | MinuteInterval+  | SecondInterval IntervalSecond+  | YearToMonthInterval+  | DayToHourInterval+  | DayToMinuteInterval+  | DayToSecondInterval IntervalSecond+  | HourToMinuteInterval+  | HourToSecondInterval IntervalSecond+  | MinuteToSecondInterval IntervalSecond+  deriving (Show, Generic, Eq, Ord)++-- |+-- ==== References+-- @+-- interval_second:+--   | SECOND_P+--   | SECOND_P '(' Iconst ')'+-- @+type IntervalSecond = Maybe Int64++-- * Names & References++-- |+-- ==== References+-- @+-- IDENT+-- @+data Ident = QuotedIdent Text | UnquotedIdent Text+  deriving (Show, Generic, Eq, Ord)++-- |+-- ==== References+-- @+-- ColId:+--   | IDENT+--   | unreserved_keyword+--   | col_name_keyword+-- @+type ColId = Ident++-- |+-- ==== References+-- @+-- ColLabel:+--   | IDENT+--   | unreserved_keyword+--   | col_name_keyword+--   | type_func_name_keyword+--   | reserved_keyword+-- @+type ColLabel = Ident++-- |+-- ==== References+-- @+-- name:+--   | ColId+-- @+type Name = ColId++-- |+-- ==== References+-- @+-- name_list:+--   | name+--   | name_list ',' name+-- @+type NameList = NonEmpty Name++-- |+-- ==== References+-- @+-- cursor_name:+--   | name+-- @+type CursorName = Name++-- |+-- ==== References+-- @+-- columnref:+--   | ColId+--   | ColId indirection+-- @+data Columnref = Columnref ColId (Maybe Indirection)+  deriving (Show, Generic, Eq, Ord)++-- |+-- ==== References+-- @+-- any_name:+--   | ColId+--   | ColId attrs+-- @+data AnyName = AnyName ColId (Maybe Attrs)+  deriving (Show, Generic, Eq, Ord)++-- |+-- ==== References+-- @+-- func_name:+--   | type_function_name+--   | ColId indirection+-- @+data FuncName+  = TypeFuncName TypeFunctionName+  | IndirectedFuncName ColId Indirection+  deriving (Show, Generic, Eq, Ord)++-- |+-- ==== References+-- @+-- type_function_name:+--   | IDENT+--   | unreserved_keyword+--   | type_func_name_keyword+-- @+type TypeFunctionName = Ident++-- |+-- ==== References+-- @+-- columnref:+--   | ColId+--   | ColId indirection+-- qualified_name:+--   | ColId+--   | ColId indirection+-- @+data QualifiedName+  = SimpleQualifiedName Ident+  | IndirectedQualifiedName Ident Indirection+  deriving (Show, Generic, Eq, Ord)++-- |+-- ==== References+-- @+-- indirection:+--   |  indirection_el+--   |  indirection indirection_el+-- @+type Indirection = NonEmpty IndirectionEl++-- |+-- ==== References+-- @+-- indirection_el:+--   |  '.' attr_name+--   |  '.' '*'+--   |  '[' a_expr ']'+--   |  '[' opt_slice_bound ':' opt_slice_bound ']'+-- opt_slice_bound:+--   |  a_expr+--   |  EMPTY+-- @+data IndirectionEl+  = AttrNameIndirectionEl Ident+  | AllIndirectionEl+  | ExprIndirectionEl AExpr+  | SliceIndirectionEl (Maybe AExpr) (Maybe AExpr)+  deriving (Show, Generic, Eq, Ord)++-- * Types++-- |+-- Typename definition extended with custom question-marks for nullability specification.+--+-- To match the standard Postgres syntax simply interpret their presence as a parsing error.+--+-- ==== References+-- @+-- Typename:+--   | SimpleTypename opt_array_bounds+--   | SETOF SimpleTypename opt_array_bounds+--   | SimpleTypename ARRAY '[' Iconst ']'+--   | SETOF SimpleTypename ARRAY '[' Iconst ']'+--   | SimpleTypename ARRAY+--   | SETOF SimpleTypename ARRAY+-- @+data Typename+  = Typename+      Bool+      -- ^ SETOF+      SimpleTypename+      Bool+      -- ^ Question mark+      (Maybe (TypenameArrayDimensions, Bool))+      -- ^ Array dimensions possibly followed by a question mark+  deriving (Show, Generic, Eq, Ord)++-- |+-- ==== References+-- @+-- Part of the Typename specification responsible for the choice between the following:+--   | opt_array_bounds+--   | ARRAY '[' Iconst ']'+--   | ARRAY+-- @+data TypenameArrayDimensions+  = BoundsTypenameArrayDimensions ArrayBounds+  | ExplicitTypenameArrayDimensions (Maybe Iconst)+  deriving (Show, Generic, Eq, Ord)++-- |+-- ==== References+-- @+-- opt_array_bounds:+--   | opt_array_bounds '[' ']'+--   | opt_array_bounds '[' Iconst ']'+--   | EMPTY+-- @+type ArrayBounds = NonEmpty (Maybe Iconst)++-- |+-- ==== References+-- @+-- SimpleTypename:+--   | GenericType+--   | Numeric+--   | Bit+--   | Character+--   | ConstDatetime+--   | ConstInterval opt_interval+--   | ConstInterval '(' Iconst ')'+-- ConstInterval:+--   | INTERVAL+-- @+data SimpleTypename+  = GenericTypeSimpleTypename GenericType+  | NumericSimpleTypename Numeric+  | BitSimpleTypename Bit+  | CharacterSimpleTypename Character+  | ConstDatetimeSimpleTypename ConstDatetime+  | ConstIntervalSimpleTypename (Either (Maybe Interval) Iconst)+  deriving (Show, Generic, Eq, Ord)++-- |+-- ==== References+-- @+-- GenericType:+--   | type_function_name opt_type_modifiers+--   | type_function_name attrs opt_type_modifiers+-- @+data GenericType = GenericType TypeFunctionName (Maybe Attrs) (Maybe TypeModifiers)+  deriving (Show, Generic, Eq, Ord)++-- |+-- ==== References+-- @+-- attrs:+--   | '.' attr_name+--   | attrs '.' attr_name+-- @+type Attrs = NonEmpty AttrName++-- |+-- ==== References+-- @+-- attr_name:+--   | ColLabel+-- @+type AttrName = ColLabel++-- |+-- ==== References+-- @+-- opt_type_modifiers:+--   | '(' expr_list ')'+--   | EMPTY+-- @+type TypeModifiers = ExprList++-- |+-- ==== References+-- @+-- type_list:+--   | Typename+--   | type_list ',' Typename+-- @+type TypeList = NonEmpty Typename++-- * Operators++-- |+-- ==== References+-- @+-- qual_Op:+--   | Op+--   | OPERATOR '(' any_operator ')'+-- @+data QualOp+  = OpQualOp Op+  | OperatorQualOp AnyOperator+  deriving (Show, Generic, Eq, Ord)++-- |+-- ==== References+-- @+-- qual_all_Op:+--   | all_Op+--   | OPERATOR '(' any_operator ')'+-- @+data QualAllOp+  = AllQualAllOp AllOp+  | AnyQualAllOp AnyOperator+  deriving (Show, Generic, Eq, Ord)++-- |+-- ==== References+-- @+-- The operator name is a sequence of up to NAMEDATALEN-1 (63 by default)+-- characters from the following list:+--+-- + - * / < > = ~ ! @ # % ^ & | ` ?+--+-- There are a few restrictions on your choice of name:+-- -- and /* cannot appear anywhere in an operator name,+-- since they will be taken as the start of a comment.+--+-- A multicharacter operator name cannot end in + or -,+-- unless the name also contains at least one of these characters:+--+-- ~ ! @ # % ^ & | ` ?+--+-- For example, @- is an allowed operator name, but *- is not.+-- This restriction allows PostgreSQL to parse SQL-compliant+-- commands without requiring spaces between tokens.+-- The use of => as an operator name is deprecated.+-- It may be disallowed altogether in a future release.+--+-- The operator != is mapped to <> on input,+-- so these two names are always equivalent.+-- @+type Op = Text++-- |+-- ==== References+-- @+-- any_operator:+--   | all_Op+--   | ColId '.' any_operator+-- @+data AnyOperator+  = AllOpAnyOperator AllOp+  | QualifiedAnyOperator ColId AnyOperator+  deriving (Show, Generic, Eq, Ord)++-- |+-- ==== References+-- @+-- all_Op:+--   | Op+--   | MathOp+-- @+data AllOp+  = OpAllOp Op+  | MathAllOp MathOp+  deriving (Show, Generic, Eq, Ord)++-- |+-- ==== References+-- @+-- MathOp:+--   | '+'+--   | '-'+--   | '*'+--   | '/'+--   | '%'+--   | '^'+--   | '<'+--   | '>'+--   | '='+--   | LESS_EQUALS+--   | GREATER_EQUALS+--   | NOT_EQUALS+-- @+data MathOp+  = PlusMathOp+  | MinusMathOp+  | AsteriskMathOp+  | SlashMathOp+  | PercentMathOp+  | ArrowUpMathOp+  | ArrowLeftMathOp+  | ArrowRightMathOp+  | EqualsMathOp+  | LessEqualsMathOp+  | GreaterEqualsMathOp+  | ArrowLeftArrowRightMathOp+  | ExclamationEqualsMathOp+  deriving (Show, Generic, Eq, Ord, Enum, Bounded)++data SymbolicExprBinOp+  = MathSymbolicExprBinOp MathOp+  | QualSymbolicExprBinOp QualOp+  deriving (Show, Generic, Eq, Ord)++data VerbalExprBinOp+  = LikeVerbalExprBinOp+  | IlikeVerbalExprBinOp+  | SimilarToVerbalExprBinOp+  deriving (Show, Generic, Eq, Ord, Enum, Bounded)++-- |+-- ==== References+-- @+--   | a_expr IS NULL_P+--   | a_expr IS TRUE_P+--   | a_expr IS FALSE_P+--   | a_expr IS UNKNOWN+--   | a_expr IS DISTINCT FROM a_expr+--   | a_expr IS OF '(' type_list ')'+--   | a_expr BETWEEN opt_asymmetric b_expr AND a_expr+--   | a_expr BETWEEN SYMMETRIC b_expr AND a_expr+--   | a_expr IN_P in_expr+--   | a_expr IS DOCUMENT_P+-- @+data AExprReversableOp+  = NullAExprReversableOp+  | TrueAExprReversableOp+  | FalseAExprReversableOp+  | UnknownAExprReversableOp+  | DistinctFromAExprReversableOp AExpr+  | OfAExprReversableOp TypeList+  | BetweenAExprReversableOp Bool BExpr AExpr+  | BetweenSymmetricAExprReversableOp BExpr AExpr+  | InAExprReversableOp InExpr+  | DocumentAExprReversableOp+  deriving (Show, Generic, Eq, Ord)++-- |+-- ==== References+-- @+--   | b_expr IS DISTINCT FROM b_expr+--   | b_expr IS NOT DISTINCT FROM b_expr+--   | b_expr IS OF '(' type_list ')'+--   | b_expr IS NOT OF '(' type_list ')'+--   | b_expr IS DOCUMENT_P+--   | b_expr IS NOT DOCUMENT_P+-- @+data BExprIsOp+  = DistinctFromBExprIsOp BExpr+  | OfBExprIsOp TypeList+  | DocumentBExprIsOp+  deriving (Show, Generic, Eq, Ord)++-- |+-- ==== References+-- @+-- subquery_Op:+--   | all_Op+--   | OPERATOR '(' any_operator ')'+--   | LIKE+--   | NOT_LA LIKE+--   | ILIKE+--   | NOT_LA ILIKE+-- @+data SubqueryOp+  = AllSubqueryOp AllOp+  | AnySubqueryOp AnyOperator+  | LikeSubqueryOp Bool+  | IlikeSubqueryOp Bool+  deriving (Show, Generic, Eq, Ord)++-- * Indexes++-- |+-- ==== References+-- @+-- index_params:+--   | index_elem+--   | index_params ',' index_elem+-- @+type IndexParams = NonEmpty IndexElem++-- |+-- ==== References+-- @+-- index_elem:+--   | ColId opt_collate opt_class opt_asc_desc opt_nulls_order+--   | func_expr_windowless opt_collate opt_class opt_asc_desc opt_nulls_order+--   | '(' a_expr ')' opt_collate opt_class opt_asc_desc opt_nulls_order+-- @+data IndexElem = IndexElem IndexElemDef (Maybe Collate) (Maybe Class) (Maybe AscDesc) (Maybe NullsOrder)+  deriving (Show, Generic, Eq, Ord)++-- |+-- ==== References+-- @+--   | ColId opt_collate opt_class opt_asc_desc opt_nulls_order+--   | func_expr_windowless opt_collate opt_class opt_asc_desc opt_nulls_order+--   | '(' a_expr ')' opt_collate opt_class opt_asc_desc opt_nulls_order+-- @+data IndexElemDef+  = IdIndexElemDef ColId+  | FuncIndexElemDef FuncExprWindowless+  | ExprIndexElemDef AExpr+  deriving (Show, Generic, Eq, Ord)++-- |+-- ==== References+-- @+-- opt_collate:+--   | COLLATE any_name+--   | EMPTY+-- @+type Collate = AnyName++-- |+-- ==== References+-- @+-- opt_class:+--   | any_name+--   | EMPTY+-- @+type Class = AnyName++-- |+-- ==== References+-- @+-- opt_asc_desc:+--   | ASC+--   | DESC+--   | EMPTY+-- @+data AscDesc = AscAscDesc | DescAscDesc+  deriving (Show, Generic, Eq, Ord, Enum, Bounded)++-- |+-- ==== References+-- @+-- opt_nulls_order:+--   | NULLS_LA FIRST_P+--   | NULLS_LA LAST_P+--   | EMPTY+-- @ data NullsOrder = FirstNullsOrder | LastNullsOrder   deriving (Show, Generic, Eq, Ord, Enum, Bounded)
library/PostgresqlSyntax/CharSet.hs view
@@ -1,9 +1,8 @@ module PostgresqlSyntax.CharSet where -import PostgresqlSyntax.Prelude import qualified Data.Text as Text import qualified PostgresqlSyntax.KeywordSet as KeywordSet-+import PostgresqlSyntax.Prelude  {-# NOINLINE symbolicBinOp #-} symbolicBinOp :: HashSet Char
library/PostgresqlSyntax/Extras/HeadedMegaparsec.hs view
@@ -1,85 +1,69 @@-{-|-Generic helpers for HeadedMegaparsec.--}+-- |+-- Generic helpers for HeadedMegaparsec. module PostgresqlSyntax.Extras.HeadedMegaparsec where -import PostgresqlSyntax.Prelude hiding (expr, try, option, some, many, sortBy, filter, head, tail, bit)-import HeadedMegaparsec hiding (string) import Control.Applicative.Combinators hiding (some) import Control.Applicative.Combinators.NonEmpty-import Text.Megaparsec (Stream, Parsec, VisualStream, TraversableStream)+import qualified Data.Text as Text+import HeadedMegaparsec hiding (string)+import PostgresqlSyntax.Prelude hiding (bit, expr, filter, head, many, option, some, sortBy, tail, try)+import Text.Megaparsec (Parsec, Stream, TraversableStream, VisualStream) import qualified Text.Megaparsec as Megaparsec import qualified Text.Megaparsec.Char as MegaparsecChar import qualified Text.Megaparsec.Char.Lexer as MegaparsecLexer-import qualified Data.Text as Text --{- $setup->>> testParser parser = either putStr print . run parser--}-+-- $setup+-- >>> testParser parser = either putStr print . run parser  -- * Executors--------------------------  run :: (Ord err, VisualStream strm, TraversableStream strm, Megaparsec.ShowErrorComponent err) => HeadedParsec err strm a -> strm -> Either String a run p = first Megaparsec.errorBundlePretty . Megaparsec.runParser (toParsec p <* Megaparsec.eof) "" - -- * Primitives-------------------------- -{-|-Lifted megaparsec\'s `Megaparsec.eof`.--}+-- |+-- Lifted megaparsec\'s `Megaparsec.eof`. eof :: (Ord err, Stream strm) => HeadedParsec err strm () eof = parse Megaparsec.eof -{-|-Lifted megaparsec\'s `Megaparsec.space`.--}+-- |+-- Lifted megaparsec\'s `Megaparsec.space`. space :: (Ord err, Stream strm, Megaparsec.Token strm ~ Char) => HeadedParsec err strm () space = parse MegaparsecChar.space -{-|-Lifted megaparsec\'s `Megaparsec.space1`.--}+-- |+-- Lifted megaparsec\'s `Megaparsec.space1`. space1 :: (Ord err, Stream strm, Megaparsec.Token strm ~ Char) => HeadedParsec err strm () space1 = parse MegaparsecChar.space1 -{-|-Lifted megaparsec\'s `Megaparsec.char`.--}+-- |+-- Lifted megaparsec\'s `Megaparsec.char`. char :: (Ord err, Stream strm, Megaparsec.Token strm ~ Char) => Char -> HeadedParsec err strm Char char a = parse (MegaparsecChar.char a) -{-|-Lifted megaparsec\'s `Megaparsec.char'`.--}+-- |+-- Lifted megaparsec\'s `Megaparsec.char'`. char' :: (Ord err, Stream strm, Megaparsec.Token strm ~ Char) => Char -> HeadedParsec err strm Char char' a = parse (MegaparsecChar.char' a) -{-|-Lifted megaparsec\'s `Megaparsec.string`.--}+-- |+-- Lifted megaparsec\'s `Megaparsec.string`. string :: (Ord err, Stream strm) => Megaparsec.Tokens strm -> HeadedParsec err strm (Megaparsec.Tokens strm) string = parse . MegaparsecChar.string -{-|-Lifted megaparsec\'s `Megaparsec.string'`.--}+-- |+-- Lifted megaparsec\'s `Megaparsec.string'`. string' :: (Ord err, Stream strm, FoldCase (Megaparsec.Tokens strm)) => Megaparsec.Tokens strm -> HeadedParsec err strm (Megaparsec.Tokens strm) string' = parse . MegaparsecChar.string' -{-|-Lifted megaparsec\'s `Megaparsec.takeWhileP`.--}+-- |+-- Lifted megaparsec\'s `Megaparsec.takeWhileP`. takeWhileP :: (Ord err, Stream strm) => Maybe String -> (Megaparsec.Token strm -> Bool) -> HeadedParsec err strm (Megaparsec.Tokens strm) takeWhileP label predicate = parse (Megaparsec.takeWhileP label predicate) -{-|-Lifted megaparsec\'s `Megaparsec.takeWhile1P`.--}+-- |+-- Lifted megaparsec\'s `Megaparsec.takeWhile1P`. takeWhile1P :: (Ord err, Stream strm) => Maybe String -> (Megaparsec.Token strm -> Bool) -> HeadedParsec err strm (Megaparsec.Tokens strm) takeWhile1P label predicate = parse (Megaparsec.takeWhile1P label predicate) @@ -92,9 +76,7 @@ float :: (Ord err, Stream strm, Megaparsec.Token strm ~ Char, RealFloat float) => HeadedParsec err strm float float = parse MegaparsecLexer.float - -- * 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@@ -106,19 +88,17 @@ 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   headEl <- elP-  let-    loop !list = do-      sepP-      asum [-          do-            end <- endP-            return (headEl :| reverse list, end)-          ,-          do-            el <- elP-            loop (el : list)-        ]-    in loop []+  let loop !list = do+        sepP+        asum+          [ do+              end <- endP+              return (headEl :| reverse list, end),+            do+              el <- elP+              loop (el : list)+          ]+   in loop []  notFollowedBy :: (Ord err, Stream strm) => HeadedParsec err strm a -> HeadedParsec err strm () notFollowedBy a = parse (Megaparsec.notFollowedBy (toParsec a))
library/PostgresqlSyntax/Extras/NonEmpty.hs view
@@ -1,33 +1,31 @@ module PostgresqlSyntax.Extras.NonEmpty where -import PostgresqlSyntax.Prelude hiding (reverse, head, tail, init, last, cons, uncons, fromList) import Data.List.NonEmpty---{-|->>> intersperseFoldMap ", " id (fromList ["a"])-"a"+import PostgresqlSyntax.Prelude hiding (cons, fromList, head, init, last, reverse, tail, uncons) ->>> intersperseFoldMap ", " id (fromList ["a", "b", "c"])-"a, b, c"--}+-- |+-- >>> intersperseFoldMap ", " id (fromList ["a"])+-- "a"+--+-- >>> intersperseFoldMap ", " id (fromList ["a", "b", "c"])+-- "a, b, c" 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)-unsnoc = let-  build1 = \ case-    a :| b -> build2 a b-  build2 a = \ case-    b : c -> build3 b (a :| []) c-    _ -> (Nothing, a)-  build3 a b = \ case-    c : d -> build3 c (cons a b) d-    _ -> (Just (reverse b), a)-  in build1+unsnoc =+  let build1 = \case+        a :| b -> build2 a b+      build2 a = \case+        b : c -> build3 b (a :| []) c+        _ -> (Nothing, a)+      build3 a b = \case+        c : d -> build3 c (cons a b) d+        _ -> (Just (reverse b), a)+   in build1  consAndUnsnoc :: a -> NonEmpty a -> (NonEmpty a, a) consAndUnsnoc a b = case unsnoc b of-    (c, d) -> case c of-      Just e -> (cons a e, d)-      Nothing -> (pure a, d)+  (c, d) -> case c of+    Just e -> (cons a e, d)+    Nothing -> (pure a, d)
library/PostgresqlSyntax/Extras/TextBuilder.hs view
@@ -3,7 +3,6 @@ import PostgresqlSyntax.Prelude import Text.Builder - char7 :: Char -> Builder char7 = char 
library/PostgresqlSyntax/KeywordSet.hs view
@@ -1,9 +1,8 @@ module PostgresqlSyntax.KeywordSet where -import PostgresqlSyntax.Prelude hiding (expression, fromList, toList) import Data.HashSet import qualified Data.Text as Text-+import PostgresqlSyntax.Prelude hiding (expression, fromList, toList)  {-# NOINLINE keyword #-} {-@@ -48,16 +47,15 @@ {-# NOINLINE typeFunctionName #-} typeFunctionName = unions [unreservedKeyword, typeFuncNameKeyword] -{-|-As per the following comment from the original scanner definition:--/*- * Likewise, if what we have left is two chars, and- * those match the tokens ">=", "<=", "=>", "<>" or- * "!=", then we must return the appropriate token- * rather than the generic Op.- */--}+-- |+-- As per the following comment from the original scanner definition:+--+-- /*+--  * Likewise, if what we have left is two chars, and+--  * those match the tokens ">=", "<=", "=>", "<>" or+--  * "!=", then we must return the appropriate token+--  * rather than the generic Op.+--  */ {-# NOINLINE nonOp #-} nonOp = fromList [">=", "<=", "=>", "<>", "!="] <> mathOp 
library/PostgresqlSyntax/Parsing.hs view
@@ -1,2140 +1,2081 @@-{-|--Our parsing strategy is to port the original Postgres parser as closely as possible.--We're using the @gram.y@ Postgres source file, which is the closest thing we have-to a Postgres syntax spec. Here's a link to it:-https://github.com/postgres/postgres/blob/master/src/backend/parser/gram.y.--Here's the essence of how the original parser is implemented, citing from-[PostgreSQL Wiki](https://wiki.postgresql.org/wiki/Developer_FAQ):--    scan.l defines the lexer, i.e. the algorithm that splits a string-    (containing an SQL statement) into a stream of tokens.-    A token is usually a single word-    (i.e., doesn't contain spaces but is delimited by spaces), -    but can also be a whole single or double-quoted string for example. -    The lexer is basically defined in terms of regular expressions -    which describe the different token types.--    gram.y defines the grammar (the syntactical structure) of SQL statements,-    using the tokens generated by the lexer as basic building blocks.-    The grammar is defined in BNF notation.-    BNF resembles regular expressions but works on the level of tokens, not characters.-    Also, patterns (called rules or productions in BNF) are named, and may be recursive,-    i.e. use themselves as sub-patterns.---}-module PostgresqlSyntax.Parsing where--import PostgresqlSyntax.Prelude hiding (expr, try, option, some, many, sortBy, filter, head, tail, bit, fromList)-import HeadedMegaparsec hiding (string)-import Control.Applicative.Combinators hiding (some)-import Control.Applicative.Combinators.NonEmpty-import PostgresqlSyntax.Extras.HeadedMegaparsec hiding (run)-import PostgresqlSyntax.Ast-import Text.Megaparsec (Stream, Parsec)-import qualified PostgresqlSyntax.Extras.HeadedMegaparsec as Extras-import qualified PostgresqlSyntax.Extras.NonEmpty as NonEmpty-import qualified Text.Megaparsec as Megaparsec-import qualified Text.Megaparsec.Char as MegaparsecChar-import qualified Text.Megaparsec.Char.Lexer as MegaparsecLexer-import qualified PostgresqlSyntax.KeywordSet as KeywordSet-import qualified PostgresqlSyntax.Predicate as Predicate-import qualified PostgresqlSyntax.Validation as Validation-import qualified Data.Text as Text-import qualified Data.List.NonEmpty as NonEmpty-import qualified Text.Builder as TextBuilder-import qualified Data.HashSet as HashSet---{- $setup->>> testParser parser = either putStr print . run parser--}---type Parser = HeadedParsec Void Text----- * Executors----------------------------run :: Parser a -> Text -> Either String a-run = Extras.run----- * Helpers----------------------------commaSeparator :: Parser ()-commaSeparator = space *> char ',' *> endHead *> space--dotSeparator :: Parser ()-dotSeparator = space *> char '.' *> endHead *> space--inBrackets :: Parser a -> Parser a-inBrackets p = char '[' *> space *> p <* endHead <* space <* char ']'--inBracketsCont :: Parser a -> Parser (Parser a)-inBracketsCont p = char '[' *> endHead *> pure (space *> p <* endHead <* space <* char ']')--inParens :: Parser a -> Parser a-inParens p = char '(' *> space *> p <* endHead <* space <* char ')'--inParensCont :: Parser a -> Parser (Parser a)-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-  space-  char '('-  endHead-  space-  _content <- _contentParser-  space-  char ')'-  pure (_result _label _content)--inParensWithClause :: Parser clause -> Parser content -> Parser content-inParensWithClause = inParensWithLabel (const id)--trueIfPresent :: Parser a -> Parser Bool-trueIfPresent p = option False (True <$ p)--{-|->>> testParser (quotedString '\'') "'abc''d'"-"abc'd"--}-quotedString :: Char -> Parser Text-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--atEnd :: Parser a -> Parser a-atEnd p = space *> p <* endHead <* space <* eof----- * PreparableStmt----------------------------preparableStmt =-  SelectPreparableStmt <$> selectStmt <|>-  InsertPreparableStmt <$> insertStmt <|>-  UpdatePreparableStmt <$> updateStmt <|>-  DeletePreparableStmt <$> deleteStmt----- * Insert----------------------------insertStmt = do-  a <- optional (wrapToHead withClause <* space1)-  keyword "insert"-  space1-  endHead-  keyword "into"-  space1-  b <- insertTarget-  space1-  c <- insertRest-  d <- optional (space1 *> onConflict)-  e <- optional (space1 *> returningClause)-  return (InsertStmt a b c d e)--insertTarget = do-  a <- qualifiedName-  endHead-  b <- optional (space1 *> keyword "as" *> space1 *> endHead *> colId)-  return (InsertTarget a b)--insertRest = asum [-    DefaultValuesInsertRest <$ (keyword "default" *> space1 *> endHead *> keyword "values")-    ,-    do-      a <- optional (inParens insertColumnList <* space1)-      b <- optional $ do-        keyword "overriding"-        space1-        endHead-        b <- overrideKind-        space1-        keyword "value"-        space1-        return b-      c <- selectStmt-      return (SelectInsertRest a b c)-  ]--overrideKind = asum [-    UserOverrideKind <$ keyword "user",-    SystemOverrideKind <$ keyword "system"-  ]--insertColumnList = sep1 commaSeparator insertColumnItem--insertColumnItem = do-  a <- colId-  endHead-  b <- optional (space1 *> indirection)-  return (InsertColumnItem a b)--onConflict = do-  keyword "on"-  space1-  keyword "conflict"-  space1-  endHead-  a <- optional (confExpr <* space1)-  keyword "do"-  space1-  b <- onConflictDo-  return (OnConflict a b)--confExpr = asum [-    WhereConfExpr <$> inParens indexParams <*> optional (space *> whereClause)-    ,-    ConstraintConfExpr <$> (keyword "on" *> space1 *> keyword "constraint" *> space1 *> endHead *> name)-  ]--onConflictDo = asum [-    NothingOnConflictDo <$ keyword "nothing"-    ,-    do-      keyword "update"-      space1-      endHead-      keyword "set"-      space1-      a <- setClauseList-      b <- optional (space1 *> whereClause)-      return (UpdateOnConflictDo a b)-  ]--returningClause = do-  keyword "returning"-  space1-  endHead-  targetList----- * Update----------------------------updateStmt = do-  a <- optional (wrapToHead withClause <* space1)-  keyword "update"-  space1-  endHead-  b <- relationExprOptAlias ["set"]-  space1-  keyword "set"-  space1-  c <- setClauseList-  d <- optional (space1 *> fromClause)-  e <- optional (space1 *> whereOrCurrentClause)-  f <- optional (space1 *> returningClause)-  return (UpdateStmt a b c d e f)--setClauseList = sep1 commaSeparator setClause--setClause = asum [-    do-      a <- inParens setTargetList -      space-      char '='-      space-      b <- aExpr-      return (TargetListSetClause a b)-    ,-    do-      a <- setTarget -      space-      char '='-      space-      b <- aExpr-      return (TargetSetClause a b)-  ]--setTarget = do-  a <- colId-  endHead-  b <- optional (space1 *> indirection)-  return (SetTarget a b)--setTargetList = sep1 commaSeparator setTarget----- * Delete----------------------------deleteStmt = do-  a <- optional (wrapToHead withClause <* space1)-  keyword "delete"-  space1-  endHead-  keyword "from"-  space1-  b <- relationExprOptAlias ["using", "where", "returning"]-  c <- optional (space1 *> usingClause)-  d <- optional (space1 *> whereOrCurrentClause)-  e <- optional (space1 *> returningClause)-  return (DeleteStmt a b c d e)--usingClause = do-  keyword "using"-  space1-  fromList----- * Select----------------------------{-|->>> test = testParser selectStmt-->>> test "select id from as"-...-  |-1 | select id from as-  |                  ^-Reserved keyword "as" used as an identifier. If that's what you intend, you have to wrap it in double quotes.--}-selectStmt = Left <$> selectNoParens <|> Right <$> selectWithParens--selectWithParens = inParens (WithParensSelectWithParens <$> selectWithParens <|> NoParensSelectWithParens <$> selectNoParens)--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)--{-|-The one that doesn't start with \"WITH\".--}-{--  | simple_select-  | select_clause sort_clause-  | select_clause opt_sort_clause for_locking_clause opt_select_limit-  | select_clause opt_sort_clause select_limit opt_for_locking_clause--}-simpleSelectNoParens = sharedSelectNoParens Nothing--withSelectNoParens = do-  _with <- wrapToHead withClause-  space1-  sharedSelectNoParens (Just _with)--selectClause = suffixRec base suffix where-  base = asum [-      Right <$> selectWithParens,-      Left <$> baseSimpleSelect-    ]-  suffix a = Left <$> extensionSimpleSelect a--baseSimpleSelect = asum [-    do-      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)-    ,-    do-      keyword "table"-      space1-      endHead-      TableSimpleSelect <$> relationExpr-    ,-    ValuesSimpleSelect <$> valuesClause-  ]--extensionSimpleSelect _headSelectClause = do-  _op <- space1 *> selectBinOp <* space1-  endHead-  _allOrDistinct <- optional (allOrDistinct <* space1)-  _selectClause <- selectClause-  return (BinSimpleSelect _op _headSelectClause _allOrDistinct _selectClause)-  -allOrDistinct = keyword "all" $> False <|> keyword "distinct" $> True--selectBinOp = asum [-    keyword "union" $> UnionSelectBinOp,-    keyword "intersect" $> IntersectSelectBinOp,-    keyword "except" $> ExceptSelectBinOp-  ]--valuesClause = do-  keyword "values"-  space-  sep1 commaSeparator $ do-    char '('-    endHead-    space-    _a <- sep1 commaSeparator aExpr-    space-    char ')'-    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)--commonTableExpr = label "common table expression" $ do-  _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 =-  True <$ keyword "materialized" <|>-  False <$ keyphrase "not materialized"--targeting = distinct <|> allWithTargetList <|> all <|> normal where-  normal = NormalTargeting <$> targetList-  allWithTargetList = do-    keyword "all"-    space1-    AllTargeting <$> Just <$> targetList-  all = keyword "all" $> AllTargeting Nothing-  distinct = do-    keyword "distinct"-    space1-    endHead-    _optOn <- optional (onExpressionsClause <* space1)-    _targetList <- targetList-    return (DistinctTargeting _optOn _targetList)--targetList = sep1 commaSeparator targetEl--{-|->>> testParser targetEl "a.b as c"-AliasedExprTargetEl (CExprAExpr (ColumnrefCExpr (Columnref (UnquotedIdent "a") (Just (AttrNameIndirectionEl (UnquotedIdent "b") :| []))))) (UnquotedIdent "c")--}-targetEl = label "target" $ asum [-    do-      _expr <- aExpr-      asum [-          do-            space1-            asum [-                AliasedExprTargetEl _expr <$> (keyword "as" *> space1 *> endHead *> colLabel)-                ,-                ImplicitlyAliasedExprTargetEl _expr <$> ident-              ]-          ,-          pure (ExprTargetEl _expr)-        ]-    ,-    AsteriskTargetEl <$ char '*'-  ]--onExpressionsClause = do-  keyword "on"-  space1-  endHead-  inParens (sep1 commaSeparator aExpr)----- * Into clause details----------------------------{--OptTempTableName:-  | TEMPORARY opt_table qualified_name-  | TEMP opt_table qualified_name-  | LOCAL TEMPORARY opt_table qualified_name-  | LOCAL TEMP opt_table qualified_name-  | GLOBAL TEMPORARY opt_table qualified_name-  | GLOBAL TEMP opt_table qualified_name-  | UNLOGGED opt_table qualified_name-  | TABLE qualified_name-  | qualified_name--}-optTempTableName = asum [-    do-      a <- asum [-          TemporaryOptTempTableName <$ keyword "temporary" <* space1,-          TempOptTempTableName <$ keyword "temp" <* space1,-          LocalTemporaryOptTempTableName <$ keyphrase "local temporary" <* space1,-          LocalTempOptTempTableName <$ keyphrase "local temp" <* space1,-          GlobalTemporaryOptTempTableName <$ keyphrase "global temporary" <* space1,-          GlobalTempOptTempTableName <$ keyphrase "global temp" <* space1,-          UnloggedOptTempTableName <$ keyword "unlogged" <* space1-        ]-      b <- option False (True <$ keyword "table" <* space1)-      c <- qualifiedName-      return (a b c)-    ,-    do-      keyword "table"-      space1-      endHead-      TableOptTempTableName <$> qualifiedName-    ,-    QualifedOptTempTableName <$> qualifiedName-  ]----- * Group by details----------------------------groupByItem = asum [-    EmptyGroupingSetGroupByItem <$ (char '(' *> space *> char ')'),-    RollupGroupByItem <$> (keyword "rollup" *> endHead *> space *> inParens (sep1 commaSeparator aExpr)),-    CubeGroupByItem <$> (keyword "cube" *> endHead *> space *> inParens (sep1 commaSeparator aExpr)),-    GroupingSetsGroupByItem <$> (keyphrase "grouping sets" *> endHead *> space *> inParens (sep1 commaSeparator groupByItem)),-    ExprGroupByItem <$> aExpr-  ]----- * Window clause details----------------------------windowDefinition = WindowDefinition <$> (colId <* space1 <* keyword "as" <* space1 <* endHead) <*> windowSpecification--{--window_specification:-  |  '(' opt_existing_window_name opt_partition_clause-            opt_sort_clause opt_frame_clause ')'--}-windowSpecification = inParens $ asum [-    do-      a <- frameClause-      return (WindowSpecification Nothing Nothing Nothing (Just a))-    ,-    do-      a <- sortClause-      b <- optional (space1 *> frameClause)-      return (WindowSpecification Nothing Nothing (Just a) b)-    ,-    do-      a <- partitionByClause-      b <- optional (space1 *> sortClause)-      c <- optional (space1 *> frameClause)-      return (WindowSpecification Nothing (Just a) b c)-    ,-    do-      a <- colId-      b <- optional (space1 *> partitionByClause)-      c <- optional (space1 *> sortClause)-      d <- optional (space1 *> frameClause)-      return (WindowSpecification (Just a) b c d)-    ,-    pure (WindowSpecification Nothing Nothing Nothing Nothing)-  ]--partitionByClause = keyphrase "partition by" *> space1 *> endHead *> sep1 commaSeparator aExpr--{--opt_frame_clause:-  |  RANGE frame_extent opt_window_exclusion_clause-  |  ROWS frame_extent opt_window_exclusion_clause-  |  GROUPS frame_extent opt_window_exclusion_clause-  |  EMPTY--}-frameClause = do-  a <- frameClauseMode <* space1 <* endHead-  b <- frameExtent-  c <- optional (space1 *> windowExclusionClause)-  return (FrameClause a b c)--frameClauseMode = asum [-    RangeFrameClauseMode <$ keyword "range",-    RowsFrameClauseMode <$ keyword "rows",-    GroupsFrameClauseMode <$ keyword "groups"-  ]--frameExtent =-  BetweenFrameExtent <$> (keyword "between" *> space1 *> endHead *> frameBound <* space1 <* keyword "and" <* space1) <*> frameBound <|>-  SingularFrameExtent <$> frameBound--{--  |  UNBOUNDED PRECEDING-  |  UNBOUNDED FOLLOWING-  |  CURRENT_P ROW-  |  a_expr PRECEDING-  |  a_expr FOLLOWING--}-frameBound =-  UnboundedPrecedingFrameBound <$ keyphrase "unbounded preceding" <|>-  UnboundedFollowingFrameBound <$ keyphrase "unbounded following" <|>-  CurrentRowFrameBound <$ keyphrase "current row" <|>-  do-    a <- aExpr-    space1-    PrecedingFrameBound a <$ keyword "preceding" <|> FollowingFrameBound a <$ keyword "following"--windowExclusionClause =-  CurrentRowWindowExclusionClause <$ keyphrase "exclude current row" <|>-  GroupWindowExclusionClause <$ keyphrase "exclude group" <|>-  TiesWindowExclusionClause <$ keyphrase "exclude ties" <|>-  NoOthersWindowExclusionClause <$ keyphrase "exclude no others"----- * Table refs----------------------------fromList = sep1 commaSeparator tableRef--fromClause = keyword "from" *> endHead *> space1 *> fromList--{-|->>> testParser tableRef "a left join b on (a.i = b.i)"-JoinTableRef (MethJoinedTable (QualJoinMeth...---}-tableRef =-  label "table reference" $ -  do-    _tr <- nonTrailingTableRef-    recur _tr-  where-    recur _tr =-      asum [-          do-            _tr2 <- wrapToHead (space1 *> trailingTableRef _tr)-            endHead-            recur _tr2-          ,-          pure _tr-        ]--nonTrailingTableRef = asum [-    lateralTableRef <|>-    wrapToHead nonLateralTableRef <|>-    relationExprTableRef <|>-    joinedTableWithAliasTableRef <|>-    inParensJoinedTableTableRef-  ]-  where-    -    {--    | relation_expr opt_alias_clause-    | relation_expr opt_alias_clause tablesample_clause-    -}-    relationExprTableRef = do-      _relationExpr <- relationExpr-      endHead-      _optAliasClause <- optional (space1 *> aliasClause)-      _optTablesampleClause <- optional (space1 *> tablesampleClause)-      return (RelationExprTableRef _relationExpr _optAliasClause _optTablesampleClause)--    {--    | LATERAL_P func_table func_alias_clause-    | LATERAL_P xmltable opt_alias_clause-    | LATERAL_P select_with_parens opt_alias_clause-    TODO: add xmltable-    -}-    lateralTableRef = do-      keyword "lateral"-      space1-      endHead-      lateralableTableRef True--    nonLateralTableRef = lateralableTableRef False--    lateralableTableRef _lateral = asum [-        do-          a <- funcTable-          b <- optional (space1 *> funcAliasClause)-          return (FuncTableRef _lateral a b)-        ,-        do-          _select <- selectWithParens-          _optAliasClause <- optional $ space1 *> aliasClause-          return (SelectTableRef _lateral _select _optAliasClause)-      ]--    inParensJoinedTableTableRef = JoinTableRef <$> inParensJoinedTable <*> pure Nothing--    joinedTableWithAliasTableRef = do-      _joinedTable <- wrapToHead (inParens joinedTable)-      space1-      _alias <- aliasClause-      return (JoinTableRef _joinedTable (Just _alias))--trailingTableRef _tableRef =-  JoinTableRef <$> trailingJoinedTable _tableRef <*> pure Nothing--relationExpr =-  label "relation expression" $-  asum-    [-      do-        keyword "only"-        space1-        _name <- qualifiedName-        return (OnlyRelationExpr _name False) -      ,-      inParensWithClause (keyword "only") qualifiedName <&> \ a -> OnlyRelationExpr a True-      ,-      do-        _name <- qualifiedName-        _asterisk <- asum-          [-            True <$ (space1 *> char '*'),-            pure False-          ]-        return (SimpleRelationExpr _name _asterisk)-    ]--relationExprOptAlias reservedKeywords = do-  a <- relationExpr-  b <- optional $ do-    space1-    b <- trueIfPresent (keyword "as" *> space1)-    c <- filteredColId reservedKeywords-    return (b, c)-  return (RelationExprOptAlias a b)--tablesampleClause = do-  keyword "tablesample"-  space1-  endHead-  a <- funcName-  space-  b <- inParens exprList-  c <- optional (space *> repeatableClause)-  return (TablesampleClause a b c)--repeatableClause = do-  keyword "repeatable"-  space-  inParens (endHead *> aExpr)--funcTable = asum [-    do-      keyword "rows"-      space1-      keyword "from"-      space-      a <- inParens (endHead *> rowsfromList)-      b <- trueIfPresent (space *> optOrdinality)-      return (RowsFromFuncTable a b)-    ,-    do-      a <- funcExprWindowless-      b <- trueIfPresent (space1 *> optOrdinality)-      return (FuncExprFuncTable a b)-  ]--rowsfromItem = do-  a <- funcExprWindowless-  endHead-  b <- optional (space1 *> colDefList)-  return (RowsfromItem a b)--rowsfromList = sep1 commaSeparator rowsfromItem--colDefList = keyword "as" *> space *> inParens (endHead *> tableFuncElementList)--optOrdinality = keyword "with" *> space1 *> keyword "ordinality"--tableFuncElementList = sep1 commaSeparator tableFuncElement--tableFuncElement = do-  a <- wrapToHead colId-  space1-  b <- typename-  c <- optional (space1 *> collateClause)-  return (TableFuncElement a b c)--collateClause = keyword "collate" *> space1 *> endHead *> anyName--funcAliasClause = asum [-    do-      keyword "as"-      asum [-          do-            space-            inParens $ do-              endHead-              AsFuncAliasClause <$> tableFuncElementList-          ,-          do-            space1-            a <- colId-            asum [-                do-                  space-                  inParens $ do-                    endHead-                    asum [-                        AsColIdFuncAliasClause a <$> wrapToHead tableFuncElementList,-                        AliasFuncAliasClause <$> AliasClause True a <$> Just <$> nameList-                      ]-                ,-                pure (AliasFuncAliasClause (AliasClause True a Nothing))-              ]-        ]-    ,-    do-      a <- colId-      asum [-          do-            space-            inParens $ do-              endHead-              asum [-                  ColIdFuncAliasClause a <$> wrapToHead tableFuncElementList,-                  AliasFuncAliasClause <$> AliasClause False a <$> Just <$> nameList-                ]-          ,-          pure (AliasFuncAliasClause (AliasClause False a Nothing))-        ]-  ]--joinedTable =-  head >>= tail-  where-    head =-      asum [-          do-            _tr <- wrapToHead nonTrailingTableRef-            space1-            trailingJoinedTable _tr-          ,-          inParensJoinedTable-        ]-    tail _jt =-      asum [-          do-            _jt2 <- wrapToHead (space1 *> trailingJoinedTable (JoinTableRef _jt Nothing))-            endHead-            tail _jt2-          ,-          pure _jt-        ]--{--  | '(' joined_table ')'--}-inParensJoinedTable = InParensJoinedTable <$> inParens joinedTable--{--  | table_ref CROSS JOIN table_ref-  | table_ref join_type JOIN table_ref join_qual-  | table_ref JOIN table_ref join_qual-  | table_ref NATURAL join_type JOIN table_ref-  | table_ref NATURAL JOIN table_ref--}-trailingJoinedTable _tr1 = asum [-    do-      keyphrase "cross join"-      endHead-      space1-      _tr2 <- nonTrailingTableRef-      return (MethJoinedTable CrossJoinMeth _tr1 _tr2)-    ,-    do-      _jt <- joinTypedJoin-      endHead-      space1-      _tr2 <- tableRef-      space1-      _jq <- joinQual-      return (MethJoinedTable (QualJoinMeth _jt _jq) _tr1 _tr2)-    ,-    do-      keyword "natural"-      endHead-      space1-      _jt <- joinTypedJoin-      space1-      _tr2 <- nonTrailingTableRef-      return (MethJoinedTable (NaturalJoinMeth _jt) _tr1 _tr2)-  ]-  where-    joinTypedJoin =-      Just <$> (joinType <* endHead <* space1 <* keyword "join") <|>-      Nothing <$ keyword "join"--joinType = asum [-    do-      keyword "full"-      endHead-      _outer <- outerAfterSpace-      return (FullJoinType _outer)-    ,-    do-      keyword "left"-      endHead-      _outer <- outerAfterSpace-      return (LeftJoinType _outer)-    ,-    do-      keyword "right"-      endHead-      _outer <- outerAfterSpace-      return (RightJoinType _outer)-    ,-    keyword "inner" $> InnerJoinType-  ]-  where-    outerAfterSpace = (space1 *> keyword "outer") $> True <|> pure False--joinQual = asum [-    keyword "using" *> space1 *> inParens (sep1 commaSeparator colId) <&> UsingJoinQual-    ,-    keyword "on" *> space1 *> aExpr <&> OnJoinQual-  ]--aliasClause = do-  (_as, _alias) <- (True,) <$> (keyword "as" *> space1 *> endHead *> colId) <|> (False,) <$> colId-  _columnAliases <- optional (space1 *> inParens (sep1 commaSeparator colId))-  return (AliasClause _as _alias _columnAliases)----- * Where----------------------------whereClause = keyword "where" *> space1 *> endHead *> aExpr--whereOrCurrentClause = do-  keyword "where"-  space1-  endHead-  asum [-      do-        keyword "current"-        space1-        keyword "of"-        space1-        endHead-        a <- cursorName-        return (CursorWhereOrCurrentClause a)-      ,-      ExprWhereOrCurrentClause <$> aExpr-    ]----- * Sorting----------------------------sortClause = do-  keyphrase "order by"-  endHead-  space1-  a <- sep1 commaSeparator sortBy-  return a--sortBy = do-  a <- filteredAExpr ["using", "asc", "desc", "nulls"]-  asum [-      do-        space1-        keyword "using"-        space1-        endHead-        b <- qualAllOp-        c <- optional (space1 *> nullsOrder)-        return (UsingSortBy a b c)-      ,-      do-        b <- optional (space1 *> ascDesc)-        c <- optional (space1 *> nullsOrder)-        return (AscDescSortBy a b c)-    ]----- * Expressions----------------------------exprList = sep1 commaSeparator aExpr--exprListInParens = inParens exprList--{-|-Notice that the tree constructed by this parser does not reflect-the precedence order of Postgres.-For the purposes of this library it simply doesn't matter,-so we're not bothering with that.--Composite on the right:->>> testParser aExpr "a = b :: int4"-SymbolicBinOpAExpr (CExprAExpr (ColumnrefCExpr (Columnref (UnquotedIdent "a") Nothing))) (MathSymbolicExprBinOp EqualsMathOp) (TypecastAExpr (CExprAExpr (ColumnrefCExpr (Columnref (UnquotedIdent "b") Nothing))) (Typename False (GenericTypeSimpleTypename (GenericType (UnquotedIdent "int4") Nothing Nothing)) False Nothing))--Composite on the left:->>> testParser aExpr "a = b :: int4 and c"-SymbolicBinOpAExpr (CExprAExpr (ColumnrefCExpr (Columnref (UnquotedIdent "a") Nothing))) (MathSymbolicExprBinOp EqualsMathOp) (AndAExpr (TypecastAExpr (CExprAExpr (ColumnrefCExpr (Columnref (UnquotedIdent "b") Nothing))) (Typename False (GenericTypeSimpleTypename (GenericType (UnquotedIdent "int4") Nothing Nothing)) False Nothing)) (CExprAExpr (ColumnrefCExpr (Columnref (UnquotedIdent "c") Nothing))))--}-aExpr = customizedAExpr cExpr--filteredAExpr = customizedAExpr . customizedCExpr . filteredColumnref--customizedAExpr cExpr = suffixRec base suffix where-  aExpr = customizedAExpr cExpr-  base = asum [-      DefaultAExpr <$ keyword "default",-      UniqueAExpr <$> (keyword "unique" *> space1 *> selectWithParens),-      OverlapsAExpr <$> wrapToHead row <*> (space1 *> keyword "overlaps" *> space1 *> endHead *> row),-      qualOpExpr aExpr PrefixQualOpAExpr,-      PlusAExpr <$> plusedExpr aExpr,-      MinusAExpr <$> minusedExpr aExpr,-      NotAExpr <$> (keyword "not" *> space1 *> aExpr),-      CExprAExpr <$> cExpr-    ]-  suffix a = asum [-      do-        space1-        b <- wrapToHead subqueryOp-        space1-        c <- wrapToHead subType-        space-        d <- Left <$> wrapToHead selectWithParens <|> Right <$> inParens aExpr-        return (SubqueryAExpr a b c d)-      ,-      typecastExpr a TypecastAExpr-      ,-      CollateAExpr a <$> (space1 *> keyword "collate" *> space1 *> endHead *> anyName)-      ,-      AtTimeZoneAExpr a <$> (space1 *> keyphrase "at time zone" *> space1 *> endHead *> aExpr)-      ,-      symbolicBinOpExpr a aExpr SymbolicBinOpAExpr-      ,-      SuffixQualOpAExpr a <$> (space *> qualOp)-      ,-      AndAExpr a <$> (space1 *> keyword "and" *> space1 *> endHead *> aExpr)-      ,-      OrAExpr a <$> (space1 *> keyword "or" *> space1 *> endHead *> aExpr)-      ,-      do-        space1-        b <- trueIfPresent (keyword "not" *> space1)-        c <- asum [-            LikeVerbalExprBinOp <$ keyword "like",-            IlikeVerbalExprBinOp <$ keyword "ilike",-            SimilarToVerbalExprBinOp <$ keyphrase "similar to"-          ]-        space1-        endHead-        d <- aExpr-        e <- optional (space1 *> keyword "escape" *> space1 *> endHead *> aExpr)-        return (VerbalExprBinOpAExpr a b c d e)-      ,-      do-        space1-        keyword "is"-        space1-        endHead-        b <- trueIfPresent (keyword "not" *> space1)-        c <- asum [-            NullAExprReversableOp <$ keyword "null",-            TrueAExprReversableOp <$ keyword "true",-            FalseAExprReversableOp <$ keyword "false",-            UnknownAExprReversableOp <$ keyword "unknown",-            DistinctFromAExprReversableOp <$> (keyword "distinct" *> space1 *> keyword "from" *> space1 *> endHead *> aExpr),-            OfAExprReversableOp <$> (keyword "of" *> space1 *> endHead *> inParens typeList),-            DocumentAExprReversableOp <$ keyword "document"-          ]-        return (ReversableOpAExpr a b c)-      ,-      do-        space1-        b <- trueIfPresent (keyword "not" *> space1)-        keyword "between"-        space1-        endHead-        c <- asum [-            BetweenSymmetricAExprReversableOp <$ (keyword "symmetric" *> space1),-            BetweenAExprReversableOp True <$ (keyword "asymmetric" *> space1),-            pure (BetweenAExprReversableOp False)-          ]-        d <- bExpr-        space1-        keyword "and"-        space1-        e <- aExpr-        return (ReversableOpAExpr a b (c d e))-      ,-      do-        space1-        b <- trueIfPresent (keyword "not" *> space1)-        keyword "in"-        space-        c <- InAExprReversableOp <$> inExpr-        return (ReversableOpAExpr a b c)-      ,-      IsnullAExpr a <$ (space1 *> keyword "isnull")-      ,-      NotnullAExpr a <$ (space1 *> keyword "notnull")-    ]--bExpr = customizedBExpr cExpr--customizedBExpr cExpr = suffixRec base suffix where-  aExpr = customizedAExpr cExpr-  bExpr = customizedBExpr cExpr-  base = asum [-      qualOpExpr bExpr QualOpBExpr,-      PlusBExpr <$> plusedExpr bExpr,-      MinusBExpr <$> minusedExpr bExpr,-      CExprBExpr <$> cExpr-    ]-  suffix a = asum [-      typecastExpr a TypecastBExpr,-      symbolicBinOpExpr a bExpr SymbolicBinOpBExpr,-      do-        space1-        keyword "is"-        space1-        endHead-        b <- trueIfPresent (keyword "not" *> space1)-        c <- asum [-            DistinctFromBExprIsOp <$> (keyphrase "distinct from" *> space1 *> endHead *> bExpr),-            OfBExprIsOp <$> (keyword "of" *> space1 *> endHead *> inParens typeList),-            DocumentBExprIsOp <$ keyword "document"-          ]-        return (IsOpBExpr a b c)-    ]--cExpr = customizedCExpr columnref--customizedCExpr columnref = asum [-    ParamCExpr <$> (char '$' *> decimal <* endHead) <*> optional (space *> indirection)-    ,-    CaseCExpr <$> caseExpr-    ,-    ImplicitRowCExpr <$> implicitRow-    ,-    ExplicitRowCExpr <$> explicitRow-    ,-    inParensWithClause (keyword "grouping") (GroupingCExpr <$> sep1 commaSeparator aExpr)-    ,-    keyword "exists" *> space *> (ExistsCExpr <$> selectWithParens)-    ,-    do-      keyword "array"-      space-      join $ asum [-          fmap (fmap (ArrayCExpr . Right)) arrayExprCont,-          fmap (fmap (ArrayCExpr . Left) . pure) selectWithParens-        ]-    ,-    do-      a <- wrapToHead selectWithParens-      endHead-      b <- optional (space *> indirection)-      return (SelectWithParensCExpr a b)-    ,-    InParensCExpr <$> (inParens aExpr <* endHead) <*> optional (space *> indirection)-    ,-    AexprConstCExpr <$> wrapToHead aexprConst-    ,-    FuncCExpr <$> funcExpr-    ,-    ColumnrefCExpr <$> columnref-  ]----- *----------------------------subqueryOp = asum [-    AnySubqueryOp <$> (keyword "operator" *> space *> endHead *> inParens anyOperator)-    ,-    do-      a <- trueIfPresent (keyword "not" *> space1)-      LikeSubqueryOp a <$ keyword "like" <|> IlikeSubqueryOp a <$ keyword "ilike"-    ,-    AllSubqueryOp <$> allOp-  ]--subType = asum [-    AnySubType <$ keyword "any",-    SomeSubType <$ keyword "some",-    AllSubType <$ keyword "all"-  ]--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)--typecastExpr :: a -> (a -> Typename -> a) -> HeadedParsec Void Text a-typecastExpr _prefix _constr = do-  space-  string "::"-  endHead-  space-  _type <- typename-  return (_constr _prefix _type)--plusedExpr expr = char '+' *> space *> expr--minusedExpr expr = char '-' *> space *> expr--qualOpExpr expr constr = constr <$> wrapToHead qualOp <*> (space *> expr)--row = ExplicitRowRow <$> explicitRow <|> ImplicitRowRow <$> implicitRow--explicitRow = keyword "row" *> space *> inParens (optional exprList)--implicitRow = inParens $ do-  a <- wrapToHead aExpr-  commaSeparator-  b <- exprList-  return $ case NonEmpty.consAndUnsnoc a b of-    (c, d) -> ImplicitRow c d--arrayExprCont = inBracketsCont $ asum [-    ArrayExprListArrayExpr <$> sep1 commaSeparator (join arrayExprCont),-    ExprListArrayExpr <$> exprList,-    pure EmptyArrayExpr-  ]--caseExpr = label "case expression" $ do-  keyword "case"-  space1-  endHead-  _arg <- optional (aExpr <* space1)-  _whenClauses <- sep1 space1 whenClause-  space1-  _default <- optional elseClause-  keyword "end"-  pure $ CaseExpr _arg _whenClauses _default--whenClause = do-  keyword "when"-  space1-  endHead-  _a <- aExpr-  space1-  keyword "then"-  space1-  _b <- aExpr-  return (WhenClause _a _b)--elseClause = do-  keyword "else"-  space1-  endHead-  a <- aExpr-  space1-  return a--funcExpr = asum [-    SubexprFuncExpr <$> funcExprCommonSubexpr,-    do-      a <- funcApplication-      endHead-      b <- optional (space1 *> withinGroupClause)-      c <- optional (space1 *> filterClause)-      d <- optional (space1 *> overClause)-      return (ApplicationFuncExpr a b c d)-  ]--funcExprWindowless = asum [-    CommonSubexprFuncExprWindowless <$> funcExprCommonSubexpr,-    ApplicationFuncExprWindowless <$> funcApplication-  ]--withinGroupClause = do-  keyphrase "within group"-  endHead-  space-  inParens sortClause--filterClause = do-  keyword "filter"-  endHead-  space-  inParens (keyword "where" *> space1 *> aExpr)--overClause = do-  keyword "over"-  space1-  endHead-  asum [-      WindowOverClause <$> windowSpecification,-      ColIdOverClause <$> colId-    ]--funcExprCommonSubexpr = asum [-    CollationForFuncExprCommonSubexpr <$> (inParensWithClause (keyphrase "collation for") aExpr)-    ,-    CurrentDateFuncExprCommonSubexpr <$ keyword "current_date"-    ,-    CurrentTimestampFuncExprCommonSubexpr <$> labeledIconst "current_timestamp"-    ,-    CurrentTimeFuncExprCommonSubexpr <$> labeledIconst "current_time"-    ,-    LocalTimestampFuncExprCommonSubexpr <$> labeledIconst "localtimestamp"-    ,-    LocalTimeFuncExprCommonSubexpr <$> labeledIconst "localtime"-    ,-    CurrentRoleFuncExprCommonSubexpr <$ keyword "current_role"-    ,-    CurrentUserFuncExprCommonSubexpr <$ keyword "current_user"-    ,-    SessionUserFuncExprCommonSubexpr <$ keyword "session_user"-    ,-    UserFuncExprCommonSubexpr <$ keyword "user"-    ,-    CurrentCatalogFuncExprCommonSubexpr <$ keyword "current_catalog"-    ,-    CurrentSchemaFuncExprCommonSubexpr <$ keyword "current_schema"-    ,-    inParensWithClause (keyword "cast") (CastFuncExprCommonSubexpr <$> aExpr <*> (space1 *> keyword "as" *> space1 *> typename))-    ,-    inParensWithClause (keyword "extract") (ExtractFuncExprCommonSubexpr <$> optional extractList)-    ,-    inParensWithClause (keyword "overlay") (OverlayFuncExprCommonSubexpr <$> overlayList)-    ,-    inParensWithClause (keyword "position") (PositionFuncExprCommonSubexpr <$> optional positionList)-    ,-    inParensWithClause (keyword "substring") (SubstringFuncExprCommonSubexpr <$> optional substrList)-    ,-    inParensWithClause (keyword "treat") (TreatFuncExprCommonSubexpr <$> aExpr <*> (space1 *> keyword "as" *> space1 *> typename))-    ,-    inParensWithClause (keyword "trim") (TrimFuncExprCommonSubexpr <$> optional (trimModifier <* space1) <*> trimList)-    ,-    inParensWithClause (keyword "nullif") (NullIfFuncExprCommonSubexpr <$> aExpr <*> (commaSeparator *> aExpr))-    ,-    inParensWithClause (keyword "coalesce") (CoalesceFuncExprCommonSubexpr <$> exprList)-    ,-    inParensWithClause (keyword "greatest") (GreatestFuncExprCommonSubexpr <$> exprList)-    ,-    inParensWithClause (keyword "least") (LeastFuncExprCommonSubexpr <$> exprList)-  ]-  where-    labeledIconst _label = keyword _label *> endHead *> optional (space *> inParens iconst)--extractList = ExtractList <$> extractArg <*> (space1 *> keyword "from" *> space1 *> aExpr)--extractArg = asum [-    YearExtractArg <$ keyword "year",-    MonthExtractArg <$ keyword "month",-    DayExtractArg <$ keyword "day",-    HourExtractArg <$ keyword "hour",-    MinuteExtractArg <$ keyword "minute",-    SecondExtractArg <$ keyword "second",-    SconstExtractArg <$> sconst,-    IdentExtractArg <$> ident-  ]--overlayList = do-  a <- aExpr-  space1-  b <- overlayPlacing-  space1-  c <- substrFrom-  d <- optional (space1 *> substrFor)-  return (OverlayList a b c d)--overlayPlacing = keyword "placing" *> space1 *> endHead *> aExpr--positionList = PositionList <$> bExpr <*> (space1 *> keyword "in" *> space1 *> bExpr)--substrList = asum [-    ExprSubstrList <$> wrapToHead aExpr <*> (space1 *> substrListFromFor),-    ExprListSubstrList <$> exprList-  ]--substrListFromFor = asum [-    do-      a <- substrFrom-      asum [-          do-            b <- space1 *> substrFor-            return (FromForSubstrListFromFor a b)-          ,-          return (FromSubstrListFromFor a)-        ]-    ,-    do-      a <- substrFor-      asum [-          do-            b <- space1 *> substrFrom-            return (ForFromSubstrListFromFor a b)-          ,-          return (ForSubstrListFromFor a)-        ]-  ]--substrFrom = keyword "from" *> space1 *> endHead *> aExpr--substrFor = keyword "for" *> space1 *> endHead *> aExpr--trimModifier =-  BothTrimModifier <$ keyword "both" <|>-  LeadingTrimModifier <$ keyword "leading" <|>-  TrailingTrimModifier <$ keyword "trailing"--trimList = asum [-    ExprFromExprListTrimList <$> wrapToHead aExpr <*> (space1 *> keyword "from" *> space1 *> endHead *> exprList)-    ,-    FromExprListTrimList <$> (keyword "from" *> space1 *> endHead *> exprList)-    ,-    ExprListTrimList <$> exprList-  ]--funcApplication = inParensWithLabel FuncApplication funcName (optional funcApplicationParams)--funcApplicationParams =-  asum-    [-      starFuncApplicationParams,-      listVariadicFuncApplicationParams,-      singleVariadicFuncApplicationParams,-      normalFuncApplicationParams-    ]--normalFuncApplicationParams = do-  _optAllOrDistinct <- optional (allOrDistinct <* space1)-  _argList <- sep1 commaSeparator funcArgExpr-  endHead-  _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)--listVariadicFuncApplicationParams = do-  (_argList, _) <- wrapToHead $ sepEnd1 commaSeparator (keyword "variadic" <* space1) funcArgExpr-  endHead-  _arg <- funcArgExpr-  _optSortClause <- optional (space1 *> sortClause)-  return (VariadicFuncApplicationParams (Just _argList) _arg _optSortClause)--starFuncApplicationParams = space *> char '*' *> endHead *> space $> StarFuncApplicationParams--{--func_arg_expr:-  | a_expr-  | param_name COLON_EQUALS a_expr-  | param_name EQUALS_GREATER a_expr-param_name:-  | type_function_name--}-funcArgExpr = asum [-    do-      a <- wrapToHead typeFunctionName-      space-      asum [-          do-            string ":="-            endHead-            b <- space *> aExpr-            return (ColonEqualsFuncArgExpr a b)-          ,-          do-            string "=>"-            endHead-            b <- space *> aExpr-            return (EqualsGreaterFuncArgExpr a b)-        ]-    ,-    ExprFuncArgExpr <$> aExpr-  ]----- * Ops----------------------------symbolicExprBinOp =-  QualSymbolicExprBinOp <$> qualOp <|>-  MathSymbolicExprBinOp <$> mathOp--lexicalExprBinOp = asum $ fmap keyphrase $ ["and", "or", "is distinct from", "is not distinct from"]--qualOp = asum [-    OpQualOp <$> op,-    OperatorQualOp <$> inParensWithClause (keyword "operator") anyOperator-  ]--qualAllOp = asum [-    AnyQualAllOp <$> (keyword "operator" *> space *> inParens (endHead *> anyOperator)),-    AllQualAllOp <$> allOp-  ]--op = do-  a <- takeWhile1P Nothing Predicate.opChar-  case Validation.op a of-    Nothing -> return a-    Just err -> fail (Text.unpack err)--anyOperator = asum [-    AllOpAnyOperator <$> allOp,-    QualifiedAnyOperator <$> colId <*> (space *> char '.' *> space *> anyOperator)-  ]--allOp = asum [-    OpAllOp <$> op,-    MathAllOp <$> mathOp-  ]--mathOp = asum [-    ArrowLeftArrowRightMathOp <$ string' "<>",-    GreaterEqualsMathOp <$ string' ">=",-    ExclamationEqualsMathOp <$ string' "!=",-    LessEqualsMathOp <$ string' "<=",-    PlusMathOp <$ char '+',-    MinusMathOp <$ char '-',-    AsteriskMathOp <$ char '*',-    SlashMathOp <$ char '/',-    PercentMathOp <$ char '%',-    ArrowUpMathOp <$ char '^',-    ArrowLeftMathOp <$ char '<',-    ArrowRightMathOp <$ char '>',-    EqualsMathOp <$ char '='-  ]----- * Constants----------------------------{-|->>> testParser aexprConst "32948023849023"-IAexprConst 32948023849023-->>> testParser aexprConst "'abc''de'"-SAexprConst "abc'de"-->>> testParser aexprConst "23.43234"-FAexprConst 23.43234-->>> testParser aexprConst "32423423.324324872"-FAexprConst 3.2423423324324872e7-->>> testParser aexprConst "NULL"-NullAexprConst--}-{--AexprConst: Iconst-      | FCONST-      | Sconst-      | BCONST-      | XCONST-      | func_name Sconst-      | func_name '(' func_arg_list opt_sort_clause ')' Sconst-      | ConstTypename Sconst-      | ConstInterval Sconst opt_interval-      | ConstInterval '(' Iconst ')' Sconst-      | TRUE_P-      | FALSE_P-      | NULL_P--}-aexprConst = asum [-    do-      keyword "interval"-      space1-      endHead-      a <- asum [-          do-            a <- sconst-            endHead-            b <- optional (space1 *> interval)-            return (StringIntervalAexprConst a b)-          ,-          do-            a <- inParens iconst-            space1-            endHead-            b <- sconst-            return (IntIntervalAexprConst a b)-        ]-      return a-    ,-    do-      a <- constTypename-      space1-      endHead-      b <- sconst-      return (ConstTypenameAexprConst a b)-    ,-    BoolAexprConst True <$ keyword "true"-    ,-    BoolAexprConst False <$ keyword "false"-    ,-    NullAexprConst <$ keyword "null" <* parse (Megaparsec.notFollowedBy MegaparsecChar.alphaNumChar)-    ,-    either IAexprConst FAexprConst <$> iconstOrFconst-    ,-    SAexprConst <$> sconst-    ,-    label "bit literal" $ do-      string' "b'"-      endHead-      a <- takeWhile1P (Just "0 or 1") (\ b -> b == '0' || b == '1')-      char '\''-      return (BAexprConst a)-    ,-    label "hex literal" $ do-      string' "x'"-      endHead-      a <- takeWhile1P (Just "Hex digit") Predicate.hexDigit-      char '\''-      return (XAexprConst a)-    ,-    wrapToHead $ do-      a <- funcName-      space-      char '('-      space-      b <- sep1 commaSeparator funcArgExpr-      c <- optional (space1 *> sortClause)-      space-      char ')'-      space1-      d <- sconst-      return (FuncAexprConst a (Just (FuncConstArgs b c)) d)-    ,-    FuncAexprConst <$> (wrapToHead funcName <* space1) <*> pure Nothing <*> sconst-  ]--iconstOrFconst = Right <$> fconst <|> Left <$> iconst--iconst = decimal--fconst = float--sconst = quotedString '\''--constTypename = asum [-    NumericConstTypename <$> numeric,-    ConstBitConstTypename <$> constBit,-    ConstCharacterConstTypename <$> constCharacter,-    ConstDatetimeConstTypename <$> constDatetime-  ]--numeric = asum [-    IntegerNumeric <$ keyword "integer",-    IntNumeric <$ keyword "int",-    SmallintNumeric <$ keyword "smallint",-    BigintNumeric <$ keyword "bigint",-    RealNumeric <$ keyword "real",-    FloatNumeric <$> (keyword "float" *> endHead *> optional (space *> inParens iconst)),-    DoublePrecisionNumeric <$ keyphrase "double precision",-    DecimalNumeric <$> (keyword "decimal" *> endHead *> optional (space *> exprListInParens)),-    DecNumeric <$> (keyword "dec" *> endHead *> optional (space *> exprListInParens)),-    NumericNumeric <$> (keyword "numeric" *> endHead *> optional (space *> exprListInParens)),-    BooleanNumeric <$ keyword "boolean"-  ]--bit = do-  keyword "bit"-  a <- option False (True <$ space1 <* keyword "varying")-  b <- optional (space1 *> exprListInParens)-  return (Bit a b)--constBit = bit--constCharacter = ConstCharacter <$> (character <* endHead) <*> optional (space *> inParens iconst)--character = asum [-    CharacterCharacter <$> (keyword "character" *> optVaryingAfterSpace),-    CharCharacter <$> (keyword "char" *> optVaryingAfterSpace),-    VarcharCharacter <$ keyword "varchar",-    NationalCharacterCharacter <$> (keyphrase "national character" *> optVaryingAfterSpace),-    NationalCharCharacter <$> (keyphrase "national char" *> optVaryingAfterSpace),-    NcharCharacter <$> (keyword "nchar" *> optVaryingAfterSpace)-  ]-  where-    optVaryingAfterSpace = True <$ space1 <* keyword "varying" <|> pure False--{--ConstDatetime:-  | TIMESTAMP '(' Iconst ')' opt_timezone-  | TIMESTAMP opt_timezone-  | TIME '(' Iconst ')' opt_timezone-  | TIME opt_timezone--}-constDatetime = asum [-    do-      keyword "timestamp"-      a <- optional (space1 *> inParens iconst)-      b <- optional (space1 *> timezone)-      return (TimestampConstDatetime a b)-    ,-    do-      keyword "time"-      a <- optional (space1 *> inParens iconst)-      b <- optional (space1 *> timezone)-      return (TimeConstDatetime a b)-  ]--timezone = asum [-    False <$ keyphrase "with time zone",-    True <$ keyphrase "without time zone"-  ]--interval = asum [-    YearToMonthInterval <$ keyphrase "year to month",-    DayToHourInterval <$ keyphrase "day to hour",-    DayToMinuteInterval <$ keyphrase "day to minute",-    DayToSecondInterval <$> (keyphrase "day to" *> space1 *> endHead *> intervalSecond),-    HourToMinuteInterval <$ keyphrase "hour to minute",-    HourToSecondInterval <$> (keyphrase "hour to" *> space1 *> endHead *> intervalSecond),-    MinuteToSecondInterval <$> (keyphrase "minute to" *> space1 *> endHead *> intervalSecond),-    YearInterval <$ keyword "year",-    MonthInterval <$ keyword "month",-    DayInterval <$ keyword "day",-    HourInterval <$ keyword "hour",-    MinuteInterval <$ keyword "minute",-    SecondInterval <$> intervalSecond-  ]--intervalSecond = do-  keyword "second"-  a <- optional (space *> inParens iconst)-  return a----- * Clauses----------------------------{--select_limit:-  | limit_clause offset_clause-  | offset_clause limit_clause-  | limit_clause-  | offset_clause--}-selectLimit =-  asum-    [-      do-        _a <- limitClause-        LimitOffsetSelectLimit _a <$> (space1 *> offsetClause) <|> pure (LimitSelectLimit _a)-      ,-      do-        _a <- offsetClause-        OffsetLimitSelectLimit _a <$> (space1 *> limitClause) <|> pure (OffsetSelectLimit _a)-    ]--{--limit_clause:-  | LIMIT select_limit_value-  | LIMIT select_limit_value ',' select_offset_value-  | FETCH first_or_next select_fetch_first_value row_or_rows ONLY-  | FETCH first_or_next row_or_rows ONLY--}-limitClause =-  (do-    keyword "limit"-    endHead-    space1-    _a <- selectLimitValue-    _b <- optional $ do-      commaSeparator-      aExpr-    return (LimitLimitClause _a _b)-  ) <|>-  (do-    keyword "fetch"-    endHead-    space1-    _a <- firstOrNext-    space1-    asum [-        do-          _b <- rowOrRows-          space1-          keyword "only"-          return (FetchOnlyLimitClause _a Nothing _b)-        ,-        do-          _b <- selectFetchFirstValue-          space1-          _c <- rowOrRows-          space1-          keyword "only"-          return (FetchOnlyLimitClause _a (Just _b) _c)-      ]-  )--offsetClause = do-  keyword "offset"-  endHead-  space1-  offsetClauseParams--offsetClauseParams =-  FetchFirstOffsetClause <$> wrapToHead selectFetchFirstValue <*> (space1 *> rowOrRows) <|>-  ExprOffsetClause <$> aExpr--{--select_limit_value:-  | a_expr-  | ALL--}-selectLimitValue =-  AllSelectLimitValue <$ keyword "all" <|>-  ExprSelectLimitValue <$> aExpr--rowOrRows =-  True <$ keyword "rows" <|>-  False <$ keyword "row"--firstOrNext =-  False <$ keyword "first" <|>-  True <$ keyword "next"--selectFetchFirstValue =-  ExprSelectFetchFirstValue <$> cExpr <|>-  NumSelectFetchFirstValue <$> (plusOrMinus <* endHead <* space) <*> iconstOrFconst--plusOrMinus = False <$ char '+' <|> True <$ char '-'----- * For Locking----------------------------{--for_locking_clause:-  | for_locking_items-  | FOR READ ONLY-for_locking_items:-  | for_locking_item-  | for_locking_items for_locking_item--}-forLockingClause = readOnly <|> items where-  readOnly = ReadOnlyForLockingClause <$ keyphrase "for read only"-  items = ItemsForLockingClause <$> sep1 space1 forLockingItem--{--for_locking_item:-  | for_locking_strength locked_rels_list opt_nowait_or_skip-locked_rels_list:-  | OF qualified_name_list-  | EMPTY-opt_nowait_or_skip:-  | NOWAIT-  | SKIP LOCKED-  | EMPTY--}-forLockingItem = do-  _strength <- forLockingStrength-  _rels <- optional $ space1 *> keyword "of" *> space1 *> endHead *> sep1 commaSeparator qualifiedName-  _nowaitOrSkip <- optional (space1 *> nowaitOrSkip)-  return (ForLockingItem _strength _rels _nowaitOrSkip)--{--for_locking_strength:-  | FOR UPDATE-  | FOR NO KEY UPDATE-  | FOR SHARE-  | FOR KEY SHARE--}-forLockingStrength =-  UpdateForLockingStrength <$ keyphrase "for update" <|>-  NoKeyUpdateForLockingStrength <$ keyphrase "for no key update" <|>-  ShareForLockingStrength <$ keyphrase "for share" <|>-  KeyForLockingStrength <$ keyphrase "for key share"--nowaitOrSkip = False <$ keyword "nowait" <|> True <$ keyphrase "skip locked"----- * References & Names----------------------------quotedName = filter (const "Empty name") (not . Text.null) (quotedString '"') & fmap QuotedIdent--{--ident_start   [A-Za-z\200-\377_]-ident_cont    [A-Za-z\200-\377_0-9\$]-identifier    {ident_start}{ident_cont}*--}-ident = quotedName <|> keywordNameByPredicate (not . Predicate.keyword)--{--ColId:-  |  IDENT-  |  unreserved_keyword-  |  col_name_keyword--}-{-# NOINLINE colId #-}-colId = 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)--{--ColLabel:-  |  IDENT-  |  unreserved_keyword-  |  col_name_keyword-  |  type_func_name_keyword-  |  reserved_keyword--}-colLabel = label "column label" $-  keywordNameFromSet KeywordSet.keyword <|> ident--{-|->>> testParser qualifiedName "a.b"-IndirectedQualifiedName (UnquotedIdent "a") (AttrNameIndirectionEl (UnquotedIdent "b") :| [])-->>> testParser qualifiedName "a.-"-...-expecting '*', column label, or white space--}-{--qualified_name:-  | ColId-  | ColId indirection--}-qualifiedName =-  IndirectedQualifiedName <$> wrapToHead colId <*> (space *> indirection) <|>-  SimpleQualifiedName <$> colId--columnref = customizedColumnref colId--filteredColumnref _keywords = customizedColumnref (filteredColId _keywords)--customizedColumnref colId = do-  a <- wrapToHead colId-  endHead-  b <- optional (space *> indirection)-  return (Columnref a b)--anyName = customizedAnyName colId--filteredAnyName _keywords = customizedAnyName (filteredColId _keywords)--customizedAnyName colId = do-  a <- wrapToHead colId-  endHead-  b <- optional (space *> attrs)-  return (AnyName a b)--name = colId--nameList = sep1 commaSeparator name--cursorName = name--{--func_name:-  | type_function_name-  | ColId indirection--}-funcName =-  IndirectedFuncName <$> wrapToHead colId <*> (space *> indirection) <|>-  TypeFuncName <$> typeFunctionName--{--type_function_name:-  | IDENT-  | unreserved_keyword-  | type_func_name_keyword--}-typeFunctionName =-  keywordNameFromSet KeywordSet.typeFunctionName <|>-  ident--{--indirection:-  | indirection_el-  | indirection indirection_el--}-indirection = some indirectionEl--{--indirection_el:-  | '.' attr_name-  | '.' '*'-  | '[' a_expr ']'-  | '[' opt_slice_bound ':' opt_slice_bound ']'-opt_slice_bound:-  | a_expr-  | EMPTY--}-indirectionEl =-  asum-    [-      do-        char '.'-        endHead-        space-        AllIndirectionEl <$ char '*' <|> AttrNameIndirectionEl <$> attrName-      ,-      do-        char '['-        endHead-        space-        _a <- asum [-            do-              char ':'-              endHead-              space-              _b <- optional aExpr-              return (SliceIndirectionEl Nothing _b)-            ,-            do-              _a <- aExpr-              asum [-                  do-                    space-                    char ':'-                    space-                    _b <- optional aExpr-                    return (SliceIndirectionEl (Just _a) _b)-                  ,-                  return (ExprIndirectionEl _a)-                ]-          ]-        space-        char ']'-        return _a-    ]--{--attr_name:-  | ColLabel--}-attrName = colLabel--keywordNameFromSet _set = keywordNameByPredicate (Predicate.inSet _set)--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-    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))--{-| Expected keyword -}-keyword a = mfilter (a ==) anyKeyword--{-|-Consume a keyphrase, ignoring case and types of spaces between words.--}-keyphrase a =-  Text.words a &-  fmap (void . MegaparsecChar.string') &-  intersperse MegaparsecChar.space1 &-  sequence_ &-  (<* Megaparsec.notFollowedBy (Megaparsec.satisfy Predicate.notFirstIdentifierChar)) &-  fmap (const (Text.toUpper a)) &-  Megaparsec.label (show a) &-  parse &-  (<* endHead)---- * Typename----------------------------typeList = sep1 commaSeparator typename--typename =-  do-    a <- option False (keyword "setof" *> space1 $> True)-    b <- simpleTypename-    endHead-    c <- trueIfPresent (space *> char '?')-    asum [-        do-          space1-          keyword "array"-          endHead-          d <- optional (space *> inBrackets iconst)-          e <- trueIfPresent (space *> char '?')-          return (Typename a b c (Just (ExplicitTypenameArrayDimensions d, e)))-        ,-        do-          space-          d <- arrayBounds-          endHead-          e <- trueIfPresent (space *> char '?')-          return (Typename a b c (Just (BoundsTypenameArrayDimensions d, e)))-        ,-        return (Typename a b c Nothing)-      ]--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-  ]--genericType = do-  a <- typeFunctionName-  endHead-  b <- optional (space *> attrs)-  c <- optional (space1 *> typeModifiers)-  return (GenericType a b c)--attrs = some (char '.' *> endHead *> space *> attrName)--typeModifiers = inParens exprList----- * Indexes----------------------------indexParams = sep1 commaSeparator indexElem--indexElem = IndexElem <$>-  (indexElemDef <* endHead) <*>-  optional (space1 *> collate) <*>-  optional (space1 *> class_) <*>-  optional (space1 *> ascDesc) <*>-  optional (space1 *> nullsOrder)--indexElemDef =-  ExprIndexElemDef <$> inParens aExpr <|>-  FuncIndexElemDef <$> funcExprWindowless <|>-  IdIndexElemDef <$> colId +-- |+--+-- Our parsing strategy is to port the original Postgres parser as closely as possible.+--+-- We're using the @gram.y@ Postgres source file, which is the closest thing we have+-- to a Postgres syntax spec. Here's a link to it:+-- https://github.com/postgres/postgres/blob/master/src/backend/parser/gram.y.+--+-- Here's the essence of how the original parser is implemented, citing from+-- [PostgreSQL Wiki](https://wiki.postgresql.org/wiki/Developer_FAQ):+--+--     scan.l defines the lexer, i.e. the algorithm that splits a string+--     (containing an SQL statement) into a stream of tokens.+--     A token is usually a single word+--     (i.e., doesn't contain spaces but is delimited by spaces),+--     but can also be a whole single or double-quoted string for example.+--     The lexer is basically defined in terms of regular expressions+--     which describe the different token types.+--+--     gram.y defines the grammar (the syntactical structure) of SQL statements,+--     using the tokens generated by the lexer as basic building blocks.+--     The grammar is defined in BNF notation.+--     BNF resembles regular expressions but works on the level of tokens, not characters.+--     Also, patterns (called rules or productions in BNF) are named, and may be recursive,+--     i.e. use themselves as sub-patterns.+module PostgresqlSyntax.Parsing where++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+import PostgresqlSyntax.Extras.HeadedMegaparsec hiding (run)+import qualified PostgresqlSyntax.Extras.HeadedMegaparsec as Extras+import qualified PostgresqlSyntax.Extras.NonEmpty as NonEmpty+import qualified PostgresqlSyntax.KeywordSet as KeywordSet+import qualified PostgresqlSyntax.Predicate as Predicate+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++type Parser = HeadedParsec Void Text++-- * Executors++run :: Parser a -> Text -> Either String a+run = Extras.run++-- * Helpers++commaSeparator :: Parser ()+commaSeparator = space *> char ',' *> endHead *> space++dotSeparator :: Parser ()+dotSeparator = space *> char '.' *> endHead *> space++inBrackets :: Parser a -> Parser a+inBrackets p = char '[' *> space *> p <* endHead <* space <* char ']'++inBracketsCont :: Parser a -> Parser (Parser a)+inBracketsCont p = char '[' *> endHead *> pure (space *> p <* endHead <* space <* char ']')++inParens :: Parser a -> Parser a+inParens p = char '(' *> space *> p <* endHead <* space <* char ')'++inParensCont :: Parser a -> Parser (Parser a)+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+  space+  char '('+  endHead+  space+  _content <- _contentParser+  space+  char ')'+  pure (_result _label _content)++inParensWithClause :: Parser clause -> Parser content -> Parser content+inParensWithClause = inParensWithLabel (const id)++trueIfPresent :: Parser a -> Parser Bool+trueIfPresent p = option False (True <$ p)++-- |+-- >>> testParser (quotedString '\'') "'abc''d'"+-- "abc'd"+quotedString :: Char -> Parser Text+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++atEnd :: Parser a -> Parser a+atEnd p = space *> p <* endHead <* space <* eof++-- * PreparableStmt++preparableStmt =+  SelectPreparableStmt <$> selectStmt+    <|> InsertPreparableStmt <$> insertStmt+    <|> UpdatePreparableStmt <$> updateStmt+    <|> DeletePreparableStmt <$> deleteStmt++-- * Insert++insertStmt = do+  a <- optional (wrapToHead withClause <* space1)+  keyword "insert"+  space1+  endHead+  keyword "into"+  space1+  b <- insertTarget+  space1+  c <- insertRest+  d <- optional (space1 *> onConflict)+  e <- optional (space1 *> returningClause)+  return (InsertStmt a b c d e)++insertTarget = do+  a <- qualifiedName+  endHead+  b <- optional (space1 *> keyword "as" *> space1 *> endHead *> colId)+  return (InsertTarget a b)++insertRest =+  asum+    [ DefaultValuesInsertRest <$ (keyword "default" *> space1 *> endHead *> keyword "values"),+      do+        a <- optional (inParens insertColumnList <* space1)+        b <- optional $ do+          keyword "overriding"+          space1+          endHead+          b <- overrideKind+          space1+          keyword "value"+          space1+          return b+        c <- selectStmt+        return (SelectInsertRest a b c)+    ]++overrideKind =+  asum+    [ UserOverrideKind <$ keyword "user",+      SystemOverrideKind <$ keyword "system"+    ]++insertColumnList = sep1 commaSeparator insertColumnItem++insertColumnItem = do+  a <- colId+  endHead+  b <- optional (space1 *> indirection)+  return (InsertColumnItem a b)++onConflict = do+  keyword "on"+  space1+  keyword "conflict"+  space1+  endHead+  a <- optional (confExpr <* space1)+  keyword "do"+  space1+  b <- onConflictDo+  return (OnConflict a b)++confExpr =+  asum+    [ WhereConfExpr <$> inParens indexParams <*> optional (space *> whereClause),+      ConstraintConfExpr <$> (keyword "on" *> space1 *> keyword "constraint" *> space1 *> endHead *> name)+    ]++onConflictDo =+  asum+    [ NothingOnConflictDo <$ keyword "nothing",+      do+        keyword "update"+        space1+        endHead+        keyword "set"+        space1+        a <- setClauseList+        b <- optional (space1 *> whereClause)+        return (UpdateOnConflictDo a b)+    ]++returningClause = do+  keyword "returning"+  space1+  endHead+  targetList++-- * Update++updateStmt = do+  a <- optional (wrapToHead withClause <* space1)+  keyword "update"+  space1+  endHead+  b <- relationExprOptAlias ["set"]+  space1+  keyword "set"+  space1+  c <- setClauseList+  d <- optional (space1 *> fromClause)+  e <- optional (space1 *> whereOrCurrentClause)+  f <- optional (space1 *> returningClause)+  return (UpdateStmt a b c d e f)++setClauseList = sep1 commaSeparator setClause++setClause =+  asum+    [ do+        a <- inParens setTargetList+        space+        char '='+        space+        b <- aExpr+        return (TargetListSetClause a b),+      do+        a <- setTarget+        space+        char '='+        space+        b <- aExpr+        return (TargetSetClause a b)+    ]++setTarget = do+  a <- colId+  endHead+  b <- optional (space1 *> indirection)+  return (SetTarget a b)++setTargetList = sep1 commaSeparator setTarget++-- * Delete++deleteStmt = do+  a <- optional (wrapToHead withClause <* space1)+  keyword "delete"+  space1+  endHead+  keyword "from"+  space1+  b <- relationExprOptAlias ["using", "where", "returning"]+  c <- optional (space1 *> usingClause)+  d <- optional (space1 *> whereOrCurrentClause)+  e <- optional (space1 *> returningClause)+  return (DeleteStmt a b c d e)++usingClause = do+  keyword "using"+  space1+  fromList++-- * Select++-- |+-- >>> test = testParser selectStmt+--+-- >>> test "select id from as"+-- ...+--   |+-- 1 | select id from as+--   |                  ^+-- Reserved keyword "as" used as an identifier. If that's what you intend, you have to wrap it in double quotes.+selectStmt = Left <$> selectNoParens <|> Right <$> selectWithParens++selectWithParens = inParens (WithParensSelectWithParens <$> selectWithParens <|> NoParensSelectWithParens <$> selectNoParens)++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)++-- |+-- The one that doesn't start with \"WITH\".+--+-- ==== References+-- @+--   | simple_select+--   | select_clause sort_clause+--   | select_clause opt_sort_clause for_locking_clause opt_select_limit+--   | select_clause opt_sort_clause select_limit opt_for_locking_clause+-- @+simpleSelectNoParens = sharedSelectNoParens Nothing++withSelectNoParens = do+  _with <- wrapToHead withClause+  space1+  sharedSelectNoParens (Just _with)++selectClause = suffixRec base suffix+  where+    base =+      asum+        [ Right <$> selectWithParens,+          Left <$> baseSimpleSelect+        ]+    suffix a = Left <$> extensionSimpleSelect a++baseSimpleSelect =+  asum+    [ do+        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),+      do+        keyword "table"+        space1+        endHead+        TableSimpleSelect <$> relationExpr,+      ValuesSimpleSelect <$> valuesClause+    ]++extensionSimpleSelect _headSelectClause = do+  _op <- space1 *> selectBinOp <* space1+  endHead+  _allOrDistinct <- optional (allOrDistinct <* space1)+  _selectClause <- selectClause+  return (BinSimpleSelect _op _headSelectClause _allOrDistinct _selectClause)++allOrDistinct = keyword "all" $> False <|> keyword "distinct" $> True++selectBinOp =+  asum+    [ keyword "union" $> UnionSelectBinOp,+      keyword "intersect" $> IntersectSelectBinOp,+      keyword "except" $> ExceptSelectBinOp+    ]++valuesClause = do+  keyword "values"+  space+  sep1 commaSeparator $ do+    char '('+    endHead+    space+    _a <- sep1 commaSeparator aExpr+    space+    char ')'+    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)++commonTableExpr = label "common table expression" $ do+  _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 =+  True <$ keyword "materialized"+    <|> False <$ keyphrase "not materialized"++targeting = distinct <|> allWithTargetList <|> all <|> normal+  where+    normal = NormalTargeting <$> targetList+    allWithTargetList = do+      keyword "all"+      space1+      AllTargeting <$> Just <$> targetList+    all = keyword "all" $> AllTargeting Nothing+    distinct = do+      keyword "distinct"+      space1+      endHead+      _optOn <- optional (onExpressionsClause <* space1)+      _targetList <- targetList+      return (DistinctTargeting _optOn _targetList)++targetList = sep1 commaSeparator targetEl++-- |+-- >>> testParser targetEl "a.b as c"+-- AliasedExprTargetEl (CExprAExpr (ColumnrefCExpr (Columnref (UnquotedIdent "a") (Just (AttrNameIndirectionEl (UnquotedIdent "b") :| []))))) (UnquotedIdent "c")+targetEl =+  label "target" $+    asum+      [ do+          _expr <- aExpr+          asum+            [ do+                space1+                asum+                  [ AliasedExprTargetEl _expr <$> (keyword "as" *> space1 *> endHead *> colLabel),+                    ImplicitlyAliasedExprTargetEl _expr <$> ident+                  ],+              pure (ExprTargetEl _expr)+            ],+        AsteriskTargetEl <$ char '*'+      ]++onExpressionsClause = do+  keyword "on"+  space1+  endHead+  inParens (sep1 commaSeparator aExpr)++-- * Into clause details++-- |+-- ==== References+-- @+-- OptTempTableName:+--   | TEMPORARY opt_table qualified_name+--   | TEMP opt_table qualified_name+--   | LOCAL TEMPORARY opt_table qualified_name+--   | LOCAL TEMP opt_table qualified_name+--   | GLOBAL TEMPORARY opt_table qualified_name+--   | GLOBAL TEMP opt_table qualified_name+--   | UNLOGGED opt_table qualified_name+--   | TABLE qualified_name+--   | qualified_name+-- @+optTempTableName =+  asum+    [ do+        a <-+          asum+            [ TemporaryOptTempTableName <$ keyword "temporary" <* space1,+              TempOptTempTableName <$ keyword "temp" <* space1,+              LocalTemporaryOptTempTableName <$ keyphrase "local temporary" <* space1,+              LocalTempOptTempTableName <$ keyphrase "local temp" <* space1,+              GlobalTemporaryOptTempTableName <$ keyphrase "global temporary" <* space1,+              GlobalTempOptTempTableName <$ keyphrase "global temp" <* space1,+              UnloggedOptTempTableName <$ keyword "unlogged" <* space1+            ]+        b <- option False (True <$ keyword "table" <* space1)+        c <- qualifiedName+        return (a b c),+      do+        keyword "table"+        space1+        endHead+        TableOptTempTableName <$> qualifiedName,+      QualifedOptTempTableName <$> qualifiedName+    ]++-- * Group by details++groupByItem =+  asum+    [ EmptyGroupingSetGroupByItem <$ (char '(' *> space *> char ')'),+      RollupGroupByItem <$> (keyword "rollup" *> endHead *> space *> inParens (sep1 commaSeparator aExpr)),+      CubeGroupByItem <$> (keyword "cube" *> endHead *> space *> inParens (sep1 commaSeparator aExpr)),+      GroupingSetsGroupByItem <$> (keyphrase "grouping sets" *> endHead *> space *> inParens (sep1 commaSeparator groupByItem)),+      ExprGroupByItem <$> aExpr+    ]++-- * Window clause details++windowDefinition = WindowDefinition <$> (colId <* space1 <* keyword "as" <* space1 <* endHead) <*> windowSpecification++-- |+-- ==== References+-- @+-- window_specification:+--   |  '(' opt_existing_window_name opt_partition_clause+--             opt_sort_clause opt_frame_clause ')'+-- @+windowSpecification =+  inParens $+    asum+      [ do+          a <- frameClause+          return (WindowSpecification Nothing Nothing Nothing (Just a)),+        do+          a <- sortClause+          b <- optional (space1 *> frameClause)+          return (WindowSpecification Nothing Nothing (Just a) b),+        do+          a <- partitionByClause+          b <- optional (space1 *> sortClause)+          c <- optional (space1 *> frameClause)+          return (WindowSpecification Nothing (Just a) b c),+        do+          a <- colId+          b <- optional (space1 *> partitionByClause)+          c <- optional (space1 *> sortClause)+          d <- optional (space1 *> frameClause)+          return (WindowSpecification (Just a) b c d),+        pure (WindowSpecification Nothing Nothing Nothing Nothing)+      ]++partitionByClause = keyphrase "partition by" *> space1 *> endHead *> sep1 commaSeparator aExpr++-- |+-- ==== References+-- @+-- opt_frame_clause:+--   |  RANGE frame_extent opt_window_exclusion_clause+--   |  ROWS frame_extent opt_window_exclusion_clause+--   |  GROUPS frame_extent opt_window_exclusion_clause+--   |  EMPTY+-- @+frameClause = do+  a <- frameClauseMode <* space1 <* endHead+  b <- frameExtent+  c <- optional (space1 *> windowExclusionClause)+  return (FrameClause a b c)++frameClauseMode =+  asum+    [ RangeFrameClauseMode <$ keyword "range",+      RowsFrameClauseMode <$ keyword "rows",+      GroupsFrameClauseMode <$ keyword "groups"+    ]++frameExtent =+  BetweenFrameExtent <$> (keyword "between" *> space1 *> endHead *> frameBound <* space1 <* keyword "and" <* space1) <*> frameBound+    <|> SingularFrameExtent <$> frameBound++-- |+-- ==== References+-- @+--   |  UNBOUNDED PRECEDING+--   |  UNBOUNDED FOLLOWING+--   |  CURRENT_P ROW+--   |  a_expr PRECEDING+--   |  a_expr FOLLOWING+-- @+frameBound =+  UnboundedPrecedingFrameBound <$ keyphrase "unbounded preceding"+    <|> UnboundedFollowingFrameBound <$ keyphrase "unbounded following"+    <|> CurrentRowFrameBound <$ keyphrase "current row"+    <|> do+      a <- aExpr+      space1+      PrecedingFrameBound a <$ keyword "preceding" <|> FollowingFrameBound a <$ keyword "following"++windowExclusionClause =+  CurrentRowWindowExclusionClause <$ keyphrase "exclude current row"+    <|> GroupWindowExclusionClause <$ keyphrase "exclude group"+    <|> TiesWindowExclusionClause <$ keyphrase "exclude ties"+    <|> NoOthersWindowExclusionClause <$ keyphrase "exclude no others"++-- * Table refs++fromList = sep1 commaSeparator tableRef++fromClause = keyword "from" *> endHead *> space1 *> fromList++-- |+-- >>> testParser tableRef "a left join b on (a.i = b.i)"+-- JoinTableRef (MethJoinedTable (QualJoinMeth...+tableRef =+  label "table reference" $+    do+      _tr <- nonTrailingTableRef+      recur _tr+  where+    recur _tr =+      asum+        [ do+            _tr2 <- wrapToHead (space1 *> trailingTableRef _tr)+            endHead+            recur _tr2,+          pure _tr+        ]++nonTrailingTableRef =+  asum+    [ lateralTableRef+        <|> wrapToHead nonLateralTableRef+        <|> relationExprTableRef+        <|> joinedTableWithAliasTableRef+        <|> inParensJoinedTableTableRef+    ]+  where+    relationExprTableRef = do+      _relationExpr <- relationExpr+      endHead+      _optAliasClause <- optional (space1 *> aliasClause)+      _optTablesampleClause <- optional (space1 *> tablesampleClause)+      return (RelationExprTableRef _relationExpr _optAliasClause _optTablesampleClause)++    lateralTableRef = do+      keyword "lateral"+      space1+      endHead+      lateralableTableRef True++    nonLateralTableRef = lateralableTableRef False++    lateralableTableRef _lateral =+      asum+        [ do+            a <- funcTable+            b <- optional (space1 *> funcAliasClause)+            return (FuncTableRef _lateral a b),+          do+            _select <- selectWithParens+            _optAliasClause <- optional $ space1 *> aliasClause+            return (SelectTableRef _lateral _select _optAliasClause)+        ]++    inParensJoinedTableTableRef = JoinTableRef <$> inParensJoinedTable <*> pure Nothing++    joinedTableWithAliasTableRef = do+      _joinedTable <- wrapToHead (inParens joinedTable)+      space1+      _alias <- aliasClause+      return (JoinTableRef _joinedTable (Just _alias))++trailingTableRef _tableRef =+  JoinTableRef <$> trailingJoinedTable _tableRef <*> pure Nothing++relationExpr =+  label "relation expression" $+    asum+      [ do+          keyword "only"+          space1+          _name <- qualifiedName+          return (OnlyRelationExpr _name False),+        inParensWithClause (keyword "only") qualifiedName <&> \a -> OnlyRelationExpr a True,+        do+          _name <- qualifiedName+          _asterisk <-+            asum+              [ True <$ (space1 *> char '*'),+                pure False+              ]+          return (SimpleRelationExpr _name _asterisk)+      ]++relationExprOptAlias reservedKeywords = do+  a <- relationExpr+  b <- optional $ do+    space1+    b <- trueIfPresent (keyword "as" *> space1)+    c <- filteredColId reservedKeywords+    return (b, c)+  return (RelationExprOptAlias a b)++tablesampleClause = do+  keyword "tablesample"+  space1+  endHead+  a <- funcName+  space+  b <- inParens exprList+  c <- optional (space *> repeatableClause)+  return (TablesampleClause a b c)++repeatableClause = do+  keyword "repeatable"+  space+  inParens (endHead *> aExpr)++funcTable =+  asum+    [ do+        keyword "rows"+        space1+        keyword "from"+        space+        a <- inParens (endHead *> rowsfromList)+        b <- trueIfPresent (space *> optOrdinality)+        return (RowsFromFuncTable a b),+      do+        a <- funcExprWindowless+        b <- trueIfPresent (space1 *> optOrdinality)+        return (FuncExprFuncTable a b)+    ]++rowsfromItem = do+  a <- funcExprWindowless+  endHead+  b <- optional (space1 *> colDefList)+  return (RowsfromItem a b)++rowsfromList = sep1 commaSeparator rowsfromItem++colDefList = keyword "as" *> space *> inParens (endHead *> tableFuncElementList)++optOrdinality = keyword "with" *> space1 *> keyword "ordinality"++tableFuncElementList = sep1 commaSeparator tableFuncElement++tableFuncElement = do+  a <- wrapToHead colId+  space1+  b <- typename+  c <- optional (space1 *> collateClause)+  return (TableFuncElement a b c)++collateClause = keyword "collate" *> space1 *> endHead *> anyName++funcAliasClause =+  asum+    [ do+        keyword "as"+        asum+          [ do+              space+              inParens $ do+                endHead+                AsFuncAliasClause <$> tableFuncElementList,+            do+              space1+              a <- colId+              asum+                [ do+                    space+                    inParens $ do+                      endHead+                      asum+                        [ AsColIdFuncAliasClause a <$> wrapToHead tableFuncElementList,+                          AliasFuncAliasClause <$> AliasClause True a <$> Just <$> nameList+                        ],+                  pure (AliasFuncAliasClause (AliasClause True a Nothing))+                ]+          ],+      do+        a <- colId+        asum+          [ do+              space+              inParens $ do+                endHead+                asum+                  [ ColIdFuncAliasClause a <$> wrapToHead tableFuncElementList,+                    AliasFuncAliasClause <$> AliasClause False a <$> Just <$> nameList+                  ],+            pure (AliasFuncAliasClause (AliasClause False a Nothing))+          ]+    ]++joinedTable =+  head >>= tail+  where+    head =+      asum+        [ do+            _tr <- wrapToHead nonTrailingTableRef+            space1+            trailingJoinedTable _tr,+          inParensJoinedTable+        ]+    tail _jt =+      asum+        [ do+            _jt2 <- wrapToHead (space1 *> trailingJoinedTable (JoinTableRef _jt Nothing))+            endHead+            tail _jt2,+          pure _jt+        ]++-- |+-- ==== References+-- @+--   | '(' joined_table ')'+-- @+inParensJoinedTable = InParensJoinedTable <$> inParens joinedTable++-- |+-- ==== References+-- @+--   | table_ref CROSS JOIN table_ref+--   | table_ref join_type JOIN table_ref join_qual+--   | table_ref JOIN table_ref join_qual+--   | table_ref NATURAL join_type JOIN table_ref+--   | table_ref NATURAL JOIN table_ref+-- @+trailingJoinedTable _tr1 =+  asum+    [ do+        keyphrase "cross join"+        endHead+        space1+        _tr2 <- nonTrailingTableRef+        return (MethJoinedTable CrossJoinMeth _tr1 _tr2),+      do+        _jt <- joinTypedJoin+        endHead+        space1+        _tr2 <- tableRef+        space1+        _jq <- joinQual+        return (MethJoinedTable (QualJoinMeth _jt _jq) _tr1 _tr2),+      do+        keyword "natural"+        endHead+        space1+        _jt <- joinTypedJoin+        space1+        _tr2 <- nonTrailingTableRef+        return (MethJoinedTable (NaturalJoinMeth _jt) _tr1 _tr2)+    ]+  where+    joinTypedJoin =+      Just <$> (joinType <* endHead <* space1 <* keyword "join")+        <|> Nothing <$ keyword "join"++joinType =+  asum+    [ do+        keyword "full"+        endHead+        _outer <- outerAfterSpace+        return (FullJoinType _outer),+      do+        keyword "left"+        endHead+        _outer <- outerAfterSpace+        return (LeftJoinType _outer),+      do+        keyword "right"+        endHead+        _outer <- outerAfterSpace+        return (RightJoinType _outer),+      keyword "inner" $> InnerJoinType+    ]+  where+    outerAfterSpace = (space1 *> keyword "outer") $> True <|> pure False++joinQual =+  asum+    [ keyword "using" *> space1 *> inParens (sep1 commaSeparator colId) <&> UsingJoinQual,+      keyword "on" *> space1 *> aExpr <&> OnJoinQual+    ]++aliasClause = do+  (_as, _alias) <- (True,) <$> (keyword "as" *> space1 *> endHead *> colId) <|> (False,) <$> colId+  _columnAliases <- optional (space1 *> inParens (sep1 commaSeparator colId))+  return (AliasClause _as _alias _columnAliases)++-- * Where++whereClause = keyword "where" *> space1 *> endHead *> aExpr++whereOrCurrentClause = do+  keyword "where"+  space1+  endHead+  asum+    [ do+        keyword "current"+        space1+        keyword "of"+        space1+        endHead+        a <- cursorName+        return (CursorWhereOrCurrentClause a),+      ExprWhereOrCurrentClause <$> aExpr+    ]++-- * Sorting++sortClause = do+  keyphrase "order by"+  endHead+  space1+  a <- sep1 commaSeparator sortBy+  return a++sortBy = do+  a <- filteredAExpr ["using", "asc", "desc", "nulls"]+  asum+    [ do+        space1+        keyword "using"+        space1+        endHead+        b <- qualAllOp+        c <- optional (space1 *> nullsOrder)+        return (UsingSortBy a b c),+      do+        b <- optional (space1 *> ascDesc)+        c <- optional (space1 *> nullsOrder)+        return (AscDescSortBy a b c)+    ]++-- * Expressions++exprList = sep1 commaSeparator aExpr++exprListInParens = inParens exprList++-- |+-- Notice that the tree constructed by this parser does not reflect+-- the precedence order of Postgres.+-- For the purposes of this library it simply doesn't matter,+-- so we're not bothering with that.+--+-- ==== Composite on the right:+--+-- >>> testParser aExpr "a = b :: int4"+-- SymbolicBinOpAExpr (CExprAExpr (ColumnrefCExpr (Columnref (UnquotedIdent "a") Nothing))) (MathSymbolicExprBinOp EqualsMathOp) (TypecastAExpr (CExprAExpr (ColumnrefCExpr (Columnref (UnquotedIdent "b") Nothing))) (Typename False (GenericTypeSimpleTypename (GenericType (UnquotedIdent "int4") Nothing Nothing)) False Nothing))+--+-- ==== Composite on the left:+--+-- >>> testParser aExpr "a = b :: int4 and c"+-- SymbolicBinOpAExpr (CExprAExpr (ColumnrefCExpr (Columnref (UnquotedIdent "a") Nothing))) (MathSymbolicExprBinOp EqualsMathOp) (AndAExpr (TypecastAExpr (CExprAExpr (ColumnrefCExpr (Columnref (UnquotedIdent "b") Nothing))) (Typename False (GenericTypeSimpleTypename (GenericType (UnquotedIdent "int4") Nothing Nothing)) False Nothing)) (CExprAExpr (ColumnrefCExpr (Columnref (UnquotedIdent "c") Nothing))))+aExpr = customizedAExpr cExpr++filteredAExpr = customizedAExpr . customizedCExpr . filteredColumnref++customizedAExpr cExpr = suffixRec base suffix+  where+    aExpr = customizedAExpr cExpr+    base =+      asum+        [ DefaultAExpr <$ keyword "default",+          UniqueAExpr <$> (keyword "unique" *> space1 *> selectWithParens),+          OverlapsAExpr <$> wrapToHead row <*> (space1 *> keyword "overlaps" *> space1 *> endHead *> row),+          qualOpExpr aExpr PrefixQualOpAExpr,+          PlusAExpr <$> plusedExpr aExpr,+          MinusAExpr <$> minusedExpr aExpr,+          NotAExpr <$> (keyword "not" *> space1 *> aExpr),+          CExprAExpr <$> cExpr+        ]+    suffix a =+      asum+        [ do+            space1+            b <- wrapToHead subqueryOp+            space1+            c <- wrapToHead subType+            space+            d <- Left <$> wrapToHead selectWithParens <|> Right <$> inParens aExpr+            return (SubqueryAExpr a b c d),+          typecastExpr a TypecastAExpr,+          CollateAExpr a <$> (space1 *> keyword "collate" *> space1 *> endHead *> anyName),+          AtTimeZoneAExpr a <$> (space1 *> keyphrase "at time zone" *> space1 *> endHead *> aExpr),+          symbolicBinOpExpr a aExpr SymbolicBinOpAExpr,+          SuffixQualOpAExpr a <$> (space *> qualOp),+          AndAExpr a <$> (space1 *> keyword "and" *> space1 *> endHead *> aExpr),+          OrAExpr a <$> (space1 *> keyword "or" *> space1 *> endHead *> aExpr),+          do+            space1+            b <- trueIfPresent (keyword "not" *> space1)+            c <-+              asum+                [ LikeVerbalExprBinOp <$ keyword "like",+                  IlikeVerbalExprBinOp <$ keyword "ilike",+                  SimilarToVerbalExprBinOp <$ keyphrase "similar to"+                ]+            space1+            endHead+            d <- aExpr+            e <- optional (space1 *> keyword "escape" *> space1 *> endHead *> aExpr)+            return (VerbalExprBinOpAExpr a b c d e),+          do+            space1+            keyword "is"+            space1+            endHead+            b <- trueIfPresent (keyword "not" *> space1)+            c <-+              asum+                [ NullAExprReversableOp <$ keyword "null",+                  TrueAExprReversableOp <$ keyword "true",+                  FalseAExprReversableOp <$ keyword "false",+                  UnknownAExprReversableOp <$ keyword "unknown",+                  DistinctFromAExprReversableOp <$> (keyword "distinct" *> space1 *> keyword "from" *> space1 *> endHead *> aExpr),+                  OfAExprReversableOp <$> (keyword "of" *> space1 *> endHead *> inParens typeList),+                  DocumentAExprReversableOp <$ keyword "document"+                ]+            return (ReversableOpAExpr a b c),+          do+            space1+            b <- trueIfPresent (keyword "not" *> space1)+            keyword "between"+            space1+            endHead+            c <-+              asum+                [ BetweenSymmetricAExprReversableOp <$ (keyword "symmetric" *> space1),+                  BetweenAExprReversableOp True <$ (keyword "asymmetric" *> space1),+                  pure (BetweenAExprReversableOp False)+                ]+            d <- bExpr+            space1+            keyword "and"+            space1+            e <- aExpr+            return (ReversableOpAExpr a b (c d e)),+          do+            space1+            b <- trueIfPresent (keyword "not" *> space1)+            keyword "in"+            space+            c <- InAExprReversableOp <$> inExpr+            return (ReversableOpAExpr a b c),+          IsnullAExpr a <$ (space1 *> keyword "isnull"),+          NotnullAExpr a <$ (space1 *> keyword "notnull")+        ]++bExpr = customizedBExpr cExpr++customizedBExpr cExpr = suffixRec base suffix+  where+    aExpr = customizedAExpr cExpr+    bExpr = customizedBExpr cExpr+    base =+      asum+        [ qualOpExpr bExpr QualOpBExpr,+          PlusBExpr <$> plusedExpr bExpr,+          MinusBExpr <$> minusedExpr bExpr,+          CExprBExpr <$> cExpr+        ]+    suffix a =+      asum+        [ typecastExpr a TypecastBExpr,+          symbolicBinOpExpr a bExpr SymbolicBinOpBExpr,+          do+            space1+            keyword "is"+            space1+            endHead+            b <- trueIfPresent (keyword "not" *> space1)+            c <-+              asum+                [ DistinctFromBExprIsOp <$> (keyphrase "distinct from" *> space1 *> endHead *> bExpr),+                  OfBExprIsOp <$> (keyword "of" *> space1 *> endHead *> inParens typeList),+                  DocumentBExprIsOp <$ keyword "document"+                ]+            return (IsOpBExpr a b c)+        ]++cExpr = customizedCExpr columnref++customizedCExpr columnref =+  asum+    [ ParamCExpr <$> (char '$' *> decimal <* endHead) <*> optional (space *> indirection),+      CaseCExpr <$> caseExpr,+      ImplicitRowCExpr <$> implicitRow,+      ExplicitRowCExpr <$> explicitRow,+      inParensWithClause (keyword "grouping") (GroupingCExpr <$> sep1 commaSeparator aExpr),+      keyword "exists" *> space *> (ExistsCExpr <$> selectWithParens),+      do+        keyword "array"+        space+        join $+          asum+            [ fmap (fmap (ArrayCExpr . Right)) arrayExprCont,+              fmap (fmap (ArrayCExpr . Left) . pure) selectWithParens+            ],+      do+        a <- wrapToHead selectWithParens+        endHead+        b <- optional (space *> indirection)+        return (SelectWithParensCExpr a b),+      InParensCExpr <$> (inParens aExpr <* endHead) <*> optional (space *> indirection),+      AexprConstCExpr <$> wrapToHead aexprConst,+      FuncCExpr <$> funcExpr,+      ColumnrefCExpr <$> columnref+    ]++-- *++subqueryOp =+  asum+    [ AnySubqueryOp <$> (keyword "operator" *> space *> endHead *> inParens anyOperator),+      do+        a <- trueIfPresent (keyword "not" *> space1)+        LikeSubqueryOp a <$ keyword "like" <|> IlikeSubqueryOp a <$ keyword "ilike",+      AllSubqueryOp <$> allOp+    ]++subType =+  asum+    [ AnySubType <$ keyword "any",+      SomeSubType <$ keyword "some",+      AllSubType <$ keyword "all"+    ]++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)++typecastExpr :: a -> (a -> Typename -> a) -> HeadedParsec Void Text a+typecastExpr _prefix _constr = do+  space+  string "::"+  endHead+  space+  _type <- typename+  return (_constr _prefix _type)++plusedExpr expr = char '+' *> space *> expr++minusedExpr expr = char '-' *> space *> expr++qualOpExpr expr constr = constr <$> wrapToHead qualOp <*> (space *> expr)++row = ExplicitRowRow <$> explicitRow <|> ImplicitRowRow <$> implicitRow++explicitRow = keyword "row" *> space *> inParens (optional exprList)++implicitRow = inParens $ do+  a <- wrapToHead aExpr+  commaSeparator+  b <- exprList+  return $ case NonEmpty.consAndUnsnoc a b of+    (c, d) -> ImplicitRow c d++arrayExprCont =+  inBracketsCont $+    asum+      [ ArrayExprListArrayExpr <$> sep1 commaSeparator (join arrayExprCont),+        ExprListArrayExpr <$> exprList,+        pure EmptyArrayExpr+      ]++caseExpr = label "case expression" $ do+  keyword "case"+  space1+  endHead+  _arg <- optional (aExpr <* space1)+  _whenClauses <- sep1 space1 whenClause+  space1+  _default <- optional elseClause+  keyword "end"+  pure $ CaseExpr _arg _whenClauses _default++whenClause = do+  keyword "when"+  space1+  endHead+  _a <- aExpr+  space1+  keyword "then"+  space1+  _b <- aExpr+  return (WhenClause _a _b)++elseClause = do+  keyword "else"+  space1+  endHead+  a <- aExpr+  space1+  return a++funcExpr =+  asum+    [ SubexprFuncExpr <$> funcExprCommonSubexpr,+      do+        a <- funcApplication+        endHead+        b <- optional (space1 *> withinGroupClause)+        c <- optional (space1 *> filterClause)+        d <- optional (space1 *> overClause)+        return (ApplicationFuncExpr a b c d)+    ]++funcExprWindowless =+  asum+    [ CommonSubexprFuncExprWindowless <$> funcExprCommonSubexpr,+      ApplicationFuncExprWindowless <$> funcApplication+    ]++withinGroupClause = do+  keyphrase "within group"+  endHead+  space+  inParens sortClause++filterClause = do+  keyword "filter"+  endHead+  space+  inParens (keyword "where" *> space1 *> aExpr)++overClause = do+  keyword "over"+  space1+  endHead+  asum+    [ WindowOverClause <$> windowSpecification,+      ColIdOverClause <$> colId+    ]++funcExprCommonSubexpr =+  asum+    [ CollationForFuncExprCommonSubexpr <$> (inParensWithClause (keyphrase "collation for") aExpr),+      CurrentDateFuncExprCommonSubexpr <$ keyword "current_date",+      CurrentTimestampFuncExprCommonSubexpr <$> labeledIconst "current_timestamp",+      CurrentTimeFuncExprCommonSubexpr <$> labeledIconst "current_time",+      LocalTimestampFuncExprCommonSubexpr <$> labeledIconst "localtimestamp",+      LocalTimeFuncExprCommonSubexpr <$> labeledIconst "localtime",+      CurrentRoleFuncExprCommonSubexpr <$ keyword "current_role",+      CurrentUserFuncExprCommonSubexpr <$ keyword "current_user",+      SessionUserFuncExprCommonSubexpr <$ keyword "session_user",+      UserFuncExprCommonSubexpr <$ keyword "user",+      CurrentCatalogFuncExprCommonSubexpr <$ keyword "current_catalog",+      CurrentSchemaFuncExprCommonSubexpr <$ keyword "current_schema",+      inParensWithClause (keyword "cast") (CastFuncExprCommonSubexpr <$> aExpr <*> (space1 *> keyword "as" *> space1 *> typename)),+      inParensWithClause (keyword "extract") (ExtractFuncExprCommonSubexpr <$> optional extractList),+      inParensWithClause (keyword "overlay") (OverlayFuncExprCommonSubexpr <$> overlayList),+      inParensWithClause (keyword "position") (PositionFuncExprCommonSubexpr <$> optional positionList),+      inParensWithClause (keyword "substring") (SubstringFuncExprCommonSubexpr <$> optional substrList),+      inParensWithClause (keyword "treat") (TreatFuncExprCommonSubexpr <$> aExpr <*> (space1 *> keyword "as" *> space1 *> typename)),+      inParensWithClause (keyword "trim") (TrimFuncExprCommonSubexpr <$> optional (trimModifier <* space1) <*> trimList),+      inParensWithClause (keyword "nullif") (NullIfFuncExprCommonSubexpr <$> aExpr <*> (commaSeparator *> aExpr)),+      inParensWithClause (keyword "coalesce") (CoalesceFuncExprCommonSubexpr <$> exprList),+      inParensWithClause (keyword "greatest") (GreatestFuncExprCommonSubexpr <$> exprList),+      inParensWithClause (keyword "least") (LeastFuncExprCommonSubexpr <$> exprList)+    ]+  where+    labeledIconst _label = keyword _label *> endHead *> optional (space *> inParens iconst)++extractList = ExtractList <$> extractArg <*> (space1 *> keyword "from" *> space1 *> aExpr)++extractArg =+  asum+    [ YearExtractArg <$ keyword "year",+      MonthExtractArg <$ keyword "month",+      DayExtractArg <$ keyword "day",+      HourExtractArg <$ keyword "hour",+      MinuteExtractArg <$ keyword "minute",+      SecondExtractArg <$ keyword "second",+      SconstExtractArg <$> sconst,+      IdentExtractArg <$> ident+    ]++overlayList = do+  a <- aExpr+  space1+  b <- overlayPlacing+  space1+  c <- substrFrom+  d <- optional (space1 *> substrFor)+  return (OverlayList a b c d)++overlayPlacing = keyword "placing" *> space1 *> endHead *> aExpr++positionList = PositionList <$> bExpr <*> (space1 *> keyword "in" *> space1 *> bExpr)++substrList =+  asum+    [ ExprSubstrList <$> wrapToHead aExpr <*> (space1 *> substrListFromFor),+      ExprListSubstrList <$> exprList+    ]++substrListFromFor =+  asum+    [ do+        a <- substrFrom+        asum+          [ do+              b <- space1 *> substrFor+              return (FromForSubstrListFromFor a b),+            return (FromSubstrListFromFor a)+          ],+      do+        a <- substrFor+        asum+          [ do+              b <- space1 *> substrFrom+              return (ForFromSubstrListFromFor a b),+            return (ForSubstrListFromFor a)+          ]+    ]++substrFrom = keyword "from" *> space1 *> endHead *> aExpr++substrFor = keyword "for" *> space1 *> endHead *> aExpr++trimModifier =+  BothTrimModifier <$ keyword "both"+    <|> LeadingTrimModifier <$ keyword "leading"+    <|> TrailingTrimModifier <$ keyword "trailing"++trimList =+  asum+    [ ExprFromExprListTrimList <$> wrapToHead aExpr <*> (space1 *> keyword "from" *> space1 *> endHead *> exprList),+      FromExprListTrimList <$> (keyword "from" *> space1 *> endHead *> exprList),+      ExprListTrimList <$> exprList+    ]++funcApplication = inParensWithLabel FuncApplication funcName (optional funcApplicationParams)++funcApplicationParams =+  asum+    [ starFuncApplicationParams,+      listVariadicFuncApplicationParams,+      singleVariadicFuncApplicationParams,+      normalFuncApplicationParams+    ]++normalFuncApplicationParams = do+  _optAllOrDistinct <- optional (allOrDistinct <* space1)+  _argList <- sep1 commaSeparator funcArgExpr+  endHead+  _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)++listVariadicFuncApplicationParams = do+  (_argList, _) <- wrapToHead $ sepEnd1 commaSeparator (keyword "variadic" <* space1) funcArgExpr+  endHead+  _arg <- funcArgExpr+  _optSortClause <- optional (space1 *> sortClause)+  return (VariadicFuncApplicationParams (Just _argList) _arg _optSortClause)++starFuncApplicationParams = space *> char '*' *> endHead *> space $> StarFuncApplicationParams++-- |+-- ==== References+-- @+-- func_arg_expr:+--   | a_expr+--   | param_name COLON_EQUALS a_expr+--   | param_name EQUALS_GREATER a_expr+-- param_name:+--   | type_function_name+-- @+funcArgExpr =+  asum+    [ do+        a <- wrapToHead typeFunctionName+        space+        asum+          [ do+              string ":="+              endHead+              b <- space *> aExpr+              return (ColonEqualsFuncArgExpr a b),+            do+              string "=>"+              endHead+              b <- space *> aExpr+              return (EqualsGreaterFuncArgExpr a b)+          ],+      ExprFuncArgExpr <$> aExpr+    ]++-- * Ops++symbolicExprBinOp =+  QualSymbolicExprBinOp <$> qualOp+    <|> MathSymbolicExprBinOp <$> mathOp++lexicalExprBinOp = asum $ fmap keyphrase $ ["and", "or", "is distinct from", "is not distinct from"]++qualOp =+  asum+    [ OpQualOp <$> op,+      OperatorQualOp <$> inParensWithClause (keyword "operator") anyOperator+    ]++qualAllOp =+  asum+    [ AnyQualAllOp <$> (keyword "operator" *> space *> inParens (endHead *> anyOperator)),+      AllQualAllOp <$> allOp+    ]++op = do+  a <- takeWhile1P Nothing Predicate.opChar+  case Validation.op a of+    Nothing -> return a+    Just err -> fail (Text.unpack err)++anyOperator =+  asum+    [ AllOpAnyOperator <$> allOp,+      QualifiedAnyOperator <$> colId <*> (space *> char '.' *> space *> anyOperator)+    ]++allOp =+  asum+    [ OpAllOp <$> op,+      MathAllOp <$> mathOp+    ]++mathOp =+  asum+    [ ArrowLeftArrowRightMathOp <$ string' "<>",+      GreaterEqualsMathOp <$ string' ">=",+      ExclamationEqualsMathOp <$ string' "!=",+      LessEqualsMathOp <$ string' "<=",+      PlusMathOp <$ char '+',+      MinusMathOp <$ char '-',+      AsteriskMathOp <$ char '*',+      SlashMathOp <$ char '/',+      PercentMathOp <$ char '%',+      ArrowUpMathOp <$ char '^',+      ArrowLeftMathOp <$ char '<',+      ArrowRightMathOp <$ char '>',+      EqualsMathOp <$ char '='+    ]++-- * Constants++-- |+-- >>> testParser aexprConst "32948023849023"+-- IAexprConst 32948023849023+--+-- >>> testParser aexprConst "'abc''de'"+-- SAexprConst "abc'de"+--+-- >>> testParser aexprConst "23.43234"+-- FAexprConst 23.43234+--+-- >>> testParser aexprConst "32423423.324324872"+-- FAexprConst 3.2423423324324872e7+--+-- >>> testParser aexprConst "NULL"+-- NullAexprConst+--+-- ==== References+-- @+-- AexprConst: Iconst+--       | FCONST+--       | Sconst+--       | BCONST+--       | XCONST+--       | func_name Sconst+--       | func_name '(' func_arg_list opt_sort_clause ')' Sconst+--       | ConstTypename Sconst+--       | ConstInterval Sconst opt_interval+--       | ConstInterval '(' Iconst ')' Sconst+--       | TRUE_P+--       | FALSE_P+--       | NULL_P+-- @+aexprConst =+  asum+    [ do+        keyword "interval"+        space1+        endHead+        a <-+          asum+            [ do+                a <- sconst+                endHead+                b <- optional (space1 *> interval)+                return (StringIntervalAexprConst a b),+              do+                a <- inParens iconst+                space1+                endHead+                b <- sconst+                return (IntIntervalAexprConst a b)+            ]+        return a,+      do+        a <- constTypename+        space1+        endHead+        b <- sconst+        return (ConstTypenameAexprConst a b),+      BoolAexprConst True <$ keyword "true",+      BoolAexprConst False <$ keyword "false",+      NullAexprConst <$ keyword "null" <* parse (Megaparsec.notFollowedBy MegaparsecChar.alphaNumChar),+      either IAexprConst FAexprConst <$> iconstOrFconst,+      SAexprConst <$> sconst,+      label "bit literal" $ do+        string' "b'"+        endHead+        a <- takeWhile1P (Just "0 or 1") (\b -> b == '0' || b == '1')+        char '\''+        return (BAexprConst a),+      label "hex literal" $ do+        string' "x'"+        endHead+        a <- takeWhile1P (Just "Hex digit") Predicate.hexDigit+        char '\''+        return (XAexprConst a),+      wrapToHead $ do+        a <- funcName+        space+        char '('+        space+        b <- sep1 commaSeparator funcArgExpr+        c <- optional (space1 *> sortClause)+        space+        char ')'+        space1+        d <- sconst+        return (FuncAexprConst a (Just (FuncConstArgs b c)) d),+      FuncAexprConst <$> (wrapToHead funcName <* space1) <*> pure Nothing <*> sconst+    ]++iconstOrFconst = Right <$> fconst <|> Left <$> iconst++iconst = decimal++fconst = float++sconst = quotedString '\''++constTypename =+  asum+    [ NumericConstTypename <$> numeric,+      ConstBitConstTypename <$> constBit,+      ConstCharacterConstTypename <$> constCharacter,+      ConstDatetimeConstTypename <$> constDatetime+    ]++numeric =+  asum+    [ IntegerNumeric <$ keyword "integer",+      IntNumeric <$ keyword "int",+      SmallintNumeric <$ keyword "smallint",+      BigintNumeric <$ keyword "bigint",+      RealNumeric <$ keyword "real",+      FloatNumeric <$> (keyword "float" *> endHead *> optional (space *> inParens iconst)),+      DoublePrecisionNumeric <$ keyphrase "double precision",+      DecimalNumeric <$> (keyword "decimal" *> endHead *> optional (space *> exprListInParens)),+      DecNumeric <$> (keyword "dec" *> endHead *> optional (space *> exprListInParens)),+      NumericNumeric <$> (keyword "numeric" *> endHead *> optional (space *> exprListInParens)),+      BooleanNumeric <$ keyword "boolean"+    ]++bit = do+  keyword "bit"+  a <- option False (True <$ space1 <* keyword "varying")+  b <- optional (space1 *> exprListInParens)+  return (Bit a b)++constBit = bit++constCharacter = ConstCharacter <$> (character <* endHead) <*> optional (space *> inParens iconst)++character =+  asum+    [ CharacterCharacter <$> (keyword "character" *> optVaryingAfterSpace),+      CharCharacter <$> (keyword "char" *> optVaryingAfterSpace),+      VarcharCharacter <$ keyword "varchar",+      NationalCharacterCharacter <$> (keyphrase "national character" *> optVaryingAfterSpace),+      NationalCharCharacter <$> (keyphrase "national char" *> optVaryingAfterSpace),+      NcharCharacter <$> (keyword "nchar" *> optVaryingAfterSpace)+    ]+  where+    optVaryingAfterSpace = True <$ space1 <* keyword "varying" <|> pure False++-- |+-- ==== References+-- @+-- ConstDatetime:+--   | TIMESTAMP '(' Iconst ')' opt_timezone+--   | TIMESTAMP opt_timezone+--   | TIME '(' Iconst ')' opt_timezone+--   | TIME opt_timezone+-- @+constDatetime =+  asum+    [ do+        keyword "timestamp"+        a <- optional (space1 *> inParens iconst)+        b <- optional (space1 *> timezone)+        return (TimestampConstDatetime a b),+      do+        keyword "time"+        a <- optional (space1 *> inParens iconst)+        b <- optional (space1 *> timezone)+        return (TimeConstDatetime a b)+    ]++timezone =+  asum+    [ False <$ keyphrase "with time zone",+      True <$ keyphrase "without time zone"+    ]++interval =+  asum+    [ YearToMonthInterval <$ keyphrase "year to month",+      DayToHourInterval <$ keyphrase "day to hour",+      DayToMinuteInterval <$ keyphrase "day to minute",+      DayToSecondInterval <$> (keyphrase "day to" *> space1 *> endHead *> intervalSecond),+      HourToMinuteInterval <$ keyphrase "hour to minute",+      HourToSecondInterval <$> (keyphrase "hour to" *> space1 *> endHead *> intervalSecond),+      MinuteToSecondInterval <$> (keyphrase "minute to" *> space1 *> endHead *> intervalSecond),+      YearInterval <$ keyword "year",+      MonthInterval <$ keyword "month",+      DayInterval <$ keyword "day",+      HourInterval <$ keyword "hour",+      MinuteInterval <$ keyword "minute",+      SecondInterval <$> intervalSecond+    ]++intervalSecond = do+  keyword "second"+  a <- optional (space *> inParens iconst)+  return a++-- * Clauses++-- |+-- ==== References+-- @+-- select_limit:+--   | limit_clause offset_clause+--   | offset_clause limit_clause+--   | limit_clause+--   | offset_clause+-- @+selectLimit =+  asum+    [ do+        _a <- limitClause+        LimitOffsetSelectLimit _a <$> (space1 *> offsetClause) <|> pure (LimitSelectLimit _a),+      do+        _a <- offsetClause+        OffsetLimitSelectLimit _a <$> (space1 *> limitClause) <|> pure (OffsetSelectLimit _a)+    ]++-- |+-- ==== References+-- @+-- limit_clause:+--   | LIMIT select_limit_value+--   | LIMIT select_limit_value ',' select_offset_value+--   | FETCH first_or_next select_fetch_first_value row_or_rows ONLY+--   | FETCH first_or_next row_or_rows ONLY+-- @+limitClause =+  ( do+      keyword "limit"+      endHead+      space1+      _a <- selectLimitValue+      _b <- optional $ do+        commaSeparator+        aExpr+      return (LimitLimitClause _a _b)+  )+    <|> ( do+            keyword "fetch"+            endHead+            space1+            _a <- firstOrNext+            space1+            asum+              [ do+                  _b <- rowOrRows+                  space1+                  keyword "only"+                  return (FetchOnlyLimitClause _a Nothing _b),+                do+                  _b <- selectFetchFirstValue+                  space1+                  _c <- rowOrRows+                  space1+                  keyword "only"+                  return (FetchOnlyLimitClause _a (Just _b) _c)+              ]+        )++offsetClause = do+  keyword "offset"+  endHead+  space1+  offsetClauseParams++offsetClauseParams =+  FetchFirstOffsetClause <$> wrapToHead selectFetchFirstValue <*> (space1 *> rowOrRows)+    <|> ExprOffsetClause <$> aExpr++-- |+-- ==== References+-- @+-- select_limit_value:+--   | a_expr+--   | ALL+-- @+selectLimitValue =+  AllSelectLimitValue <$ keyword "all"+    <|> ExprSelectLimitValue <$> aExpr++rowOrRows =+  True <$ keyword "rows"+    <|> False <$ keyword "row"++firstOrNext =+  False <$ keyword "first"+    <|> True <$ keyword "next"++selectFetchFirstValue =+  ExprSelectFetchFirstValue <$> cExpr+    <|> NumSelectFetchFirstValue <$> (plusOrMinus <* endHead <* space) <*> iconstOrFconst++plusOrMinus = False <$ char '+' <|> True <$ char '-'++-- * For Locking++-- |+-- ==== References+-- @+-- for_locking_clause:+--   | for_locking_items+--   | FOR READ ONLY+-- for_locking_items:+--   | for_locking_item+--   | for_locking_items for_locking_item+-- @+forLockingClause = readOnly <|> items+  where+    readOnly = ReadOnlyForLockingClause <$ keyphrase "for read only"+    items = ItemsForLockingClause <$> sep1 space1 forLockingItem++-- |+-- ==== References+-- @+-- for_locking_item:+--   | for_locking_strength locked_rels_list opt_nowait_or_skip+-- locked_rels_list:+--   | OF qualified_name_list+--   | EMPTY+-- opt_nowait_or_skip:+--   | NOWAIT+--   | SKIP LOCKED+--   | EMPTY+-- @+forLockingItem = do+  _strength <- forLockingStrength+  _rels <- optional $ space1 *> keyword "of" *> space1 *> endHead *> sep1 commaSeparator qualifiedName+  _nowaitOrSkip <- optional (space1 *> nowaitOrSkip)+  return (ForLockingItem _strength _rels _nowaitOrSkip)++-- |+-- ==== References+-- @+-- for_locking_strength:+--   | FOR UPDATE+--   | FOR NO KEY UPDATE+--   | FOR SHARE+--   | FOR KEY SHARE+-- @+forLockingStrength =+  UpdateForLockingStrength <$ keyphrase "for update"+    <|> NoKeyUpdateForLockingStrength <$ keyphrase "for no key update"+    <|> ShareForLockingStrength <$ keyphrase "for share"+    <|> KeyForLockingStrength <$ keyphrase "for key share"++nowaitOrSkip = False <$ keyword "nowait" <|> True <$ keyphrase "skip locked"++-- * References & Names++quotedName = filter (const "Empty name") (not . Text.null) (quotedString '"') & fmap QuotedIdent++-- |+-- ==== References+-- @+-- ident_start   [A-Za-z\200-\377_]+-- ident_cont    [A-Za-z\200-\377_0-9\$]+-- identifier    {ident_start}{ident_cont}*+-- @+ident = quotedName <|> keywordNameByPredicate (not . Predicate.keyword)++-- |+-- ==== References+-- @+-- ColId:+--   |  IDENT+--   |  unreserved_keyword+--   |  col_name_keyword+-- @+{-# NOINLINE colId #-}+colId =+  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)++-- |+-- ==== References+-- @+-- ColLabel:+--   |  IDENT+--   |  unreserved_keyword+--   |  col_name_keyword+--   |  type_func_name_keyword+--   |  reserved_keyword+-- @+colLabel =+  label "column label" $+    keywordNameFromSet KeywordSet.keyword <|> ident++-- |+-- >>> testParser qualifiedName "a.b"+-- IndirectedQualifiedName (UnquotedIdent "a") (AttrNameIndirectionEl (UnquotedIdent "b") :| [])+--+-- >>> testParser qualifiedName "a.-"+-- ...+-- expecting '*', column label, or white space+--+-- ==== References+-- @+-- qualified_name:+--   | ColId+--   | ColId indirection+-- @+qualifiedName =+  IndirectedQualifiedName <$> wrapToHead colId <*> (space *> indirection)+    <|> SimpleQualifiedName <$> colId++columnref = customizedColumnref colId++filteredColumnref _keywords = customizedColumnref (filteredColId _keywords)++customizedColumnref colId = do+  a <- wrapToHead colId+  endHead+  b <- optional (space *> indirection)+  return (Columnref a b)++anyName = customizedAnyName colId++filteredAnyName _keywords = customizedAnyName (filteredColId _keywords)++customizedAnyName colId = do+  a <- wrapToHead colId+  endHead+  b <- optional (space *> attrs)+  return (AnyName a b)++name = colId++nameList = sep1 commaSeparator name++cursorName = name++-- |+-- ==== References+-- @+-- func_name:+--   | type_function_name+--   | ColId indirection+-- @+funcName =+  IndirectedFuncName <$> wrapToHead colId <*> (space *> indirection)+    <|> TypeFuncName <$> typeFunctionName++-- |+-- ==== References+-- @+-- type_function_name:+--   | IDENT+--   | unreserved_keyword+--   | type_func_name_keyword+-- @+typeFunctionName =+  keywordNameFromSet KeywordSet.typeFunctionName+    <|> ident++-- |+-- ==== References+-- @+-- indirection:+--   | indirection_el+--   | indirection indirection_el+-- @+indirection = some indirectionEl++-- |+-- ==== References+-- @+-- indirection_el:+--   | '.' attr_name+--   | '.' '*'+--   | '[' a_expr ']'+--   | '[' opt_slice_bound ':' opt_slice_bound ']'+-- opt_slice_bound:+--   | a_expr+--   | EMPTY+-- @+indirectionEl =+  asum+    [ do+        char '.'+        endHead+        space+        AllIndirectionEl <$ char '*' <|> AttrNameIndirectionEl <$> attrName,+      do+        char '['+        endHead+        space+        _a <-+          asum+            [ do+                char ':'+                endHead+                space+                _b <- optional aExpr+                return (SliceIndirectionEl Nothing _b),+              do+                _a <- aExpr+                asum+                  [ do+                      space+                      char ':'+                      space+                      _b <- optional aExpr+                      return (SliceIndirectionEl (Just _a) _b),+                    return (ExprIndirectionEl _a)+                  ]+            ]+        space+        char ']'+        return _a+    ]++-- |+-- ==== References+-- @+-- attr_name:+--   | ColLabel+-- @+attrName = colLabel++keywordNameFromSet _set = keywordNameByPredicate (Predicate.inSet _set)++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+      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))++-- | Expected keyword+keyword a = mfilter (a ==) anyKeyword++-- |+-- Consume a keyphrase, ignoring case and types of spaces between words.+keyphrase a =+  Text.words a+    & fmap (void . MegaparsecChar.string')+    & intersperse MegaparsecChar.space1+    & sequence_+    & (<* Megaparsec.notFollowedBy (Megaparsec.satisfy Predicate.notFirstIdentifierChar))+    & fmap (const (Text.toUpper a))+    & Megaparsec.label (show a)+    & parse+    & (<* endHead)++-- * Typename++typeList = sep1 commaSeparator typename++typename =+  do+    a <- option False (keyword "setof" *> space1 $> True)+    b <- simpleTypename+    endHead+    c <- trueIfPresent (space *> char '?')+    asum+      [ do+          space1+          keyword "array"+          endHead+          d <- optional (space *> inBrackets iconst)+          e <- trueIfPresent (space *> char '?')+          return (Typename a b c (Just (ExplicitTypenameArrayDimensions d, e))),+        do+          space+          d <- arrayBounds+          endHead+          e <- trueIfPresent (space *> char '?')+          return (Typename a b c (Just (BoundsTypenameArrayDimensions d, e))),+        return (Typename a b c Nothing)+      ]++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+    ]++genericType = do+  a <- typeFunctionName+  endHead+  b <- optional (space *> attrs)+  c <- optional (space1 *> typeModifiers)+  return (GenericType a b c)++attrs = some (char '.' *> endHead *> space *> attrName)++typeModifiers = inParens exprList++-- * Indexes++indexParams = sep1 commaSeparator indexElem++indexElem =+  IndexElem+    <$> (indexElemDef <* endHead)+    <*> optional (space1 *> collate)+    <*> optional (space1 *> class_)+    <*> optional (space1 *> ascDesc)+    <*> optional (space1 *> nullsOrder)++indexElemDef =+  ExprIndexElemDef <$> inParens aExpr+    <|> FuncIndexElemDef <$> funcExprWindowless+    <|> IdIndexElemDef <$> colId  collate = keyword "collate" *> space1 *> endHead *> anyName 
library/PostgresqlSyntax/Predicate.hs view
@@ -1,39 +1,33 @@ module PostgresqlSyntax.Predicate where -import PostgresqlSyntax.Prelude hiding (expression) import qualified Data.HashSet as HashSet import qualified PostgresqlSyntax.CharSet as CharSet import qualified PostgresqlSyntax.KeywordSet as KeywordSet-+import PostgresqlSyntax.Prelude hiding (expression)  -- * Generic-------------------------- -{-|->>> test = oneOf [(==3), (==7), (==3), (==5)]->>> test 1-False-->>> test 3-True-->>> test 5-True--}+-- |+-- >>> test = oneOf [(==3), (==7), (==3), (==5)]+-- >>> test 1+-- False+--+-- >>> test 3+-- True+--+-- >>> test 5+-- True oneOf :: [a -> Bool] -> a -> Bool-oneOf = foldr (\ a b c -> a c || b c) (const False)+oneOf = foldr (\a b c -> a c || b c) (const False)  inSet :: (Eq a, Hashable a) => HashSet a -> a -> Bool inSet = flip HashSet.member - -- *--------------------------  hexDigit = inSet CharSet.hexDigit  -- *--------------------------  {- ident_start   [A-Za-z\200-\377_]@@ -67,7 +61,6 @@ symbolicBinOpChar = inSet CharSet.symbolicBinOp  -- ** Op chars--------------------------  opChar = inSet CharSet.op 
library/PostgresqlSyntax/Prelude.hs view
@@ -1,26 +1,25 @@ module PostgresqlSyntax.Prelude-( -  module Exports,-  showAsText,-  suffixRec,-)+  ( module Exports,+    showAsText,+    suffixRec,+  ) where --- base-------------------------- import Control.Applicative as Exports import Control.Arrow as Exports hiding (first, second) import Control.Category as Exports import Control.Concurrent as Exports import Control.Exception as Exports-import Control.Monad as Exports hiding (fail, mapM_, sequence_, forM_, msum, mapM, sequence, forM)-import Control.Monad.IO.Class as Exports+import Control.Monad as Exports hiding (fail, forM, forM_, mapM, mapM_, msum, sequence, sequence_) import Control.Monad.Fail as Exports import Control.Monad.Fix as Exports hiding (fix)+import Control.Monad.IO.Class as Exports import Control.Monad.ST as Exports import Data.Bifunctor as Exports import Data.Bits as Exports import Data.Bool as Exports+import Data.ByteString as Exports (ByteString)+import Data.CaseInsensitive as Exports (CI, FoldCase) import Data.Char as Exports import Data.Coerce as Exports import Data.Complex as Exports@@ -32,19 +31,23 @@ import Data.Function as Exports hiding (id, (.)) import Data.Functor as Exports import Data.Functor.Identity as Exports-import Data.Int as Exports+import Data.HashMap.Strict as Exports (HashMap)+import Data.HashSet as Exports (HashSet)+import Data.Hashable as Exports (Hashable) import Data.IORef as Exports+import Data.Int as Exports import Data.Ix as Exports-import Data.List as Exports hiding (sortOn, isSubsequenceOf, uncons, concat, foldr, foldl1, maximum, minimum, product, sum, all, and, any, concatMap, elem, foldl, foldr1, notElem, or, find, maximumBy, minimumBy, mapAccumL, mapAccumR, foldl')-import Data.List.NonEmpty as Exports (NonEmpty(..))+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.NonEmpty as Exports (NonEmpty (..)) import Data.Maybe as Exports-import Data.Monoid as Exports hiding (Last(..), First(..), (<>))+import Data.Monoid as Exports hiding (First (..), Last (..), (<>)) import Data.Ord as Exports import Data.Proxy as Exports import Data.Ratio as Exports-import Data.Semigroup as Exports import Data.STRef as Exports+import Data.Semigroup as Exports import Data.String as Exports+import Data.Text as Exports (Text) import Data.Traversable as Exports import Data.Tuple as Exports import Data.Unique as Exports@@ -55,13 +58,12 @@ import Foreign.ForeignPtr as Exports import Foreign.Ptr as Exports import Foreign.StablePtr as Exports-import Foreign.Storable as Exports hiding (sizeOf, alignment)-import GHC.Conc as Exports hiding (orElse, withMVar, threadWaitWriteSTM, threadWaitWrite, threadWaitReadSTM, threadWaitRead)-import GHC.Exts as Exports (lazy, inline, sortWith, groupWith, IsList(fromList, Item))+import Foreign.Storable as Exports hiding (alignment, sizeOf)+import GHC.Conc as Exports hiding (orElse, threadWaitRead, threadWaitReadSTM, threadWaitWrite, threadWaitWriteSTM, withMVar)+import GHC.Exts as Exports (IsList (Item, fromList), groupWith, inline, lazy, sortWith) import GHC.Generics as Exports (Generic, Generic1) import GHC.IO.Exception as Exports import Numeric as Exports-import Prelude as Exports hiding (fail, concat, foldr, mapM_, sequence_, foldl1, maximum, minimum, product, sum, all, and, any, concatMap, elem, foldl, foldr1, notElem, or, mapM, sequence, id, (.)) import System.Environment as Exports import System.Exit as Exports import System.IO as Exports@@ -71,40 +73,18 @@ 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, readPrec_to_P, readP_to_Prec, readPrec_to_S, readS_to_Prec)-import Text.Printf as Exports (printf, hPrintf)-import Text.Read as Exports (Read(..), readMaybe, readEither)+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---- bytestring---------------------------import Data.ByteString as Exports (ByteString)---- text---------------------------import Data.Text as Exports (Text)---- unordered-containers---------------------------import Data.HashSet as Exports (HashSet)-import Data.HashMap.Strict as Exports (HashMap)---- hashable---------------------------import Data.Hashable as Exports (Hashable)---- case-insensitive---------------------------import Data.CaseInsensitive as Exports (CI, FoldCase)-+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 >>> fromString -{-|-Compose a monad, which attempts to extend a value, based on the following input.-It does that recursively until the suffix alternative fails.--}+-- |+-- 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
library/PostgresqlSyntax/Rendering.hs view
@@ -1,17 +1,15 @@ module PostgresqlSyntax.Rendering where -import PostgresqlSyntax.Prelude hiding (aExpr, try, option, many, sortBy, bit, fromList)-import PostgresqlSyntax.Ast-import Text.Builder hiding (char7, intDec, int64Dec, doubleDec)-import PostgresqlSyntax.Extras.TextBuilder-import qualified PostgresqlSyntax.Extras.NonEmpty as NonEmpty import qualified Data.List.NonEmpty as NonEmpty import qualified Data.Text as Text import qualified Data.Text.Encoding as Text-+import PostgresqlSyntax.Ast+import qualified PostgresqlSyntax.Extras.NonEmpty as NonEmpty+import PostgresqlSyntax.Extras.TextBuilder+import PostgresqlSyntax.Prelude hiding (aExpr, bit, fromList, many, option, sortBy, try)+import Text.Builder hiding (char7, doubleDec, int64Dec, intDec)  -- * Execution--------------------------  toByteString :: Builder -> ByteString toByteString = Text.encodeUtf8 . toText@@ -19,9 +17,7 @@ toText :: Builder -> Text toText = run - -- * Helpers--------------------------  commaNonEmpty :: (a -> Builder) -> NonEmpty a -> Builder commaNonEmpty = NonEmpty.intersperseFoldMap ", "@@ -47,34 +43,32 @@ suffixMaybe :: (a -> Builder) -> Maybe a -> Builder suffixMaybe a = foldMap (mappend " " . a) - -- * Statements-------------------------- -preparableStmt = \ case+preparableStmt = \case   SelectPreparableStmt a -> selectStmt a   InsertPreparableStmt a -> insertStmt a   UpdatePreparableStmt a -> updateStmt a   DeletePreparableStmt a -> deleteStmt a - -- * Insert--------------------------  insertStmt (InsertStmt a b c d e) =-  prefixMaybe withClause a <>-  "INSERT INTO " <>-  insertTarget b <> " " <> insertRest c <>-  suffixMaybe onConflict d <>-  suffixMaybe returningClause e+  prefixMaybe withClause a+    <> "INSERT INTO "+    <> insertTarget b+    <> " "+    <> insertRest c+    <> suffixMaybe onConflict d+    <> suffixMaybe returningClause e  insertTarget (InsertTarget a b) =   qualifiedName a <> foldMap (mappend " AS " . colId) b -insertRest = \ case+insertRest = \case   SelectInsertRest a b c ->-    optLexemes [-        fmap (inParens . insertColumnList) a,+    optLexemes+      [ fmap (inParens . insertColumnList) a,         fmap insertRestOverriding b,         Just (selectStmt c)       ]@@ -82,7 +76,7 @@  insertRestOverriding a = "OVERRIDING " <> overrideKind a <> " VALUE" -overrideKind = \ case+overrideKind = \case   UserOverrideKind -> "USER"   SystemOverrideKind -> "SYSTEM" @@ -92,31 +86,32 @@  onConflict (OnConflict a b) = "ON CONFLICT" <> suffixMaybe confExpr a <> " DO " <> onConflictDo b -onConflictDo = \ case+onConflictDo = \case   UpdateOnConflictDo a b -> "UPDATE SET " <> setClauseList a <> suffixMaybe whereClause b   NothingOnConflictDo -> "NOTHING" -confExpr = \ case+confExpr = \case   WhereConfExpr a b -> inParens (indexParams a) <> suffixMaybe whereClause b   ConstraintConfExpr a -> "ON CONSTRAINT " <> name a  returningClause = mappend "RETURNING " . targetList - -- * Update--------------------------  updateStmt (UpdateStmt a b c d e f) =-  prefixMaybe withClause a <>-  "UPDATE " <> relationExprOptAlias b <> " " <>-  "SET " <> setClauseList c <>-  suffixMaybe fromClause d <>-  suffixMaybe whereOrCurrentClause e <>-  suffixMaybe returningClause f+  prefixMaybe withClause a+    <> "UPDATE "+    <> relationExprOptAlias b+    <> " "+    <> "SET "+    <> setClauseList c+    <> suffixMaybe fromClause d+    <> suffixMaybe whereOrCurrentClause e+    <> suffixMaybe returningClause f  setClauseList = commaNonEmpty setClause -setClause = \ case+setClause = \case   TargetSetClause a b -> setTarget a <> " = " <> aExpr b   TargetListSetClause a b -> inParens (setTargetList a) <> " = " <> aExpr b @@ -124,48 +119,44 @@  setTargetList = commaNonEmpty setTarget - -- * Delete--------------------------  deleteStmt (DeleteStmt a b c d e) =-  prefixMaybe withClause a <>-  "DELETE FROM " <> relationExprOptAlias b <>-  suffixMaybe usingClause c <>-  suffixMaybe whereOrCurrentClause d <>-  suffixMaybe returningClause e+  prefixMaybe withClause a+    <> "DELETE FROM "+    <> relationExprOptAlias b+    <> suffixMaybe usingClause c+    <> suffixMaybe whereOrCurrentClause d+    <> suffixMaybe returningClause e  usingClause = mappend "USING " . fromList - -- * Select-------------------------- -selectStmt = \ case+selectStmt = \case   Left a -> selectNoParens a   Right a -> selectWithParens a  selectNoParens (SelectNoParens a b c d e) =   optLexemes-    [-      fmap withClause a,+    [ fmap withClause a,       Just (selectClause b),       fmap sortClause c,       fmap selectLimit d,       fmap forLockingClause e     ] -selectWithParens = inParens . \ case-  NoParensSelectWithParens a -> selectNoParens a-  WithParensSelectWithParens a -> selectWithParens a+selectWithParens =+  inParens . \case+    NoParensSelectWithParens a -> selectNoParens a+    WithParensSelectWithParens a -> selectWithParens a  withClause (WithClause a b) =   "WITH " <> bool "" "RECURSIVE " a <> commaNonEmpty commonTableExpr b  commonTableExpr (CommonTableExpr a b c d) =   optLexemes-    [-      Just (ident a),+    [ Just (ident a),       fmap (inParens . commaNonEmpty ident) b,       Just "AS",       fmap materialization c,@@ -174,18 +165,17 @@  materialization = bool "NOT MATERIALIZED" "MATERIALIZED" -selectLimit = \ case+selectLimit = \case   LimitOffsetSelectLimit a b -> lexemes [limitClause a, offsetClause b]   OffsetLimitSelectLimit a b -> lexemes [offsetClause a, limitClause b]   LimitSelectLimit a -> limitClause a   OffsetSelectLimit a -> offsetClause a -limitClause = \ case+limitClause = \case   LimitLimitClause a b -> "LIMIT " <> selectLimitValue a <> foldMap (mappend ", " . aExpr) b   FetchOnlyLimitClause a b c ->     optLexemes-      [-        Just "FETCH",+      [ Just "FETCH",         Just (firstOrNext a),         fmap selectFetchFirstValue b,         Just (rowOrRows c),@@ -196,33 +186,32 @@  rowOrRows = bool "ROW" "ROWS" -selectFetchFirstValue = \ case+selectFetchFirstValue = \case   ExprSelectFetchFirstValue a -> cExpr a   NumSelectFetchFirstValue a b -> bool "+" "-" a <> intOrFloat b  intOrFloat = either int64Dec doubleDec -selectLimitValue = \ case+selectLimitValue = \case   ExprSelectLimitValue a -> aExpr a   AllSelectLimitValue -> "ALL" -offsetClause = \ case+offsetClause = \case   ExprOffsetClause a -> "OFFSET " <> aExpr a   FetchFirstOffsetClause a b -> "OFFSET " <> selectFetchFirstValue a <> " " <> rowOrRows b -forLockingClause = \ case+forLockingClause = \case   ItemsForLockingClause a -> spaceNonEmpty forLockingItem a   ReadOnlyForLockingClause -> "FOR READ ONLY"  forLockingItem (ForLockingItem a b c) =   optLexemes-    [-      Just (forLockingStrength a),+    [ Just (forLockingStrength a),       fmap lockedRelsList b,       fmap nowaitOrSkip c     ] -forLockingStrength = \ case+forLockingStrength = \case   UpdateForLockingStrength -> "FOR UPDATE"   NoKeyUpdateForLockingStrength -> "FOR NO KEY UPDATE"   ShareForLockingStrength -> "FOR SHARE"@@ -234,11 +223,10 @@  selectClause = either simpleSelect selectWithParens -simpleSelect = \ case+simpleSelect = \case   NormalSimpleSelect a b c d e f g ->     optLexemes-      [-        Just "SELECT",+      [ Just "SELECT",         fmap targeting a,         fmap intoClause b,         fmap fromClause c,@@ -249,14 +237,14 @@       ]   ValuesSimpleSelect a -> valuesClause a   TableSimpleSelect a -> "TABLE " <> relationExpr a-  BinSimpleSelect a b c d -> selectClause b <> " " <> selectBinOp a <> foldMap (mappend " ". allOrDistinct) c <> " " <> selectClause d+  BinSimpleSelect a b c d -> selectClause b <> " " <> selectBinOp a <> foldMap (mappend " " . allOrDistinct) c <> " " <> selectClause d -selectBinOp = \ case+selectBinOp = \case   UnionSelectBinOp -> "UNION"   IntersectSelectBinOp -> "INTERSECT"   ExceptSelectBinOp -> "EXCEPT" -targeting = \ case+targeting = \case   NormalTargeting a -> targetList a   AllTargeting a -> "ALL" <> suffixMaybe targetList a   DistinctTargeting a b -> "DISTINCT" <> suffixMaybe onExpressionsClause a <> " " <> commaNonEmpty targetEl b@@ -265,19 +253,17 @@  onExpressionsClause a = "ON (" <> commaNonEmpty aExpr a <> ")" -targetEl = \ case+targetEl = \case   AliasedExprTargetEl a b -> aExpr a <> " AS " <> ident b   ImplicitlyAliasedExprTargetEl a b -> aExpr a <> " " <> ident b   ExprTargetEl a -> aExpr a   AsteriskTargetEl -> "*" - -- * Select Into--------------------------  intoClause a = "INTO " <> optTempTableName a -optTempTableName = \ case+optTempTableName = \case   TemporaryOptTempTableName a b -> optLexemes [Just "TEMPORARY", bool Nothing (Just "TABLE") a, Just (qualifiedName b)]   TempOptTempTableName a b -> optLexemes [Just "TEMP", bool Nothing (Just "TABLE") a, Just (qualifiedName b)]   LocalTemporaryOptTempTableName a b -> optLexemes [Just "LOCAL TEMPORARY", bool Nothing (Just "TABLE") a, Just (qualifiedName b)]@@ -288,30 +274,28 @@   TableOptTempTableName a -> "TABLE " <> qualifiedName a   QualifedOptTempTableName a -> qualifiedName a - -- * From--------------------------  fromClause a = "FROM " <> fromList a  fromList = commaNonEmpty tableRef -tableRef = \ case+tableRef = \case   RelationExprTableRef a b c ->-    optLexemes [-        Just (relationExpr a),+    optLexemes+      [ Just (relationExpr a),         fmap aliasClause b,         fmap tablesampleClause c       ]   FuncTableRef a b c ->-    optLexemes [-        if a then Just "LATERAL" else Nothing,+    optLexemes+      [ if a then Just "LATERAL" else Nothing,         Just (funcTable b),         fmap funcAliasClause c       ]   SelectTableRef a b c ->-    optLexemes [-        if a then Just "LATERAL" else Nothing,+    optLexemes+      [ if a then Just "LATERAL" else Nothing,         Just (selectWithParens b),         fmap aliasClause c       ]@@ -319,7 +303,7 @@     Just c -> inParens (joinedTable a) <> " " <> aliasClause c     Nothing -> joinedTable a -relationExpr = \ case+relationExpr = \case   SimpleRelationExpr a b -> qualifiedName a <> bool "" " *" b   OnlyRelationExpr a b -> "ONLY " <> bool qualifiedName (inParens . qualifiedName) b a @@ -332,7 +316,7 @@  repeatableClause a = "REPEATABLE (" <> aExpr a <> ")" -funcTable = \ case+funcTable = \case   FuncExprFuncTable a b -> funcExprWindownless a <> bool "" " WITH ORDINALITY" b   RowsFromFuncTable a b -> "ROWS FROM (" <> rowsfromList a <> ")" <> bool "" " WITH ORDINALITY" b @@ -350,136 +334,120 @@  aliasClause (AliasClause a b c) =   optLexemes-    [-      if a then Just "AS" else Nothing,+    [ if a then Just "AS" else Nothing,       Just (ident b),       fmap (inParens . commaNonEmpty ident) c     ] -funcAliasClause = \ case+funcAliasClause = \case   AliasFuncAliasClause a -> aliasClause a   AsFuncAliasClause a -> "AS (" <> tableFuncElementList a <> ")"   AsColIdFuncAliasClause a b -> "AS " <> colId a <> " (" <> tableFuncElementList b <> ")"   ColIdFuncAliasClause a b -> colId a <> " (" <> tableFuncElementList b <> ")" -joinedTable = \ case+joinedTable = \case   InParensJoinedTable a -> inParens (joinedTable a)   MethJoinedTable a b c -> case a of     CrossJoinMeth -> tableRef b <> " CROSS JOIN " <> tableRef c     QualJoinMeth d e -> tableRef b <> suffixMaybe joinType d <> " JOIN " <> tableRef c <> " " <> joinQual e     NaturalJoinMeth d -> tableRef b <> " NATURAL" <> suffixMaybe joinType d <> " JOIN " <> tableRef c -joinType = \ case+joinType = \case   FullJoinType a -> "FULL" <> if a then " OUTER" else ""   LeftJoinType a -> "LEFT" <> if a then " OUTER" else ""   RightJoinType a -> "RIGHT" <> if a then " OUTER" else ""   InnerJoinType -> "INNER" -joinQual = \ case-  UsingJoinQual a -> "USING (" <> commaNonEmpty ident a <> ")" +joinQual = \case+  UsingJoinQual a -> "USING (" <> commaNonEmpty ident a <> ")"   OnJoinQual a -> "ON " <> aExpr a - -- * Where--------------------------  whereClause a = "WHERE " <> aExpr a -whereOrCurrentClause = \ case+whereOrCurrentClause = \case   ExprWhereOrCurrentClause a -> "WHERE " <> aExpr a   CursorWhereOrCurrentClause a -> "WHERE CURRENT OF " <> cursorName a - -- * Group By--------------------------  groupClause a = "GROUP BY " <> commaNonEmpty groupByItem a -groupByItem = \ case+groupByItem = \case   ExprGroupByItem a -> aExpr a   EmptyGroupingSetGroupByItem -> "()"   RollupGroupByItem a -> "ROLLUP (" <> commaNonEmpty aExpr a <> ")"   CubeGroupByItem a -> "CUBE (" <> commaNonEmpty aExpr a <> ")"   GroupingSetsGroupByItem a -> "GROUPING SETS (" <> commaNonEmpty groupByItem a <> ")" - -- * Having--------------------------  havingClause a = "HAVING " <> aExpr a - -- * Window--------------------------  windowClause a = "WINDOW " <> commaNonEmpty windowDefinition a  windowDefinition (WindowDefinition a b) = ident a <> " AS " <> windowSpecification b  windowSpecification (WindowSpecification a b c d) =-  inParens $ optLexemes-    [-      fmap ident a,-      fmap partitionClause b,-      fmap sortClause c,-      fmap frameClause d-    ]+  inParens $+    optLexemes+      [ fmap ident a,+        fmap partitionClause b,+        fmap sortClause c,+        fmap frameClause d+      ]  partitionClause a = "PARTITION BY " <> commaNonEmpty aExpr a  frameClause (FrameClause a b c) =   optLexemes-    [-      Just (frameClauseMode a),+    [ Just (frameClauseMode a),       Just (frameExtent b),       fmap windowExclusionCause c     ] -frameClauseMode = \ case+frameClauseMode = \case   RangeFrameClauseMode -> "RANGE"   RowsFrameClauseMode -> "ROWS"   GroupsFrameClauseMode -> "GROUPS" -frameExtent = \ case+frameExtent = \case   SingularFrameExtent a -> frameBound a   BetweenFrameExtent a b -> "BETWEEN " <> frameBound a <> " AND " <> frameBound b -frameBound = \ case+frameBound = \case   UnboundedPrecedingFrameBound -> "UNBOUNDED PRECEDING"   UnboundedFollowingFrameBound -> "UNBOUNDED FOLLOWING"   CurrentRowFrameBound -> "CURRENT ROW"   PrecedingFrameBound a -> aExpr a <> " PRECEDING"   FollowingFrameBound a -> aExpr a <> " FOLLOWING" -windowExclusionCause = \ case+windowExclusionCause = \case   CurrentRowWindowExclusionClause -> "EXCLUDE CURRENT ROW"   GroupWindowExclusionClause -> "EXCLUDE GROUP"   TiesWindowExclusionClause -> "EXCLUDE TIES"   NoOthersWindowExclusionClause -> "EXCLUDE NO OTHERS" - -- * Order By--------------------------  sortClause a = "ORDER BY " <> commaNonEmpty sortBy a -sortBy = \ case+sortBy = \case   UsingSortBy a b c -> aExpr a <> " USING " <> qualAllOp b <> suffixMaybe nullsOrder c   AscDescSortBy a b c -> aExpr a <> suffixMaybe ascDesc b <> suffixMaybe nullsOrder c - -- * Values--------------------------  valuesClause a = "VALUES " <> commaNonEmpty (inParens . commaNonEmpty aExpr) a - -- * Exprs--------------------------  exprList = commaNonEmpty aExpr -aExpr = \ case+aExpr = \case   CExprAExpr a -> cExpr a   TypecastAExpr a b -> aExpr a <> " :: " <> typename b   CollateAExpr a b -> aExpr a <> " COLLATE " <> anyName b@@ -501,7 +469,7 @@   UniqueAExpr a -> "UNIQUE " <> selectWithParens a   DefaultAExpr -> "DEFAULT" -bExpr = \ case+bExpr = \case   CExprBExpr a -> cExpr a   TypecastBExpr a b -> bExpr a <> " :: " <> typename b   PlusBExpr a -> "+ " <> bExpr a@@ -510,7 +478,7 @@   QualOpBExpr a b -> qualOp a <> " " <> bExpr b   IsOpBExpr a b c -> bExpr a <> " " <> bExprIsOp b c -cExpr = \ case+cExpr = \case   ColumnrefCExpr a -> columnref a   AexprConstCExpr a -> aexprConst a   ParamCExpr a b -> "$" <> intDec a <> foldMap indirection b@@ -524,11 +492,9 @@   ImplicitRowCExpr a -> implicitRow a   GroupingCExpr a -> "GROUPING " <> inParens (exprList a) - -- * Ops-------------------------- -aExprReversableOp a = \ case+aExprReversableOp a = \case   NullAExprReversableOp -> bool "IS " "IS NOT " a <> "NULL"   TrueAExprReversableOp -> bool "IS " "IS NOT " a <> "TRUE"   FalseAExprReversableOp -> bool "IS " "IS NOT " a <> "FALSE"@@ -540,45 +506,47 @@   InAExprReversableOp b -> bool "" "NOT " a <> "IN " <> inExpr b   DocumentAExprReversableOp -> bool "IS " "IS NOT " a <> "DOCUMENT" -verbalExprBinOp a = mappend (bool "" "NOT " a) . \ case-  LikeVerbalExprBinOp -> "LIKE"-  IlikeVerbalExprBinOp -> "ILIKE"-  SimilarToVerbalExprBinOp -> "SIMILAR TO"+verbalExprBinOp a =+  mappend (bool "" "NOT " a) . \case+    LikeVerbalExprBinOp -> "LIKE"+    IlikeVerbalExprBinOp -> "ILIKE"+    SimilarToVerbalExprBinOp -> "SIMILAR TO" -subqueryOp = \ case+subqueryOp = \case   AllSubqueryOp a -> allOp a   AnySubqueryOp a -> "OPERATOR " <> inParens (anyOperator a)   LikeSubqueryOp a -> bool "" "NOT " a <> "LIKE"   IlikeSubqueryOp a -> bool "" "NOT " a <> "ILIKE" -bExprIsOp a = mappend (bool "IS " "IS NOT " a) . \ case-  DistinctFromBExprIsOp b -> "DISTINCT FROM " <> bExpr b-  OfBExprIsOp a -> "OF " <> inParens (typeList a)-  DocumentBExprIsOp -> "DOCUMENT"+bExprIsOp a =+  mappend (bool "IS " "IS NOT " a) . \case+    DistinctFromBExprIsOp b -> "DISTINCT FROM " <> bExpr b+    OfBExprIsOp a -> "OF " <> inParens (typeList a)+    DocumentBExprIsOp -> "DOCUMENT" -symbolicExprBinOp = \ case+symbolicExprBinOp = \case   MathSymbolicExprBinOp a -> mathOp a   QualSymbolicExprBinOp a -> qualOp a -qualOp = \ case+qualOp = \case   OpQualOp a -> op a   OperatorQualOp a -> "OPERATOR (" <> anyOperator a <> ")" -qualAllOp = \ case+qualAllOp = \case   AllQualAllOp a -> allOp a   AnyQualAllOp a -> "OPERATOR (" <> anyOperator a <> ")"  op = text -anyOperator = \ case+anyOperator = \case   AllOpAnyOperator a -> allOp a   QualifiedAnyOperator a b -> colId a <> "." <> anyOperator b -allOp = \ case+allOp = \case   OpAllOp a -> op a   MathAllOp a -> mathOp a -mathOp = \ case+mathOp = \case   PlusMathOp -> char7 '+'   MinusMathOp -> char7 '-'   AsteriskMathOp -> char7 '*'@@ -593,34 +561,34 @@   ArrowLeftArrowRightMathOp -> "<>"   ExclamationEqualsMathOp -> "!=" - -- *-------------------------- -inExpr = \ case+inExpr = \case   SelectInExpr a -> selectWithParens a   ExprListInExpr a -> inParens (exprList a) -caseExpr (CaseExpr a b c) = optLexemes [-    Just "CASE",-    fmap aExpr a,-    Just (spaceNonEmpty whenClause b),-    fmap caseDefault c,-    Just "END"-  ]+caseExpr (CaseExpr a b c) =+  optLexemes+    [ Just "CASE",+      fmap aExpr a,+      Just (spaceNonEmpty whenClause b),+      fmap caseDefault c,+      Just "END"+    ]  whenClause (WhenClause a b) = "WHEN " <> aExpr a <> " THEN " <> aExpr b  caseDefault a = "ELSE " <> aExpr a -arrayExpr = inBrackets . \ case-  ExprListArrayExpr a -> exprList a-  ArrayExprListArrayExpr a -> arrayExprList a-  EmptyArrayExpr -> mempty+arrayExpr =+  inBrackets . \case+    ExprListArrayExpr a -> exprList a+    ArrayExprListArrayExpr a -> arrayExprList a+    EmptyArrayExpr -> mempty  arrayExprList = commaNonEmpty arrayExpr -row = \ case+row = \case   ExplicitRowRow a -> explicitRow a   ImplicitRowRow a -> implicitRow a @@ -631,46 +599,44 @@ funcApplication (FuncApplication a b) =   funcName a <> "(" <> foldMap funcApplicationParams b <> ")" -funcApplicationParams = \ case+funcApplicationParams = \case   NormalFuncApplicationParams a b c ->     optLexemes-      [-        fmap allOrDistinct a,+      [ fmap allOrDistinct a,         Just (commaNonEmpty funcArgExpr b),         fmap sortClause c       ]   VariadicFuncApplicationParams a b c ->     optLexemes-      [-        fmap (flip mappend "," . commaNonEmpty funcArgExpr) a,+      [ fmap (flip mappend "," . commaNonEmpty funcArgExpr) a,         Just "VARIADIC",         Just (funcArgExpr b),         fmap sortClause c       ]   StarFuncApplicationParams -> "*" -allOrDistinct = \ case+allOrDistinct = \case   False -> "ALL"   True -> "DISTINCT" -funcArgExpr = \ case+funcArgExpr = \case   ExprFuncArgExpr a -> aExpr a   ColonEqualsFuncArgExpr a b -> ident a <> " := " <> aExpr b   EqualsGreaterFuncArgExpr a b -> ident a <> " => " <> aExpr b  -- ** Func Expr-------------------------- -funcExpr = \ case-  ApplicationFuncExpr a b c d -> optLexemes [-      Just (funcApplication a),-      fmap withinGroupClause b,-      fmap filterClause c,-      fmap overClause d-    ]+funcExpr = \case+  ApplicationFuncExpr a b c d ->+    optLexemes+      [ Just (funcApplication a),+        fmap withinGroupClause b,+        fmap filterClause c,+        fmap overClause d+      ]   SubexprFuncExpr a -> funcExprCommonSubexpr a -funcExprWindownless = \ case+funcExprWindownless = \case   ApplicationFuncExprWindowless a -> funcApplication a   CommonSubexprFuncExprWindowless a -> funcExprCommonSubexpr a @@ -678,11 +644,11 @@  filterClause a = "FILTER (WHERE " <> aExpr a <> ")" -overClause = \ case+overClause = \case   WindowOverClause a -> "OVER " <> windowSpecification a   ColIdOverClause a -> "OVER " <> colId a -funcExprCommonSubexpr = \ case+funcExprCommonSubexpr = \case   CollationForFuncExprCommonSubexpr a -> "COLLATION FOR (" <> aExpr a <> ")"   CurrentDateFuncExprCommonSubexpr -> "CURRENT_DATE"   CurrentTimeFuncExprCommonSubexpr a -> "CURRENT_TIME" <> suffixMaybe (inParens . iconst) a@@ -709,7 +675,7 @@  extractList (ExtractList a b) = extractArg a <> " FROM " <> aExpr b -extractArg = \ case+extractArg = \case   IdentExtractArg a -> ident a   YearExtractArg -> "YEAR"   MonthExtractArg -> "MONTH"@@ -725,11 +691,11 @@  positionList (PositionList a b) = bExpr a <> " IN " <> bExpr b -substrList = \ case+substrList = \case   ExprSubstrList a b -> aExpr a <> " " <> substrListFromFor b   ExprListSubstrList a -> exprList a -substrListFromFor = \ case+substrListFromFor = \case   FromForSubstrListFromFor a b -> substrFrom a <> " " <> substrFor b   ForFromSubstrListFromFor a b -> substrFor a <> " " <> substrFrom b   FromSubstrListFromFor a -> substrFrom a@@ -739,21 +705,19 @@  substrFor a = "FOR " <> aExpr a -trimModifier = \ case+trimModifier = \case   BothTrimModifier -> "BOTH"   LeadingTrimModifier -> "LEADING"   TrailingTrimModifier -> "TRAILING" -trimList = \ case+trimList = \case   ExprFromExprListTrimList a b -> aExpr a <> " FROM " <> exprList b   FromExprListTrimList a -> "FROM " <> exprList a   ExprListTrimList a -> exprList a - -- * AexprConsts-------------------------- -aexprConst = \ case+aexprConst = \case   IAexprConst a -> iconst a   FAexprConst a -> fconst a   SAexprConst a -> sconst a@@ -774,13 +738,13 @@  funcAexprConstArgList (FuncConstArgs a b) = commaNonEmpty funcArgExpr a <> suffixMaybe sortClause b -constTypename = \ case+constTypename = \case   NumericConstTypename a -> numeric a   ConstBitConstTypename a -> constBit a   ConstCharacterConstTypename a -> constCharacter a   ConstDatetimeConstTypename a -> constDatetime a -numeric = \ case+numeric = \case   IntNumeric -> "INT"   IntegerNumeric -> "INTEGER"   SmallintNumeric -> "SMALLINT"@@ -789,21 +753,22 @@   FloatNumeric a -> "FLOAT" <> suffixMaybe (inParens . int64Dec) a   DoublePrecisionNumeric -> "DOUBLE PRECISION"   DecimalNumeric a -> "DECIMAL" <> suffixMaybe (inParens . commaNonEmpty aExpr) a-  DecNumeric a -> "DEC" <> suffixMaybe (inParens . commaNonEmpty aExpr )a+  DecNumeric a -> "DEC" <> suffixMaybe (inParens . commaNonEmpty aExpr) a   NumericNumeric a -> "NUMERIC" <> suffixMaybe (inParens . commaNonEmpty aExpr) a   BooleanNumeric -> "BOOLEAN" -bit (Bit a b) = optLexemes [-    Just "BIT",-    bool Nothing (Just "VARYING") a,-    fmap (inParens . commaNonEmpty aExpr) b-  ]+bit (Bit a b) =+  optLexemes+    [ Just "BIT",+      bool Nothing (Just "VARYING") a,+      fmap (inParens . commaNonEmpty aExpr) b+    ]  constBit = bit  constCharacter (ConstCharacter a b) = character a <> suffixMaybe (inParens . int64Dec) b -character = \ case+character = \case   CharacterCharacter a -> "CHARACTER" <> bool "" " VARYING" a   CharCharacter a -> "CHAR" <> bool "" " VARYING" a   VarcharCharacter -> "VARCHAR"@@ -811,23 +776,25 @@   NationalCharCharacter a -> "NATIONAL CHAR" <> bool "" " VARYING" a   NcharCharacter a -> "NCHAR" <> bool "" " VARYING" a -constDatetime = \ case-  TimestampConstDatetime a b -> optLexemes [-      Just "TIMESTAMP",-      fmap (inParens . int64Dec) a,-      fmap timezone b-    ]-  TimeConstDatetime a b -> optLexemes [-      Just "TIME",-      fmap (inParens . int64Dec) a,-      fmap timezone b-    ]+constDatetime = \case+  TimestampConstDatetime a b ->+    optLexemes+      [ Just "TIMESTAMP",+        fmap (inParens . int64Dec) a,+        fmap timezone b+      ]+  TimeConstDatetime a b ->+    optLexemes+      [ Just "TIME",+        fmap (inParens . int64Dec) a,+        fmap timezone b+      ] -timezone = \ case+timezone = \case   False -> "WITH TIME ZONE"   True -> "WITHOUT TIME ZONE" -interval = \ case+interval = \case   YearInterval -> "YEAR"   MonthInterval -> "MONTH"   DayInterval -> "DAY"@@ -842,27 +809,25 @@   HourToSecondInterval a -> "HOUR TO " <> intervalSecond a   MinuteToSecondInterval a -> "MINUTE TO " <> intervalSecond a -intervalSecond = \ case-  Nothing -> "SECOND" +intervalSecond = \case+  Nothing -> "SECOND"   Just a -> "SECOND " <> inParens (int64Dec a) - -- * Names and refs--------------------------  columnref (Columnref a b) = colId a <> foldMap indirection b -ident = \ case+ident = \case   QuotedIdent a -> char7 '"' <> text (Text.replace "\"" "\"\"" a) <> char7 '"'   UnquotedIdent a -> text a -qualifiedName = \ case+qualifiedName = \case   SimpleQualifiedName a -> ident a   IndirectedQualifiedName a b -> ident a <> indirection b  indirection = foldMap indirectionEl -indirectionEl = \ case+indirectionEl = \case   AttrNameIndirectionEl a -> "." <> ident a   AllIndirectionEl -> ".*"   ExprIndirectionEl a -> "[" <> aExpr a <> "]"@@ -880,15 +845,13 @@  typeFunctionName = ident -funcName = \ case+funcName = \case   TypeFuncName a -> typeFunctionName a   IndirectedFuncName a b -> colId a <> indirection b  anyName (AnyName a b) = colId a <> foldMap attrs b - -- * Types--------------------------  typename (Typename a b c d) =   bool "" "SETOF " a <> simpleTypename b <> foldMap typenameArrayDimensionsWithQuestionMark d@@ -896,13 +859,13 @@ typenameArrayDimensionsWithQuestionMark (a, b) =   typenameArrayDimensions a -typenameArrayDimensions = \ case+typenameArrayDimensions = \case   BoundsTypenameArrayDimensions a -> arrayBounds a   ExplicitTypenameArrayDimensions a -> " ARRAY" <> foldMap (inBrackets . iconst) a  arrayBounds = spaceNonEmpty (inBrackets . foldMap iconst) -simpleTypename = \ case+simpleTypename = \case   GenericTypeSimpleTypename a -> genericType a   NumericSimpleTypename a -> numeric a   BitSimpleTypename a -> bit a@@ -918,25 +881,23 @@  typeList = commaNonEmpty typename -subType = \ case+subType = \case   AnySubType -> "ANY"   SomeSubType -> "SOME"   AllSubType -> "ALL" - -- * Indexes--------------------------  indexParams = commaNonEmpty indexElem  indexElem (IndexElem a b c d e) =-  indexElemDef a <>-  suffixMaybe collate b <>-  suffixMaybe class_ c <>-  suffixMaybe ascDesc d <>-  suffixMaybe nullsOrder e+  indexElemDef a+    <> suffixMaybe collate b+    <> suffixMaybe class_ c+    <> suffixMaybe ascDesc d+    <> suffixMaybe nullsOrder e -indexElemDef = \ case+indexElemDef = \case   IdIndexElemDef a -> colId a   FuncIndexElemDef a -> funcExprWindownless a   ExprIndexElemDef a -> inParens (aExpr a)@@ -945,10 +906,10 @@  class_ = anyName -ascDesc = \ case+ascDesc = \case   AscAscDesc -> "ASC"   DescAscDesc -> "DESC" -nullsOrder = \ case+nullsOrder = \case   FirstNullsOrder -> "NULLS FIRST"   LastNullsOrder -> "NULLS LAST"
library/PostgresqlSyntax/Validation.hs view
@@ -1,48 +1,52 @@ module PostgresqlSyntax.Validation where -import PostgresqlSyntax.Prelude hiding (expression) import qualified Data.HashSet as HashSet import qualified Data.Text as Text import qualified PostgresqlSyntax.KeywordSet as HashSet import qualified PostgresqlSyntax.Predicate as Predicate-+import PostgresqlSyntax.Prelude hiding (expression)  {--The operator name is a sequence of up to NAMEDATALEN-1 (63 by default) +The operator name is a sequence of up to NAMEDATALEN-1 (63 by default) characters from the following list:  + - * / < > = ~ ! @ # % ^ & | ` ?  There are a few restrictions on your choice of name:--- and /* cannot appear anywhere in an operator name, +-- and /* cannot appear anywhere in an operator name, since they will be taken as the start of a comment. -A multicharacter operator name cannot end in + or -, +A multicharacter operator name cannot end in + or -, unless the name also contains at least one of these characters:  ~ ! @ # % ^ & | ` ? -For example, @- is an allowed operator name, but *- is not. -This restriction allows PostgreSQL to parse SQL-compliant +For example, @- is an allowed operator name, but *- is not.+This restriction allows PostgreSQL to parse SQL-compliant commands without requiring spaces between tokens.-The use of => as an operator name is deprecated. +The use of => as an operator name is deprecated. It may be disallowed altogether in a future release. -The operator != is mapped to <> on input, +The operator != is mapped to <> on input, so these two names are always equivalent. -} op :: Text -> Maybe Text op a =   if Text.null a     then Just ("Operator is empty")-    else if Text.isInfixOf "--" a-      then Just ("Operator contains a prohibited \"--\" sequence: " <> a)-      else if Text.isInfixOf "/*" a-        then Just ("Operator contains a prohibited \"/*\" sequence: " <> a)-        else if Predicate.inSet HashSet.nonOp a-          then Just ("Operator is not generic: " <> a)-          else if Text.find Predicate.prohibitionLiftingOpChar a & isJust-            then Nothing-            else if Predicate.prohibitedOpChar (Text.last a)-              then Just ("Operator ends with a prohibited char: " <> a)-              else Nothing+    else+      if Text.isInfixOf "--" a+        then Just ("Operator contains a prohibited \"--\" sequence: " <> a)+        else+          if Text.isInfixOf "/*" a+            then Just ("Operator contains a prohibited \"/*\" sequence: " <> a)+            else+              if Predicate.inSet HashSet.nonOp a+                then Just ("Operator is not generic: " <> a)+                else+                  if Text.find Predicate.prohibitionLiftingOpChar a & isJust+                    then Nothing+                    else+                      if Predicate.prohibitedOpChar (Text.last a)+                        then Just ("Operator ends with a prohibited char: " <> a)+                        else Nothing
postgresql-syntax.cabal view
@@ -1,5 +1,5 @@ name: postgresql-syntax-version: 0.4+version: 0.4.0.1 category: Database, PostgreSQL, Parsing synopsis: PostgreSQL AST parsing and rendering description:@@ -40,14 +40,14 @@   build-depends:     base >=4.12 && <5,     bytestring >=0.10 && <0.12,-    case-insensitive >=1.2 && <2,-    hashable >=1.2 && <2,+    case-insensitive >=1.2.1 && <2,+    hashable >=1.3.5 && <2,     headed-megaparsec >=0.2.0.1 && <0.3,-    megaparsec >=9 && <10,-    parser-combinators >=1.1 && <1.4,-    text >=1 && <2,-    text-builder >=0.6.6.1 && <0.7,-    unordered-containers >=0.2.10 && <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
tasty-test/Main.hs view
@@ -1,45 +1,71 @@ module Main where -import Prelude hiding (assert)+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.Runners import Test.Tasty.HUnit import Test.Tasty.QuickCheck-import qualified Test.QuickCheck as QuickCheck-import qualified PostgresqlSyntax.Ast as Ast-import qualified PostgresqlSyntax.Parsing as Parsing-import qualified PostgresqlSyntax.Rendering as Rendering-import qualified Data.Text as Text-+import Test.Tasty.Runners+import Prelude hiding (assert) -main = 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-          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"-            ]-        ]-  ]+main =+  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+                      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"+                  ]+              ]+      ]