@@ -14,6 +14,7 @@ import ProjectM36.DatabaseContextFunction
1414import qualified ProjectM36.Attribute as A
1515import qualified Data.Map as M
1616import qualified Data.HashSet as HS
17+import qualified Data.Set as S
1718import Control.Monad.State hiding (join)
1819import Control.Exception
1920import Data.Maybe
@@ -113,10 +114,14 @@ evalRelationalExpr (RelationVariable name _) = do
113114 Nothing -> Left $ RelVarNotDefinedError name
114115
115116evalRelationalExpr (Project attrNames expr) = do
116− rel <- evalRelationalExpr expr
117− case rel of
118− Right rel2 -> return $ project attrNames rel2
119− Left err -> return $ Left err
117+ eAttrNameSet <- evalAttributeNames attrNames expr
118+ case eAttrNameSet of
119+ Left err -> pure (Left err)
120+ Right attrNameSet -> do
121+ rel <- evalRelationalExpr expr
122+ case rel of
123+ Right rel2 -> pure $ project attrNameSet rel2
124+ Left err -> pure $ Left err
120125
121126evalRelationalExpr (Union exprA exprB) = do
122127 relA <- evalRelationalExpr exprA
@@ -173,11 +178,15 @@ evalRelationalExpr (Rename oldAttrName newAttrName relExpr) = do
173178 Right rel -> return $ rename oldAttrName newAttrName rel
174179 Left err -> return $ Left err
175180
176−evalRelationalExpr (Group oldAttrNameSet newAttrName relExpr) = do
177− evald <- evalRelationalExpr relExpr
178− case evald of
179− Right rel -> return $ group oldAttrNameSet newAttrName rel
180− Left err -> return $ Left err
181+evalRelationalExpr (Group oldAttrNames newAttrName relExpr) = do
182+ eOldAttrNameSet <- evalAttributeNames oldAttrNames relExpr
183+ case eOldAttrNameSet of
184+ Left err -> pure (Left err)
185+ Right oldAttrNameSet -> do
186+ evald <- evalRelationalExpr relExpr
187+ case evald of
188+ Right rel -> return $ group oldAttrNameSet newAttrName rel
189+ Left err -> return $ Left err
181190
182191evalRelationalExpr (Ungroup attrName relExpr) = do
183192 evald <- evalRelationalExpr relExpr
@@ -871,3 +880,52 @@ evalTupleExpr attrs (TupleExpr tupMap) = do
871880 _ <- either throwE pure (validateTuple tup' tConss)
872881 pure tup'
873882
883+evalAttributeNames :: AttributeNames -> RelationalExpr -> RelationalExprState (Either RelationalError (S.Set AttributeName))
884+evalAttributeNames attrNames expr = do
885+ eExprType <- typeForRelationalExpr expr
886+ case eExprType of
887+ Left err -> pure (Left err)
888+ Right exprTyp -> do
889+ let typeNameSet = S.fromList (V.toList (A.attributeNames (attributes exprTyp)))
890+ case attrNames of
891+ AttributeNames names ->
892+ case A.projectionAttributesForNames names (attributes exprTyp) of
893+ Left err -> pure (Left err)
894+ Right attrs -> pure (Right (S.fromList (V.toList (A.attributeNames attrs))))
895+
896+ InvertedAttributeNames names -> do
897+ let nonExistentAttributeNames = A.attributeNamesNotContained names typeNameSet
898+ if not (S.null nonExistentAttributeNames) then
899+ pure (Left (AttributeNamesMismatchError nonExistentAttributeNames))
900+ else
901+ pure (Right (A.nonMatchingAttributeNameSet names typeNameSet))
902+
903+ UnionAttributeNames namesA namesB -> do
904+ eNameSetA <- evalAttributeNames namesA expr
905+ case eNameSetA of
906+ Left err -> pure (Left err)
907+ Right nameSetA -> do
908+ eNameSetB <- evalAttributeNames namesB expr
909+ case eNameSetB of
910+ Left err -> pure (Left err)
911+ Right nameSetB ->
912+ pure (Right (S.union nameSetA nameSetB))
913+
914+ IntersectAttributeNames namesA namesB -> do
915+ eNameSetA <- evalAttributeNames namesA expr
916+ case eNameSetA of
917+ Left err -> pure (Left err)
918+ Right nameSetA -> do
919+ eNameSetB <- evalAttributeNames namesB expr
920+ case eNameSetB of
921+ Left err -> pure (Left err)
922+ Right nameSetB ->
923+ pure (Right (S.intersection nameSetA nameSetB))
924+
925+ RelationalExprAttributeNames attrExpr -> do
926+ eAttrExprType <- typeForRelationalExpr attrExpr
927+ case eAttrExprType of
928+ Left err -> pure (Left err)
929+ Right attrExprType -> pure (Right (A.attributeNameSet (attributes attrExprType)))
930+
931+