@@ -66,7 +66,6 @@ mkDatabaseContextEvalState context = DatabaseContextEvalState {
6666data RelationalExprEnv = RelationalExprEnv {
6767 re_context :: DatabaseContext,
6868 re_graph :: TransactionGraph,
69− re_currentTransId :: TransactionId,
7069 re_extra :: Maybe (Either RelationTuple Attributes)
7170 }
7271
@@ -88,21 +87,14 @@ runRelationalExprM env m = runIdentity (runExceptT (runReaderT m env))
8887reGraph :: RelationalExprM TransactionGraph
8988reGraph = re_graph <$> R.ask
9089
91−currentTrans :: RelationalExprM Transaction
92−currentTrans = do
93− tid <- re_currentTransId <$> R.ask
94− graph <- re_graph <$> R.ask
95− lift $ except $ transactionForId tid graph
96−
97−reTransId :: RelationalExprM TransactionId
98−reTransId = re_currentTransId <$> R.ask
90+reContext :: RelationalExprM DatabaseContext
91+reContext = re_context <$> R.ask
9992
100−mkRelationalExprEnv :: DatabaseContext -> TransactionId -> TransactionGraph -> RelationalExprEnv
101−mkRelationalExprEnv ctx currentTransId graph =
93+mkRelationalExprEnv :: DatabaseContext -> TransactionGraph -> RelationalExprEnv
94+mkRelationalExprEnv ctx graph =
10295 RelationalExprEnv
10396 { re_context = ctx,
10497 re_graph = graph,
105− re_currentTransId = currentTransId,
10698 re_extra = Nothing }
10799
108100askEnv :: GraphRefRelationalExprM GraphRefRelationalExprEnv
@@ -159,7 +151,7 @@ dbcGraph = dce_graph <$> RWS.ask
159151
160152dbcRelationalExprEnv :: DatabaseContextEvalMonad RelationalExprEnv
161153dbcRelationalExprEnv =
162− mkRelationalExprEnv <$> getStateContext <*> dbcTransId <*> dbcGraph
154+ mkRelationalExprEnv <$> getStateContext <*> dbcGraph
163155
164156getStateContext :: DatabaseContextEvalMonad DatabaseContext
165157getStateContext = dbc_context <$> get
@@ -167,10 +159,12 @@ getStateContext = dbc_context <$> get
167159putStateContext :: DatabaseContext -> DatabaseContextEvalMonad ()
168160putStateContext ctx' = do
169161 s <- get
170− put (s {dbc_context = ctx'})
171−
162+ put (s {dbc_context = ctx', dbc_dirty = True})
163+
164+-- | The context is optionally passed down along in cases where the current context is uncommitted.
172165data GraphRefRelationalExprEnv =
173166 GraphRefRelationalExprEnv {
167+ gre_context :: Maybe DatabaseContext,
174168 gre_graph :: TransactionGraph,
175169 gre_extra :: Maybe (Either RelationTuple Attributes)
176170 }
@@ -182,11 +176,20 @@ gfTransForId tid = do
182176 graph <- gfGraph
183177 lift $ except $ transactionForId tid graph
184178
179+gfDatabaseContextForMarker :: GraphRefTransactionMarker -> GraphRefRelationalExprM DatabaseContext
180+gfDatabaseContextForMarker (TransactionMarker transId) = concreteDatabaseContext <$> gfTransForId transId
181+gfDatabaseContextForMarker UncommittedContextMarker = do
182+ mctx <- gre_context <$> askEnv
183+ case mctx of
184+ Nothing -> throwError NoUncommittedContextInEvalError
185+ Just ctx -> pure ctx
186+
185187runGraphRefRelationalExprM :: GraphRefRelationalExprEnv -> GraphRefRelationalExprM a -> Either RelationalError a
186188runGraphRefRelationalExprM env m = runIdentity (runExceptT (runReaderT m env))
187189
188−freshGraphRefRelationalExprEnv :: TransactionGraph -> GraphRefRelationalExprEnv
189−freshGraphRefRelationalExprEnv graph = GraphRefRelationalExprEnv {
190+freshGraphRefRelationalExprEnv :: Maybe DatabaseContext -> TransactionGraph -> GraphRefRelationalExprEnv
191+freshGraphRefRelationalExprEnv mctx graph = GraphRefRelationalExprEnv {
192+ gre_context = mctx,
190193 gre_graph = graph,
191194 gre_extra = Nothing
192195 }
@@ -385,11 +388,12 @@ evalGraphRefDatabaseContextExpr :: GraphRefDatabaseContextExpr -> DatabaseContex
385388evalGraphRefDatabaseContextExpr NoOperation = pure ()
386389
387390evalGraphRefDatabaseContextExpr (Define relVarName attrExprs) = do
391+ context <- getStateContext
388392 relvars <- fmap relationVariables getStateContext
389393 tConss <- fmap typeConstructorMapping getStateContext
390394 graph <- dbcGraph
391395 let eAttrs = runGraphRefRelationalExprM gfEnv (mapM evalGraphRefAttrExpr attrExprs)
392− gfEnv = freshGraphRefRelationalExprEnv graph
396+ gfEnv = freshGraphRefRelationalExprEnv (Just context) graph
393397 case eAttrs of
394398 Left err -> dbErr err
395399 Right attrsList -> do
@@ -416,7 +420,7 @@ evalGraphRefDatabaseContextExpr (Assign relVarName expr) = do
416420 Just existingRel -> do
417421 let eExpectedType = runGraphRefRelationalExprM reEnv (typeForGraphRefRelationalExpr existingRel)
418422 eNewExprType = runGraphRefRelationalExprM reEnv (typeForGraphRefRelationalExpr expr)
419− reEnv = freshGraphRefRelationalExprEnv graph
423+ reEnv = freshGraphRefRelationalExprEnv (Just context) graph
420424 case eExpectedType of
421425 Left err -> dbErr err
422426 Right expectedType ->
@@ -429,34 +433,32 @@ evalGraphRefDatabaseContextExpr (Assign relVarName expr) = do
429433 dbErr (RelationTypeMismatchError (attributes expectedType) (attributes newExprType))
430434
431435evalGraphRefDatabaseContextExpr (Insert relVarName relExpr) = do
432− transId <- dbcTransId
433436 evalGraphRefDatabaseContextExpr (Assign relVarName
434437 (Union
435− (RelationVariable relVarName transId)
438+ (RelationVariable relVarName UncommittedContextMarker)
436439 relExpr))
437440
438441evalGraphRefDatabaseContextExpr (Delete relVarName predicate) = do
439442 transId <- dbcTransId
440− let rv = RelationVariable relVarName transId
443+ let rv = RelationVariable relVarName (TransactionMarker transId)
441444 setRelVar relVarName (Restrict (NotPredicate predicate) rv)
442445
443446--union of restricted+updated portion and the unrestricted+unupdated portion
444447evalGraphRefDatabaseContextExpr (Update relVarName atomExprMap pred') = do
445448 context <- getStateContext
446449 transId <- dbcTransId
447− graph <- dbcGraph
448450 let relVarMap = relationVariables context
449451 case M.lookup relVarName relVarMap of
450452 Nothing -> dbErr (RelVarNotDefinedError relVarName)
451453 Just _ -> do
452454 let unrestrictedPortion = Restrict (NotPredicate pred') rv
453− rv = RelationVariable relVarName transId
455+ rv = RelationVariable relVarName (TransactionMarker transId)
454456 tmpAttr attr = "_tmp_" <> attr --this could certainly be improved to verify that there is no attribute name conflict
455457 updateAttr nam atomExpr = Extend (AttributeExtendTupleExpr (tmpAttr nam) atomExpr)
456458 projectAndRename attr expr = Rename (tmpAttr attr) attr (Project (InvertedAttributeNames (S.singleton attr)) expr)
457459 --TODO restrictedPortion = Restrict pred'
458460 updated = foldr (\(oldname, atomExpr) accum ->
459− let procAtomExpr = runProcessExprM transId graph (processAtomExpr atomExpr) in
461+ let procAtomExpr = runProcessExprM UncommittedContextMarker (processAtomExpr atomExpr) in
460462 updateAttr oldname procAtomExpr accum
461463 ) rv (M.toList atomExprMap)
462464 -- the atomExprMap could reference other attributes, so we must perform multi-pass folds
@@ -535,15 +537,10 @@ evalGraphRefDatabaseContextExpr (RemoveTypeConstructor tConsName) = do
535537 let newTypes = filter (\(tCons, _) -> TCD.name tCons /= tConsName) oldTypes
536538 putStateContext $ currentContext { typeConstructorMapping = newTypes }
537539
538−evalGraphRefDatabaseContextExpr (MultipleExpr _) = do
540+evalGraphRefDatabaseContextExpr (MultipleExpr exprs) = do
539541 --the multiple expressions must pass the same context around- not the old unmodified context
540− unimplemented
541−{- evald <- forM exprs (\expr -> evalGraphRefDatabaseContextExpr expr)
542− --some lifting magic needed here
543− case lefts evald of
544− [] -> pure ()
545− errs -> dbErr (someErrors errs)
546− -}
542+ mapM_ (\expr -> evalGraphRefDatabaseContextExpr expr) exprs
543+
547544evalGraphRefDatabaseContextExpr (RemoveAtomFunction funcName) = do
548545 currentContext <- getStateContext
549546 let atomFuncs = atomFunctions currentContext
@@ -574,7 +571,7 @@ evalGraphRefDatabaseContextExpr (ExecuteDatabaseContextFunction funcName atomArg
574571 --resolve atom arguments
575572 let eAtomTypes = mapM (\atomExpr -> runGraphRefRelationalExprM gfEnv (typeForGraphRefAtomExpr emptyAttributes atomExpr)) atomArgExprs
576573 eFunc = databaseContextFunctionForName funcName (dbcFunctions context)
577− gfEnv = freshGraphRefRelationalExprEnv graph
574+ gfEnv = freshGraphRefRelationalExprEnv (Just context) graph
578575 case eFunc of
579576 Left err -> dbErr err
580577 Right func -> do
@@ -591,8 +588,7 @@ evalGraphRefDatabaseContextExpr (ExecuteDatabaseContextFunction funcName atomArg
591588 Left err -> Just err
592589 Right _ -> Nothing) (zip (dbcFuncType func) atomTypes)
593590 typeErrors = catMaybes mValidTypes
594− eAtomArgs = unimplemented
595− --eAtomArgs = map (\arg -> runReader (evalAtomExpr emptyTuple arg) relExprState) atomArgExprs
591+ eAtomArgs = map (\arg -> runGraphRefRelationalExprM gfEnv (evalGraphRefAtomExpr emptyTuple arg)) atomArgExprs
596592 if length (lefts eAtomArgs) > 1 then
597593 dbErr (someErrors (lefts eAtomArgs))
598594 else if not (null typeErrors) then
@@ -638,7 +634,7 @@ getDBCIORelationalExprEnv :: DatabaseContextIOEvalMonad RelationalExprEnv
638634getDBCIORelationalExprEnv = do
639635 context <- getDBCIOContext
640636 env <- RWS.ask
641− pure $ mkRelationalExprEnv context (dbcio_transId env) (dbcio_graph env)
637+ pure $ mkRelationalExprEnv context (dbcio_graph env)
642638
643639evalGraphRefDatabaseContextIOExpr :: GraphRefDatabaseContextIOExpr -> DatabaseContextIOEvalMonad (Either RelationalError ())
644640evalGraphRefDatabaseContextIOExpr (AddAtomFunction funcName funcType script) = do
@@ -751,7 +747,7 @@ evalGraphRefDatabaseContextIOExpr (CreateArbitraryRelation relVarName attrExprs
751747 case existingRelVar of
752748 Nothing -> pure $ Left (RelVarNotDefinedError relVarName)
753749 Just existingRel -> do
754− let gfEnv = freshGraphRefRelationalExprEnv graph
750+ let gfEnv = freshGraphRefRelationalExprEnv (Just currentContext) graph
755751 case runGraphRefRelationalExprM gfEnv (typeForGraphRefRelationalExpr existingRel) of
756752 Left err -> pure (Left err)
757753 Right relType -> do
@@ -791,18 +787,18 @@ checkConstraints context transId graph@(TransactionGraph graphHeads transSet) =
791787 deps = inclusionDependencies context
792788 -- no optimization available here, really? perhaps the optimizer should be passed down to here or the eval function should be passed through the environment
793789 checkIncDep depName (InclusionDependency subsetExpr supersetExpr) = do
794− let process = runProcessExprM transId graph
790+ let process = runProcessExprM UncommittedContextMarker
795791 gfSubsetExpr = process (processRelationalExpr subsetExpr)
796792 gfSupersetExpr = process (processRelationalExpr supersetExpr)
797793 --if both expressions are of a single-attribute (such as with a simple foreign key), the names of the attributes are irrelevant (they need not match) because the expression is unambiguous, but special-casing this to rename the attribute automatically would not be orthogonal behavior and probably cause confusion. Instead, special case the error to make it clear.
798− let gfEnv = freshGraphRefRelationalExprEnv graph
794+ let gfEnv = freshGraphRefRelationalExprEnv (Just context) graph
799795 runGfRel = runGraphRefRelationalExprM gfEnv
800796 typeSub <- runGfRel (typeForGraphRefRelationalExpr gfSubsetExpr)
801797 typeSuper <- runGfRel (typeForGraphRefRelationalExpr gfSupersetExpr)
802798 when (typeSub /= typeSuper) (Left (RelationTypeMismatchError (attributes typeSub) (attributes typeSuper)))
803799 let checkExpr = Equals gfSupersetExpr (Union gfSubsetExpr gfSupersetExpr)
804800 gfEvald = runGraphRefRelationalExprM gfEnv' (evalGraphRefRelationalExpr checkExpr)
805− gfEnv' = freshGraphRefRelationalExprEnv potentialGraph
801+ gfEnv' = freshGraphRefRelationalExprEnv (Just context) potentialGraph
806802 case gfEvald of
807803 Left err -> Left err
808804 Right resultRel -> if resultRel == relationTrue then
@@ -818,9 +814,9 @@ typeForRelationalExpr expr = do
818814 --replace the relationVariables context element with a cloned set of relation devoid of tuples
819815 --evalRelationalExpr could still return an existing relation with tuples, so strip them
820816 graph <- reGraph
821− transId <- reTransId
822− let gfExpr = runProcessExprM transId graph (processRelationalExpr expr)
823− gfEnv = freshGraphRefRelationalExprEnv graph
817+ context <- reContext
818+ let gfExpr = runProcessExprM UncommittedContextMarker (processRelationalExpr expr)
819+ gfEnv = freshGraphRefRelationalExprEnv (Just context) graph
824820 runGf = runGraphRefRelationalExprM gfEnv (typeForGraphRefRelationalExpr gfExpr)
825821 lift $ except $ runGf
826822
@@ -934,18 +930,64 @@ extendGraphRefTupleExpressionProcessor relIn (AttributeExtendTupleExpr newAttrNa
934930 atomExprType' <- verifyGraphRefAtomExprTypes relIn atomExpr atomExprType
935931 let newAttrs = A.attributesFromList [Attribute newAttrName atomExprType']
936932 newAndOldAttrs = A.addAttributes (attributes relIn) newAttrs
937− pure (newAndOldAttrs, \tup ->
938− --let substate = mergeTuplesIntoGraphRefRelationalExprEnv tup renv in
939− case unimplemented {-runReader (evalAtomExpr tup atomExpr) substate-} of
940− Left err -> Left err
941− Right atom -> Right (tupleAtomExtend newAttrName atom tup)
933+ env <- ask
934+ pure (newAndOldAttrs, \tup -> do
935+ let gfEnv = mergeTuplesIntoGraphRefRelationalExprEnv tup env
936+ atom <- runGraphRefRelationalExprM gfEnv (evalGraphRefAtomExpr tup atomExpr)
937+ Right (tupleAtomExtend newAttrName atom tup)
942938 )
943939
944940evalGraphRefAtomExpr :: RelationTuple -> GraphRefAtomExpr -> GraphRefRelationalExprM Atom
945−evalGraphRefAtomExpr = unimplemented
941+evalGraphRefAtomExpr tupIn (AttributeAtomExpr attrName) =
942+ case atomForAttributeName attrName tupIn of
943+ Right atom -> pure atom
944+ Left err@(NoSuchAttributeNamesError _) -> do
945+ env <- askEnv
946+ case gre_extra env of
947+ Nothing -> throwError err
948+ Just (Left ctxtup) -> lift $ except $ atomForAttributeName attrName ctxtup
949+ Just (Right _) -> throwError err
950+ Left err -> throwError err
951+evalGraphRefAtomExpr _ (NakedAtomExpr atom) = pure atom
952+evalGraphRefAtomExpr tupIn (FunctionAtomExpr funcName arguments tid) = do
953+ argTypes <- mapM (typeForGraphRefAtomExpr (tupleAttributes tupIn)) arguments
954+ context <- gfDatabaseContextForMarker tid
955+ let functions = atomFunctions context
956+ func <- lift $ except (atomFunctionForName funcName functions)
957+ let expectedArgCount = length (atomFuncType func) - 1
958+ actualArgCount = length argTypes
959+ safeInit [] = [] -- different behavior from normal init
960+ safeInit xs = init xs
961+ if expectedArgCount /= actualArgCount then
962+ throwError (FunctionArgumentCountMismatchError expectedArgCount actualArgCount)
963+ else do
964+ let zippedArgs = zip (safeInit (atomFuncType func)) argTypes
965+ mapM_ (\(expType, actType) -> do
966+ lift $ except (atomTypeVerify expType actType)) zippedArgs
967+ evaldArgs <- mapM (evalGraphRefAtomExpr tupIn) arguments
968+ case evalAtomFunction func evaldArgs of
969+ Left err -> throwError (AtomFunctionUserError err)
970+ Right result -> do
971+ --validate that the result matches the expected type
972+ _ <- lift $ except (atomTypeVerify (last (atomFuncType func)) (atomTypeForAtom result))
973+ pure result
974+evalGraphRefAtomExpr tupIn (RelationAtomExpr relExpr) = do
975+ --merge existing state tuple context into new state tuple context to support an arbitrary number of levels, but new attributes trounce old attributes
976+ env <- ask
977+ let gfEnv = mergeTuplesIntoGraphRefRelationalExprEnv tupIn env
978+ relAtom <- lift $ except $ runGraphRefRelationalExprM gfEnv (evalGraphRefRelationalExpr relExpr)
979+ pure (RelationAtom relAtom)
980+evalGraphRefAtomExpr tupIn cons@(ConstructedAtomExpr dConsName dConsArgs _) = do --why is the tid unused here? suspicious
981+ let mergeEnv = mergeTuplesIntoGraphRefRelationalExprEnv tupIn
982+ aType <- local mergeEnv (typeForGraphRefAtomExpr (tupleAttributes tupIn) cons)
983+ argAtoms <- local mergeEnv $
984+ mapM (evalGraphRefAtomExpr tupIn) dConsArgs
985+ pure (ConstructedAtom dConsName aType argAtoms)
946986
987+{-
947988evalAtomExpr :: RelationTuple -> AtomExpr -> RelationalExprM Atom
948−evalAtomExpr = unimplemented
989+evalAtomExpr tupIn expr =
990+ -}
949991{-
950992
951993evalAtomExpr tupIn (AttributeAtomExpr attrName) = case atomForAttributeName attrName tupIn of
@@ -1011,7 +1053,7 @@ typeForGraphRefAtomExpr attrs (AttributeAtomExpr attrName) = do
10111053
10121054typeForGraphRefAtomExpr _ (NakedAtomExpr atom) = pure (atomTypeForAtom atom)
10131055typeForGraphRefAtomExpr attrs (FunctionAtomExpr funcName atomArgs transId) = do
1014− funcs <- atomFunctions . concreteDatabaseContext <$> gfTransForId transId
1056+ funcs <- atomFunctions <$> gfDatabaseContextForMarker transId
10151057 case atomFunctionForName funcName funcs of
10161058 Left err -> throwError err
10171059 Right func -> do
@@ -1029,7 +1071,7 @@ typeForGraphRefAtomExpr attrs (RelationAtomExpr relExpr) = do
10291071typeForGraphRefAtomExpr attrs (ConstructedAtomExpr dConsName dConsArgs tid) =
10301072 do
10311073 argsTypes <- mapM (typeForGraphRefAtomExpr attrs) dConsArgs
1032− tConsMap <- typeConstructorMapping . concreteDatabaseContext <$> gfTransForId tid
1074+ tConsMap <- typeConstructorMapping <$> gfDatabaseContextForMarker tid
10331075 lift $ except $ atomTypeForDataConstructor tConsMap dConsName argsTypes
10341076
10351077-- | Validate that the type of the AtomExpr matches the expected type.
@@ -1051,7 +1093,7 @@ verifyGraphRefAtomExprTypes relIn (AttributeAtomExpr attrName) expectedType = do
10511093verifyGraphRefAtomExprTypes _ (NakedAtomExpr atom) expectedType =
10521094 lift $ except $ atomTypeVerify expectedType (atomTypeForAtom atom)
10531095verifyGraphRefAtomExprTypes relIn (FunctionAtomExpr funcName funcArgExprs tid) expectedType = do
1054− context <- concreteDatabaseContext <$> gfTransForId tid
1096+ context <- gfDatabaseContextForMarker tid
10551097 let functions = atomFunctions context
10561098 func <- lift $ except $ atomFunctionForName funcName functions
10571099 let expectedArgTypes = atomFuncType func
@@ -1077,7 +1119,7 @@ verifyGraphRefAtomExprTypes rel cons@ConstructedAtomExpr{} expectedType = do
10771119-- | Look up the type's name and create a new attribute.
10781120evalGraphRefAttrExpr :: GraphRefAttributeExpr -> GraphRefRelationalExprM Attribute
10791121evalGraphRefAttrExpr (AttributeAndTypeNameExpr attrName tCons transId) = do
1080− tConsMap <- typeConstructorMapping . concreteDatabaseContext <$> gfTransForId transId
1122+ tConsMap <- typeConstructorMapping <$> gfDatabaseContextForMarker transId
10811123 aType <- lift $ except $ atomTypeForTypeConstructorValidate True tCons tConsMap M.empty
10821124 lift $ except $ validateAtomType aType tConsMap
10831125 pure $ Attribute attrName aType
@@ -1179,7 +1221,7 @@ evalGraphRefRelationalExpr (MakeStaticRelation attributeSet tupleSet) =
11791221 lift $ except $ mkRelation attributeSet tupleSet
11801222evalGraphRefRelationalExpr (ExistingRelation rel) = pure rel
11811223evalGraphRefRelationalExpr (RelationVariable name tid) = do
1182− ctx <- concreteDatabaseContext <$> gfTransForId tid
1224+ ctx <- gfDatabaseContextForMarker tid
11831225 case M.lookup name (relationVariables ctx) of
11841226 Nothing -> throwError (RelVarNotDefinedError name)
11851227 Just rv -> evalGraphRefRelationalExpr rv
@@ -1263,7 +1305,7 @@ typeForGraphRefRelationalExpr (MakeRelationFromExprs mAttrExprs tupleExprs) = do
12631305 pure $ emptyRelationWithAttrs retAttrs
12641306
12651307typeForGraphRefRelationalExpr (RelationVariable rvName tid) = do
1266− relVars <- relationVariables . concreteDatabaseContext <$> gfTransForId tid
1308+ relVars <- relationVariables <$> gfDatabaseContextForMarker tid
12671309 case M.lookup rvName relVars of
12681310 Nothing -> throwError (RelVarNotDefinedError rvName)
12691311 Just rvExpr -> typeForGraphRefRelationalExpr rvExpr
@@ -1341,7 +1383,7 @@ evalGraphRefAttributeNames attrNames expr = do
13411383
13421384evalGraphRefAttributeExpr :: GraphRefAttributeExpr -> GraphRefRelationalExprM Attribute
13431385evalGraphRefAttributeExpr (AttributeAndTypeNameExpr attrName tCons tid) = do
1344− tConsMap <- typeConstructorMapping . concreteDatabaseContext <$> gfTransForId tid
1386+ tConsMap <- typeConstructorMapping <$> gfDatabaseContextForMarker tid
13451387 case atomTypeForTypeConstructorValidate True tCons tConsMap M.empty of
13461388 Left err -> throwError err
13471389 Right aType -> do
@@ -1381,7 +1423,7 @@ relationVariablesAsRelation relVarMap graph = do
13811423 attrs = A.attributesFromList [Attribute "name" TextAtomType,
13821424 Attribute "attributes" (RelationAtomType subrelAttrs)]
13831425 mkRvDesc (rvName, gfExpr) = do
1384− let gfEnv = freshGraphRefRelationalExprEnv graph
1426+ let gfEnv = freshGraphRefRelationalExprEnv Nothing graph
13851427 gfType <- runGraphRefRelationalExprM gfEnv (typeForGraphRefRelationalExpr gfExpr)
13861428 pure (rvName, gfType)
13871429 relVarToAtomList (rvName, rel) = [TextAtom rvName, attributesToRel (attributes rel)]
@@ -1393,3 +1435,4 @@ relationVariablesAsRelation relVarMap graph = do
13931435 let tups = map relVarToAtomList rvs
13941436 mkRelationFromList attrs tups
13951437
1438+