algebra-sql-0.3.0.0: src/Database/Algebra/SQL/Query/Substitution.hs
-- This module provides functions to replace references within queries.
module Database.Algebra.SQL.Query.Substitution
( replaceReferencesSelectStmt
) where
import Control.Monad (liftM)
import qualified Database.Algebra.SQL.Query as Q
type SubstitutionFunction = Q.ReferenceType -> Q.FromExpr
-- | Replaces all references in this 'Q.SelectStmt' with the result from the
-- given function.
replaceReferencesSelectStmt :: SubstitutionFunction
-> Q.SelectStmt
-> Q.SelectStmt
replaceReferencesSelectStmt r body =
body
{ Q.selectClause = map (replaceReferencesSelectColumn r)
$ Q.selectClause body
, Q.fromClause = map (replaceReferencesFromPart r) $ Q.fromClause body
, Q.whereClause = liftM (replaceReferencesColumnExpr r) $ Q.whereClause body
, Q.groupByClause = map (replaceReferencesColumnExpr r)
$ Q.groupByClause body
, Q.orderByClause = map (replaceReferencesOrderExpr r)
$ Q.orderByClause body
}
replaceReferencesSelectColumn :: SubstitutionFunction
-> Q.SelectColumn
-> Q.SelectColumn
replaceReferencesSelectColumn r (Q.SCAlias e a) =
Q.SCAlias (replaceReferencesExtendedExpr r e) a
replaceReferencesSelectColumn r (Q.SCExpr e) =
Q.SCExpr $ replaceReferencesExtendedExpr r e
replaceReferencesExtendedExpr :: SubstitutionFunction
-> Q.ExtendedExpr
-> Q.ExtendedExpr
replaceReferencesExtendedExpr r (Q.EEBase v) =
Q.EEBase $ replaceReferencesValueExprTemplate replaceReferencesExtendedExpr
r
v
replaceReferencesExtendedExpr r (Q.EEWinFun fun part ord frame) =
Q.EEWinFun (replaceReferencesWindowFunction r fun)
(liftM (replaceReferencesAggrExpr r) part)
(map (replaceReferencesWindowOrderExpr r) ord)
frame
replaceReferencesExtendedExpr r (Q.EEAggrExpr ae) =
Q.EEAggrExpr $ replaceReferencesAggrExpr r ae
-- | Generic value expression substitution function.
replaceReferencesValueExprTemplate :: (SubstitutionFunction -> a -> a)
-> SubstitutionFunction
-> Q.ValueExprTemplate a
-> Q.ValueExprTemplate a
replaceReferencesValueExprTemplate replaceReferencesRec r ve = case ve of
Q.VEBinApp bf fe se ->
Q.VEBinApp bf
(replaceReferencesRec r fe)
(replaceReferencesRec r se)
Q.VEUnApp uf e -> Q.VEUnApp uf (replaceReferencesRec r e)
Q.VECase cE tE eE -> Q.VECase (replaceReferencesRec r cE)
(replaceReferencesRec r tE)
(replaceReferencesRec r eE)
Q.VEExists q -> Q.VEExists $ replaceReferencesValueQuery r q
Q.VEIn ae q -> Q.VEIn (replaceReferencesRec r ae)
(replaceReferencesValueQuery r q)
Q.VEColumn _ _ -> ve
Q.VEValue _ -> ve
replaceReferencesColumnExpr :: SubstitutionFunction
-> Q.ColumnExpr
-> Q.ColumnExpr
replaceReferencesColumnExpr r (Q.CEBase v) =
Q.CEBase $ replaceReferencesValueExprTemplate replaceReferencesColumnExpr
r
v
replaceReferencesAggrExpr :: SubstitutionFunction
-> Q.AggrExpr
-> Q.AggrExpr
replaceReferencesAggrExpr r (Q.AEBase v) =
Q.AEBase $ replaceReferencesValueExprTemplate replaceReferencesAggrExpr
r
v
replaceReferencesAggrExpr r (Q.AEAggregate v f) =
Q.AEAggregate (liftM (replaceReferencesColumnExpr r) v) f
replaceReferencesFromPart :: SubstitutionFunction
-> Q.FromPart
-> Q.FromPart
replaceReferencesFromPart r (Q.FPAlias e a c) =
Q.FPAlias (replaceReferencesFromExpr r e) a c
replaceReferencesFromExpr :: SubstitutionFunction
-> Q.FromExpr
-> Q.FromExpr
replaceReferencesFromExpr r (Q.FESubQuery q) =
Q.FESubQuery $ replaceReferencesValueQuery r q
replaceReferencesFromExpr r (Q.FEVariable v) = r v
replaceReferencesFromExpr r (Q.FEExplicitJoin op leftArg rightArg) =
Q.FEExplicitJoin op
(replaceReferencesFromPart r leftArg)
(replaceReferencesFromPart r rightArg)
replaceReferencesFromExpr _ t = t
replaceReferencesValueQuery :: SubstitutionFunction
-> Q.ValueQuery
-> Q.ValueQuery
replaceReferencesValueQuery r (Q.VQSelect s) =
Q.VQSelect $ replaceReferencesSelectStmt r s
replaceReferencesValueQuery r
(Q.VQWith bindings body) =
Q.VQWith (map f bindings) $ replaceReferencesValueQuery r body
where f (n, oC, q) = (n, oC, replaceReferencesValueQuery r q)
replaceReferencesValueQuery r
(Q.VQBinarySetOperation lq rq o) =
Q.VQBinarySetOperation (replaceReferencesValueQuery r lq)
(replaceReferencesValueQuery r rq)
o
replaceReferencesValueQuery _ q = q
replaceReferencesOrderExpr :: SubstitutionFunction
-> Q.OrderExpr
-> Q.OrderExpr
replaceReferencesOrderExpr r (Q.OE ee d) =
Q.OE (replaceReferencesExtendedExpr r ee) d
replaceReferencesWindowOrderExpr :: SubstitutionFunction
-> Q.WindowOrderExpr
-> Q.WindowOrderExpr
replaceReferencesWindowOrderExpr r (Q.WOE ae d) =
Q.WOE (replaceReferencesAggrExpr r ae) d
replaceReferencesWindowFunction :: SubstitutionFunction
-> Q.WindowFunction
-> Q.WindowFunction
replaceReferencesWindowFunction r (Q.WFMax a) =
Q.WFMax (replaceReferencesColumnExpr r a)
replaceReferencesWindowFunction r (Q.WFMin a) =
Q.WFMin (replaceReferencesColumnExpr r a)
replaceReferencesWindowFunction r (Q.WFSum a) =
Q.WFSum (replaceReferencesColumnExpr r a)
replaceReferencesWindowFunction r (Q.WFAvg a) =
Q.WFAvg (replaceReferencesColumnExpr r a)
replaceReferencesWindowFunction r (Q.WFAll a) =
Q.WFAll (replaceReferencesColumnExpr r a)
replaceReferencesWindowFunction r (Q.WFAny a) =
Q.WFAny (replaceReferencesColumnExpr r a)
replaceReferencesWindowFunction r (Q.WFFirstValue a) =
Q.WFFirstValue (replaceReferencesColumnExpr r a)
replaceReferencesWindowFunction r (Q.WFLastValue a) =
Q.WFLastValue (replaceReferencesColumnExpr r a)
replaceReferencesWindowFunction _ Q.WFCount =
Q.WFCount
replaceReferencesWindowFunction _ Q.WFRank =
Q.WFRank
replaceReferencesWindowFunction _ Q.WFDenseRank =
Q.WFDenseRank
replaceReferencesWindowFunction _ Q.WFRowNumber =
Q.WFRowNumber