module Database.Selda.Transform where
import Database.Selda.Column
import Database.Selda.SQL
import Database.Selda.Query.Type
import Database.Selda.Types
removeDeadCols :: [ColName] -> SQL -> SQL
removeDeadCols live sql =
case source sql' of
EmptyTable -> sql'
TableName _ -> sql'
Values _ _ -> sql'
RawSql _ -> sql'
Product qs -> sql' {source = Product $ map noDead qs}
Join jt on l r -> sql' {source = Join jt on (noDead l) (noDead r)}
where
noDead = removeDeadCols live'
sql' = keepCols (allNonOutputColNames sql ++ live) sql
live' = allColNames sql'
allColNames :: SQL -> [ColName]
allColNames sql = colNames (cols sql) ++ allNonOutputColNames sql
allNonOutputColNames :: SQL -> [ColName]
allNonOutputColNames sql = concat
[ concatMap allNamesIn (restricts sql)
, colNames (groups sql)
, colNames (map snd $ ordering sql)
, case source sql of
Join _ on _ _ -> allNamesIn on
_ -> []
]
colNames :: [SomeCol SQL] -> [ColName]
colNames cs = concat
[ [n | Some c <- cs, n <- allNamesIn c]
, [n | Named _ c <- cs, n <- allNamesIn c]
, [n | Named n _ <- cs]
]
keepCols :: [ColName] -> SQL -> SQL
keepCols live sql = sql {cols = filtered}
where
filtered = filter (`oneOf` live) (cols sql)
oneOf (Some (AggrEx _ _)) _ = True
oneOf (Named _ (AggrEx _ _)) _ = True
oneOf (Some (Col n)) ns = n `elem` ns
oneOf (Named n _) ns = n `elem` ns
oneOf _ _ = False
state2sql :: GenState -> SQL
state2sql (GenState [sql] srs _ _ _) =
sql {restricts = restricts sql ++ srs}
state2sql (GenState ss srs _ _ _) =
SQL (allCols ss) (Product ss) srs [] [] Nothing False
allCols :: [SQL] -> [SomeCol SQL]
allCols sqls = [outCol col | sql <- sqls, col <- cols sql]
where
outCol (Named n _) = Some (Col n)
outCol c = c