on master help sign in
resolve TupleExprs within their own transaction contexts
commit584b01dae33f13761644230c882de04a734c2e67 authorAgentM <agentm@themactionfaction.com> dateMon 20 Apr 2020, 23:43 (7 years ago) parent4beffa3
3 files changed+32−22
src/lib/ProjectM36/Error.hs+1 src/lib/ProjectM36/GraphRefRelationalExpr.hs+19−17 src/lib/ProjectM36/RelationalExpression.hs+12−5
src/lib/ProjectM36/Error.hs+1
@@ -100,6 +100,7 @@ data RelationalError = NoSuchAttributeNamesError (S.Set AttributeName)
100100 | NonConcreteSchemaPlanError
101101
102102 | NoUncommittedContextInEvalError
103+ | TupleExprsReferenceMultipleMarkersError
103104
104105 | MultipleErrors [RelationalError]
105106 deriving (Show,Eq,Generic,Binary,Typeable, NFData)
src/lib/ProjectM36/GraphRefRelationalExpr.hs+19−17
@@ -1,32 +1,31 @@
11module ProjectM36.GraphRefRelationalExpr where
22--evaluate relational expressions across the entire transaction graph to support cross-transaction referencing
33import ProjectM36.Base
4−import ProjectM36.Error
54import qualified Data.Set as S
65
7−-- core evaluation function- all other relational expr forms compile to GraphRefRelationalExpr
8−eval :: GraphRefRelationalExpr -> TransactionGraph -> Either RelationalError Relation
9−eval = undefined
10−{-eval (MakeRelationFromExprs mAttrExprs tupleExprs) graph = do
11− mAttrs <- case mAttrExprs of
12− Just _ ->
13− Just . A.attributesFromList <$> mapM (evalAttrExpr tConss) (fromMaybe [] mAttrExprs)
14− Nothing -> pure Nothing
15− tuples <- mapM (evalTupleExpr mAttrs) tupleExprs
16− let attrs = fromMaybe firstTupleAttrs mAttrs
17− firstTupleAttrs = if null tuples then A.emptyAttributes else tupleAttributes (head tuples)
18− mkRelation attrs (RelationTupleSet tuples)
19−
20−
21−-}
6+--import Debug.Trace
227
238data SingularTransactionRef = SingularTransactionRef GraphRefTransactionMarker |
249 MultipleTransactionsRef |
2510 NoTransactionsRef
2611 deriving (Eq, Show)
12+
13+instance Semigroup SingularTransactionRef where
14+ NoTransactionsRef <> x = x
15+ MultipleTransactionsRef <> _ = MultipleTransactionsRef
16+ SingularTransactionRef tidA <> s@(SingularTransactionRef tidB) =
17+ if tidA == tidB then
18+ s
19+ else
20+ MultipleTransactionsRef
21+ s@SingularTransactionRef{} <> NoTransactionsRef = s
22+ _ <> MultipleTransactionsRef = MultipleTransactionsRef
23+
24+instance Monoid SingularTransactionRef where
25+ mempty = NoTransactionsRef
2726
2827-- | return `Just transid` if this GraphRefRelationalExpr refers to just one transaction in the graph. This is useful for determining if certain optimizations can apply.
29−singularTransaction :: GraphRefRelationalExpr -> SingularTransactionRef
28+singularTransaction :: Foldable t => t GraphRefTransactionMarker -> SingularTransactionRef
3029singularTransaction expr =
3130 if S.null transSet then
3231 NoTransactionsRef
@@ -44,3 +43,6 @@ inSameTransaction exprA exprB = case (stA, stB) of
4443 _ -> Nothing
4544 where stA = singularTransaction exprA
4645 stB = singularTransaction exprB
46+
47+singularTransactions :: (Foldable f, Foldable t) => f (t GraphRefTransactionMarker) -> SingularTransactionRef
48+singularTransactions fs = foldMap singularTransaction fs
src/lib/ProjectM36/RelationalExpression.hs+12−5
@@ -15,6 +15,7 @@ import ProjectM36.DataTypes.Primitive
1515import ProjectM36.AtomFunction
1616import ProjectM36.DatabaseContextFunction
1717import ProjectM36.Arbitrary
18+import ProjectM36.GraphRefRelationalExpr
1819import ProjectM36.Transaction
1920import qualified ProjectM36.Attribute as A
2021import qualified Data.Map as M
@@ -111,7 +112,7 @@ mergeTuplesIntoGraphRefRelationalExprEnv tupIn e =
111112 new_elems = Just (Left newTuple)
112113 mergedTupMap = M.union (tupleToMap tupIn) (tupleToMap (envTuple e))
113114 newTuple = mkRelationTupleFromMap mergedTupMap
114−
115+
115116mergeAttributesIntoGraphRefRelationalExprEnv :: Attributes -> GraphRefRelationalExprEnv -> GraphRefRelationalExprEnv
116117mergeAttributesIntoGraphRefRelationalExprEnv attrsIn e = e { gre_extra = newattrs }
117118 where
@@ -185,7 +186,7 @@ gfDatabaseContextForMarker (TransactionMarker transId) = concreteDatabaseContext
185186gfDatabaseContextForMarker UncommittedContextMarker = do
186187 mctx <- gre_context <$> askEnv
187188 case mctx of
188− Nothing -> throwError NoUncommittedContextInEvalError
189+ Nothing -> throwError (traceStack "relexpr" NoUncommittedContextInEvalError)
189190 Just ctx -> pure ctx
190191
191192runGraphRefRelationalExprM :: GraphRefRelationalExprEnv -> GraphRefRelationalExprM a -> Either RelationalError a
@@ -1131,6 +1132,7 @@ evalGraphRefAttrExpr (NakedAttributeExpr attr) = pure attr
11311132
11321133-- for tuple type concrete resolution (Nothing ==> Maybe Int) when the attributes hint is Nothing, we need to first process all the tuples, then extract the concrete types on a per-attribute basis, then reprocess the tuples to include the concrete types
11331134evalGraphRefTupleExprs :: Maybe Attributes -> [GraphRefTupleExpr] -> GraphRefRelationalExprM [RelationTuple]
1135+evalGraphRefTupleExprs _ [] = pure []
11341136evalGraphRefTupleExprs mAttrs tupleExprs = do
11351137 tuples <- mapM (evalGraphRefTupleExpr mAttrs) tupleExprs
11361138 finalAttrs <- case mAttrs of
@@ -1150,8 +1152,13 @@ evalGraphRefTupleExprs mAttrs tupleExprs = do
11501152 Left _ -> accAttr
11511153 Right val -> val) (zip (V.toList $ tupleAttributes tup) acc)) (V.toList $ tupleAttributes headTuple) tailTuples
11521154 pure (A.attributesFromList mostResolvedTypes)
1153− --is it OK to get the tConsMap like this and use it uniformly across the tuples- couldn't the tuple expressions use types from other parts of the graph? Maybe it's OK because this is only used
1154− tConsMap <- typeConstructorMapping <$> gfDatabaseContextForMarker UncommittedContextMarker
1155+ --strategy: if all the tuple expr transaction markers refer to one location, then we can pass the type constructor mapping from that location, otherwise, we cannot assume that the types are the same
1156+ tConsMap <- case singularTransactions tupleExprs of
1157+ SingularTransactionRef commonTransId -> do
1158+ typeConstructorMapping <$> gfDatabaseContextForMarker commonTransId
1159+ NoTransactionsRef -> pure [] --no custom type constructors are referenced, so no tConsMap is needed
1160+ -- if there are multiple transaction markers in the TupleExprs, then we can't assume a single type constructor mapping- this could be improved in the future, but if all the tuples are fully resolved, then we don't need further resolution
1161+ _ -> throwError TupleExprsReferenceMultipleMarkersError
11551162 lift $ except $ validateAttributes tConsMap finalAttrs
11561163 mapM (\tup -> lift $ except $ resolveTypesInTuple finalAttrs tConsMap tup) tuples
11571164
@@ -1386,7 +1393,7 @@ typeForGraphRefRelationalExpr expr@(With withs _) = do
13861393 case M.lookup macroName rvs of
13871394 Just _ -> lift $ except $ Left (RelVarAlreadyDefinedError macroName) --this error does not include the transaction marker, but should be good enough to identify the cause
13881395 Nothing -> pure ()
1389− mapM checkMacroName (map fst withs)
1396+ mapM_ checkMacroName (map fst withs)
13901397 typeForGraphRefRelationalExpr expr'
13911398
13921399evalGraphRefAttributeNames :: GraphRefAttributeNames -> GraphRefRelationalExpr -> GraphRefRelationalExprM (S.Set AttributeName)