packages feed

dsh-sql-0.2.0.0: src/Database/DSH/Backend/Sql/Opt/Properties/Auxiliary.hs

-- | Some auxiliary functions for property inference.
module Database.DSH.Backend.Sql.Opt.Properties.Auxiliary where

import qualified Data.List                   as L
import qualified Data.Map                    as M
import qualified Data.Set.Monad              as S

import           Database.Algebra.Table.Lang

(∪) :: Ord a => S.Set a -> S.Set a -> S.Set a
(∪) = S.union

(∩) :: Ord a => S.Set a -> S.Set a -> S.Set a
(∩) = S.intersection

(∖) :: Ord a => S.Set a -> S.Set a -> S.Set a
(∖) = S.difference

(∈) :: Ord a => a -> S.Set a -> Bool
(∈) = S.member

(⊆) :: Ord a => S.Set a -> S.Set a -> Bool
(⊆) = S.isSubsetOf

-- | Singleton set abbreviation
ss :: Ord a => a -> S.Set a
ss = S.singleton

-- | List set abbreviation
ls :: Ord a => [a] -> S.Set a
ls = S.fromList

unionss :: Ord a => S.Set (S.Set a) -> S.Set a
unionss = S.foldr (∪) S.empty

exprCols :: Expr -> S.Set Attr
exprCols (BinAppE _ e1 e2) = exprCols e1 ∪ exprCols e2
exprCols (IfE c t e)       = exprCols c ∪ exprCols t ∪ exprCols e
exprCols (UnAppE _ e)      = exprCols e
exprCols (ColE c)          = S.singleton c
exprCols (ConstE _)        = S.empty

aggrInput :: AggrType -> S.Set Attr
aggrInput (Avg e)   = exprCols e
aggrInput (Max e)   = exprCols e
aggrInput (Min e)   = exprCols e
aggrInput (Sum e)   = exprCols e
aggrInput (All e)   = exprCols e
aggrInput (Any e)   = exprCols e
aggrInput (Count e) = exprCols e
aggrInput CountStar = S.empty

winFunInput :: WinFun -> S.Set Attr
winFunInput (WinAvg e)        = exprCols e
winFunInput (WinMax e)        = exprCols e
winFunInput (WinMin e)        = exprCols e
winFunInput (WinSum e)        = exprCols e
winFunInput (WinAll e)        = exprCols e
winFunInput (WinAny e)        = exprCols e
winFunInput (WinFirstValue e) = exprCols e
winFunInput (WinLastValue e)  = exprCols e
winFunInput WinCount          = S.empty

mapCol :: Proj -> Maybe (Attr, Attr)
mapCol (a, ColE b)                   = Just (a, b)
mapCol (a, UnAppE (Cast _) (ColE b)) = Just (a, b)
mapCol _                             = Nothing

-- | Build a map from a projection list that maps each attribute to
-- its new names after projection. Only attributes that are simply
-- renamed are considered.
mapColMulti :: [Proj] -> M.Map Attr (S.Set Attr)
mapColMulti projs = L.foldl' insertMap M.empty projs
  where
    insertMap m (a, ColE b)                   = M.insertWith S.union b (ss a) m
    insertMap m (a, UnAppE (Cast _) (ColE b)) = M.insertWith S.union b (ss a) m
    insertMap m _                             = m

mColE :: Expr -> Maybe Attr
mColE (ColE c) = Just c
mColE _        = Nothing