module Sqel.Data.SelectExpr where

import qualified Exon

import Sqel.Data.Dd (QOp)
import Sqel.Data.FragType (FragType, renderWithFragKeyword)
import Sqel.Data.Selector (Selector)
import Sqel.Data.Sql (Sql, ToSql (toSql))

data SelectAtom =
  SelectAtom {
    SelectAtom -> FragType
type_ :: FragType,
    SelectAtom -> Selector -> Int -> Sql
code :: Selector -> Int -> Sql
  }
  deriving stock (forall x. Rep SelectAtom x -> SelectAtom
forall x. SelectAtom -> Rep SelectAtom x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep SelectAtom x -> SelectAtom
$cfrom :: forall x. SelectAtom -> Rep SelectAtom x
Generic)

data SelectFragment =
  SelectFragment {
     SelectFragment -> FragType
type_ :: FragType,
     SelectFragment -> Sql
content :: Sql
  }
  deriving stock (Int -> SelectFragment -> ShowS
[SelectFragment] -> ShowS
SelectFragment -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [SelectFragment] -> ShowS
$cshowList :: [SelectFragment] -> ShowS
show :: SelectFragment -> String
$cshow :: SelectFragment -> String
showsPrec :: Int -> SelectFragment -> ShowS
$cshowsPrec :: Int -> SelectFragment -> ShowS
Show, SelectFragment -> SelectFragment -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: SelectFragment -> SelectFragment -> Bool
$c/= :: SelectFragment -> SelectFragment -> Bool
== :: SelectFragment -> SelectFragment -> Bool
$c== :: SelectFragment -> SelectFragment -> Bool
Eq, forall x. Rep SelectFragment x -> SelectFragment
forall x. SelectFragment -> Rep SelectFragment x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep SelectFragment x -> SelectFragment
$cfrom :: forall x. SelectFragment -> Rep SelectFragment x
Generic, Eq SelectFragment
SelectFragment -> SelectFragment -> Bool
SelectFragment -> SelectFragment -> Ordering
SelectFragment -> SelectFragment -> SelectFragment
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
min :: SelectFragment -> SelectFragment -> SelectFragment
$cmin :: SelectFragment -> SelectFragment -> SelectFragment
max :: SelectFragment -> SelectFragment -> SelectFragment
$cmax :: SelectFragment -> SelectFragment -> SelectFragment
>= :: SelectFragment -> SelectFragment -> Bool
$c>= :: SelectFragment -> SelectFragment -> Bool
> :: SelectFragment -> SelectFragment -> Bool
$c> :: SelectFragment -> SelectFragment -> Bool
<= :: SelectFragment -> SelectFragment -> Bool
$c<= :: SelectFragment -> SelectFragment -> Bool
< :: SelectFragment -> SelectFragment -> Bool
$c< :: SelectFragment -> SelectFragment -> Bool
compare :: SelectFragment -> SelectFragment -> Ordering
$ccompare :: SelectFragment -> SelectFragment -> Ordering
Ord)

renderSelectFragment :: SelectFragment -> Sql
renderSelectFragment :: SelectFragment -> Sql
renderSelectFragment SelectFragment {Sql
FragType
content :: Sql
type_ :: FragType
$sel:content:SelectFragment :: SelectFragment -> Sql
$sel:type_:SelectFragment :: SelectFragment -> FragType
..} =
  Sql -> FragType -> Sql
renderWithFragKeyword Sql
content FragType
type_

instance ToSql [SelectFragment] where
  toSql :: [SelectFragment] -> Sql
toSql = forall a (t :: * -> *). (Monoid a, Foldable t) => a -> t a -> a
Exon.intercalate Sql
" " forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap SelectFragment -> Sql
renderSelectFragment forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Ord a => [a] -> [a]
sort

data SelectExpr =
  SelectExprAtom FragType (Int -> Sql)
  |
  SelectExprList QOp [SelectExpr]
  |
  SelectExprSum [SelectExpr]
  |
  SelectExprNot SelectExpr
  |
  SelectExprIgnore