@@ -195,7 +195,8 @@ evalRelationalExpr (Restrict predicateExpr relExpr) = do
195 eFilterFunc <- predicateRestrictionFilter (attributes rel) predicateExpr
195 eFilterFunc <- predicateRestrictionFilter (attributes rel) predicateExpr
196 case eFilterFunc of
196 case eFilterFunc of
197 Left err -> return $ Left err
197 Left err -> return $ Left err
198+ Right filterfunc -> do
198− Right filterfunc -> return $ restrict filterfunc rel
199+ pure (restrict filterfunc rel)
200evalRelationalExpr (Equals relExprA relExprB) = do
201evalRelationalExpr (Equals relExprA relExprB) = do
201 evaldA <- evalRelationalExpr relExprA
202 evaldA <- evalRelationalExpr relExprA
@@ -334,7 +335,7 @@ evalDatabaseContextExpr (Update relVarName atomExprMap restrictionPredicateExpr)
334 if cardinality restrictedPortion == Finite 0 then
335 if cardinality restrictedPortion == Finite 0 then
335 pure Nothing
336 pure Nothing
337− unrestrictedPortion <- restrict (not . predicateFunc) rel
338+ unrestrictedPortion <- restrict (\tup -> predicateFunc tup >>= pure . not) rel
338 updatedPortion <- relMap (updateTupleWithAtomExprs atomExprMap context) restrictedPortion
339 updatedPortion <- relMap (updateTupleWithAtomExprs atomExprMap context) restrictedPortion
339 updatedRel <- union updatedPortion unrestrictedPortion
340 updatedRel <- union updatedPortion unrestrictedPortion
340 pure (Just updatedRel)
341 pure (Just updatedRel)
@@ -614,52 +615,73 @@ liftE v = do
614 Right val -> pure val
615 Right val -> pure val
616{- used for restrictions- take the restrictionpredicate and return the corresponding filter function -}
617{- used for restrictions- take the restrictionpredicate and return the corresponding filter function -}
617−predicateRestrictionFilter :: Attributes -> RestrictionPredicateExpr -> RelationalExprState (Either RelationalError (RelationTuple -> Bool))
618+predicateRestrictionFilter :: Attributes -> RestrictionPredicateExpr -> RelationalExprState (Either RelationalError RestrictionFilter)
618predicateRestrictionFilter attrs (AndPredicate expr1 expr2) = do
619predicateRestrictionFilter attrs (AndPredicate expr1 expr2) = do
619 runExceptT $ do
620 runExceptT $ do
620 expr1v <- liftE (predicateRestrictionFilter attrs expr1)
621 expr1v <- liftE (predicateRestrictionFilter attrs expr1)
621 expr2v <- liftE (predicateRestrictionFilter attrs expr2)
622 expr2v <- liftE (predicateRestrictionFilter attrs expr2)
622− pure (\x -> expr1v x && expr2v x)
624+ ev1 <- expr1v x
624predicateRestrictionFilter attrs (OrPredicate expr1 expr2) = do
628predicateRestrictionFilter attrs (OrPredicate expr1 expr2) = do
625 runExceptT $ do
629 runExceptT $ do
626 expr1v <- liftE (predicateRestrictionFilter attrs expr1)
630 expr1v <- liftE (predicateRestrictionFilter attrs expr1)
627 expr2v <- liftE (predicateRestrictionFilter attrs expr2)
631 expr2v <- liftE (predicateRestrictionFilter attrs expr2)
628− pure (\x -> expr1v x || expr2v x)
633+ ev1 <- expr1v x
630−predicateRestrictionFilter _ TruePredicate = pure (Right (\_ -> True))
637+predicateRestrictionFilter _ TruePredicate = pure (Right (\_ -> pure True))
632predicateRestrictionFilter attrs (NotPredicate expr) = do
639predicateRestrictionFilter attrs (NotPredicate expr) = do
633 runExceptT $ do
640 runExceptT $ do
634 exprv <- liftE (predicateRestrictionFilter attrs expr)
641 exprv <- liftE (predicateRestrictionFilter attrs expr)
635− pure (\x -> not (exprv x))
643+ ev <- exprv x
646+--optimization opportunity: if the subexpression does not reference attributes in the top-level expression, then it need only be evaluated once, statically, outside the tuple filter- see historical implementation here
637−predicateRestrictionFilter _ (RelationalExprPredicate relExpr) = runExceptT $ do
647+predicateRestrictionFilter _ (RelationalExprPredicate relExpr) = do
638− --merge attrs into to state attributes
648+ rstate <- ask
639− rel <- liftE (evalRelationalExpr relExpr)
649+ pure (Right (\tup -> case runReader (evalRelationalExpr relExpr) (mergeTuplesIntoRelationalExprState tup rstate) of
640− if rel == relationTrue then
650+ Left err -> Left err
641− pure (\_ -> True)
651+ Right rel -> if arity rel /= 0 then
642− else if rel == relationFalse then
645− throwE (PredicateExpressionError "Relational restriction filter must evaluate to 'true' or 'false'")
652+ Left (PredicateExpressionError "Relational restriction filter must evaluate to 'true' or 'false'")
654+ pure (rel == relationTrue)))
647predicateRestrictionFilter attrs (AttributeEqualityPredicate attrName atomExpr) = do
656predicateRestrictionFilter attrs (AttributeEqualityPredicate attrName atomExpr) = do
648− --merge attrs into the state attributes
649 rstate <- ask
657 rstate <- ask
658+ let (attrs', ctxtup') = case rstate of
659+ RelationalExprStateElems _ -> (attrs, emptyTuple)
660+ RelationalExprStateAttrsElems _ _ -> (attrs, emptyTuple)
661+ RelationalExprStateTupleElems _ ctxtup -> (A.union attrs (tupleAttributes ctxtup), ctxtup)
650 runExceptT $ do
662 runExceptT $ do
651− atomExprType <- liftE (typeFromAtomExpr attrs atomExpr)
663+ atomExprType <- liftE (typeFromAtomExpr attrs' atomExpr)
652− attr <- either throwE pure (A.attributeForName attrName attrs)
664+ attr <- either throwE pure $ case A.attributeForName attrName attrs of
665+ Right attr -> Right attr
666+ Left (NoSuchAttributeNamesError _) -> case A.attributeForName attrName (tupleAttributes ctxtup') of
667+ Right ctxattr -> Right ctxattr
668+ Left err2@(NoSuchAttributeNamesError _) -> Left err2
669+ Left err -> Left err
670+ Left err -> Left err
653 if atomExprType /= A.atomType attr then
671 if atomExprType /= A.atomType attr then
654 throwE (TupleAttributeTypeMismatchError (A.attributesFromList [attr]))
672 throwE (TupleAttributeTypeMismatchError (A.attributesFromList [attr]))
656− pure $ \tupleIn -> case atomForAttributeName attrName tupleIn of
674+ pure $ \tupleIn -> let evalAndCmp atomIn = case atomEvald of
657− Left _ -> False
675+ Right atomCmp -> atomCmp == atomIn
658− Right atomIn ->
676+ Left _ -> False
659− let atomEvald = runReader (evalAtomExpr tupleIn atomExpr) rstate in
677+ atomEvald = runReader (evalAtomExpr tupleIn atomExpr) rstate
660− case atomEvald of
678+ in
661− Right atomCmp -> atomCmp == atomIn
679+ pure $ case atomForAttributeName attrName tupleIn of
680+ Left (NoSuchAttributeNamesError _) -> case atomForAttributeName attrName ctxtup' of
682+ Right ctxatom -> evalAndCmp ctxatom
662− Left _ -> False
683+ Left _ -> False
684+ Right atomIn -> evalAndCmp atomIn
663-- in the future, it would be useful to do typechecking on the attribute and atom expr filters in advance
685-- in the future, it would be useful to do typechecking on the attribute and atom expr filters in advance
664predicateRestrictionFilter attrs (AtomExprPredicate atomExpr) = do
686predicateRestrictionFilter attrs (AtomExprPredicate atomExpr) = do
665 --merge attrs into the state attributes
687 --merge attrs into the state attributes
@@ -670,13 +692,13 @@ predicateRestrictionFilter attrs (AtomExprPredicate atomExpr) = do
670 throwE (AtomTypeMismatchError aType BoolAtomType)
692 throwE (AtomTypeMismatchError aType BoolAtomType)
672 pure (\tupleIn -> do
694 pure (\tupleIn -> do
673− case runReader (evalAtomExpr tupleIn atomExpr) rstate of
695+ pure $ case runReader (evalAtomExpr tupleIn atomExpr) rstate of
674 Left _ -> False
696 Left _ -> False
675 Right boolAtomValue -> boolAtomValue == BoolAtom True)
697 Right boolAtomValue -> boolAtomValue == BoolAtom True)
677tupleExprCheckNewAttrName :: AttributeName -> Relation -> Either RelationalError Relation
699tupleExprCheckNewAttrName :: AttributeName -> Relation -> Either RelationalError Relation
678−tupleExprCheckNewAttrName attrName rel = if isRight $ attributeForName attrName rel then
700+tupleExprCheckNewAttrName attrName rel = if isRight (attributeForName attrName rel) then
679− Left $ AttributeNameInUseError attrName
701+ Left (error "SPAMMIT" $ AttributeNameInUseError attrName)
681 Right rel
703 Right rel
@@ -742,19 +764,18 @@ evalAtomExpr tupIn cons@(ConstructedAtomExpr dConsName dConsArgs ()) = runExcept
743typeFromAtomExpr :: Attributes -> AtomExpr -> RelationalExprState (Either RelationalError AtomType)
765typeFromAtomExpr :: Attributes -> AtomExpr -> RelationalExprState (Either RelationalError AtomType)
744typeFromAtomExpr attrs (AttributeAtomExpr attrName) = do
766typeFromAtomExpr attrs (AttributeAtomExpr attrName) = do
745− --first, check if the attribute is in the immediate attributes
746 rstate <- ask
767 rstate <- ask
747 case A.atomTypeForAttributeName attrName attrs of
768 case A.atomTypeForAttributeName attrName attrs of
748 Right aType -> pure (Right aType)
769 Right aType -> pure (Right aType)
749 Left err@(NoSuchAttributeNamesError _) -> case rstate of
770 Left err@(NoSuchAttributeNamesError _) -> case rstate of
750 RelationalExprStateAttrsElems _ attrs' -> case A.attributeForName attrName attrs' of
771 RelationalExprStateAttrsElems _ attrs' -> case A.attributeForName attrName attrs' of
751− Left err' -> pure (Left err')
772+ Left err' -> pure (error "SPAMMO2" $ Left err')
752 Right attr -> pure (Right (A.atomType attr))
773 Right attr -> pure (Right (A.atomType attr))
753− RelationalExprStateElems _ -> pure (Left err)
774+ RelationalExprStateElems _ -> pure (error (show attrs) $ Left err)
754 RelationalExprStateTupleElems _ tup -> case atomForAttributeName attrName tup of
775 RelationalExprStateTupleElems _ tup -> case atomForAttributeName attrName tup of
755− Left err' -> pure (Left err')
776+ Left err' -> pure (error "STAMP" $ Left err')
756 Right atom -> pure (Right (atomTypeForAtom atom))
777 Right atom -> pure (Right (atomTypeForAtom atom))
757− Left err -> pure (Left err)
778+ Left err -> pure (error "GONK" $ Left err)
758typeFromAtomExpr _ (NakedAtomExpr atom) = pure (Right (atomTypeForAtom atom))
779typeFromAtomExpr _ (NakedAtomExpr atom) = pure (Right (atomTypeForAtom atom))
759typeFromAtomExpr attrs (FunctionAtomExpr funcName atomArgs _) = do
780typeFromAtomExpr attrs (FunctionAtomExpr funcName atomArgs _) = do
760 context <- liftM stateElemsContext ask
781 context <- liftM stateElemsContext ask
@@ -795,7 +816,7 @@ verifyAtomExprTypes relIn (AttributeAtomExpr attrName) expectedType = runExceptT
795 RelationalExprStateTupleElems _ _ -> throwE err
816 RelationalExprStateTupleElems _ _ -> throwE err
796 RelationalExprStateElems _ -> throwE err
817 RelationalExprStateElems _ -> throwE err
797 RelationalExprStateAttrsElems _ attrs -> case A.attributeForName attrName attrs of
818 RelationalExprStateAttrsElems _ attrs -> case A.attributeForName attrName attrs of
798− Left err' -> throwE err'
819+ Left err' -> throwE (error "GONK" err')
799 Right attrType -> either throwE pure (atomTypeVerify expectedType (A.atomType attrType))
820 Right attrType -> either throwE pure (atomTypeVerify expectedType (A.atomType attrType))
800 Left err -> throwE err
821 Left err -> throwE err
801verifyAtomExprTypes _ (NakedAtomExpr atom) expectedType = pure (atomTypeVerify expectedType (atomTypeForAtom atom))
822verifyAtomExprTypes _ (NakedAtomExpr atom) expectedType = pure (atomTypeVerify expectedType (atomTypeForAtom atom))