@@ -74,7 +74,7 @@ singletonValueFromRelation rel@(Relation _ tupSet) = if cardinality rel /= Count
7474union :: Relation -> Relation -> Either RelationalError Relation
7575union (Relation attrs1 tupSet1) (Relation attrs2 tupSet2) =
7676 if not (attrs1 == attrs2)
77− then Left $ AttributeNameMismatchError (T.pack (show attrs1 ++ show attrs2))
77+ then Left $ AttributeNamesMismatchError (A.attributeNameSet (A.attributesDifference attrs1 attrs2))
7878 else
7979 Right $ Relation attrs1 newtuples
8080 where
@@ -82,22 +82,18 @@ union (Relation attrs1 tupSet1) (Relation attrs2 tupSet2) =
8282
8383project :: AttributeNames -> Relation -> Either RelationalError Relation
8484project projectionAttrNames rel =
85− if not $ A.attributeNamesContained selectedAttrNames (attributeNames rel)
86− then Left $ AttributeNameMismatchError ""
87− else
88− relFold folder (Right $ Relation newAttrs HS.empty) rel
85+ case AS.projectionAttributesForAttributeNames (attributes rel) projectionAttrNames of
86+ Left err -> Left err
87+ Right newAttrs -> relFold (folder newAttrs) (Right $ Relation newAttrs HS.empty) rel
8988 where
90− selectedAttrNames = A.attributeNameSet newAttrs
91− newAttrs = AS.projectionAttributesForAttributeNames (attributes rel) projectionAttrNames
92− folder :: RelationTuple -> Either RelationalError Relation -> Either RelationalError Relation
93− folder tupleToProject acc = case acc of
89+ folder newAttrs tupleToProject acc = case acc of
9490 Left err -> Left err
95− Right acc2 -> union acc2 (Relation newAttrs (HS.singleton (tupleProject selectedAttrNames tupleToProject)))
91+ Right acc2 -> union acc2 (Relation newAttrs (HS.singleton (tupleProject (A.attributeNameSet newAttrs) tupleToProject)))
9692
9793rename :: AttributeName -> AttributeName -> Relation -> Either RelationalError Relation
9894rename oldAttrName newAttrName rel@(Relation oldAttrs oldTupSet) =
9995 if not attributeValid
100− then Left $ AttributeNameMismatchError ""
96+ then Left $ AttributeNamesMismatchError (S.singleton oldAttrName)
10197 else if newAttributeInUse
10298 then Left $ AttributeNameInUseError newAttrName
10399 else
@@ -141,16 +137,18 @@ group groupAttrNames newAttrName rel@(Relation oldAttrs tupleSet) = do
141137--algorithm: self-join with image relation
142138group :: AttributeNames -> AttributeName -> Relation -> Either RelationalError Relation
143139group groupAttrNames newAttrName rel = do
144− nonGroupProjection <- project nonGroupAttrNames rel
145− relMogrify mogrifier newAttrs nonGroupProjection
146− where
147− newAttrs = A.addAttribute groupAttr (AS.projectionAttributesForAttributeNames (attributes rel) nonGroupAttrNames)
148− groupAttr = Attribute newAttrName (RelationAtomType (AS.projectionAttributesForAttributeNames (attributes rel) groupAttrNames))
149− nonGroupAttrNames = AS.invertAttributeNames groupAttrNames
150− mogrifier tupIn = tupleExtend tupIn (matchingRelTuple tupIn)
140+ let nonGroupAttrNames = AS.invertAttributeNames groupAttrNames
141+ nonGroupProjectionAttributes <- AS.projectionAttributesForAttributeNames (attributes rel) nonGroupAttrNames
142+ groupProjectionAttributes <- AS.projectionAttributesForAttributeNames (attributes rel) groupAttrNames
143+ let groupAttr = Attribute newAttrName (RelationAtomType groupProjectionAttributes)
151144 matchingRelTuple tupIn = case imageRelationFor tupIn rel of
152145 Right rel2 -> RelationTuple (V.singleton groupAttr) (V.singleton (RelationAtom rel2))
153146 Left _ -> undefined
147+ mogrifier tupIn = tupleExtend tupIn (matchingRelTuple tupIn)
148+ newAttrs = A.addAttribute groupAttr nonGroupProjectionAttributes
149+ nonGroupProjection <- project nonGroupAttrNames rel
150+ relMogrify mogrifier newAttrs nonGroupProjection
151+
154152
155153--help restriction function
156154--returns a subrelation of