on master help sign in
WIP compilation checkpoint
commitc612d043d6c9f21fea1fec0064ebb32e34358fde authorAgentM <agentm@themactionfaction.com> dateSun 5 Jan 2020, 19:23 (7 years ago) parentf8e6f19
24 files changed+328−232
examples/blog.hs+8−6 project-m36.cabal−14 src/bin/ProjectM36/Server/RemoteCallTypes/Json.hs+3 src/bin/TutorialD/Interpreter.hs+3−1 src/bin/TutorialD/Interpreter/Base.hs+2 src/bin/TutorialD/Interpreter/DatabaseContextExpr.hs+5−1 src/bin/TutorialD/Interpreter/Export/Base.hs+3 src/bin/TutorialD/Interpreter/Import/Base.hs+3 src/bin/TutorialD/tutd.hs+2 src/bin/benchmark/bigrel.hs+14−4 src/lib/ProjectM36/Base.hs+33−27 src/lib/ProjectM36/Client.hs+24−19 src/lib/ProjectM36/DatabaseContext.hs+6−2 src/lib/ProjectM36/DatabaseContextFunctionUtils.hs+3−3 src/lib/ProjectM36/Error.hs+2 src/lib/ProjectM36/GraphRefRelationalExpr.hs+2−2 src/lib/ProjectM36/IsomorphicSchema.hs+3−3 src/lib/ProjectM36/NormalizeExpr.hs+10−13 src/lib/ProjectM36/Notifications.hs+4−4 src/lib/ProjectM36/RelationalExpression.hs+102−59 src/lib/ProjectM36/Server.hs+13−2 src/lib/ProjectM36/StaticOptimizer.hs+80−68 src/lib/ProjectM36/TransGraphRelationalExpression.hs+2−2 test/TutorialD/Interpreter/TestBase.hs+1−2
examples/blog.hs+8−6
@@ -1,5 +1,5 @@
11-- a simple example of a blog schema
2−{-# LANGUAGE DeriveAnyClass, DeriveGeneric, OverloadedStrings #-}
2+{-# LANGUAGE DeriveAnyClass, DeriveGeneric, OverloadedStrings, CPP #-}
33
44import ProjectM36.Client
55import ProjectM36.Base
@@ -17,7 +17,9 @@ import Data.Time.Clock
1717import Data.Time.Calendar
1818import Control.DeepSeq
1919import Data.Proxy
20+#if __GLASGOW_HASKELL__ <= 802
2021import Data.Monoid
22+#endif
2123import Data.List
2224import Control.Monad (when, forM_)
2325
@@ -33,7 +35,7 @@ import Data.Time.Format
3335data Blog = Blog {
3436 title :: T.Text,
3537 entry :: T.Text,
36− stamp :: UTCTime,
38+ tstamp :: UTCTime,
3739 category :: Category --note that this type is an algebraic data type
3840 }
3941 deriving (Generic, Show) --derive Generic so that Tupleable can use default instances
@@ -103,11 +105,11 @@ insertSampleData :: SessionId -> Connection -> IO ()
103105insertSampleData sessionId conn = do
104106 let blogs = [Blog { title = "Haskell Lenses",
105107 entry = "I wear Haskell rose-colored lenses.",
106− stamp = UTCTime (fromGregorian 2017 5 8) (secondsToDiffTime 1000),
108+ tstamp = UTCTime (fromGregorian 2017 5 8) (secondsToDiffTime 1000),
107109 category = Food },
108110 Blog { title = "Haskell Monad Analogy",
109111 entry = "Monads are like burritos going through intestines.",
110− stamp = UTCTime (fromGregorian 2017 6 10) (secondsToDiffTime 2000),
112+ tstamp = UTCTime (fromGregorian 2017 6 10) (secondsToDiffTime 2000),
111113 category = Cats }
112114 ]
113115 comments = [Comment { blogTitle = "Haskell Lenses",
@@ -136,7 +138,7 @@ listBlogs sessionId conn = do
136138 Left err -> render500 (toHtml (show err))
137139 Right blogRel -> do
138140 blogs <- liftIO (toList blogRel) >>= mapM (handleWebError . fromTuple) :: ActionM [Blog]
139− let sortedBlogs = sortBy (\b1 b2 -> stamp b1 `compare` stamp b2) blogs
141+ let sortedBlogs = sortBy (\b1 b2 -> tstamp b1 `compare` tstamp b2) blogs
140142 html . renderHtml $ do
141143 h1 "Blog Posts"
142144 forM_ sortedBlogs $ \blog -> a ! href (toValue $ "/blog/" <> title blog) $ h2 (toHtml (title blog))
@@ -182,7 +184,7 @@ showBlogEntry sessionId conn = do
182184 render $ do
183185 --show blog details
184186 h1 (toHtml (title blog))
185− p (toHtml ("Posted at " <> formatStamp (stamp blog) <> " under " <> show (category blog)))
187+ p (toHtml ("Posted at " <> formatStamp (tstamp blog) <> " under " <> show (category blog)))
186188 p (toHtml (entry blog))
187189 hr
188190 h3 "Comments"
project-m36.cabal−14
@@ -227,20 +227,6 @@ Executable project-m36-server
227227 Default-Language: Haskell2010
228228 Default-Extensions: OverloadedStrings
229229
230−Executable bigrel
231− Default-Language: Haskell2010
232− Default-Extensions: OverloadedStrings
233− Build-Depends: base, HUnit, Cabal, containers, hashable, unordered-containers, mtl, vector, vector-binary-instances, time, hashable-time, bytestring, uuid, stm, deepseq, deepseq-generics, binary, parallel, cassava, attoparsec, gnuplot, directory, temporary, haskeline, megaparsec, text, base64-bytestring, data-interval, filepath, optparse-applicative, stm-containers, list-t, ghc, ghc-paths, transformers, project-m36, random, MonadRandom, semigroups
234− Other-Modules: TutorialD.Interpreter.Base,
235− TutorialD.Interpreter.DatabaseContextExpr,
236− TutorialD.Interpreter.RelationalExpr,
237− TutorialD.Interpreter.Types
238− main-is: benchmark/bigrel.hs
239− GHC-Options: -Wall -threaded -rtsopts
240− HS-Source-Dirs: ./src/bin
241− if flag(profiler)
242− GHC-Prof-Options: -fprof-auto -rtsopts -threaded -Wall
243−
244230Benchmark basic-benchmark
245231 Default-Language: Haskell2010
246232 Default-Extensions: OverloadedStrings
src/bin/ProjectM36/Server/RemoteCallTypes/Json.hs+3
@@ -149,3 +149,6 @@ instance FromJSON PersistenceError
149149
150150instance ToJSON AtomFunctionError
151151instance FromJSON AtomFunctionError
152+
153+instance ToJSON WithNameExpr
154+instance FromJSON WithNameExpr
src/bin/TutorialD/Interpreter.hs+3−1
@@ -1,4 +1,4 @@
1−{-# LANGUAGE GADTs, LambdaCase #-}
1+{-# LANGUAGE GADTs, LambdaCase, CPP #-}
22module TutorialD.Interpreter where
33import TutorialD.Interpreter.Base
44import TutorialD.Interpreter.RODatabaseContextOperator
@@ -28,7 +28,9 @@ import System.Console.Haskeline
2828import System.Directory (getHomeDirectory)
2929import qualified Data.Text as T
3030import System.IO (hPutStrLn, stderr)
31+#if __GLASGOW_HASKELL__ <= 802
3132import Data.Monoid
33+#endif
3234import Data.List (isPrefixOf)
3335import Control.Exception
3436import System.Exit
src/bin/TutorialD/Interpreter/Base.hs+2
@@ -35,7 +35,9 @@ import qualified Data.Text.IO as TIO
3535import System.IO
3636import ProjectM36.Relation.Show.Term
3737import GHC.Generics
38+#if __GLASGOW_HASKELL__ <= 802
3839import Data.Monoid
40+#endif
3941import qualified Data.UUID as U
4042import Control.Monad.Random
4143import Data.List.NonEmpty as NE
src/bin/TutorialD/Interpreter/DatabaseContextExpr.hs+5−1
@@ -1,3 +1,4 @@
1+{-# LANGUAGE CPP #-}
12module TutorialD.Interpreter.DatabaseContextExpr where
23import ProjectM36.Base
34import TutorialD.Interpreter.Base
@@ -11,7 +12,9 @@ import ProjectM36.Error
1112import qualified ProjectM36.RelationalExpression as RE
1213import ProjectM36.Key
1314import ProjectM36.FunctionalDependency
15+#if __GLASGOW_HASKELL__ <= 802
1416import Data.Monoid
17+#endif
1518import Data.Functor
1619
1720--parsers which create "database expressions" which modify the database context (such as relvar assignment)
@@ -200,7 +203,8 @@ interpretDatabaseContextExpr context transId graph tutdstring =
200203 Left err -> Left $ PM36E.ParseError (T.pack (show err))
201204 Right parsed -> do
202205 let env = RE.mkDatabaseContextEvalEnv transId graph
203− RE.dbc_context <$> RE.runDatabaseContextEvalMonad context env (optimizeAndEvalDatabaseContextExpr True parsed)
206+ x <- RE.dbc_context <$> RE.runDatabaseContextEvalMonad context env (optimizeAndEvalDatabaseContextExpr True parsed)
207+ pure x
204208
205209{-
206210--no optimization
src/bin/TutorialD/Interpreter/Export/Base.hs+3
@@ -1,7 +1,10 @@
1+{-# LANGUAGE CPP #-}
12module TutorialD.Interpreter.Export.Base where
23import ProjectM36.Base
34import ProjectM36.Error
5+#if __GLASGOW_HASKELL__ <= 802
46import Data.Monoid
7+#endif
58
69data RelVarDataExportOperator = RelVarDataExportOperator RelationalExpr FilePath (RelVarDataExportOperator -> Relation -> IO (Maybe RelationalError))
710
src/bin/TutorialD/Interpreter/Import/Base.hs+3
@@ -1,7 +1,10 @@
1+{-# LANGUAGE CPP #-}
12module TutorialD.Interpreter.Import.Base where
23import ProjectM36.Base
34import ProjectM36.Error
5+#if __GLASGOW_HASKELL__ <= 802
46import Data.Monoid
7+#endif
58
69-- | import data into a relation variable
710data RelVarDataImportOperator = RelVarDataImportOperator RelVarName FilePath (RelVarName -> TypeConstructorMapping -> Attributes -> FilePath -> IO (Either RelationalError DatabaseContextExpr))
src/bin/TutorialD/tutd.hs+2
@@ -7,7 +7,9 @@ import ProjectM36.Server
77import System.IO
88import Options.Applicative
99import System.Exit
10+#if __GLASGOW_HASKELL__ <= 802
1011import Data.Monoid
12+#endif
1113import Data.Maybe
1214import qualified Data.Text as T
1315
src/bin/benchmark/bigrel.hs+14−4
@@ -4,12 +4,14 @@ import ProjectM36.Base
44import ProjectM36.Relation
55import ProjectM36.DateExamples
66import ProjectM36.Error
7+import ProjectM36.StaticOptimizer
78import qualified ProjectM36.Attribute as A
89import qualified Data.Text as T
910--import ProjectM36.Relation.Show.CSV
1011import ProjectM36.Relation.Show.HTML
1112import TutorialD.Interpreter.DatabaseContextExpr (interpretDatabaseContextExpr)
1213import ProjectM36.RelationalExpression
14+import ProjectM36.TransactionGraph
1315--import qualified Data.HashSet as HS
1416--import qualified Data.ByteString.Lazy.Char8 as BS
1517--import qualified Data.IntMap as IM
@@ -23,6 +25,9 @@ import Control.Monad.State
2325import Control.DeepSeq
2426import Data.Text hiding (map)
2527import Data.Monoid
28+import Data.Time.Clock
29+import Data.UUID
30+import Data.UUID.V4
2631
2732{-
2833dumpcsv :: Relation -> IO ()
@@ -60,13 +65,18 @@ matrixRun (BigrelArgs attributeCount tupleCount tutd) =
6065 Right rel -> if tutd == "" then
6166 putStrLn "Done."
6267 else do
68+ now <- getCurrentTime
69+ tid <- nextRandom
6370 let setx = Assign "x" (ExistingRelation (force rel))
64− (context,_,_) = execState (evalDatabaseContextExpr setx) (freshDatabaseState dateExamples)
65− interpreted = interpretDatabaseContextExpr context tutd
71+ graph = bootstrapTransactionGraph now tid dateExamples
72+ env = mkDatabaseContextEvalEnv tid graph
73+ eNewState = runDatabaseContextEvalMonad dateExamples env (optimizeAndEvalDatabaseContextExpr True setx)
6674 --plan = interpretRODatabaseContextOp context $ ":showplan " ++ tutd
6775 --displayOpResult plan
68− case interpreted of
69− Right context' -> TIO.putStrLn $ relationAsHTML (relationVariables context' M.! "x")
76+ case eNewState of
77+ Right newState -> do
78+ let ctx = dbc_context newState
79+ TIO.putStrLn $ relationAsHTML (relationVariables ctx M.! "x")
7080 Left err -> hPrint stderr err
7181
7282{-
src/lib/ProjectM36/Base.hs+33−27
@@ -1,4 +1,4 @@
1−{-# LANGUAGE ExistentialQuantification,DeriveGeneric,DeriveAnyClass,FlexibleInstances,OverloadedStrings, DeriveFoldable, DeriveFunctor #-}
1+{-# LANGUAGE ExistentialQuantification,DeriveGeneric,DeriveAnyClass,FlexibleInstances,OverloadedStrings, DeriveFoldable, DeriveFunctor, DeriveTraversable #-}
22{-# OPTIONS_GHC -fno-warn-orphans #-}
33
44module ProjectM36.Base where
@@ -13,6 +13,7 @@ import Data.UUID (UUID)
1313import Control.DeepSeq (NFData, rnf)
1414import Control.DeepSeq.Generics (genericRnf)
1515import GHC.Generics (Generic)
16+import GHC.Stack
1617import qualified Data.Vector as V
1718import qualified Data.List as L
1819import Data.Text (Text,unpack)
@@ -216,21 +217,19 @@ data RelationalExprBase a =
216217 --Summarize :: AtomExpr -> AttributeName -> RelationalExpr -> RelationalExpr -> RelationalExpr -- a special case of Extend
217218 --Evaluate relationalExpr with scoped views
218219 With [(WithNameExprBase a, RelationalExprBase a)] (RelationalExprBase a)
219− deriving (Show, Eq, Generic, NFData, Foldable, Functor)
220+ deriving (Show, Eq, Generic, NFData, Foldable, Functor, Traversable)
220221
221222instance Binary RelationalExpr
222223
223224data WithNameExprBase a = WithNameExpr RelVarName a
224− deriving (Show, Eq, Generic, NFData, Foldable, Functor)
225+ deriving (Show, Eq, Generic, NFData, Foldable, Functor, Traversable)
225226
226227type WithNameExpr = WithNameExprBase ()
227228
228229instance Binary WithNameExpr
229230
230−type GraphRefWithNameExpr = WithNameExprBase TransactionId
231+type GraphRefWithNameExpr = WithNameExprBase GraphRefTransactionMarker
231232
232−instance Binary GraphRefWithNameExpr
233−
234233type NotificationName = StringType
235234type Notifications = M.Map NotificationName Notification
236235
@@ -276,8 +275,12 @@ data DataConstructorDefArg = DataConstructorDefTypeConstructorArg TypeConstructo
276275type InclusionDependencies = M.Map IncDepName InclusionDependency
277276type RelationVariables = M.Map RelVarName GraphRefRelationalExpr
278277
278+data GraphRefTransactionMarker = TransactionMarker TransactionId |
279+ UncommittedContextMarker
280+ deriving (Eq, Show, Binary, Generic, NFData, Ord)
281+
279282-- a fundamental relational expr to which other relational expressions compile
280−type GraphRefRelationalExpr = RelationalExprBase TransactionId
283+type GraphRefRelationalExpr = RelationalExprBase GraphRefTransactionMarker
281284
282285type SchemaName = StringType
283286
@@ -322,7 +325,7 @@ type DatabaseContextExprName = StringType
322325
323326type DatabaseContextExpr = DatabaseContextExprBase ()
324327
325−type GraphRefDatabaseContextExpr = DatabaseContextExprBase TransactionId
328+type GraphRefDatabaseContextExpr = DatabaseContextExprBase GraphRefTransactionMarker
326329
327330instance Binary GraphRefDatabaseContextExpr
328331
@@ -369,13 +372,13 @@ data DatabaseContextIOExprBase a =
369372 CreateArbitraryRelation RelVarName [AttributeExprBase a] Range
370373 deriving (Show, Eq, Generic, Binary)
371374
372−type GraphRefDatabaseContextIOExpr = DatabaseContextIOExprBase TransactionId
375+type GraphRefDatabaseContextIOExpr = DatabaseContextIOExprBase GraphRefTransactionMarker
373376
374377type DatabaseContextIOExpr = DatabaseContextIOExprBase ()
375378
376379type RestrictionPredicateExpr = RestrictionPredicateExprBase ()
377380
378−type GraphRefRestrictionPredicateExpr = RestrictionPredicateExprBase TransactionId
381+type GraphRefRestrictionPredicateExpr = RestrictionPredicateExprBase GraphRefTransactionMarker
379382
380383-- | Restriction predicates are boolean algebra components which, when composed, indicate whether or not a tuple should be retained during a restriction (filtering) operation.
381384data RestrictionPredicateExprBase a =
@@ -386,7 +389,7 @@ data RestrictionPredicateExprBase a =
386389 RelationalExprPredicate (RelationalExprBase a) | --type must be same as true and false relations (no attributes)
387390 AtomExprPredicate (AtomExprBase a) | --atom must evaluate to boolean
388391 AttributeEqualityPredicate AttributeName (AtomExprBase a) -- relationalexpr must result in relation with single tuple
389− deriving (Show, Eq, Generic, NFData, Foldable, Functor)
392+ deriving (Show, Eq, Generic, NFData, Foldable, Functor, Traversable)
390393
391394instance Binary RestrictionPredicateExpr
392395
@@ -448,7 +451,7 @@ instance Ord Transaction where
448451
449452type AtomExpr = AtomExprBase ()
450453
451−type GraphRefAtomExpr = AtomExprBase TransactionId
454+type GraphRefAtomExpr = AtomExprBase GraphRefTransactionMarker
452455
453456-- | An atom expression represents an action to take when extending a relation or when statically defining a relation or a new tuple.
454457data AtomExprBase a = AttributeAtomExpr AttributeName |
@@ -456,16 +459,16 @@ data AtomExprBase a = AttributeAtomExpr AttributeName |
456459 FunctionAtomExpr AtomFunctionName [AtomExprBase a] a |
457460 RelationAtomExpr (RelationalExprBase a) |
458461 ConstructedAtomExpr DataConstructorName [AtomExprBase a] a
459− deriving (Eq,Show,Generic, NFData, Foldable, Functor)
462+ deriving (Eq,Show,Generic, NFData, Foldable, Functor, Traversable)
460463
461464instance Binary AtomExpr
462465
463466-- | Used in tuple creation when creating a relation.
464467data ExtendTupleExprBase a = AttributeExtendTupleExpr AttributeName (AtomExprBase a)
465− deriving (Show, Eq, Generic, NFData, Foldable, Functor)
468+ deriving (Show, Eq, Generic, NFData, Foldable, Functor, Traversable)
466469
467470type ExtendTupleExpr = ExtendTupleExprBase ()
468−type GraphRefExtendTupleExpr = ExtendTupleExprBase TransactionId
471+type GraphRefExtendTupleExpr = ExtendTupleExprBase GraphRefTransactionMarker
469472
470473instance Binary ExtendTupleExpr
471474
@@ -513,11 +516,11 @@ data AttributeNamesBase a = AttributeNames (S.Set AttributeName) |
513516 UnionAttributeNames (AttributeNamesBase a) (AttributeNamesBase a) |
514517 IntersectAttributeNames (AttributeNamesBase a) (AttributeNamesBase a) |
515518 RelationalExprAttributeNames (RelationalExprBase a) -- use attribute names from the relational expression's type
516− deriving (Eq, Show, Generic, NFData, Foldable, Functor)
519+ deriving (Eq, Show, Generic, NFData, Foldable, Functor, Traversable)
517520
518521type AttributeNames = AttributeNamesBase ()
519522
520−type GraphRefAttributeNames = AttributeNamesBase TransactionId
523+type GraphRefAttributeNames = AttributeNamesBase GraphRefTransactionMarker
521524
522525instance Binary AttributeNames
523526
@@ -528,22 +531,22 @@ data PersistenceStrategy = NoPersistence | -- ^ no filesystem persistence/memory
528531 deriving (Show, Read)
529532
530533type AttributeExpr = AttributeExprBase ()
531−type GraphRefAttributeExpr = AttributeExprBase TransactionId
534+type GraphRefAttributeExpr = AttributeExprBase GraphRefTransactionMarker
532535
533536-- | Create attributes dynamically.
534537data AttributeExprBase a = AttributeAndTypeNameExpr AttributeName TypeConstructor a |
535538 NakedAttributeExpr Attribute
536− deriving (Eq, Show, Generic, Binary, NFData, Foldable, Functor)
539+ deriving (Eq, Show, Generic, Binary, NFData, Foldable, Functor, Traversable)
537540
538541-- | Dynamically create a tuple from attribute names and 'AtomExpr's.
539542newtype TupleExprBase a = TupleExpr (M.Map AttributeName (AtomExprBase a))
540− deriving (Eq, Show, Generic, NFData, Foldable, Functor)
543+ deriving (Eq, Show, Generic, NFData, Foldable, Functor, Traversable)
541544
542545instance Binary TupleExpr
543546
544547type TupleExpr = TupleExprBase ()
545548
546−type GraphRefTupleExpr = TupleExprBase TransactionId
549+type GraphRefTupleExpr = TupleExprBase GraphRefTransactionMarker
547550
548551data MergeStrategy =
549552 -- | After a union merge, the merge transaction is a result of union'ing relvars of the same name, introducing all uniquely-named relvars, union of constraints, union of atom functions, notifications, and types (unless the names and definitions collide, e.g. two types of the same name with different definitions)
@@ -616,19 +619,22 @@ atomTypeVars (RelationAtomType attrs) = S.unions (map attrTypeVars (V.toList att
616619atomTypeVars (ConstructedAtomType _ tvMap) = M.keysSet tvMap
617620atomTypeVars (TypeVariableType nam) = S.singleton nam
618621
619−unimplemented :: a
622+unimplemented :: HasCallStack => a
620623unimplemented = undefined
621624
622625--for serializing GraphRefRelationalExpr as part of transaction serialization
623−instance Binary (TupleExprBase TransactionId)
626+instance Binary (TupleExprBase GraphRefTransactionMarker)
624627
625628instance Binary GraphRefRelationalExpr
626629
627−instance Binary (AtomExprBase TransactionId)
630+instance Binary (AtomExprBase GraphRefTransactionMarker)
628631
629−instance Binary (AttributeNamesBase TransactionId)
632+instance Binary (AttributeNamesBase GraphRefTransactionMarker)
630633
631−instance Binary (RestrictionPredicateExprBase TransactionId)
634+instance Binary (RestrictionPredicateExprBase GraphRefTransactionMarker)
632635
633−instance Binary (ExtendTupleExprBase TransactionId)
636+instance Binary (ExtendTupleExprBase GraphRefTransactionMarker)
637+
638+instance Binary GraphRefWithNameExpr
639+
634640
src/lib/ProjectM36/Client.hs+24−19
@@ -135,8 +135,10 @@ import Control.Exception.Base
135135import GHC.Conc.Sync
136136
137137import Network.Transport (Transport(closeTransport))
138−
139−#if MIN_VERSION_network_transport_tcp(0,6,0)
138+#if MIN_VERSION_network_transport_tcp(0,7,0)
139+import Network.Transport.TCP (createTransport, defaultTCPParameters, TCPAddr(..), TCPAddrInfo(..))
140+import Network.Transport.TCP.Internal (encodeEndPointAddress)
141+#elif MIN_VERSION_network_transport_tcp(0,6,0)
140142import Network.Transport.TCP (createTransport, defaultTCPParameters)
141143import Network.Transport.TCP.Internal (encodeEndPointAddress)
142144#else
@@ -271,8 +273,15 @@ remoteDBLookupName = (++) "db-"
271273
272274createLocalNode :: IO (LocalNode, Transport)
273275createLocalNode = do
274−#if MIN_VERSION_network_transport_tcp(0,6,0)
275− eLocalTransport <- createTransport "127.0.0.1" "0" (\sn -> ("127.0.0.1", sn)) defaultTCPParameters
276+#if MIN_VERSION_network_transport_tcp(0,7,0)
277+ let addrInfo = TCPAddrInfo {
278+ tcpBindHost = "127.0.0.1",
279+ tcpBindPort = "0",
280+ tcpExternalAddress = \sn -> ("127.0.0.1", sn)
281+ }
282+ eLocalTransport <- createTransport (Addressable addrInfo) defaultTCPParameters
283+#elif MIN_VERSION_network_transport_tcp(0,6,0)
284+ eLocalTransport <- createTransport "127.0.0.1" "0" ) defaultTCPParameters
276285#else
277286 eLocalTransport <- createTransport "127.0.0.1" "0" defaultTCPParameters
278287#endif
@@ -573,7 +582,7 @@ executeRelationalExpr sessionId (InProcessConnection conf) expr = excEither $ at
573582 Right expr'' -> do
574583 let graphTvar = ipTransactionGraph conf
575584 graph <- readTVar graphTvar
576− let reEnv = RE.mkRelationalExprEnv (Sess.concreteDatabaseContext session) (Sess.parentId session) graph
585+ let reEnv = RE.mkRelationalExprEnv (Sess.concreteDatabaseContext session) graph
577586 case optimizeAndEvalRelationalExpr reEnv expr'' of
578587 Right rel -> pure (force (Right rel)) -- this is necessary so that any undefined/error exceptions are spit out here
579588 Left err -> pure (Left err)
@@ -685,17 +694,16 @@ executeGraphExprSTM_ freshId sessionId session sessions graphExpr graph graphTVa
685694
686695-- process notifications for commits
687696executeCommitExprSTM_
688− :: TransactionId
689− -> TransactionGraph
697+ :: TransactionGraph
690698 -> DatabaseContext
691699 -> DatabaseContext
692700 -> ClientNodes
693701 -> STM (EvaluatedNotifications, ClientNodes)
694−executeCommitExprSTM_ transId graph oldContext newContext nodes = do
702+executeCommitExprSTM_ graph oldContext newContext nodes = do
695703 let nots = notifications oldContext
696− fireNots = notificationChanges nots transId graph oldContext newContext
704+ fireNots = notificationChanges nots graph oldContext newContext
697705 evaldNots = M.map mkEvaldNot fireNots
698− evalInContext expr ctx = optimizeAndEvalRelationalExpr (RE.mkRelationalExprEnv ctx transId graph) expr
706+ evalInContext expr ctx = optimizeAndEvalRelationalExpr (RE.mkRelationalExprEnv ctx graph) expr
699707
700708 mkEvaldNot notif = EvaluatedNotification { notification = notif,
701709 reportOldRelation = evalInContext (reportOldExpr notif) oldContext,
@@ -878,8 +886,7 @@ typeForRelationalExprSTM sessionId (InProcessConnection conf) relExpr = do
878886 Left err -> pure (Left err)
879887 Right relExpr' -> do
880888 graph <- readTVar (ipTransactionGraph conf)
881− let transId = Sess.parentId session
882− reEnv = RE.mkRelationalExprEnv (Sess.concreteDatabaseContext session) transId graph
889+ let reEnv = RE.mkRelationalExprEnv (Sess.concreteDatabaseContext session) graph
883890 pure $ RE.runRelationalExprM reEnv (RE.typeForRelationalExpr relExpr')
884891
885892typeForRelationalExprSTM _ _ _ = error "typeForRelationalExprSTM called on non-local connection"
@@ -923,9 +930,9 @@ planForDatabaseContextExpr sessionId (InProcessConnection conf) dbExpr = do
923930 Left err -> pure $ Left err
924931 Right (session, _) ->
925932 if schemaName session == defaultSchemaName then do
926− let transId = Sess.parentId session
927− gfExpr = runProcessExprM transId graph (processDatabaseContextExpr dbExpr)
928− pure $ runGraphRefStaticOptimizerMonad graph (optimizeGraphRefDatabaseContextExpr gfExpr)
933+ let ctx = Sess.concreteDatabaseContext session
934+ gfExpr = runProcessExprM UncommittedContextMarker (processDatabaseContextExpr dbExpr)
935+ pure $ runGraphRefStaticOptimizerMonad (Just ctx) graph (optimizeGraphRefDatabaseContextExpr gfExpr)
929936 else -- don't show any optimization because the current optimization infrastructure relies on access to the base context- this probably underscores the need for each schema to have its own DatabaseContext, even if it is generated on-the-fly-}
930937 pure (Left NonConcreteSchemaPlanError)
931938
@@ -960,11 +967,10 @@ relationVariablesAsRelation sessionId (InProcessConnection conf) = do
960967 Left err -> pure (Left err)
961968 Right (session, schema) -> do
962969 let context = Sess.concreteDatabaseContext session
963− transId = Sess.parentId session
964970 if Sess.schemaName session == defaultSchemaName then
965971 pure $ RE.relationVariablesAsRelation (relationVariables context) graph
966972 else
967− case Schema.relationVariablesInSchema schema context transId graph of
973+ case Schema.relationVariablesInSchema schema of
968974 Left err -> pure (Left err)
969975 Right relvars -> pure $ RE.relationVariablesAsRelation relvars graph
970976
@@ -1128,8 +1134,7 @@ commitLock_ sessionId conf stmBlock = do
11281134 Left err -> pure $ Left err
11291135 Right previousTrans ->
11301136 if not (Prelude.null transactionIdsToPersist) then do
1131− let transId = Sess.parentId newSession
1132− (evaldNots, nodes) <- executeCommitExprSTM_ transId graph' (Trans.concreteDatabaseContext previousTrans) (Sess.concreteDatabaseContext session) clientNodes
1137+ (evaldNots, nodes) <- executeCommitExprSTM_ graph' (Trans.concreteDatabaseContext previousTrans) (Sess.concreteDatabaseContext session) clientNodes
11331138 nodesToNotify <- stmSetToList nodes
11341139 pure $ Right (evaldNots, nodesToNotify, graph', transactionIdsToPersist)
11351140 else pure (Right (M.empty, [], graph', []))
src/lib/ProjectM36/DatabaseContext.hs+6−2
@@ -14,12 +14,16 @@ empty = DatabaseContext { inclusionDependencies = M.empty,
1414 atomFunctions = HS.empty,
1515 dbcFunctions = HS.empty,
1616 typeConstructorMapping = [] }
17+
18+-- | Remove TransactionId markers on GraphRefRelationalExpr
19+stripGraphRefRelationalExpr :: GraphRefRelationalExpr -> RelationalExpr
20+stripGraphRefRelationalExpr = fmap (const ())
1721
1822-- | convert an existing database context into its constituent expression.
1923databaseContextAsDatabaseContextExpr :: DatabaseContext -> DatabaseContextExpr
20−databaseContextAsDatabaseContextExpr _ = unimplemented {-MultipleExpr $ relVarsExprs ++ incDepsExprs ++ funcsExprs
24+databaseContextAsDatabaseContextExpr context = MultipleExpr $ relVarsExprs ++ incDepsExprs ++ funcsExprs
2125 where
22− relVarsExprs = map (\(name, rel) -> --Assign name (ExistingRelation rel)) (M.toList (relationVariables context))
26+ relVarsExprs = map (\(name, rel) -> Assign name (stripGraphRefRelationalExpr rel)) (M.toList (relationVariables context))
2327 incDepsExprs :: [DatabaseContextExpr]
2428 incDepsExprs = map (uncurry AddInclusionDependency) (M.toList (inclusionDependencies context))
2529 funcsExprs = [] -- map (\func -> ) (HS.toList funcs) -- there are no databaseExprs to add atom functions yet-}
src/lib/ProjectM36/DatabaseContextFunctionUtils.hs+3−3
@@ -14,9 +14,9 @@ executeDatabaseContextExpr expr transId graph context' =
1414 env = mkDatabaseContextEvalEnv transId graph
1515 run = runDatabaseContextEvalMonad context' env (optimizeAndEvalDatabaseContextExpr True expr)
1616
17−executeRelationalExpr :: RelationalExpr -> DatabaseContext -> TransactionId -> TransactionGraph -> Either RelationalError Relation
18−executeRelationalExpr expr context transId graph =
17+executeRelationalExpr :: RelationalExpr -> DatabaseContext -> TransactionGraph -> Either RelationalError Relation
18+executeRelationalExpr expr context graph =
1919 run
2020 where
21− env = mkRelationalExprEnv context transId graph
21+ env = mkRelationalExprEnv context graph
2222 run = optimizeAndEvalRelationalExpr env expr
src/lib/ProjectM36/Error.hs+2
@@ -98,6 +98,8 @@ data RelationalError = NoSuchAttributeNamesError (S.Set AttributeName)
9898 | ImproperDatabaseStateError
9999
100100 | NonConcreteSchemaPlanError
101+
102+ | NoUncommittedContextInEvalError
101103
102104 | MultipleErrors [RelationalError]
103105 deriving (Show,Eq,Generic,Binary,Typeable, NFData)
src/lib/ProjectM36/GraphRefRelationalExpr.hs+2−2
@@ -20,7 +20,7 @@ eval = undefined
2020
2121-}
2222
23−data SingularTransactionRef = SingularTransactionRef TransactionId |
23+data SingularTransactionRef = SingularTransactionRef GraphRefTransactionMarker |
2424 MultipleTransactionsRef |
2525 NoTransactionsRef
2626 deriving (Eq, Show)
@@ -38,7 +38,7 @@ singularTransaction expr =
3838 transSet = foldr (\transId acc -> S.insert transId acc) S.empty expr
3939
4040-- | Return True if two 'GraphRefRelationalExpr's both refer exclusively to the same transaction (or none at all).
41−inSameTransaction :: GraphRefRelationalExpr -> GraphRefRelationalExpr -> Maybe TransactionId
41+inSameTransaction :: GraphRefRelationalExpr -> GraphRefRelationalExpr -> Maybe GraphRefTransactionMarker
4242inSameTransaction exprA exprB = case (stA, stB) of
4343 (SingularTransactionRef tA, SingularTransactionRef tB) | tA == tB -> Just tA
4444 _ -> Nothing
src/lib/ProjectM36/IsomorphicSchema.hs+3−3
@@ -256,14 +256,14 @@ inclusionDependencyInSchema schema (InclusionDependency rexprA rexprB) = do
256256inclusionDependenciesInSchema :: Schema -> InclusionDependencies -> Either RelationalError InclusionDependencies
257257inclusionDependenciesInSchema schema incDeps = M.fromList <$> mapM (\(depName, dep) -> inclusionDependencyInSchema schema dep >>= \newDep -> pure (depName, newDep)) (M.toList incDeps)
258258
259−relationVariablesInSchema :: Schema -> DatabaseContext -> TransactionId -> TransactionGraph -> Either RelationalError RelationVariables
260−relationVariablesInSchema schema@(Schema morphs) context transId graph = foldM transform M.empty morphs
259+relationVariablesInSchema :: Schema -> Either RelationalError RelationVariables
260+relationVariablesInSchema schema@(Schema morphs) = foldM transform M.empty morphs
261261 where
262262 transform newRvMap morph = do
263263 let rvNames = isomorphInRelVarNames morph
264264 rvAssocs <- mapM (\rv -> do
265265 expr' <- processRelationalExprInSchema schema (RelationVariable rv ())
266− let gfExpr = runProcessExprM transId graph (processRelationalExpr expr')
266+ let gfExpr = runProcessExprM UncommittedContextMarker (processRelationalExpr expr')
267267 pure (rv, gfExpr)) rvNames
268268 pure (M.union newRvMap (M.fromList rvAssocs))
269269
src/lib/ProjectM36/NormalizeExpr.hs+10−13
@@ -5,18 +5,15 @@ import Control.Monad.Trans.Reader as R
55import qualified Data.Map as M
66
77--used to process/normalize exprs to their respective graph ref forms
8−type ProcessExprM a = Reader (TransactionGraph, TransactionId) a
8+type ProcessExprM a = Reader GraphRefTransactionMarker a
99
1010type CurrentTransactionId = TransactionId
1111
12−runProcessExprM :: CurrentTransactionId -> TransactionGraph -> ProcessExprM a -> a
13−runProcessExprM tid graph m = runReader m (graph, tid)
12+runProcessExprM :: GraphRefTransactionMarker -> ProcessExprM a -> a
13+runProcessExprM mtid m = runReader m mtid
1414
15−askGraph :: ProcessExprM TransactionGraph
16−askGraph = fst <$> R.ask
17−
18−askTid :: ProcessExprM CurrentTransactionId
19−askTid = snd <$> R.ask
15+askMarker :: ProcessExprM GraphRefTransactionMarker
16+askMarker = R.ask
2017
2118-- convert a RelationalExpr into a GraphRefRelationalExpr using the current trans Id
2219processRelationalExpr :: RelationalExpr -> ProcessExprM GraphRefRelationalExpr
@@ -28,7 +25,7 @@ processRelationalExpr (MakeRelationFromExprs mAttrs tupleExprs) = do
2825processRelationalExpr (MakeStaticRelation attrs tupSet) = pure (MakeStaticRelation attrs tupSet)
2926processRelationalExpr (ExistingRelation rel) = pure (ExistingRelation rel)
3027--requires current trans id and graph
31−processRelationalExpr (RelationVariable rv ()) = RelationVariable rv <$> askTid
28+processRelationalExpr (RelationVariable rv ()) = RelationVariable rv <$> askMarker
3229processRelationalExpr (Project attrNames expr) = Project <$> processAttributeNames attrNames <*> processRelationalExpr expr
3330processRelationalExpr (Union exprA exprB) = Union <$> processRelationalExpr exprA <*> processRelationalExpr exprB
3431processRelationalExpr (Join exprA exprB) = Join <$> processRelationalExpr exprA <*> processRelationalExpr exprB
@@ -49,7 +46,7 @@ processRelationalExpr (With macros expr) =
4946
5047processWithNameExpr :: WithNameExpr -> ProcessExprM GraphRefWithNameExpr
5148processWithNameExpr (WithNameExpr rvname ()) =
52− WithNameExpr rvname <$> askTid
49+ WithNameExpr rvname <$> askMarker
5350
5451processAttributeNames :: AttributeNames -> ProcessExprM GraphRefAttributeNames
5552processAttributeNames (AttributeNames nameSet) = pure $ AttributeNames nameSet
@@ -114,9 +111,9 @@ processAtomExpr :: AtomExpr -> ProcessExprM GraphRefAtomExpr
114111processAtomExpr (AttributeAtomExpr nam) = pure $ AttributeAtomExpr nam
115112processAtomExpr (NakedAtomExpr atom) = pure $ NakedAtomExpr atom
116113processAtomExpr (FunctionAtomExpr fName atomExprs ()) =
117− FunctionAtomExpr fName <$> mapM processAtomExpr atomExprs <*> askTid
114+ FunctionAtomExpr fName <$> mapM processAtomExpr atomExprs <*> askMarker
118115processAtomExpr (RelationAtomExpr expr) = RelationAtomExpr <$> processRelationalExpr expr
119−processAtomExpr (ConstructedAtomExpr dConsName atomExprs ()) = ConstructedAtomExpr dConsName <$> mapM processAtomExpr atomExprs <*> askTid
116+processAtomExpr (ConstructedAtomExpr dConsName atomExprs ()) = ConstructedAtomExpr dConsName <$> mapM processAtomExpr atomExprs <*> askMarker
120117
121118processTupleExpr :: TupleExpr -> ProcessExprM GraphRefTupleExpr
122119processTupleExpr (TupleExpr tMap) =
@@ -125,6 +122,6 @@ processTupleExpr (TupleExpr tMap) =
125122--convert AttributeExpr to GraphRefAttributeExpr
126123processAttributeExpr :: AttributeExpr -> ProcessExprM GraphRefAttributeExpr
127124processAttributeExpr (AttributeAndTypeNameExpr nam tCons ()) =
128− AttributeAndTypeNameExpr nam tCons <$> askTid
125+ AttributeAndTypeNameExpr nam tCons <$> askMarker
129126processAttributeExpr (NakedAttributeExpr attr) = pure $ NakedAttributeExpr attr
130127
src/lib/ProjectM36/Notifications.hs+4−4
@@ -7,13 +7,13 @@ import qualified Data.Map as M
77import Data.Either (isRight)
88
99-- | Returns the notifications which should be triggered based on the transition from the first 'DatabaseContext' to the second 'DatabaseContext'.
10−notificationChanges :: Notifications -> TransactionId -> TransactionGraph -> DatabaseContext -> DatabaseContext -> Notifications
11−notificationChanges nots tid graph context1 context2 = M.filter notificationFilter nots
10+notificationChanges :: Notifications -> TransactionGraph -> DatabaseContext -> DatabaseContext -> Notifications
11+notificationChanges nots graph context1 context2 = M.filter notificationFilter nots
1212 where
1313 notificationFilter (Notification chExpr _ _) = oldChangeEval /= newChangeEval && isRight oldChangeEval
1414 where
15− oldChangeEval = evalChangeExpr chExpr (mkRelationalExprEnv context1 tid graph)
16− newChangeEval = evalChangeExpr chExpr (mkRelationalExprEnv context2 tid graph)
15+ oldChangeEval = evalChangeExpr chExpr (mkRelationalExprEnv context1 graph)
16+ newChangeEval = evalChangeExpr chExpr (mkRelationalExprEnv context2 graph)
1717
1818 evalChangeExpr :: RelationalExpr -> RelationalExprEnv -> Either RelationalError Relation
1919 evalChangeExpr chExpr env =
src/lib/ProjectM36/RelationalExpression.hs+102−59
@@ -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+
src/lib/ProjectM36/Server.hs+13−2
@@ -8,7 +8,11 @@ import ProjectM36.Server.Config (ServerConfig(..))
88import ProjectM36.FSType
99
1010import Control.Monad.IO.Class (liftIO)
11−import Network.Transport.TCP (createTransport, defaultTCPParameters)
11+#if MIN_VERSION_network_transport_tcp(0,7,0)
12+import Network.Transport.TCP (createTransport, defaultTCPParameters, TCPAddr(..), TCPAddrInfo(..))
13+#else
14+import Network.Transport.TCP (createTransport, defaultTCPParameters)
15+#endif
1216import Network.Transport (EndPointAddress(..), newEndPoint, address)
1317import Control.Distributed.Process.Node (initRemoteTable, runProcess, newLocalNode, initRemoteTable)
1418import Control.Distributed.Process.Extras.Time (Delay(..))
@@ -117,7 +121,14 @@ launchServer daemonConfig mAddressMVar = do
117121 Right conn -> do
118122 let hostname = bindHost daemonConfig
119123 port = bindPort daemonConfig
120−#if MIN_VERSION_network_transport_tcp(0,6,0)
124+#if MIN_VERSION_network_transport_tcp(0,7,0)
125+ addrInfo = TCPAddrInfo {
126+ tcpBindHost = hostname,
127+ tcpBindPort = show port,
128+ tcpExternalAddress = \sn -> (hostname, sn)
129+ }
130+ etransport <- createTransport (Addressable addrInfo) defaultTCPParameters
131+#elif MIN_VERSION_network_transport_tcp(0,6,0)
121132 etransport <- createTransport hostname (show port) (\nam -> (hostname, nam)) defaultTCPParameters
122133#else
123134 etransport <- createTransport hostname (show port) defaultTCPParameters
src/lib/ProjectM36/StaticOptimizer.hs+80−68
@@ -3,7 +3,7 @@ import ProjectM36.Base
33import ProjectM36.GraphRefRelationalExpr
44import ProjectM36.Relation
55import ProjectM36.RelationalExpression
6−import ProjectM36.TransGraphRelationalExpression as TGRE
6+import ProjectM36.TransGraphRelationalExpression as TGRE hiding (askGraph)
77import ProjectM36.Error
88import ProjectM36.Transaction
99import ProjectM36.NormalizeExpr
@@ -23,45 +23,56 @@ type StaticOptimizerEnv = RelationalExprEnv
2323type StaticOptimizerMonad a = ReaderT StaticOptimizerEnv (ExceptT RelationalError Identity) a
2424-- the static optimizer performs optimizations which need not take any specific-relation statistics into account
2525
26−type GraphRefStaticOptimizerMonad a = ReaderT TransactionGraph (ExceptT RelationalError Identity) a
26+type GraphRefStaticOptimizerMonad a = ReaderT (Maybe DatabaseContext, TransactionGraph) (ExceptT RelationalError Identity) a
2727
2828-- | A temporary function to be replaced by IO-based implementation.
2929optimizeAndEvalRelationalExpr :: RelationalExprEnv -> RelationalExpr -> Either RelationalError Relation
3030optimizeAndEvalRelationalExpr env expr = do
31− let gfExpr = runProcessExprM tid graph (processRelationalExpr expr)
32− tid = re_currentTransId env
31+ let gfExpr = runProcessExprM UncommittedContextMarker (processRelationalExpr expr) -- references parent tid instead of context! options- I could add the context to the graph with a new transid or implement an evalRelationalExpr in RE.hs to use the context (which is what I had previously)
3332 graph = re_graph env
34− gfEnv = freshGraphRefRelationalExprEnv graph
35− optExpr <- runGraphRefStaticOptimizerMonad (re_graph env) (fullOptimizeGraphRefRelationalExpr gfExpr)
33+ ctx = re_context env
34+ gfEnv = freshGraphRefRelationalExprEnv (Just ctx) graph
35+ optExpr <- runGraphRefStaticOptimizerMonad (Just ctx) (re_graph env) (fullOptimizeGraphRefRelationalExpr gfExpr)
3636 runGraphRefRelationalExprM gfEnv (evalGraphRefRelationalExpr optExpr)
3737
38+askGraph :: GraphRefStaticOptimizerMonad TransactionGraph
39+askGraph = snd <$> ask
40+
41+askContext :: GraphRefStaticOptimizerMonad DatabaseContext
42+askContext = do
43+ mctx <- fst <$> ask
44+ case mctx of
45+ Nothing -> throwError NoUncommittedContextInEvalError
46+ Just ctx -> pure ctx
47+
48+askMaybeContext :: GraphRefStaticOptimizerMonad (Maybe DatabaseContext)
49+askMaybeContext = fst <$> ask
50+
3851optimizeAndEvalDatabaseContextExpr :: Bool -> DatabaseContextExpr -> DatabaseContextEvalMonad ()
3952optimizeAndEvalDatabaseContextExpr optimize expr = do
40− tid <- dce_transId <$> ask
4153 graph <- dce_graph <$> ask
42− let gfExpr = runProcessExprM tid graph (processDatabaseContextExpr expr)
54+ let gfExpr = runProcessExprM UncommittedContextMarker (processDatabaseContextExpr expr)
4355 eOptExpr = if optimize then
44− runGraphRefStaticOptimizerMonad graph (optimizeGraphRefDatabaseContextExpr gfExpr)
56+ runGraphRefStaticOptimizerMonad Nothing graph (optimizeGraphRefDatabaseContextExpr gfExpr)
4557 else
4658 pure gfExpr
4759 case eOptExpr of
4860 Left err -> throwError err
4961 Right optExpr -> evalGraphRefDatabaseContextExpr optExpr
5062
63+
5164optimizeAndEvalTransGraphRelationalExpr :: TransactionGraph -> TransGraphRelationalExpr -> Either RelationalError Relation
5265optimizeAndEvalTransGraphRelationalExpr graph tgExpr = do
5366 gfExpr <- TGRE.process (TransGraphEvalEnv graph) tgExpr
54− optExpr <- runGraphRefStaticOptimizerMonad graph (fullOptimizeGraphRefRelationalExpr gfExpr)
55− let gfEnv = freshGraphRefRelationalExprEnv graph
67+ optExpr <- runGraphRefStaticOptimizerMonad Nothing graph (fullOptimizeGraphRefRelationalExpr gfExpr)
68+ let gfEnv = freshGraphRefRelationalExprEnv Nothing graph
5669 runGraphRefRelationalExprM gfEnv (evalGraphRefRelationalExpr optExpr)
5770
5871optimizeAndEvalDatabaseContextIOExpr :: DatabaseContextIOExpr -> DatabaseContextIOEvalMonad (Either RelationalError ())
5972optimizeAndEvalDatabaseContextIOExpr expr = do
6073 env <- getDBCIORelationalExprEnv
61− let gfExpr = runProcessExprM tid graph (processDatabaseContextIOExpr expr)
74+ let gfExpr = runProcessExprM UncommittedContextMarker (processDatabaseContextIOExpr expr)
6275 eOptExpr = runStaticOptimizerMonad env (optimizeDatabaseContextIOExpr gfExpr)
63− tid = re_currentTransId env
64− graph = re_graph env
6576 case eOptExpr of
6677 Left err -> pure (Left err)
6778 Right optExpr ->
@@ -71,12 +82,11 @@ optimizeAndEvalDatabaseContextIOExpr expr = do
7182runStaticOptimizerMonad :: RelationalExprEnv -> StaticOptimizerMonad a -> Either RelationalError a
7283runStaticOptimizerMonad env m = runIdentity (runExceptT (runReaderT m env))
7384
74−runGraphRefStaticOptimizerMonad :: TransactionGraph -> GraphRefStaticOptimizerMonad a -> Either RelationalError a
75−runGraphRefStaticOptimizerMonad graph m = runIdentity (runExceptT (runReaderT m graph))
85+runGraphRefStaticOptimizerMonad :: Maybe DatabaseContext -> TransactionGraph -> GraphRefStaticOptimizerMonad a -> Either RelationalError a
86+runGraphRefStaticOptimizerMonad ctx graph m = runIdentity (runExceptT (runReaderT m (ctx, graph)))
7687
77−--RelationalExprEnv should not be necessary for graph ref re optimization!
78−optimizeGraphRefRelationalExpr' :: TransactionGraph -> GraphRefRelationalExpr -> Either RelationalError GraphRefRelationalExpr
79−optimizeGraphRefRelationalExpr' graph expr = runIdentity (runExceptT (runReaderT (optimizeGraphRefRelationalExpr expr) graph))
88+optimizeGraphRefRelationalExpr' :: Maybe DatabaseContext -> TransactionGraph -> GraphRefRelationalExpr -> Either RelationalError GraphRefRelationalExpr
89+optimizeGraphRefRelationalExpr' mctx graph expr = runIdentity (runExceptT (runReaderT (optimizeGraphRefRelationalExpr expr) (mctx,graph)))
8090
8191fullOptimizeGraphRefRelationalExpr :: GraphRefRelationalExpr -> GraphRefStaticOptimizerMonad GraphRefRelationalExpr
8292fullOptimizeGraphRefRelationalExpr expr = do
@@ -98,9 +108,9 @@ optimizeGraphRefRelationalExpr e@(RelationVariable _ _) = pure e
98108
99109--remove project of attributes which removes no attributes
100110optimizeGraphRefRelationalExpr (Project attrNameSet expr) = do
101− graph <- ask
111+ graph <- askGraph
102112 let relType = runGraphRefRelationalExprM gfEnv (typeForGraphRefRelationalExpr expr)
103− gfEnv = freshGraphRefRelationalExprEnv graph
113+ gfEnv = freshGraphRefRelationalExprEnv Nothing graph
104114 case relType of
105115 Left err -> throwError err
106116 Right relType2
@@ -137,12 +147,13 @@ optimizeGraphRefRelationalExpr (Join exprA exprB) = do
137147 pure (Join optExprA optExprB)
138148
139149optimizeGraphRefRelationalExpr (Difference exprA exprB) = do
140− graph <- ask
150+ graph <- askGraph
151+ context <- askMaybeContext
141152 optExprA <- optimizeGraphRefRelationalExpr exprA
142153 optExprB <- optimizeGraphRefRelationalExpr exprB
143154 if optExprA == optExprB then do --A difference A == A where false
144155 let eEmptyRel = runGraphRefRelationalExprM gfEnv (typeForGraphRefRelationalExpr optExprA)
145− gfEnv = freshGraphRefRelationalExprEnv graph
156+ gfEnv = freshGraphRefRelationalExprEnv context graph
146157 case eEmptyRel of
147158 Left err -> throwError err
148159 Right emptyRel -> pure (ExistingRelation emptyRel)
@@ -159,13 +170,13 @@ optimizeGraphRefRelationalExpr (Ungroup attrName expr) =
159170
160171--remove restriction of nothing
161172optimizeGraphRefRelationalExpr (Restrict predicate expr) = do
162− graph <- ask
173+ graph <- askGraph
163174 optimizedPredicate <- applyStaticPredicateOptimization predicate
164175 case optimizedPredicate of
165176 optimizedPredicate' | isTrueExpr optimizedPredicate' -> optimizeGraphRefRelationalExpr expr -- remove predicate entirely
166177 optimizedPredicate' | isFalseExpr optimizedPredicate' -> do -- replace where false predicate with empty relation with attributes from relexpr
167178 let attributesRel = runGraphRefRelationalExprM gfEnv (typeForGraphRefRelationalExpr expr)
168− gfEnv = freshGraphRefRelationalExprEnv graph
179+ gfEnv = freshGraphRefRelationalExprEnv Nothing graph
169180 case attributesRel of
170181 Left err -> throwError err
171182 Right attributesRelA -> pure $ MakeStaticRelation (attributes attributesRelA) emptyTupleSet
@@ -229,9 +240,9 @@ optimizeGraphRefDatabaseContextExpr c@(ExecuteDatabaseContextFunction _ _) = pur
229240
230241--applyStaticDatabaseOptimization (MultipleExpr exprs) = pure $ Right $ MultipleExpr exprs
231242--for multiple expressions, we must evaluate
232−optimizeGraphRefDatabaseContextExpr (MultipleExpr _) = do
243+optimizeGraphRefDatabaseContextExpr x@(MultipleExpr _) = pure x
233244 --a previous expression in the exprs list could create a relvar; we don't want to miss it, so we clear the tuples and execute the expression to get an empty relation in the relvar
234− unimplemented
245+-- unimplemented
235246{- let processEmptyRelVars env = env { relationVariables = mkEmptyRelVars (relationVariables env) }
236247 MultipleExpr <$> local processEmptyRelVars (mapM applyStaticDatabaseOptimization exprs)-}
237248
@@ -331,56 +342,57 @@ isStaticAtomExpr RelationAtomExpr{} = False
331342--if the projection of a join only uses the attributes from one of the expressions and there is a foreign key relationship between the expressions, we know that the join is inconsequential and can be removed
332343applyStaticJoinElimination :: GraphRefRelationalExpr -> GraphRefStaticOptimizerMonad GraphRefRelationalExpr
333344applyStaticJoinElimination expr@(Project attrNameSet (Join exprA exprB)) = do
334− graph <- ask
345+ graph <- askGraph
335346 case inSameTransaction exprA exprB of
336347 -- the sub exprs are in different transactions or none at all, so we cannot extract inclusion dependencies across transaction boundaries
337− Nothing -> pure expr
338− Just commonTransId -> do
339− let typeForExpr e = lift $ except $ runGraphRefRelationalExprM gfEnv (typeForGraphRefRelationalExpr e)
340− gfEnv = freshGraphRefRelationalExprEnv graph
341− projType <- typeForExpr expr
342− typeA <- typeForExpr exprA
343− typeB <- typeForExpr exprB
344− let matchesProjectionAttributes
345− | attrNames projType `S.isSubsetOf` attrNames typeA =
346− Just ((exprA, typeA), (exprB, typeB))
347− | attrNames projType `S.isSubsetOf` attrNames typeB =
348− Just ((exprB, typeB), (exprA, typeA))
349− | otherwise =
350− Nothing
351− attrNames = A.attributeNameSet . attributes
352− case matchesProjectionAttributes of
353− Nothing -> -- this optimization does not apply
354− pure expr
355− Just ((joinedExpr, joinedType), (unjoinedExpr, _)) -> do
348+ Nothing -> pure expr
349+ Just marker -> do
350+ commonContext <- case marker of
351+ UncommittedContextMarker -> askContext
352+ TransactionMarker tid -> concreteDatabaseContext <$> lift (except (transactionForId tid graph))
353+ let typeForExpr e = lift $ except $ runGraphRefRelationalExprM gfEnv (typeForGraphRefRelationalExpr e)
354+ gfEnv = freshGraphRefRelationalExprEnv (Just commonContext) graph
355+
356+ projType <- typeForExpr expr
357+ typeA <- typeForExpr exprA
358+ typeB <- typeForExpr exprB
359+ let matchesProjectionAttributes
360+ | attrNames projType `S.isSubsetOf` attrNames typeA =
361+ Just ((exprA, typeA), (exprB, typeB))
362+ | attrNames projType `S.isSubsetOf` attrNames typeB =
363+ Just ((exprB, typeB), (exprA, typeA))
364+ | otherwise =
365+ Nothing
366+ attrNames = A.attributeNameSet . attributes
367+ case matchesProjectionAttributes of
368+ Nothing -> -- this optimization does not apply
369+ pure expr
370+ Just ((joinedExpr, joinedType), (unjoinedExpr, _)) -> do
356371 --lookup transaction
357− trans <- lift $ except (transactionForId commonTransId graph)
358372 --scan inclusion dependencies for a foreign key relationship
359− let incDeps = inclusionDependencies commonContext
360− commonContext = concreteDatabaseContext trans
361− reEnv = mkRelationalExprEnv commonContext commonTransId graph
362− fkConstraint = foldM isFkConstraint False incDeps
373+ let incDeps = inclusionDependencies commonContext
374+ fkConstraint = foldM isFkConstraint False incDeps
363375 --search for matching fk constraint
364− isFkConstraint acc (InclusionDependency (Project subAttrNames subrv) (Project _ superrv)) = do
365− let gfSubAttrNames = processM (processAttributeNames subAttrNames)
366− gfSubRv = processM (processRelationalExpr subrv)
367− gfSuperRv = processM (processRelationalExpr superrv)
368− processM = runProcessExprM commonTransId graph
369− case runGraphRefRelationalExprM gfEnv (evalGraphRefAttributeNames gfSubAttrNames expr) of
370− Left _ -> pure acc
371− Right subAttrNameSet ->
372− pure (acc || (joinedExpr == gfSubRv &&
376+ isFkConstraint acc (InclusionDependency (Project subAttrNames subrv) (Project _ superrv)) = do
377+ let gfSubAttrNames = processM (processAttributeNames subAttrNames)
378+ gfSubRv = processM (processRelationalExpr subrv)
379+ gfSuperRv = processM (processRelationalExpr superrv)
380+ processM = runProcessExprM marker
381+ case runGraphRefRelationalExprM gfEnv (evalGraphRefAttributeNames gfSubAttrNames expr) of
382+ Left _ -> pure acc
383+ Right subAttrNameSet ->
384+ pure (acc || (joinedExpr == gfSubRv &&
373385 unjoinedExpr == gfSuperRv &&
374386 -- the fk attribute is one of the projection attributes
375387 A.attributeNamesContained subAttrNameSet (A.attributeNameSet (attributes joinedType))
376388 ))
377− isFkConstraint acc _ = pure acc
378− case fkConstraint of
379− Right True -> --join elimination optimization applies
380− optimizeGraphRefRelationalExpr (Project attrNameSet joinedExpr)
381− Right False -> --join elimination optimization does not apply
382− pure expr
383− Left err -> throwError err
389+ isFkConstraint acc _ = pure acc
390+ case fkConstraint of
391+ Right True -> --join elimination optimization applies
392+ optimizeGraphRefRelationalExpr (Project attrNameSet joinedExpr)
393+ Right False -> --join elimination optimization does not apply
394+ pure expr
395+ Left err -> throwError err
384396
385397applyStaticJoinElimination expr = pure expr
386398
src/lib/ProjectM36/TransGraphRelationalExpression.hs+2−2
@@ -58,8 +58,8 @@ liftE = lift . except
5858askGraph :: TransGraphEvalMonad TransactionGraph
5959askGraph = tge_graph <$> ask
6060
61−findTransId :: TransactionIdLookup -> TransGraphEvalMonad TransactionId
62−findTransId tlook = transactionId <$> findTrans tlook
61+findTransId :: TransactionIdLookup -> TransGraphEvalMonad GraphRefTransactionMarker
62+findTransId tlook = TransactionMarker . transactionId <$> findTrans tlook
6363
6464findTrans :: TransactionIdLookup -> TransGraphEvalMonad Transaction
6565findTrans tlook = do
test/TutorialD/Interpreter/TestBase.hs+1−2
@@ -19,8 +19,7 @@ dateExamplesConnection callback = do
1919 case eSessionId of
2020 Left err -> error (show err)
2121 Right sessionId -> do
22− mapM_ (\(rvName,rvRel) -> executeDatabaseContextExpr sessionId conn (Assign rvName (Base.ExistingRelation rvRel))) (M.toList (Base.relationVariables dateExamples))
23− mapM_ (\(idName,incDep) -> executeDatabaseContextExpr sessionId conn (AddInclusionDependency idName incDep)) (M.toList incDeps)
22+ executeDatabaseContextExpr sessionId conn (databaseContextAsDatabaseContextExpr dateExamples
2423 --skipping atom functions for now- there are no atom function manipulation operators yet
2524 commit sessionId conn >>= eitherFail
2625 pure (sessionId, conn)