module Opaleye.SQLite.Internal.Optimize where
import Prelude hiding (product)
import qualified Opaleye.SQLite.Internal.PrimQuery as PQ
import qualified Data.List.NonEmpty as NEL
optimize :: PQ.PrimQuery -> PQ.PrimQuery
optimize = mergeProduct . removeUnit
removeUnit :: PQ.PrimQuery -> PQ.PrimQuery
removeUnit = PQ.foldPrimQuery (PQ.Unit, PQ.BaseTable, product, PQ.Aggregate,
PQ.Order, PQ.Limit, PQ.Join, PQ.Values,
PQ.Binary)
where product pqs pes = PQ.Product pqs' pes
where pqs' = case NEL.filter (not . PQ.isUnit) pqs of
[] -> return PQ.Unit
xs -> NEL.fromList xs
mergeProduct :: PQ.PrimQuery -> PQ.PrimQuery
mergeProduct = PQ.foldPrimQuery (PQ.Unit, PQ.BaseTable, product, PQ.Aggregate,
PQ.Order, PQ.Limit, PQ.Join, PQ.Values,
PQ.Binary)
where product pqs pes = PQ.Product pqs' (pes ++ pes')
where pqs' = pqs >>= queries
queries (PQ.Product qs _) = qs
queries q = return q
pes' = NEL.toList pqs >>= conds
conds (PQ.Product _ cs) = cs
conds _ = []