@@ -9,9 +9,11 @@ import ProjectM36.AtomType
99import ProjectM36.AtomFunctionBody
1010import ProjectM36.DataTypes.Primitive
1111import ProjectM36.AtomFunction
12+import ProjectM36.StaticOptimizer
1213import qualified ProjectM36.Attribute as A
1314import qualified Data.Map as M
1415import qualified Data.HashSet as HS
16+import qualified Data.Set as S
1517import Control.Monad.State hiding (join)
1618import Control.Exception
1719import Data.Maybe
@@ -25,6 +27,8 @@ import Control.Monad.Trans.Except
2527import GHC
2628import GHC.Paths
2729
30+import Debug.Trace
31+
2832-- we need to pass around a higher level RelationTuple and Attributes in order to solve #52
2933data RelationalExprStateElems = RelationalExprStateTupleElems DatabaseContext RelationTuple | -- used when fully evaluating a relexpr
3034 RelationalExprStateAttrsElems DatabaseContext Attributes | --used when evaluating the type of a relexpr
@@ -420,11 +424,14 @@ updateTupleWithAtomExprs exprMap context tupIn = do
420424
421425--run verification on all constraints
422426checkConstraints :: DatabaseContext -> Maybe RelationalError
423−checkConstraints context = case failures of
424− [] -> Nothing
425− l:_ -> Just l
427+checkConstraints context = case optimizedIncDepMap of
428+ Left err -> Just err
429+ Right filteredIncDepMap -> case failures filteredIncDepMap of
430+ [] -> Nothing
431+ l -> Just (MultipleErrors l)
426432 where
427− failures = M.elems $ M.mapMaybeWithKey checkIncDep deps
433+ optimizedIncDepMap = filterInclusionDependenciesForValidation deps
434+ failures incDeps = M.elems $ M.mapMaybeWithKey checkIncDep incDeps
428435 deps = inclusionDependencies context
429436 eval expr = evalState (evalRelationalExpr expr) (RelationalExprStateElems context)
430437 checkIncDep depName (InclusionDependency subsetExpr supersetExpr) = do
@@ -688,3 +695,55 @@ evalTupleExpr attrs (TupleExpr tupMap) = runExceptT $ do
688695 _ <- either throwE pure (validateTuple tup' tConss)
689696 pure tup'
690697
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
703+
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)
722+ where
723+ folder e exprs = func (foldl (foldRelationalExprs func) accum exprs) e
724+
725+-- | Scan tupleExpr to return RelationExprs.
726+tupleExprRelationalExprs :: TupleExprBase a -> [RelationalExprBase a]
727+tupleExprRelationalExprs (TupleExpr amap) = concat (map atomExprRelationalExprs (M.elems amap))
728+
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 _ = []
734+
735+restrictionPredicateRelationalExprs :: RestrictionPredicateExprBase a -> [RelationalExprBase a]
736+restrictionPredicateRelationalExprs predi = case predi of
737+ TruePredicate -> []
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
744+
745+extendTupleRelationalExprs :: ExtendTupleExprBase a -> [RelationalExprBase a]
746+extendTupleRelationalExprs (AttributeExtendTupleExpr _ atomExpr) = atomExprRelationalExprs atomExpr
747+
748+relvarReferences :: InclusionDependency -> S.Set RelVarName
749+relvarReferences (InclusionDependency super sub) = S.union (relationVariableNames super) (relationVariableNames sub)