<commit_before>
> -- | These is the pretty printing functions, which produce SQL
> -- source from ASTs. The code attempts to format the output in a
> -- readable way.
> module Language.SQL.SimpleSQL.Pretty
>     (prettyQueryExpr
>     ,prettyValueExpr
>     ,prettyQueryExprs
>     ) where

> import Language.SQL.SimpleSQL.Syntax
> import Text.PrettyPrint
> import Data.Maybe

> -- | Convert a query expr ast to concrete syntax.
> prettyQueryExpr :: QueryExpr -> String
> prettyQueryExpr = render . queryExpr

> -- | Convert a value expr ast to concrete syntax.
> prettyValueExpr :: ValueExpr -> String
> prettyValueExpr = render . valueExpr

> -- | Convert a list of query exprs to concrete syntax. A semi colon
> -- is inserted after each query expr.
> prettyQueryExprs :: [QueryExpr] -> String
> prettyQueryExprs = render . vcat . map ((<> text ";\n") . queryExpr)

= value expressions

> valueExpr :: ValueExpr -> Doc
> valueExpr (StringLit s) = quotes $ text $ doubleUpQuotes s
>   where doubleUpQuotes [] = []
>         doubleUpQuotes ('\'':cs) = '\'':'\'':doubleUpQuotes cs
>         doubleUpQuotes (c:cs) = c:doubleUpQuotes cs

> valueExpr (NumLit s) = text s
> valueExpr (IntervalLit v u p) =
>     text "interval" <+> quotes (text v)
>     <+> text u
>     <+> maybe empty (parens . text . show ) p
> valueExpr (Iden i) = name i
> valueExpr Star = text "*"
> valueExpr Parameter = text "?"

> valueExpr (App f es) = name f <> parens (commaSep (map valueExpr es))

> valueExpr (AggregateApp f d es od) =
>     name f
>     <> parens ((case d of
>                   Just Distinct -> text "distinct"
>                   Just All -> text "all"
>                   Nothing -> empty)
>                <+> commaSep (map valueExpr es)
>                <+> orderBy od)

> valueExpr (WindowApp f es pb od fr) =
>     name f <> parens (commaSep $ map valueExpr es)
>     <+> text "over"
>     <+> parens ((case pb of
>                     [] -> empty
>                     _ -> text "partition by"
>                           <+> nest 13 (commaSep $ map valueExpr pb))
>                 <+> orderBy od
>     <+> maybe empty frd fr)
>   where
>     frd (FrameFrom rs fp) = rsd rs <+> fpd fp
>     frd (FrameBetween rs fps fpe) =
>         rsd rs <+> text "between" <+> fpd fps
>         <+> text "and" <+> fpd fpe
>     rsd rs = case rs of
>                  FrameRows -> text "rows"
>                  FrameRange -> text "range"
>     fpd UnboundedPreceding = text "unbounded preceding"
>     fpd UnboundedFollowing = text "unbounded following"
>     fpd Current = text "current row"
>     fpd (Preceding e) = valueExpr e <+> text "preceding"
>     fpd (Following e) = valueExpr e <+> text "following"

> valueExpr (SpecialOp nm [a,b,c]) | nm `elem` [Name "between"
>                                               ,Name "not between"] =
>   sep [valueExpr a
>       ,name nm <+> valueExpr b
>       ,nest (length (unname nm) + 1) $ text "and" <+> valueExpr c]

> valueExpr (SpecialOp (Name "rowctor") as) =
>     parens $ commaSep $ map valueExpr as

> valueExpr (SpecialOp nm es) =
>   name nm <+> parens (commaSep $ map valueExpr es)

> valueExpr (SpecialOpK nm fs as) =
>     name nm <> parens (sep $ catMaybes
>         ((fmap valueExpr fs)
>          : map (\(n,e) -> Just (text n <+> valueExpr e)) as))

