@@ -18,7 +18,7 @@ import qualified ProjectM36.Attribute as A
1818import qualified Data.Map as M
1919import qualified Data.HashSet as HS
2020import qualified Data.Set as S
21−import Control.Monad.RWS.Strict as RWS
21+import Control.Monad.RWS.Strict as RWS hiding (join)
2222import Control.Monad.Trans.Class (lift)
2323import Control.Exception
2424import Data.Maybe
@@ -27,10 +27,11 @@ import Data.Char (isUpper)
2727import qualified Data.Text as T
2828import qualified Data.Vector as V
2929import qualified ProjectM36.TypeConstructorDef as TCD
30−import Control.Monad.Except
30+import Control.Monad.Except hiding (join)
3131import Control.Monad.Trans.Except (except)
32−import Control.Monad.Reader as R
32+import Control.Monad.Reader as R hiding (join)
3333import ProjectM36.NormalizeExpr
34+import ProjectM36.WithNameExpr
3435import Test.QuickCheck
3536import GHC
3637import GHC.Paths
@@ -38,11 +39,6 @@ import Data.Time.Clock
3839import Data.Time.Calendar
3940import qualified Data.List.NonEmpty as NE
4041import Data.Functor.Identity
41−import Control.Monad
42−import Control.Monad.IO.Class
43−#if __GLASGOW_HASKELL__ <= 802
44−import Data.Monoid
45−#endif
4642
4743data DatabaseContextExprDetails = CountUpdatedTuples
4844
@@ -86,14 +82,12 @@ instance Show RelationalExprEnv where
8682--used to eval relationalexpr
8783type RelationalExprM a = ReaderT RelationalExprEnv (ExceptT RelationalError Identity) a
8884
85+runRelationalExprM :: RelationalExprEnv -> RelationalExprM a -> Either RelationalError a
86+runRelationalExprM env m = runIdentity (runExceptT (runReaderT m env))
87+
8988reGraph :: RelationalExprM TransactionGraph
9089reGraph = re_graph <$> R.ask
9190
92−gfTransForId :: TransactionId -> GraphRefRelationalExprM Transaction
93−gfTransForId tid = do
94− graph <- gfGraph
95− lift $ except $ transactionForId tid graph
96−
9791currentTrans :: RelationalExprM Transaction
9892currentTrans = do
9993 tid <- re_currentTransId <$> R.ask
@@ -183,6 +177,11 @@ data GraphRefRelationalExprEnv =
183177
184178type GraphRefRelationalExprM a = ReaderT GraphRefRelationalExprEnv (ExceptT RelationalError Identity) a
185179
180+gfTransForId :: TransactionId -> GraphRefRelationalExprM Transaction
181+gfTransForId tid = do
182+ graph <- gfGraph
183+ lift $ except $ transactionForId tid graph
184+
186185runGraphRefRelationalExprM :: GraphRefRelationalExprEnv -> GraphRefRelationalExprM a -> Either RelationalError a
187186runGraphRefRelationalExprM env m = runIdentity (runExceptT (runReaderT m env))
188187
@@ -388,7 +387,6 @@ evalGraphRefDatabaseContextExpr NoOperation = pure ()
388387evalGraphRefDatabaseContextExpr (Define relVarName attrExprs) = do
389388 relvars <- fmap relationVariables getStateContext
390389 tConss <- fmap typeConstructorMapping getStateContext
391− relEnv <- dbcRelationalExprEnv
392390 graph <- dbcGraph
393391 let eAttrs = runGraphRefRelationalExprM gfEnv (mapM evalGraphRefAttrExpr attrExprs)
394392 gfEnv = freshGraphRefRelationalExprEnv graph
@@ -456,7 +454,7 @@ evalGraphRefDatabaseContextExpr (Update relVarName atomExprMap pred') = do
456454 tmpAttr attr = "_tmp_" <> attr --this could certainly be improved to verify that there is no attribute name conflict
457455 updateAttr nam atomExpr = Extend (AttributeExtendTupleExpr (tmpAttr nam) atomExpr)
458456 projectAndRename attr expr = Rename (tmpAttr attr) attr (Project (InvertedAttributeNames (S.singleton attr)) expr)
459− restrictedPortion = Restrict pred'
457+ --TODO restrictedPortion = Restrict pred'
460458 updated = foldr (\(oldname, atomExpr) accum ->
461459 let procAtomExpr = runProcessExprM transId graph (processAtomExpr atomExpr) in
462460 updateAttr oldname procAtomExpr accum
@@ -572,7 +570,6 @@ evalGraphRefDatabaseContextExpr (RemoveDatabaseContextFunction funcName) = do
572570
573571evalGraphRefDatabaseContextExpr (ExecuteDatabaseContextFunction funcName atomArgExprs) = do
574572 context <- getStateContext
575− relExprEnv <- dbcRelationalExprEnv
576573 graph <- dbcGraph
577574 --resolve atom arguments
578575 let eAtomTypes = mapM (\atomExpr -> runGraphRefRelationalExprM gfEnv (typeForGraphRefAtomExpr emptyAttributes atomExpr)) atomArgExprs
@@ -744,7 +741,6 @@ evalGraphRefDatabaseContextIOExpr (CreateArbitraryRelation relVarName attrExprs
744741 --create graph ref expr
745742 let gfExpr = Define relVarName attrExprs
746743 evalEnv = mkDatabaseContextEvalEnv (dbcio_transId env) (dbcio_graph env)
747− transId = dbcio_transId env
748744 graph = dbcio_graph env
749745 case runDatabaseContextEvalMonad currentContext evalEnv (evalGraphRefDatabaseContextExpr gfExpr) of
750746 Left err -> pure (Left err)
@@ -755,8 +751,8 @@ evalGraphRefDatabaseContextIOExpr (CreateArbitraryRelation relVarName attrExprs
755751 case existingRelVar of
756752 Nothing -> pure $ Left (RelVarNotDefinedError relVarName)
757753 Just existingRel -> do
758− let env = freshGraphRefRelationalExprEnv graph
759− case runGraphRefRelationalExprM env (typeForGraphRefRelationalExpr existingRel) of
754+ let gfEnv = freshGraphRefRelationalExprEnv graph
755+ case runGraphRefRelationalExprM gfEnv (typeForGraphRefRelationalExpr existingRel) of
760756 Left err -> pure (Left err)
761757 Right relType -> do
762758 let expectedAttributes = attributes relType
@@ -793,7 +789,6 @@ checkConstraints context transId graph@(TransactionGraph graphHeads transSet) =
793789 tempTrans = Transaction U.nil (TransactionInfo (transId NE.:| []) tempStamp) tempSchemas
794790
795791 deps = inclusionDependencies context
796− reEnv = mkRelationalExprEnv context transId graph
797792 -- no optimization available here, really? perhaps the optimizer should be passed down to here or the eval function should be passed through the environment
798793 checkIncDep depName (InclusionDependency subsetExpr supersetExpr) = do
799794 let process = runProcessExprM transId graph
@@ -806,8 +801,8 @@ checkConstraints context transId graph@(TransactionGraph graphHeads transSet) =
806801 typeSuper <- runGfRel (typeForGraphRefRelationalExpr gfSupersetExpr)
807802 when (typeSub /= typeSuper) (Left (RelationTypeMismatchError (attributes typeSub) (attributes typeSuper)))
808803 let checkExpr = Equals gfSupersetExpr (Union gfSubsetExpr gfSupersetExpr)
809− gfEvald = runGraphRefRelationalExprM gfEnv (evalGraphRefRelationalExpr checkExpr)
810− gfEnv = freshGraphRefRelationalExprEnv potentialGraph
804+ gfEvald = runGraphRefRelationalExprM gfEnv' (evalGraphRefRelationalExpr checkExpr)
805+ gfEnv' = freshGraphRefRelationalExprEnv potentialGraph
811806 case gfEvald of
812807 Left err -> Left err
813808 Right resultRel -> if resultRel == relationTrue then
@@ -930,7 +925,7 @@ tupleExprCheckNewAttrName attrName rel = if isRight (attributeForName attrName r
930925
931926extendGraphRefTupleExpressionProcessor :: Relation -> GraphRefExtendTupleExpr -> GraphRefRelationalExprM (Attributes, RelationTuple -> Either RelationalError RelationTuple)
932927extendGraphRefTupleExpressionProcessor relIn (AttributeExtendTupleExpr newAttrName atomExpr) = do
933− renv <- askEnv
928+-- renv <- askEnv
934929 -- check that the attribute name is not in use
935930 case tupleExprCheckNewAttrName newAttrName relIn of
936931 Left err -> throwError err
@@ -939,7 +934,8 @@ extendGraphRefTupleExpressionProcessor relIn (AttributeExtendTupleExpr newAttrNa
939934 atomExprType' <- verifyGraphRefAtomExprTypes relIn atomExpr atomExprType
940935 let newAttrs = A.attributesFromList [Attribute newAttrName atomExprType']
941936 newAndOldAttrs = A.addAttributes (attributes relIn) newAttrs
942− pure (newAndOldAttrs, \tup -> let substate = mergeTuplesIntoGraphRefRelationalExprEnv tup renv in
937+ pure (newAndOldAttrs, \tup ->
938+ --let substate = mergeTuplesIntoGraphRefRelationalExprEnv tup renv in
943939 case unimplemented {-runReader (evalAtomExpr tup atomExpr) substate-} of
944940 Left err -> Left err
945941 Right atom -> Right (tupleAtomExtend newAttrName atom tup)
@@ -1011,6 +1007,7 @@ typeForGraphRefAtomExpr attrs (AttributeAtomExpr attrName) = do
10111007 Left _ -> case atomForAttributeName attrName envTup of
10121008 Right atom -> pure (atomTypeForAtom atom)
10131009 Left _ -> throwError err
1010+ Left err -> throwError err
10141011
10151012typeForGraphRefAtomExpr _ (NakedAtomExpr atom) = pure (atomTypeForAtom atom)
10161013typeForGraphRefAtomExpr attrs (FunctionAtomExpr funcName atomArgs transId) = do
@@ -1049,6 +1046,8 @@ verifyGraphRefAtomExprTypes relIn (AttributeAtomExpr attrName) expectedType = do
10491046 case A.attributeForName attrName attrs' of
10501047 Left err' -> throwError err'
10511048 Right attrType -> lift $ except $ atomTypeVerify expectedType (A.atomType attrType)
1049+ Left err -> throwError err
1050+
10521051verifyGraphRefAtomExprTypes _ (NakedAtomExpr atom) expectedType =
10531052 lift $ except $ atomTypeVerify expectedType (atomTypeForAtom atom)
10541053verifyGraphRefAtomExprTypes relIn (FunctionAtomExpr funcName funcArgExprs tid) expectedType = do
@@ -1165,14 +1164,72 @@ evalAttributeNames attrNames expr = do
11651164 Right attrExprType -> pure (Right (A.attributeNameSet (attributes attrExprType)))
11661165-}
11671166
1167+--temporary implementation until we have a proper planner+executor
11681168evalGraphRefRelationalExpr :: GraphRefRelationalExpr -> GraphRefRelationalExprM Relation
1169−--evalGraphRefRelationalExpr (MakeRelationaFromExprs
1169+evalGraphRefRelationalExpr (MakeRelationFromExprs mAttrExprs tupleExprs) = do
1170+ mAttrs <- case mAttrExprs of
1171+ Just _ ->
1172+ Just . A.attributesFromList <$> mapM evalGraphRefAttrExpr (fromMaybe [] mAttrExprs)
1173+ Nothing -> pure Nothing
1174+ tuples <- mapM (evalGraphRefTupleExpr mAttrs) tupleExprs
1175+ let attrs = fromMaybe firstTupleAttrs mAttrs
1176+ firstTupleAttrs = if null tuples then A.emptyAttributes else tupleAttributes (head tuples)
1177+ lift $ except $ mkRelation attrs (RelationTupleSet tuples)
1178+evalGraphRefRelationalExpr (MakeStaticRelation attributeSet tupleSet) =
1179+ lift $ except $ mkRelation attributeSet tupleSet
1180+evalGraphRefRelationalExpr (ExistingRelation rel) = pure rel
11701181evalGraphRefRelationalExpr (RelationVariable name tid) = do
11711182 ctx <- concreteDatabaseContext <$> gfTransForId tid
11721183 case M.lookup name (relationVariables ctx) of
11731184 Nothing -> throwError (RelVarNotDefinedError name)
11741185 Just rv -> evalGraphRefRelationalExpr rv
1175−
1186+evalGraphRefRelationalExpr (Project attrNames expr) = do
1187+ attrNameSet <- evalGraphRefAttributeNames attrNames expr
1188+ rel <- evalGraphRefRelationalExpr expr
1189+ lift $ except $ project attrNameSet rel
1190+evalGraphRefRelationalExpr (Union exprA exprB) = do
1191+ relA <- evalGraphRefRelationalExpr exprA
1192+ relB <- evalGraphRefRelationalExpr exprB
1193+ lift $ except $ union relA relB
1194+evalGraphRefRelationalExpr (Join exprA exprB) = do
1195+ relA <- evalGraphRefRelationalExpr exprA
1196+ relB <- evalGraphRefRelationalExpr exprB
1197+ lift $ except $ join relA relB
1198+evalGraphRefRelationalExpr (Rename oldName newName expr) = do
1199+ rel <- evalGraphRefRelationalExpr expr
1200+ lift $ except $ rename oldName newName rel
1201+evalGraphRefRelationalExpr (Difference exprA exprB) = do
1202+ relA <- evalGraphRefRelationalExpr exprA
1203+ relB <- evalGraphRefRelationalExpr exprB
1204+ lift $ except $ difference relA relB
1205+evalGraphRefRelationalExpr (Group groupAttrNames newAttrName expr) = do
1206+ groupNames <- evalGraphRefAttributeNames groupAttrNames expr
1207+ rel <- evalGraphRefRelationalExpr expr
1208+ lift $ except $ group groupNames newAttrName rel
1209+evalGraphRefRelationalExpr (Ungroup groupAttrName expr) = do
1210+ rel <- evalGraphRefRelationalExpr expr
1211+ lift $ except $ ungroup groupAttrName rel
1212+evalGraphRefRelationalExpr (Restrict predExpr expr) = do
1213+ rel <- evalGraphRefRelationalExpr expr
1214+ filt <- predicateRestrictionFilter (attributes rel) predExpr
1215+ lift $ except $ restrict filt rel
1216+evalGraphRefRelationalExpr (Equals exprA exprB) = do
1217+ relA <- evalGraphRefRelationalExpr exprA
1218+ relB <- evalGraphRefRelationalExpr exprB
1219+ pure $ if relA == relB then relationTrue else relationFalse
1220+evalGraphRefRelationalExpr (NotEquals exprA exprB) = do
1221+ relA <- evalGraphRefRelationalExpr exprA
1222+ relB <- evalGraphRefRelationalExpr exprB
1223+ pure $ if relA == relB then relationFalse else relationTrue
1224+evalGraphRefRelationalExpr (Extend extendTupleExpr expr) = do
1225+ rel <- evalGraphRefRelationalExpr expr
1226+ (newAttrs, tupProc) <- extendGraphRefTupleExpressionProcessor rel extendTupleExpr
1227+ lift $ except $ relMogrify tupProc newAttrs rel
1228+evalGraphRefRelationalExpr expr@With{} = do
1229+ --strategy A: add relation variables to the contexts in the graph
1230+ --strategy B: drop in macros in place (easier programmatically)
1231+ --strategy B implementation
1232+ evalGraphRefRelationalExpr (substituteWithNameMacros [] expr)
11761233
11771234dbContextForTransId :: TransactionId -> TransactionGraph -> Either RelationalError DatabaseContext
11781235dbContextForTransId tid graph = do
@@ -1193,28 +1250,71 @@ transactionForId tid graph
11931250typeForGraphRefRelationalExpr :: GraphRefRelationalExpr -> GraphRefRelationalExprM Relation
11941251typeForGraphRefRelationalExpr (MakeStaticRelation attrs _) = lift $ except $ mkRelation attrs emptyTupleSet
11951252typeForGraphRefRelationalExpr (ExistingRelation rel) = pure (emptyRelationWithAttrs (attributes rel))
1196−typeForGraphRefRelationalExpr (MakeRelationFromExprs mAttrExprs tupleExprs) =
1197− case mAttrExprs of
1198− Just attrExprs -> do
1199− attrs <- mapM (\e -> evalGraphRefAttributeExpr e) attrExprs
1200− pure (emptyRelationWithAttrs (attributesFromList attrs))
1253+typeForGraphRefRelationalExpr (MakeRelationFromExprs mAttrExprs tupleExprs) = do
1254+ mAttrs <- case mAttrExprs of
1255+ Just attrExprs -> do
1256+ attrs <- mapM (\e -> evalGraphRefAttributeExpr e) attrExprs
1257+ pure (Just (attributesFromList attrs))
1258+ Nothing -> pure Nothing
1259+ tuples <- mapM (evalGraphRefTupleExpr mAttrs) tupleExprs
1260+ let retAttrs = case tuples of
1261+ (tup:_) -> tupleAttributes tup
1262+ [] -> fromMaybe A.emptyAttributes mAttrs
1263+ pure $ emptyRelationWithAttrs retAttrs
1264+
12011265typeForGraphRefRelationalExpr (RelationVariable rvName tid) = do
12021266 relVars <- relationVariables . concreteDatabaseContext <$> gfTransForId tid
12031267 case M.lookup rvName relVars of
12041268 Nothing -> throwError (RelVarNotDefinedError rvName)
12051269 Just rvExpr -> typeForGraphRefRelationalExpr rvExpr
12061270typeForGraphRefRelationalExpr (Project attrNames expr) = do
1207− exprType <- typeForGraphRefRelationalExpr expr
1271+ exprType' <- typeForGraphRefRelationalExpr expr
12081272 projectionAttrs <- evalGraphRefAttributeNames attrNames expr
1209− lift $ except $ project projectionAttrs exprType
1210−
1273+ lift $ except $ project projectionAttrs exprType'
1274+typeForGraphRefRelationalExpr (Union exprA exprB) = do
1275+ exprA' <- typeForGraphRefRelationalExpr exprA
1276+ exprB' <- typeForGraphRefRelationalExpr exprB
1277+ lift $ except $ union exprA' exprB'
1278+typeForGraphRefRelationalExpr (Join exprA exprB) = do
1279+ exprA' <- typeForGraphRefRelationalExpr exprA
1280+ exprB' <- typeForGraphRefRelationalExpr exprB
1281+ lift $ except $ join exprA' exprB'
1282+typeForGraphRefRelationalExpr (Rename oldAttr newAttr expr) = do
1283+ expr' <- typeForGraphRefRelationalExpr expr
1284+ lift $ except $ rename oldAttr newAttr expr'
1285+typeForGraphRefRelationalExpr (Difference exprA exprB) = do
1286+ exprA' <- typeForGraphRefRelationalExpr exprA
1287+ exprB' <- typeForGraphRefRelationalExpr exprB
1288+ lift $ except $ difference exprA' exprB'
1289+typeForGraphRefRelationalExpr (Group groupNames attrName expr) = do
1290+ expr' <- typeForGraphRefRelationalExpr expr
1291+ groupNames' <- evalGraphRefAttributeNames groupNames expr
1292+ lift $ except $ group groupNames' attrName expr'
1293+typeForGraphRefRelationalExpr (Ungroup groupAttrName expr) = do
1294+ expr' <- typeForGraphRefRelationalExpr expr
1295+ lift $ except $ ungroup groupAttrName expr'
1296+typeForGraphRefRelationalExpr (Restrict pred' expr) = do
1297+ expr' <- typeForGraphRefRelationalExpr expr
1298+ filt <- predicateRestrictionFilter (attributes expr') pred'
1299+ lift $ except $ restrict filt expr'
1300+typeForGraphRefRelationalExpr Equals{} = do
1301+ pure relationFalse
1302+typeForGraphRefRelationalExpr NotEquals{} = do
1303+ pure relationFalse
1304+typeForGraphRefRelationalExpr (Extend extendTupleExpr expr) = do
1305+ rel <- typeForGraphRefRelationalExpr expr
1306+ evalGraphRefRelationalExpr (Extend extendTupleExpr (ExistingRelation rel))
1307+typeForGraphRefRelationalExpr expr@With{} = do
1308+ let expr' = substituteWithNameMacros [] expr
1309+ typeForGraphRefRelationalExpr expr'
1310+
12111311evalGraphRefAttributeNames :: GraphRefAttributeNames -> GraphRefRelationalExpr -> GraphRefRelationalExprM (S.Set AttributeName)
12121312evalGraphRefAttributeNames attrNames expr = do
1213− exprType <- typeForGraphRefRelationalExpr expr
1214− let typeNameSet = S.fromList (V.toList (A.attributeNames (attributes exprType)))
1313+ exprType' <- typeForGraphRefRelationalExpr expr
1314+ let typeNameSet = S.fromList (V.toList (A.attributeNames (attributes exprType')))
12151315 case attrNames of
12161316 AttributeNames names ->
1217− case A.projectionAttributesForNames names (attributes exprType) of
1317+ case A.projectionAttributesForNames names (attributes exprType') of
12181318 Left err -> throwError err
12191319 Right attrs -> pure (S.fromList (V.toList (A.attributeNames attrs)))
12201320
@@ -1248,6 +1348,7 @@ evalGraphRefAttributeExpr (AttributeAndTypeNameExpr attrName tCons tid) = do
12481348 case validateAtomType aType tConsMap of
12491349 Left err -> throwError err
12501350 Right _ -> pure (Attribute attrName aType)
1351+evalGraphRefAttributeExpr (NakedAttributeExpr attr) = pure attr
12511352
12521353mkEmptyRelVars :: RelationVariables -> RelationVariables
12531354mkEmptyRelVars rvMap = M.map mkEmptyRelVar rvMap
@@ -1263,11 +1364,11 @@ mkEmptyRelVars rvMap = M.map mkEmptyRelVar rvMap
12631364 mkEmptyRelVar (Difference exprA exprB) = Difference (mkEmptyRelVar exprA) (mkEmptyRelVar exprB)
12641365 mkEmptyRelVar (Group attrNames attrName expr) = Group attrNames attrName (mkEmptyRelVar expr)
12651366 mkEmptyRelVar (Ungroup attrName expr) = Ungroup attrName (mkEmptyRelVar expr)
1266− mkEmptyRelVar (Restrict pred expr) = Restrict pred (mkEmptyRelVar expr)
1367+ mkEmptyRelVar (Restrict pred' expr) = Restrict pred' (mkEmptyRelVar expr)
12671368 mkEmptyRelVar (Equals exprA exprB) = Equals (mkEmptyRelVar exprA) (mkEmptyRelVar exprB)
12681369 mkEmptyRelVar (NotEquals exprA exprB) = NotEquals (mkEmptyRelVar exprA) (mkEmptyRelVar exprB)
12691370 mkEmptyRelVar (Extend extTuple expr) = Extend extTuple (mkEmptyRelVar expr)
1270− mkEmptyRelVar (With macros expr) = With (map (\(rv, expr) -> (rv, mkEmptyRelVar expr)) macros) (mkEmptyRelVar expr)
1371+ mkEmptyRelVar (With macros expr) = With (map (\(rv, expr') -> (rv, mkEmptyRelVar expr')) macros) (mkEmptyRelVar expr)
12711372
12721373
12731374dbErr :: RelationalError -> DatabaseContextEvalMonad ()