@@ -9,9 +9,11 @@ import ProjectM36.AtomType
9import ProjectM36.AtomFunctionBody
9import ProjectM36.AtomFunctionBody
10import ProjectM36.DataTypes.Primitive
10import ProjectM36.DataTypes.Primitive
11import ProjectM36.AtomFunction
11import ProjectM36.AtomFunction
12+import ProjectM36.StaticOptimizer
12import qualified ProjectM36.Attribute as A
13import qualified ProjectM36.Attribute as A
13import qualified Data.Map as M
14import qualified Data.Map as M
14import qualified Data.HashSet as HS
15import qualified Data.HashSet as HS
16+import qualified Data.Set as S
15import Control.Monad.State hiding (join)
17import Control.Monad.State hiding (join)
16import Control.Exception
18import Control.Exception
17import Data.Maybe
19import Data.Maybe
@@ -25,6 +27,8 @@ import Control.Monad.Trans.Except
26import GHC.Paths
28import GHC.Paths
28-- we need to pass around a higher level RelationTuple and Attributes in order to solve #52
32-- we need to pass around a higher level RelationTuple and Attributes in order to solve #52
29data RelationalExprStateElems = RelationalExprStateTupleElems DatabaseContext RelationTuple | -- used when fully evaluating a relexpr
33data RelationalExprStateElems = RelationalExprStateTupleElems DatabaseContext RelationTuple | -- used when fully evaluating a relexpr
30 RelationalExprStateAttrsElems DatabaseContext Attributes | --used when evaluating the type of a relexpr
34 RelationalExprStateAttrsElems DatabaseContext Attributes | --used when evaluating the type of a relexpr
@@ -420,11 +424,14 @@ updateTupleWithAtomExprs exprMap context tupIn = do
421--run verification on all constraints
425--run verification on all constraints
422checkConstraints :: DatabaseContext -> Maybe RelationalError
426checkConstraints :: DatabaseContext -> Maybe RelationalError
423−checkConstraints context = case failures of
427+checkConstraints context = case optimizedIncDepMap of
428+ Left err -> Just err
429+ Right filteredIncDepMap -> case failures filteredIncDepMap of
424− [] -> Nothing
430+ [] -> Nothing
425− l:_ -> Just l
431+ l -> Just (MultipleErrors l)
433+ optimizedIncDepMap = filterInclusionDependenciesForValidation deps
427− failures = M.elems $ M.mapMaybeWithKey checkIncDep deps
434+ failures incDeps = M.elems $ M.mapMaybeWithKey checkIncDep incDeps
428 deps = inclusionDependencies context
435 deps = inclusionDependencies context
429 eval expr = evalState (evalRelationalExpr expr) (RelationalExprStateElems context)
436 eval expr = evalState (evalRelationalExpr expr) (RelationalExprStateElems context)
430 checkIncDep depName (InclusionDependency subsetExpr supersetExpr) = do
437 checkIncDep depName (InclusionDependency subsetExpr supersetExpr) = do
@@ -688,3 +695,55 @@ evalTupleExpr attrs (TupleExpr tupMap) = runExceptT $ do
688 _ <- either throwE pure (validateTuple tup' tConss)
695 _ <- either throwE pure (validateTuple tup' tConss)
689 pure tup'
696 pure tup'
698+ -- | Return all relation variable names mentioned in the relational expression. This is used by the constraint static optimizer to determine which relvars are relevant.
699+relationVariableNames :: Show a => RelationalExprBase a -> S.Set RelVarName
700+relationVariableNames relExpr = foldRelationalExprs (\names re -> case re of
701+ RelationVariable name _ -> S.insert name names
702+ _ -> names) S.empty relExpr
704+-- | Return all the unit RelationalExprs. This is useful, for example, for finding all mentions of relation
705+foldRelationalExprs :: (b -> RelationalExprBase a -> b) -> b -> RelationalExprBase a -> b
706+foldRelationalExprs func accum expr = case expr of
707+ e@(MakeRelationFromExprs _ tupleExprs) -> foldl func accum (e : concatMap tupleExprRelationalExprs tupleExprs)
708+ e@(MakeStaticRelation _ _) -> folder e []
709+ e@(ExistingRelation _) -> folder e []
710+ e@(RelationVariable _ _) -> folder e []
711+ e@(Project _ expr2) -> folder e [expr2]
712+ e@(Union exprA exprB) -> folder e [exprA, exprB]
713+ e@(Join exprA exprB) -> folder e [exprA, exprB]
714+ e@(Rename _ _ expr2) -> folder e [expr2]
715+ e@(Difference exprA exprB) -> folder e [exprA, exprB]
716+ e@(Group _ _ expr2) -> folder e [expr2]
717+ e@(Ungroup _ expr2) -> folder e [expr2]
718+ e@(Restrict predi expr2) -> folder e (expr2 : restrictionPredicateRelationalExprs predi)
719+ e@(Equals exprA exprB) -> folder e [exprA, exprB]
720+ e@(NotEquals exprA exprB) -> folder e [exprA, exprB]
721+ e@(Extend extendExpr expr2) -> folder e (expr2 : extendTupleRelationalExprs extendExpr)
723+ folder e exprs = func (foldl (foldRelationalExprs func) accum exprs) e
725+-- | Scan tupleExpr to return RelationExprs.
726+tupleExprRelationalExprs :: TupleExprBase a -> [RelationalExprBase a]
727+tupleExprRelationalExprs (TupleExpr amap) = concat (map atomExprRelationalExprs (M.elems amap))
729+atomExprRelationalExprs :: AtomExprBase a -> [RelationalExprBase a]
730+atomExprRelationalExprs (FunctionAtomExpr _ exprs _) = concatMap atomExprRelationalExprs exprs
731+atomExprRelationalExprs (RelationAtomExpr expr) = [expr]
732+atomExprRelationalExprs (ConstructedAtomExpr _ exprs _) = concatMap atomExprRelationalExprs exprs
733+atomExprRelationalExprs _ = []
735+restrictionPredicateRelationalExprs :: RestrictionPredicateExprBase a -> [RelationalExprBase a]
736+restrictionPredicateRelationalExprs predi = case predi of
738+ AndPredicate exprA exprB -> restrictionPredicateRelationalExprs exprA ++ restrictionPredicateRelationalExprs exprB
739+ OrPredicate exprA exprB -> restrictionPredicateRelationalExprs exprA ++ restrictionPredicateRelationalExprs exprB
740+ NotPredicate expr -> restrictionPredicateRelationalExprs expr
741+ RelationalExprPredicate relExpr -> foldRelationalExprs (\acc expr -> expr : acc) [] relExpr
742+ AtomExprPredicate atomExpr -> atomExprRelationalExprs atomExpr
743+ AttributeEqualityPredicate _ atomExpr -> atomExprRelationalExprs atomExpr
745+extendTupleRelationalExprs :: ExtendTupleExprBase a -> [RelationalExprBase a]
746+extendTupleRelationalExprs (AttributeExtendTupleExpr _ atomExpr) = atomExprRelationalExprs atomExpr
748+relvarReferences :: InclusionDependency -> S.Set RelVarName
749+relvarReferences (InclusionDependency super sub) = S.union (relationVariableNames super) (relationVariableNames sub)