module PostgresqlSyntax.Ast.SelectStmt where

import PostgresqlSyntax.Algebra
import {-# SOURCE #-} PostgresqlSyntax.Ast.SelectNoParens (SelectNoParens)
import {-# SOURCE #-} PostgresqlSyntax.Ast.SelectWithParens (SelectWithParens)
import qualified PostgresqlSyntax.Helpers.Gens as Gens
import PostgresqlSyntax.Prelude
import qualified Test.QuickCheck as Qc

-- |
-- ==== References
-- @
-- SelectStmt:
--   |  select_no_parens
--   |  select_with_parens
-- @
data SelectStmt
  = NoParensSelectStmt SelectNoParens
  | WithParensSelectStmt SelectWithParens
  deriving (Int -> SelectStmt -> ShowS
[SelectStmt] -> ShowS
SelectStmt -> String
(Int -> SelectStmt -> ShowS)
-> (SelectStmt -> String)
-> ([SelectStmt] -> ShowS)
-> Show SelectStmt
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> SelectStmt -> ShowS
showsPrec :: Int -> SelectStmt -> ShowS
$cshow :: SelectStmt -> String
show :: SelectStmt -> String
$cshowList :: [SelectStmt] -> ShowS
showList :: [SelectStmt] -> ShowS
Show, (forall x. SelectStmt -> Rep SelectStmt x)
-> (forall x. Rep SelectStmt x -> SelectStmt) -> Generic SelectStmt
forall x. Rep SelectStmt x -> SelectStmt
forall x. SelectStmt -> Rep SelectStmt x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. SelectStmt -> Rep SelectStmt x
from :: forall x. SelectStmt -> Rep SelectStmt x
$cto :: forall x. Rep SelectStmt x -> SelectStmt
to :: forall x. Rep SelectStmt x -> SelectStmt
Generic, SelectStmt -> SelectStmt -> Bool
(SelectStmt -> SelectStmt -> Bool)
-> (SelectStmt -> SelectStmt -> Bool) -> Eq SelectStmt
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: SelectStmt -> SelectStmt -> Bool
== :: SelectStmt -> SelectStmt -> Bool
$c/= :: SelectStmt -> SelectStmt -> Bool
/= :: SelectStmt -> SelectStmt -> Bool
Eq, Eq SelectStmt
Eq SelectStmt =>
(SelectStmt -> SelectStmt -> Ordering)
-> (SelectStmt -> SelectStmt -> Bool)
-> (SelectStmt -> SelectStmt -> Bool)
-> (SelectStmt -> SelectStmt -> Bool)
-> (SelectStmt -> SelectStmt -> Bool)
-> (SelectStmt -> SelectStmt -> SelectStmt)
-> (SelectStmt -> SelectStmt -> SelectStmt)
-> Ord SelectStmt
SelectStmt -> SelectStmt -> Bool
SelectStmt -> SelectStmt -> Ordering
SelectStmt -> SelectStmt -> SelectStmt
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: SelectStmt -> SelectStmt -> Ordering
compare :: SelectStmt -> SelectStmt -> Ordering
$c< :: SelectStmt -> SelectStmt -> Bool
< :: SelectStmt -> SelectStmt -> Bool
$c<= :: SelectStmt -> SelectStmt -> Bool
<= :: SelectStmt -> SelectStmt -> Bool
$c> :: SelectStmt -> SelectStmt -> Bool
> :: SelectStmt -> SelectStmt -> Bool
$c>= :: SelectStmt -> SelectStmt -> Bool
>= :: SelectStmt -> SelectStmt -> Bool
$cmax :: SelectStmt -> SelectStmt -> SelectStmt
max :: SelectStmt -> SelectStmt -> SelectStmt
$cmin :: SelectStmt -> SelectStmt -> SelectStmt
min :: SelectStmt -> SelectStmt -> SelectStmt
Ord, Typeable SelectStmt
Typeable SelectStmt =>
(forall (c :: * -> *).
 (forall d b. Data d => c (d -> b) -> d -> c b)
 -> (forall g. g -> c g) -> SelectStmt -> c SelectStmt)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c SelectStmt)
-> (SelectStmt -> Constr)
-> (SelectStmt -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c SelectStmt))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e))
    -> Maybe (c SelectStmt))
-> ((forall b. Data b => b -> b) -> SelectStmt -> SelectStmt)
-> (forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> SelectStmt -> r)
-> (forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> SelectStmt -> r)
-> (forall u. (forall d. Data d => d -> u) -> SelectStmt -> [u])
-> (forall u.
    Int -> (forall d. Data d => d -> u) -> SelectStmt -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> SelectStmt -> m SelectStmt)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> SelectStmt -> m SelectStmt)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> SelectStmt -> m SelectStmt)
-> Data SelectStmt
SelectStmt -> Constr
SelectStmt -> DataType
(forall b. Data b => b -> b) -> SelectStmt -> SelectStmt
forall a.
Typeable a =>
(forall (c :: * -> *).
 (forall d b. Data d => c (d -> b) -> d -> c b)
 -> (forall g. g -> c g) -> a -> c a)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c a)