> valueExpr (PrefixOp f e) = name f <+> valueExpr e
> valueExpr (PostfixOp f e) = valueExpr e <+> name f
> valueExpr e@(BinOp _ op _) | op `elem` [Name "and", Name "or"] =
>     -- special case for and, or, get all the ands so we can vcat them
>     -- nicely
>     case ands e of
>       (e':es) -> vcat (valueExpr e'
>                        : map ((name op <+>) . valueExpr) es)
>       [] -> empty -- shouldn't be possible
>   where
>     ands (BinOp a op' b) | op == op' = ands a ++ ands b
>     ands x = [x]
> -- special case for . we don't use whitespace
> valueExpr (BinOp e0 (Name ".") e1) =
>     valueExpr e0 <> text "." <> valueExpr e1
> valueExpr (BinOp e0 f e1) =
>     valueExpr e0 <+> name f <+> valueExpr e1

> valueExpr (Case t ws els) =
>     sep $ [text "case" <+> maybe empty valueExpr t]
>           ++ map w ws
>           ++ maybeToList (fmap e els)
>           ++ [text "end"]
>   where
>     w (t0,t1) =
>       text "when" <+> nest 5 (commaSep $ map valueExpr t0)
>       <+> text "then" <+> nest 5 (valueExpr t1)
>     e el = text "else" <+> nest 5 (valueExpr el)
> valueExpr (Parens e) = parens $ valueExpr e
> valueExpr (Cast e tn) =
>     text "cast" <> parens (sep [valueExpr e
>                                ,text "as"
>                                ,typeName tn])

> valueExpr (TypedLit tn s) =
>     typeName tn <+> quotes (text s)

> valueExpr (SubQueryExpr ty qe) =
>     (case ty of
>         SqSq -> empty
>         SqExists -> text "exists"
>         SqAll -> text "all"
>         SqSome -> text "some"
>         SqAny -> text "any"
>     ) <+> parens (queryExpr qe)

> valueExpr (In b se x) =
>     valueExpr se <+>
>     (if b then empty else text "not")
>     <+> text "in"
>     <+> parens (nest (if b then 3 else 7) $
>                  case x of
>                      InList es -> commaSep $ map valueExpr es
>                      InQueryExpr qe -> queryExpr qe)

> unname :: Name -> String
> unname (QName n) = "\"" ++ n ++ "\""
> unname (Name n) = n

> name :: Name -> Doc
> name (QName n) = doubleQuotes $ text n
> name (Name n) = text n

> typeName :: TypeName -> Doc
> typeName (TypeName t) = text t
> typeName (PrecTypeName t a) = text t <+> parens (text $ show a)
> typeName (PrecScaleTypeName t a b) =
>     text t <+> parens (text (show a) <+> comma <+> text (show b))


= query expressions

> queryExpr :: QueryExpr -> Doc
> queryExpr (Select d sl fr wh gb hv od off fe) =
>   sep [text "select"
>       ,case d of
>           All -> empty
>           Distinct -> text "distinct"
>       ,nest 7 $ sep [selectList sl]
>       ,from fr
>       ,maybeValueExpr "where" wh
>       ,grpBy gb
>       ,maybeValueExpr "having" hv
>       ,orderBy od
>       ,maybe empty (\e -> text "offset" <+> valueExpr e <+> text "rows") off
>       ,maybe empty (\e -> text "fetch next" <+> valueExpr e
>                           <+> text "rows only") fe
>       ]
> queryExpr (CombineQueryExpr q1 ct d c q2) =
>   sep [queryExpr q1
>       ,text (case ct of
>                 Union -> "union"
>                 Intersect -> "intersect"
>                 Except -> "except")
>        <+> case d of
>                All -> empty
>                Distinct -> text "distinct"
>        <+> case c of
>                Corresponding -> text "corresponding"
>                Respectively -> empty
>       ,queryExpr q2]
> queryExpr (With rc withs qe) =
>   text "with" <+> (if rc then text "recursive" else empty)
>   <+> vcat [nest 5
>             (vcat $ punctuate comma $ flip map withs $ \(n,q) ->
>              alias n <+> text "as" <+> parens (queryExpr q))<commit_msg>change pretty printer to output 'fetch first' instead of 'fetch next'<commit_after>
> -- | These is the pretty printing functions, which produce SQL
> -- source from ASTs. The code attempts to format the output in a
> -- readable way.
> module Language.SQL.SimpleSQL.Pretty
>     (prettyQueryExpr
>     ,prettyValueExpr
>     ,prettyQueryExprs
>     ) where

> import Language.SQL.SimpleSQL.Syntax
> import Text.PrettyPrint
> import Data.Maybe

> -- | Convert a query expr ast to concrete syntax.
> prettyQueryExpr :: QueryExpr -> String
> prettyQueryExpr = render . queryExpr

> -- | Convert a value expr ast to concrete syntax.
> prettyValueExpr :: ValueExpr -> String
> prettyValueExpr = render . valueExpr

> -- | Convert a list of query exprs to concrete syntax. A semi colon
> -- is inserted after each query expr.
> prettyQueryExprs :: [QueryExpr] -> String
> prettyQueryExprs = render . vcat . map ((<> text ";\n") . queryExpr)

= value expressions

> valueExpr :: ValueExpr -> Doc
> valueExpr (StringLit s) = quotes $ text $ doubleUpQuotes s
>   where doubleUpQuotes [] = []
>         doubleUpQuotes ('\'':cs) = '\'':'\'':doubleUpQuotes cs
>         doubleUpQuotes (c:cs) = c:doubleUpQuotes cs

> valueExpr (NumLit s) = text s
> valueExpr (IntervalLit v u p) =
>     text "interval" <+> quotes (text v)
>     <+> text u
>     <+> maybe empty (parens . text . show ) p
> valueExpr (Iden i) = name i
> valueExpr Star = text "*"
> valueExpr Parameter = text "?"

> valueExpr (App f es) = name f <> parens (commaSep (map valueExpr es))

> valueExpr (AggregateApp f d es od) =
>     name f
>     <> parens ((case d of
>                   Just Distinct -> text "distinct"
>                   Just All -> text "all"
>                   Nothing -> empty)
>                <+> commaSep (map valueExpr es)
>                <+> orderBy od)

> valueExpr (WindowApp f es pb od fr) =
>     name f <> parens (commaSep $ map valueExpr es)
>     <+> text "over"
>     <+> parens ((case pb of
>                     [] -> empty
>                     _ -> text "partition by"
>                           <+> nest 13 (commaSep $ map valueExpr pb))
>                 <+> orderBy od
>     <+> maybe empty frd fr)
>   where
>     frd (FrameFrom rs fp) = rsd rs <+> fpd fp
>     frd (FrameBetween rs fps fpe) =
>         rsd rs <+> text "between" <+> fpd fps
>         <+> text "and" <+> fpd fpe
>     rsd rs = case rs of
>                  FrameRows -> text "rows"
>                  FrameRange -> text "range"
>     fpd UnboundedPreceding = text "unbounded preceding"
>     fpd UnboundedFollowing = text "unbounded following"
>     fpd Current = text "current row"
>     fpd (Preceding e) = valueExpr e <+> text "preceding"
>     fpd (Following e) = valueExpr e <+> text "following"

> valueExpr (SpecialOp nm [a,b,c]) | nm `elem` [Name "between"
>                                               ,Name "not between"] =
>   sep [valueExpr a
>       ,name nm <+> valueExpr b
>       ,nest (length (unname nm) + 1) $ text "and" <+> valueExpr c]

> valueExpr (SpecialOp (Name "rowctor") as) =
>     parens $ commaSep $ map valueExpr as

> valueExpr (SpecialOp nm es) =
>   name nm <+> parens (commaSep $ map valueExpr es)

> valueExpr (SpecialOpK nm fs as) =
>     name nm <> parens (sep $ catMaybes
>         ((fmap valueExpr fs)
>          : map (\(n,e) -> Just (text n <+> valueExpr e)) as))

> valueExpr (PrefixOp f e) = name f <+> valueExpr e
> valueExpr (PostfixOp f e) = valueExpr e <+> name f
> valueExpr e@(BinOp _ op _) | op `elem` [Name "and", Name "or"] =
>     -- special case for and, or, get all the ands so we can vcat them
>     -- nicely
>     case ands e of
>       (e':es) -> vcat (valueExpr e'
>                        : map ((name op <+>) . valueExpr) es)
>       [] -> empty -- shouldn't be possible
>   where
>     ands (BinOp a op' b) | op == op' = ands a ++ ands b
>     ands x = [x]
> -- special case for . we don't use whitespace
> valueExpr (BinOp e0 (Name ".") e1) =
>     valueExpr e0 <> text "." <> valueExpr e1
> valueExpr (BinOp e0 f e1) =
>     valueExpr e0 <+> name f <+> valueExpr e1

> valueExpr (Case t ws els) =
>     sep $ [text "case" <+> maybe empty valueExpr t]
>           ++ map w ws
>           ++ maybeToList (fmap e els)
>           ++ [text "end"]
>   where
>     w (t0,t1) =
>       text "when" <+> nest 5 (commaSep $ map valueExpr t0)
>       <+> text "then" <+> nest 5 (valueExpr t1)
>     e el = text "else" <+> nest 5 (valueExpr el)
> valueExpr (Parens e) = parens $ valueExpr e
> valueExpr (Cast e tn) =
>     text "cast" <> parens (sep [valueExpr e
>                                ,text "as"
>                                ,typeName tn])

> valueExpr (TypedLit tn s) =
>     typeName tn <+> quotes (text s)

> valueExpr (SubQueryExpr ty qe) =
>     (case ty of
>         SqSq -> empty
>         SqExists -> text "exists"
>         SqAll -> text "all"
>         SqSome -> text "some"
>         SqAny -> text "any"
>     ) <+> parens (queryExpr qe)

> valueExpr (In b se x) =
>     valueExpr se <+>
>     (if b then empty else text "not")
>     <+> text "in"
>     <+> parens (nest (if b then 3 else 7) $
>                  case x of
>                      InList es -> commaSep $ map valueExpr es
>                      InQueryExpr qe -> queryExpr qe)

> unname :: Name -> String
> unname (QName n) = "\"" ++ n ++ "\""
> unname (Name n) = n

> name :: Name -> Doc
> name (QName n) = doubleQuotes $ text n
> name (Name n) = text n

> typeName :: TypeName -> Doc
> typeName (TypeName t) = text t
> typeName (PrecTypeName t a) = text t <+> parens (text $ show a)
> typeName (PrecScaleTypeName t a b) =
>     text t <+> parens (text (show a) <+> comma <+> text (show b))


= query expressions

> queryExpr :: QueryExpr -> Doc
> queryExpr (Select d sl fr wh gb hv od off fe) =
>   sep [text "select"
>       ,case d of
>           All -> empty
>           Distinct -> text "distinct"
>       ,nest 7 $ sep [selectList sl]
>       ,from fr
>       ,maybeValueExpr "where" wh
>       ,grpBy gb
>       ,maybeValueExpr "having" hv
>       ,orderBy od
>       ,maybe empty (\e -> text "offset" <+> valueExpr e <+> text "rows") off
>       ,maybe empty (\e -> text "fetch first" <+> valueExpr e
>                           <+> text "rows only") fe
>       ]
> queryExpr (CombineQueryExpr q1 ct d c q2) =
>   sep [queryExpr q1
>       ,text (case ct of
>                 Union -> "union"
>                 Intersect -> "intersect"
>                 Except -> "except")
>        <+> case d of
>                All -> empty
>                Distinct -> text "distinct"
>        <+> case c of
>                Corresponding -> text "corresponding"
>                Respectively -> empty
>       ,queryExpr q2]
> queryExpr (With rc withs qe) =
>   text "with" <+> (if rc then text "recursive" else empty)
>   <+> vcat [nest 5
>             (vcat $ punctuate comma $ flip map withs $ \(n,q) ->
>              alias n <+> text "as" <+> parens (queryExpr q))
{'fraction_non_alphanumeric': 0.14011364453715025, 'fraction_numerical': 0.003740199956843847, 'mean_word_length': 2.008872538411599, 'pattern_counts': {'":': 0, '<': 119, '<?xml version=': 0, '>': 539, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '225358', 'n_tokens_mistral': 4771, 'n_tokens_neox': 4598, 'n_words': 1579}