-> (a -> Constr)
-> (a -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c a))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
-> ((forall b. Data b => b -> b) -> a -> a)
-> (forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall u. (forall d. Data d => d -> u) -> a -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> Data a
forall u. Int -> (forall d. Data d => d -> u) -> SelectStmt -> u
forall u. (forall d. Data d => d -> u) -> SelectStmt -> [u]
forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> SelectStmt -> r
forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> SelectStmt -> r
forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> SelectStmt -> m SelectStmt
forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> SelectStmt -> m SelectStmt
forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c SelectStmt
forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> SelectStmt -> c SelectStmt
forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c SelectStmt)
forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c SelectStmt)
$cgfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> SelectStmt -> c SelectStmt
gfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> SelectStmt -> c SelectStmt
$cgunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c SelectStmt
gunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c SelectStmt
$ctoConstr :: SelectStmt -> Constr
toConstr :: SelectStmt -> Constr
$cdataTypeOf :: SelectStmt -> DataType
dataTypeOf :: SelectStmt -> DataType
$cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c SelectStmt)
dataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c SelectStmt)
$cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c SelectStmt)
dataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c SelectStmt)
$cgmapT :: (forall b. Data b => b -> b) -> SelectStmt -> SelectStmt
gmapT :: (forall b. Data b => b -> b) -> SelectStmt -> SelectStmt
$cgmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> SelectStmt -> r
gmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> SelectStmt -> r
$cgmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> SelectStmt -> r
gmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> SelectStmt -> r
$cgmapQ :: forall u. (forall d. Data d => d -> u) -> SelectStmt -> [u]
gmapQ :: forall u. (forall d. Data d => d -> u) -> SelectStmt -> [u]
$cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> SelectStmt -> u
gmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> SelectStmt -> u
$cgmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> SelectStmt -> m SelectStmt
gmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> SelectStmt -> m SelectStmt
$cgmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> SelectStmt -> m SelectStmt
gmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> SelectStmt -> m SelectStmt
$cgmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> SelectStmt -> m SelectStmt
gmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> SelectStmt -> m SelectStmt
Data)

instance IsAst SelectStmt where
  toTextBuilder :: Settings -> SelectStmt -> TextBuilder
toTextBuilder Settings
settings = \case
    NoParensSelectStmt SelectNoParens
a -> Settings -> SelectNoParens -> TextBuilder
forall a. IsAst a => Settings -> a -> TextBuilder
toTextBuilder Settings
settings SelectNoParens
a
    WithParensSelectStmt SelectWithParens
a -> Settings -> SelectWithParens -> TextBuilder
forall a. IsAst a => Settings -> a -> TextBuilder
toTextBuilder Settings
settings SelectWithParens
a
  parser :: Settings -> Parser SelectStmt
parser Settings
settings = SelectNoParens -> SelectStmt
NoParensSelectStmt (SelectNoParens -> SelectStmt)
-> HeadedParsec Void Text SelectNoParens -> Parser SelectStmt
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Settings -> HeadedParsec Void Text SelectNoParens
forall a. IsAst a => Settings -> Parser a
parser Settings
settings Parser SelectStmt -> Parser SelectStmt -> Parser SelectStmt
forall a.
HeadedParsec Void Text a
-> HeadedParsec Void Text a -> HeadedParsec Void Text a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> SelectWithParens -> SelectStmt
WithParensSelectStmt (SelectWithParens -> SelectStmt)
-> HeadedParsec Void Text SelectWithParens -> Parser SelectStmt
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Settings -> HeadedParsec Void Text SelectWithParens
forall a. IsAst a => Settings -> Parser a
parser Settings
settings

instance Qc.Arbitrary SelectStmt where
  shrink :: SelectStmt -> [SelectStmt]
shrink = SelectStmt -> [SelectStmt]
forall a.
(Generic a, RecursivelyShrink (Rep a), GSubterms (Rep a) a) =>
a -> [a]
Qc.genericShrink

  -- @WithParensSelectStmt@ is unreachable via this type's own @parser@:
  -- @NoParensSelectStmt@'s alternative is tried first, and
  -- 'PostgresqlSyntax.Ast.SelectClause' (reachable from any
  -- @select_no_parens@ with every other clause absent) always accepts a
  -- parenthesized select too — so any @'(' select ')'@ text always parses
  -- as @NoParensSelectStmt (SelectNoParens Nothing (WithParensSelectClause
  -- _) Nothing Nothing Nothing)@, never as a bare @WithParensSelectStmt@.
  -- Generating the latter would therefore never round-trip.
  arbitrary :: Gen SelectStmt
arbitrary = SelectNoParens -> SelectStmt
NoParensSelectStmt (SelectNoParens -> SelectStmt)
-> Gen SelectNoParens -> Gen SelectStmt
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Gen SelectNoParens -> Gen SelectNoParens
forall a. Gen a -> Gen a
Gens.downscale Gen SelectNoParens
forall a. Arbitrary a => Gen a
Qc.arbitrary