{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE FlexibleContexts #-}
module ProjectM36.StaticOptimizer where
import ProjectM36.Base
import ProjectM36.GraphRefRelationalExpr
import ProjectM36.Relation
import ProjectM36.RelationalExpression
import ProjectM36.TransGraphRelationalExpression as TGRE hiding (askGraph)
import ProjectM36.Error
import ProjectM36.Transaction
import ProjectM36.NormalizeExpr
import qualified ProjectM36.Attribute as A
import qualified ProjectM36.AttributeNames as AS
import ProjectM36.TupleSet
import Control.Monad.State
import Control.Monad.Reader
import Control.Monad.Except
import Control.Monad.Trans.Except
import Data.Functor.Identity
import qualified Data.Map as M
import qualified Data.Set as S

-- the static optimizer performs optimizations which need not take any specific-relation statistics into account

data GraphRefSOptRelationalExprEnv =
  GraphRefSOptRelationalExprEnv
  {
    GraphRefSOptRelationalExprEnv -> TransactionGraph
ore_graph :: TransactionGraph,
    GraphRefSOptRelationalExprEnv -> Maybe DatabaseContext
ore_mcontext :: Maybe DatabaseContext
  }
  
type GraphRefSOptRelationalExprM a = ReaderT GraphRefSOptRelationalExprEnv (ExceptT RelationalError Identity) a

data GraphRefSOptDatabaseContextExprEnv =
  GraphRefSOptDatabaseContextExprEnv
  {
    GraphRefSOptDatabaseContextExprEnv -> TransactionGraph
odce_graph :: TransactionGraph,
    GraphRefSOptDatabaseContextExprEnv -> DatabaseContext
odce_context :: DatabaseContext, --not optional for DatabaseContextExpr evaluation
    GraphRefSOptDatabaseContextExprEnv -> TransactionId
odce_transId :: TransactionId -- parent if context is committed- needed because MultipleExpr optimization requires running the DatabaseContextExprs (with empty relvars)
    }

type GraphRefSOptDatabaseContextExprM a = ReaderT GraphRefSOptDatabaseContextExprEnv (ExceptT RelationalError Identity) a

-- | A temporary function to be replaced by IO-based implementation.
optimizeAndEvalRelationalExpr :: RelationalExprEnv -> RelationalExpr -> Either RelationalError Relation
optimizeAndEvalRelationalExpr :: RelationalExprEnv
-> RelationalExpr -> Either RelationalError Relation
optimizeAndEvalRelationalExpr RelationalExprEnv
env RelationalExpr
expr = do
  let gfExpr :: GraphRefRelationalExpr
gfExpr = GraphRefTransactionMarker
-> ProcessExprM GraphRefRelationalExpr -> GraphRefRelationalExpr
forall a. GraphRefTransactionMarker -> ProcessExprM a -> a
runProcessExprM GraphRefTransactionMarker
UncommittedContextMarker (RelationalExpr -> ProcessExprM GraphRefRelationalExpr
processRelationalExpr RelationalExpr
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)
      graph :: TransactionGraph
graph = RelationalExprEnv -> TransactionGraph
re_graph RelationalExprEnv
env
      ctx :: DatabaseContext
ctx = RelationalExprEnv -> DatabaseContext
re_context RelationalExprEnv
env
      gfEnv :: GraphRefRelationalExprEnv
gfEnv = Maybe DatabaseContext
-> TransactionGraph -> GraphRefRelationalExprEnv
freshGraphRefRelationalExprEnv (DatabaseContext -> Maybe DatabaseContext
forall a. a -> Maybe a
Just DatabaseContext
ctx) TransactionGraph
graph
  GraphRefRelationalExpr
optExpr <- Maybe DatabaseContext
-> TransactionGraph
-> GraphRefSOptRelationalExprM GraphRefRelationalExpr
-> Either RelationalError GraphRefRelationalExpr
forall a.
Maybe DatabaseContext
-> TransactionGraph
-> GraphRefSOptRelationalExprM a
-> Either RelationalError a
runGraphRefSOptRelationalExprM (DatabaseContext -> Maybe DatabaseContext
forall a. a -> Maybe a
Just DatabaseContext
ctx) (RelationalExprEnv -> TransactionGraph
re_graph RelationalExprEnv
env) (GraphRefRelationalExpr
-> GraphRefSOptRelationalExprM GraphRefRelationalExpr
fullOptimizeGraphRefRelationalExpr GraphRefRelationalExpr
gfExpr)
  GraphRefRelationalExprEnv
-> GraphRefRelationalExprM Relation
-> Either RelationalError Relation
forall a.
GraphRefRelationalExprEnv
-> GraphRefRelationalExprM a -> Either RelationalError a
runGraphRefRelationalExprM GraphRefRelationalExprEnv
gfEnv (GraphRefRelationalExpr -> GraphRefRelationalExprM Relation
evalGraphRefRelationalExpr GraphRefRelationalExpr
optExpr)

class Monad m => AskGraphContext m where
  askGraph :: m TransactionGraph
  askContext :: m DatabaseContext

instance AskGraphContext (ReaderT GraphRefSOptDatabaseContextExprEnv (ExceptT RelationalError Identity)) where
  askGraph :: ReaderT
  GraphRefSOptDatabaseContextExprEnv
  (ExceptT RelationalError Identity)
  TransactionGraph
askGraph = (GraphRefSOptDatabaseContextExprEnv -> TransactionGraph)
-> ReaderT
     GraphRefSOptDatabaseContextExprEnv
     (ExceptT RelationalError Identity)
     TransactionGraph
forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
asks GraphRefSOptDatabaseContextExprEnv -> TransactionGraph
odce_graph
  askContext :: ReaderT
  GraphRefSOptDatabaseContextExprEnv
  (ExceptT RelationalError Identity)
  DatabaseContext
askContext = (GraphRefSOptDatabaseContextExprEnv -> DatabaseContext)
-> ReaderT
     GraphRefSOptDatabaseContextExprEnv
     (ExceptT RelationalError Identity)
     DatabaseContext
forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
asks GraphRefSOptDatabaseContextExprEnv -> DatabaseContext
odce_context 

instance AskGraphContext (ReaderT GraphRefSOptRelationalExprEnv (ExceptT RelationalError Identity)) where
  askGraph :: ReaderT
  GraphRefSOptRelationalExprEnv
  (ExceptT RelationalError Identity)
  TransactionGraph
askGraph = (GraphRefSOptRelationalExprEnv -> TransactionGraph)
-> ReaderT
     GraphRefSOptRelationalExprEnv
     (ExceptT RelationalError Identity)
     TransactionGraph
forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
asks GraphRefSOptRelationalExprEnv -> TransactionGraph
ore_graph
  askContext :: ReaderT
  GraphRefSOptRelationalExprEnv
  (ExceptT RelationalError Identity)
  DatabaseContext
askContext = do
    Maybe DatabaseContext
mctx <- (GraphRefSOptRelationalExprEnv -> Maybe DatabaseContext)
-> ReaderT
     GraphRefSOptRelationalExprEnv
     (ExceptT RelationalError Identity)
     (Maybe DatabaseContext)
forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
asks GraphRefSOptRelationalExprEnv -> Maybe DatabaseContext
ore_mcontext
    case Maybe DatabaseContext
mctx of
      Maybe DatabaseContext
Nothing -> RelationalError
-> ReaderT
     GraphRefSOptRelationalExprEnv
     (ExceptT RelationalError Identity)
     DatabaseContext
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError RelationalError
NoUncommittedContextInEvalError
      Just DatabaseContext
ctx -> DatabaseContext
-> ReaderT
     GraphRefSOptRelationalExprEnv
     (ExceptT RelationalError Identity)
     DatabaseContext
forall (f :: * -> *) a. Applicative f => a -> f a
pure DatabaseContext
ctx

askTransId :: GraphRefSOptDatabaseContextExprM TransactionId
askTransId :: GraphRefSOptDatabaseContextExprM TransactionId
askTransId = (GraphRefSOptDatabaseContextExprEnv -> TransactionId)
-> GraphRefSOptDatabaseContextExprM TransactionId
forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
asks GraphRefSOptDatabaseContextExprEnv -> TransactionId
odce_transId

askMaybeContext :: GraphRefSOptRelationalExprM (Maybe DatabaseContext)
askMaybeContext :: ReaderT
  GraphRefSOptRelationalExprEnv
  (ExceptT RelationalError Identity)
  (Maybe DatabaseContext)
askMaybeContext = (GraphRefSOptRelationalExprEnv -> Maybe DatabaseContext)
-> ReaderT
     GraphRefSOptRelationalExprEnv
     (ExceptT RelationalError Identity)
     (Maybe DatabaseContext)
forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
asks GraphRefSOptRelationalExprEnv -> Maybe DatabaseContext
ore_mcontext

optimizeDatabaseContextExpr :: DatabaseContextExpr -> GraphRefSOptDatabaseContextExprM GraphRefDatabaseContextExpr
optimizeDatabaseContextExpr :: DatabaseContextExpr
-> GraphRefSOptDatabaseContextExprM GraphRefDatabaseContextExpr
optimizeDatabaseContextExpr DatabaseContextExpr
expr = do
  let gfExpr :: GraphRefDatabaseContextExpr
gfExpr = GraphRefTransactionMarker
-> ProcessExprM GraphRefDatabaseContextExpr
-> GraphRefDatabaseContextExpr
forall a. GraphRefTransactionMarker -> ProcessExprM a -> a
runProcessExprM GraphRefTransactionMarker
UncommittedContextMarker (DatabaseContextExpr -> ProcessExprM GraphRefDatabaseContextExpr
processDatabaseContextExpr DatabaseContextExpr
expr)
  GraphRefDatabaseContextExpr
-> GraphRefSOptDatabaseContextExprM GraphRefDatabaseContextExpr
optimizeGraphRefDatabaseContextExpr GraphRefDatabaseContextExpr
gfExpr
  
optimizeAndEvalDatabaseContextExpr :: Bool -> DatabaseContextExpr -> DatabaseContextEvalMonad ()
optimizeAndEvalDatabaseContextExpr :: Bool -> DatabaseContextExpr -> DatabaseContextEvalMonad ()
optimizeAndEvalDatabaseContextExpr Bool
optimize DatabaseContextExpr
expr = do
  TransactionGraph
graph <- (DatabaseContextEvalEnv -> TransactionGraph)
-> RWST
     DatabaseContextEvalEnv
     ()
     DatabaseContextEvalState
     (ExceptT RelationalError Identity)
     TransactionGraph
forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
asks DatabaseContextEvalEnv -> TransactionGraph
dce_graph
  TransactionId
transId <- (DatabaseContextEvalEnv -> TransactionId)
-> RWST
     DatabaseContextEvalEnv
     ()
     DatabaseContextEvalState
     (ExceptT RelationalError Identity)
     TransactionId
forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
asks DatabaseContextEvalEnv -> TransactionId
dce_transId
  DatabaseContext
context <- DatabaseContextEvalMonad DatabaseContext
getStateContext
  let gfExpr :: GraphRefDatabaseContextExpr
gfExpr = GraphRefTransactionMarker
-> ProcessExprM GraphRefDatabaseContextExpr
-> GraphRefDatabaseContextExpr
forall a. GraphRefTransactionMarker -> ProcessExprM a -> a
runProcessExprM GraphRefTransactionMarker
UncommittedContextMarker (DatabaseContextExpr -> ProcessExprM GraphRefDatabaseContextExpr
processDatabaseContextExpr DatabaseContextExpr
expr)
      eOptExpr :: Either RelationalError GraphRefDatabaseContextExpr
eOptExpr = if Bool
optimize then
                   TransactionId
-> DatabaseContext
-> TransactionGraph
-> GraphRefSOptDatabaseContextExprM GraphRefDatabaseContextExpr
-> Either RelationalError GraphRefDatabaseContextExpr
forall a.
TransactionId
-> DatabaseContext
-> TransactionGraph
-> GraphRefSOptDatabaseContextExprM a
-> Either RelationalError a
runGraphRefSOptDatabaseContextExprM TransactionId
transId DatabaseContext
context TransactionGraph
graph (GraphRefDatabaseContextExpr
-> GraphRefSOptDatabaseContextExprM GraphRefDatabaseContextExpr
optimizeGraphRefDatabaseContextExpr GraphRefDatabaseContextExpr
gfExpr)
                   else
                   GraphRefDatabaseContextExpr
-> Either RelationalError GraphRefDatabaseContextExpr
forall (f :: * -> *) a. Applicative f => a -> f a
pure GraphRefDatabaseContextExpr
gfExpr
  case Either RelationalError GraphRefDatabaseContextExpr
eOptExpr of
    Left RelationalError
err -> RelationalError -> DatabaseContextEvalMonad ()
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError RelationalError
err
    Right GraphRefDatabaseContextExpr
optExpr -> GraphRefDatabaseContextExpr -> DatabaseContextEvalMonad ()
evalGraphRefDatabaseContextExpr GraphRefDatabaseContextExpr
optExpr


optimizeAndEvalTransGraphRelationalExpr :: TransactionGraph -> TransGraphRelationalExpr -> Either RelationalError Relation
optimizeAndEvalTransGraphRelationalExpr :: TransactionGraph
-> TransGraphRelationalExpr -> Either RelationalError Relation
optimizeAndEvalTransGraphRelationalExpr TransactionGraph
graph TransGraphRelationalExpr
tgExpr = do
  GraphRefRelationalExpr
gfExpr <- TransGraphEvalEnv
-> TransGraphRelationalExpr
-> Either RelationalError GraphRefRelationalExpr
TGRE.process (TransactionGraph -> TransGraphEvalEnv
TransGraphEvalEnv TransactionGraph
graph) TransGraphRelationalExpr
tgExpr
  GraphRefRelationalExpr
optExpr <- Maybe DatabaseContext
-> TransactionGraph
-> GraphRefSOptRelationalExprM GraphRefRelationalExpr
-> Either RelationalError GraphRefRelationalExpr
forall a.
Maybe DatabaseContext
-> TransactionGraph
-> GraphRefSOptRelationalExprM a
-> Either RelationalError a
runGraphRefSOptRelationalExprM Maybe DatabaseContext
forall a. Maybe a
Nothing TransactionGraph
graph (GraphRefRelationalExpr
-> GraphRefSOptRelationalExprM GraphRefRelationalExpr
fullOptimizeGraphRefRelationalExpr GraphRefRelationalExpr
gfExpr)
  let gfEnv :: GraphRefRelationalExprEnv
gfEnv = Maybe DatabaseContext
-> TransactionGraph -> GraphRefRelationalExprEnv
freshGraphRefRelationalExprEnv Maybe DatabaseContext
forall a. Maybe a
Nothing TransactionGraph
graph
  GraphRefRelationalExprEnv
-> GraphRefRelationalExprM Relation
-> Either RelationalError Relation
forall a.
GraphRefRelationalExprEnv
-> GraphRefRelationalExprM a -> Either RelationalError a
runGraphRefRelationalExprM GraphRefRelationalExprEnv
gfEnv (GraphRefRelationalExpr -> GraphRefRelationalExprM Relation
evalGraphRefRelationalExpr GraphRefRelationalExpr
optExpr)

optimizeAndEvalDatabaseContextIOExpr :: DatabaseContextIOExpr -> DatabaseContextIOEvalMonad (Either RelationalError ())
optimizeAndEvalDatabaseContextIOExpr :: DatabaseContextIOExpr
-> DatabaseContextIOEvalMonad (Either RelationalError ())
optimizeAndEvalDatabaseContextIOExpr DatabaseContextIOExpr
expr = do
  TransactionId
transId <- (DatabaseContextIOEvalEnv -> TransactionId)
-> RWST
     DatabaseContextIOEvalEnv
     ()
     DatabaseContextEvalState
     IO
     TransactionId
forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
asks DatabaseContextIOEvalEnv -> TransactionId
dbcio_transId
  DatabaseContext
ctx <- DatabaseContextIOEvalMonad DatabaseContext
getDBCIOContext
  TransactionGraph
graph <- (DatabaseContextIOEvalEnv -> TransactionGraph)
-> RWST
     DatabaseContextIOEvalEnv
     ()
     DatabaseContextEvalState
     IO
     TransactionGraph
forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
asks DatabaseContextIOEvalEnv -> TransactionGraph
dbcio_graph
  let gfExpr :: GraphRefDatabaseContextIOExpr
gfExpr = GraphRefTransactionMarker
-> ProcessExprM GraphRefDatabaseContextIOExpr
-> GraphRefDatabaseContextIOExpr
forall a. GraphRefTransactionMarker -> ProcessExprM a -> a
runProcessExprM GraphRefTransactionMarker
UncommittedContextMarker (DatabaseContextIOExpr -> ProcessExprM GraphRefDatabaseContextIOExpr
processDatabaseContextIOExpr DatabaseContextIOExpr
expr)
      eOptExpr :: Either RelationalError GraphRefDatabaseContextIOExpr
eOptExpr = TransactionId
-> DatabaseContext
-> TransactionGraph
-> GraphRefSOptDatabaseContextExprM GraphRefDatabaseContextIOExpr
-> Either RelationalError GraphRefDatabaseContextIOExpr
forall a.
TransactionId
-> DatabaseContext
-> TransactionGraph
-> GraphRefSOptDatabaseContextExprM a
-> Either RelationalError a
runGraphRefSOptDatabaseContextExprM TransactionId
transId DatabaseContext
ctx TransactionGraph
graph (GraphRefDatabaseContextIOExpr
-> GraphRefSOptDatabaseContextExprM GraphRefDatabaseContextIOExpr
optimizeDatabaseContextIOExpr GraphRefDatabaseContextIOExpr
gfExpr)
  case Either RelationalError GraphRefDatabaseContextIOExpr
eOptExpr of
    Left RelationalError
err -> Either RelationalError ()
-> DatabaseContextIOEvalMonad (Either RelationalError ())
forall (f :: * -> *) a. Applicative f => a -> f a
pure (RelationalError -> Either RelationalError ()
forall a b. a -> Either a b
Left RelationalError
err)
    Right GraphRefDatabaseContextIOExpr
optExpr ->
      GraphRefDatabaseContextIOExpr
-> DatabaseContextIOEvalMonad (Either RelationalError ())
evalGraphRefDatabaseContextIOExpr GraphRefDatabaseContextIOExpr
optExpr

{-  
runStaticOptimizerMonad :: RelationalExprEnv -> StaticOptimizerMonad a -> Either RelationalError a
runStaticOptimizerMonad env m = runIdentity (runExceptT (runReaderT m env))
-}

runGraphRefSOptRelationalExprM ::
  Maybe DatabaseContext ->  
  TransactionGraph ->
  GraphRefSOptRelationalExprM a ->
  Either RelationalError a
runGraphRefSOptRelationalExprM :: Maybe DatabaseContext
-> TransactionGraph
-> GraphRefSOptRelationalExprM a
-> Either RelationalError a
runGraphRefSOptRelationalExprM Maybe DatabaseContext
mctx TransactionGraph
graph GraphRefSOptRelationalExprM a
m = Identity (Either RelationalError a) -> Either RelationalError a
forall a. Identity a -> a
runIdentity (ExceptT RelationalError Identity a
-> Identity (Either RelationalError a)
forall e (m :: * -> *) a. ExceptT e m a -> m (Either e a)
runExceptT (GraphRefSOptRelationalExprM a
-> GraphRefSOptRelationalExprEnv
-> ExceptT RelationalError Identity a
forall r (m :: * -> *) a. ReaderT r m a -> r -> m a
runReaderT GraphRefSOptRelationalExprM a
m GraphRefSOptRelationalExprEnv
env))
  where
    env :: GraphRefSOptRelationalExprEnv
env = GraphRefSOptRelationalExprEnv :: TransactionGraph
-> Maybe DatabaseContext -> GraphRefSOptRelationalExprEnv
GraphRefSOptRelationalExprEnv {
      ore_graph :: TransactionGraph
ore_graph = TransactionGraph
graph,
      ore_mcontext :: Maybe DatabaseContext
ore_mcontext = Maybe DatabaseContext
mctx
      }
  

runGraphRefSOptDatabaseContextExprM ::
  TransactionId ->
  DatabaseContext ->
  TransactionGraph ->
  GraphRefSOptDatabaseContextExprM a ->
  Either RelationalError a
runGraphRefSOptDatabaseContextExprM :: TransactionId
-> DatabaseContext
-> TransactionGraph
-> GraphRefSOptDatabaseContextExprM a
-> Either RelationalError a
runGraphRefSOptDatabaseContextExprM TransactionId
tid DatabaseContext
ctx TransactionGraph
graph GraphRefSOptDatabaseContextExprM a
m =
  Identity (Either RelationalError a) -> Either RelationalError a
forall a. Identity a -> a
runIdentity (ExceptT RelationalError Identity a
-> Identity (Either RelationalError a)
forall e (m :: * -> *) a. ExceptT e m a -> m (Either e a)
runExceptT (GraphRefSOptDatabaseContextExprM a
-> GraphRefSOptDatabaseContextExprEnv
-> ExceptT RelationalError Identity a
forall r (m :: * -> *) a. ReaderT r m a -> r -> m a
runReaderT GraphRefSOptDatabaseContextExprM a
m GraphRefSOptDatabaseContextExprEnv
env))
  where
    env :: GraphRefSOptDatabaseContextExprEnv
env = GraphRefSOptDatabaseContextExprEnv :: TransactionGraph
-> DatabaseContext
-> TransactionId
-> GraphRefSOptDatabaseContextExprEnv
GraphRefSOptDatabaseContextExprEnv {
      odce_graph :: TransactionGraph
odce_graph = TransactionGraph
graph,
      odce_context :: DatabaseContext
odce_context = DatabaseContext
ctx,
      odce_transId :: TransactionId
odce_transId = TransactionId
tid
      }

optimizeGraphRefRelationalExpr' ::
  Maybe DatabaseContext ->
  TransactionGraph ->
  GraphRefRelationalExpr ->
  Either RelationalError GraphRefRelationalExpr
optimizeGraphRefRelationalExpr' :: Maybe DatabaseContext
-> TransactionGraph
-> GraphRefRelationalExpr
-> Either RelationalError GraphRefRelationalExpr
optimizeGraphRefRelationalExpr' Maybe DatabaseContext
mctx TransactionGraph
graph GraphRefRelationalExpr
expr =
  Identity (Either RelationalError GraphRefRelationalExpr)
-> Either RelationalError GraphRefRelationalExpr
forall a. Identity a -> a
runIdentity (ExceptT RelationalError Identity GraphRefRelationalExpr
-> Identity (Either RelationalError GraphRefRelationalExpr)
forall e (m :: * -> *) a. ExceptT e m a -> m (Either e a)
runExceptT (GraphRefSOptRelationalExprM GraphRefRelationalExpr
-> GraphRefSOptRelationalExprEnv
-> ExceptT RelationalError Identity GraphRefRelationalExpr
forall r (m :: * -> *) a. ReaderT r m a -> r -> m a
runReaderT (GraphRefRelationalExpr
-> GraphRefSOptRelationalExprM GraphRefRelationalExpr
optimizeGraphRefRelationalExpr GraphRefRelationalExpr
expr) GraphRefSOptRelationalExprEnv
env))
  where
    env :: GraphRefSOptRelationalExprEnv
env = GraphRefSOptRelationalExprEnv :: TransactionGraph
-> Maybe DatabaseContext -> GraphRefSOptRelationalExprEnv
GraphRefSOptRelationalExprEnv {
      ore_graph :: TransactionGraph
ore_graph = TransactionGraph
graph,
      ore_mcontext :: Maybe DatabaseContext
ore_mcontext = Maybe DatabaseContext
mctx
      }

-- | optimize relational expression within database context expr monad
liftGraphRefRelExpr :: GraphRefSOptRelationalExprM a -> GraphRefSOptDatabaseContextExprM a
liftGraphRefRelExpr :: GraphRefSOptRelationalExprM a -> GraphRefSOptDatabaseContextExprM a
liftGraphRefRelExpr GraphRefSOptRelationalExprM a
m = do
  DatabaseContext
context <- (GraphRefSOptDatabaseContextExprEnv -> DatabaseContext)
-> ReaderT
     GraphRefSOptDatabaseContextExprEnv
     (ExceptT RelationalError Identity)
     DatabaseContext
forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
asks GraphRefSOptDatabaseContextExprEnv -> DatabaseContext
odce_context
  TransactionGraph
graph <- (GraphRefSOptDatabaseContextExprEnv -> TransactionGraph)
-> ReaderT
     GraphRefSOptDatabaseContextExprEnv
     (ExceptT RelationalError Identity)
     TransactionGraph
forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
asks GraphRefSOptDatabaseContextExprEnv -> TransactionGraph
odce_graph
  ExceptT RelationalError Identity a
-> GraphRefSOptDatabaseContextExprM a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (ExceptT RelationalError Identity a
 -> GraphRefSOptDatabaseContextExprM a)
-> ExceptT RelationalError Identity a
-> GraphRefSOptDatabaseContextExprM a
forall a b. (a -> b) -> a -> b
$ Either RelationalError a -> ExceptT RelationalError Identity a
forall (m :: * -> *) e a. Monad m => Either e a -> ExceptT e m a
except (Either RelationalError a -> ExceptT RelationalError Identity a)
-> Either RelationalError a -> ExceptT RelationalError Identity a
forall a b. (a -> b) -> a -> b
$ Maybe DatabaseContext
-> TransactionGraph
-> GraphRefSOptRelationalExprM a
-> Either RelationalError a
forall a.
Maybe DatabaseContext
-> TransactionGraph
-> GraphRefSOptRelationalExprM a
-> Either RelationalError a
runGraphRefSOptRelationalExprM (DatabaseContext -> Maybe DatabaseContext
forall a. a -> Maybe a
Just DatabaseContext
context) TransactionGraph
graph GraphRefSOptRelationalExprM a
m
  
fullOptimizeGraphRefRelationalExpr :: GraphRefRelationalExpr -> GraphRefSOptRelationalExprM GraphRefRelationalExpr
fullOptimizeGraphRefRelationalExpr :: GraphRefRelationalExpr
-> GraphRefSOptRelationalExprM GraphRefRelationalExpr
fullOptimizeGraphRefRelationalExpr GraphRefRelationalExpr
expr = do
  GraphRefRelationalExpr
optExpr <- GraphRefRelationalExpr
-> GraphRefSOptRelationalExprM GraphRefRelationalExpr
optimizeGraphRefRelationalExpr GraphRefRelationalExpr
expr
  let optExpr' :: GraphRefRelationalExpr
optExpr' = GraphRefRelationalExpr -> GraphRefRelationalExpr
applyStaticRestrictionPushdown (GraphRefRelationalExpr -> GraphRefRelationalExpr
applyStaticRestrictionCollapse GraphRefRelationalExpr
optExpr)
  GraphRefRelationalExpr
-> GraphRefSOptRelationalExprM GraphRefRelationalExpr
applyStaticJoinElimination GraphRefRelationalExpr
optExpr'

-- apply optimizations which merely remove steps to become no-ops: example: projection of a relation across all of its attributes => original relation

--should optimizations offer the possibility to pure errors? If they perform the up-front type-checking, maybe so
optimizeGraphRefRelationalExpr :: GraphRefRelationalExpr -> GraphRefSOptRelationalExprM GraphRefRelationalExpr
optimizeGraphRefRelationalExpr :: GraphRefRelationalExpr
-> GraphRefSOptRelationalExprM GraphRefRelationalExpr
optimizeGraphRefRelationalExpr e :: GraphRefRelationalExpr
e@(MakeStaticRelation Attributes
_ RelationTupleSet
_) = GraphRefRelationalExpr
-> GraphRefSOptRelationalExprM GraphRefRelationalExpr
forall (f :: * -> *) a. Applicative f => a -> f a
pure GraphRefRelationalExpr
e

optimizeGraphRefRelationalExpr e :: GraphRefRelationalExpr
e@MakeRelationFromExprs{} = GraphRefRelationalExpr
-> GraphRefSOptRelationalExprM GraphRefRelationalExpr
forall (f :: * -> *) a. Applicative f => a -> f a
pure GraphRefRelationalExpr
e

optimizeGraphRefRelationalExpr e :: GraphRefRelationalExpr
e@(ExistingRelation Relation
_) = GraphRefRelationalExpr
-> GraphRefSOptRelationalExprM GraphRefRelationalExpr
forall (f :: * -> *) a. Applicative f => a -> f a
pure GraphRefRelationalExpr
e

optimizeGraphRefRelationalExpr e :: GraphRefRelationalExpr
e@(RelationVariable RelVarName
_ GraphRefTransactionMarker
_) = GraphRefRelationalExpr
-> GraphRefSOptRelationalExprM GraphRefRelationalExpr
forall (f :: * -> *) a. Applicative f => a -> f a
pure GraphRefRelationalExpr
e
  
--remove project of attributes which removes no attributes
optimizeGraphRefRelationalExpr (Project AttributeNamesBase GraphRefTransactionMarker
attrNameSet GraphRefRelationalExpr
expr) = do
  TransactionGraph
graph <- ReaderT
  GraphRefSOptRelationalExprEnv
  (ExceptT RelationalError Identity)
  TransactionGraph
forall (m :: * -> *). AskGraphContext m => m TransactionGraph
askGraph
  Maybe DatabaseContext
mctx <- ReaderT
  GraphRefSOptRelationalExprEnv
  (ExceptT RelationalError Identity)
  (Maybe DatabaseContext)
askMaybeContext
  let relType :: Either RelationalError Relation
relType = GraphRefRelationalExprEnv
-> GraphRefRelationalExprM Relation
-> Either RelationalError Relation
forall a.
GraphRefRelationalExprEnv
-> GraphRefRelationalExprM a -> Either RelationalError a
runGraphRefRelationalExprM GraphRefRelationalExprEnv
gfEnv (GraphRefRelationalExpr -> GraphRefRelationalExprM Relation
typeForGraphRefRelationalExpr GraphRefRelationalExpr
expr)
      gfEnv :: GraphRefRelationalExprEnv
gfEnv = Maybe DatabaseContext
-> TransactionGraph -> GraphRefRelationalExprEnv
freshGraphRefRelationalExprEnv Maybe DatabaseContext
mctx TransactionGraph
graph
  case Either RelationalError Relation
relType of
    Left RelationalError
err -> RelationalError
-> GraphRefSOptRelationalExprM GraphRefRelationalExpr
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError RelationalError
err
    Right Relation
relType2 
      | AttributeNamesBase GraphRefTransactionMarker
forall a. AttributeNamesBase a
AS.all AttributeNamesBase GraphRefTransactionMarker
-> AttributeNamesBase GraphRefTransactionMarker -> Bool
forall a. Eq a => a -> a -> Bool
== AttributeNamesBase GraphRefTransactionMarker
attrNameSet ->        
        GraphRefRelationalExpr
-> GraphRefSOptRelationalExprM GraphRefRelationalExpr
optimizeGraphRefRelationalExpr GraphRefRelationalExpr
expr
      | Set RelVarName -> AttributeNamesBase GraphRefTransactionMarker
forall a. Set RelVarName -> AttributeNamesBase a
AttributeNames (Relation -> Set RelVarName
attributeNames Relation
relType2) AttributeNamesBase GraphRefTransactionMarker
-> AttributeNamesBase GraphRefTransactionMarker -> Bool
forall a. Eq a => a -> a -> Bool
== AttributeNamesBase GraphRefTransactionMarker
attrNameSet ->
        GraphRefRelationalExpr
-> GraphRefSOptRelationalExprM GraphRefRelationalExpr
optimizeGraphRefRelationalExpr GraphRefRelationalExpr
expr
      | Bool
otherwise -> do
        GraphRefRelationalExpr
optSubExpr <- GraphRefRelationalExpr
-> GraphRefSOptRelationalExprM GraphRefRelationalExpr
optimizeGraphRefRelationalExpr GraphRefRelationalExpr
expr 
        GraphRefRelationalExpr
-> GraphRefSOptRelationalExprM GraphRefRelationalExpr
forall (f :: * -> *) a. Applicative f => a -> f a
pure (AttributeNamesBase GraphRefTransactionMarker
-> GraphRefRelationalExpr -> GraphRefRelationalExpr
forall a.
AttributeNamesBase a
-> RelationalExprBase a -> RelationalExprBase a
Project AttributeNamesBase GraphRefTransactionMarker
attrNameSet GraphRefRelationalExpr
optSubExpr)
                           
optimizeGraphRefRelationalExpr (Union GraphRefRelationalExpr
exprA GraphRefRelationalExpr
exprB) = do
  GraphRefRelationalExpr
optExprA <- GraphRefRelationalExpr
-> GraphRefSOptRelationalExprM GraphRefRelationalExpr
optimizeGraphRefRelationalExpr GraphRefRelationalExpr
exprA
  GraphRefRelationalExpr
optExprB <- GraphRefRelationalExpr
-> GraphRefSOptRelationalExprM GraphRefRelationalExpr
optimizeGraphRefRelationalExpr GraphRefRelationalExpr
exprB
  -- (x where pred1) union (x where pred2) -> (x where pred1 or pred2)
  case (GraphRefRelationalExpr
optExprA, GraphRefRelationalExpr
optExprB) of 
          (Restrict RestrictionPredicateExprBase GraphRefTransactionMarker
predA (RelationVariable RelVarName
nameA GraphRefTransactionMarker
sA),
           Restrict RestrictionPredicateExprBase GraphRefTransactionMarker
predB (RelationVariable RelVarName
nameB GraphRefTransactionMarker
sB)) | RelVarName
nameA RelVarName -> RelVarName -> Bool
forall a. Eq a => a -> a -> Bool
== RelVarName
nameB Bool -> Bool -> Bool
&& GraphRefTransactionMarker
sA GraphRefTransactionMarker -> GraphRefTransactionMarker -> Bool
forall a. Eq a => a -> a -> Bool
== GraphRefTransactionMarker
sB -> GraphRefRelationalExpr
-> GraphRefSOptRelationalExprM GraphRefRelationalExpr
forall (f :: * -> *) a. Applicative f => a -> f a
pure (RestrictionPredicateExprBase GraphRefTransactionMarker
-> GraphRefRelationalExpr -> GraphRefRelationalExpr
forall a.
RestrictionPredicateExprBase a
-> RelationalExprBase a -> RelationalExprBase a
Restrict (RestrictionPredicateExprBase GraphRefTransactionMarker
-> RestrictionPredicateExprBase GraphRefTransactionMarker
-> RestrictionPredicateExprBase GraphRefTransactionMarker
forall a.
RestrictionPredicateExprBase a
-> RestrictionPredicateExprBase a -> RestrictionPredicateExprBase a
AndPredicate RestrictionPredicateExprBase GraphRefTransactionMarker
predA RestrictionPredicateExprBase GraphRefTransactionMarker
predB) (RelVarName -> GraphRefTransactionMarker -> GraphRefRelationalExpr
forall a. RelVarName -> a -> RelationalExprBase a
RelationVariable RelVarName
nameA GraphRefTransactionMarker
sA))
          (GraphRefRelationalExpr
exprA', GraphRefRelationalExpr
exprB') | GraphRefRelationalExpr -> Bool
forall a. RelationalExprBase a -> Bool
isEmptyRelationExpr GraphRefRelationalExpr
exprA' -> GraphRefRelationalExpr
-> GraphRefSOptRelationalExprM GraphRefRelationalExpr
forall (f :: * -> *) a. Applicative f => a -> f a
pure GraphRefRelationalExpr
exprB'
                           | GraphRefRelationalExpr -> Bool
forall a. RelationalExprBase a -> Bool
isEmptyRelationExpr GraphRefRelationalExpr
exprB' -> GraphRefRelationalExpr
-> GraphRefSOptRelationalExprM GraphRefRelationalExpr
forall (f :: * -> *) a. Applicative f => a -> f a
pure GraphRefRelationalExpr
exprA'
          (GraphRefRelationalExpr, GraphRefRelationalExpr)
_ -> if GraphRefRelationalExpr
optExprA GraphRefRelationalExpr -> GraphRefRelationalExpr -> Bool
forall a. Eq a => a -> a -> Bool
== GraphRefRelationalExpr
optExprB then           
            GraphRefRelationalExpr
-> GraphRefSOptRelationalExprM GraphRefRelationalExpr
forall (f :: * -> *) a. Applicative f => a -> f a
pure GraphRefRelationalExpr
optExprA
            else
            GraphRefRelationalExpr
-> GraphRefSOptRelationalExprM GraphRefRelationalExpr
forall (f :: * -> *) a. Applicative f => a -> f a
pure (GraphRefRelationalExpr
 -> GraphRefSOptRelationalExprM GraphRefRelationalExpr)
-> GraphRefRelationalExpr
-> GraphRefSOptRelationalExprM GraphRefRelationalExpr
forall a b. (a -> b) -> a -> b
$ GraphRefRelationalExpr
-> GraphRefRelationalExpr -> GraphRefRelationalExpr
forall a.
RelationalExprBase a
-> RelationalExprBase a -> RelationalExprBase a
Union GraphRefRelationalExpr
optExprA GraphRefRelationalExpr
optExprB
                            
optimizeGraphRefRelationalExpr (Join GraphRefRelationalExpr
exprA GraphRefRelationalExpr
exprB) = do
  GraphRefRelationalExpr
optExprA <- GraphRefRelationalExpr
-> GraphRefSOptRelationalExprM GraphRefRelationalExpr
optimizeGraphRefRelationalExpr GraphRefRelationalExpr
exprA
  GraphRefRelationalExpr
optExprB <- GraphRefRelationalExpr
-> GraphRefSOptRelationalExprM GraphRefRelationalExpr
optimizeGraphRefRelationalExpr GraphRefRelationalExpr
exprB
  -- if the relvars to join are the same but with predicates, then just AndPredicate the predicates
  case (GraphRefRelationalExpr
optExprA, GraphRefRelationalExpr
optExprB) of
          (Restrict RestrictionPredicateExprBase GraphRefTransactionMarker
predA (RelationVariable RelVarName
nameA GraphRefTransactionMarker
sA),
           Restrict RestrictionPredicateExprBase GraphRefTransactionMarker
predB (RelationVariable RelVarName
nameB GraphRefTransactionMarker
sB)) | RelVarName
nameA RelVarName -> RelVarName -> Bool
forall a. Eq a => a -> a -> Bool
== RelVarName
nameB Bool -> Bool -> Bool
&& GraphRefTransactionMarker
sA GraphRefTransactionMarker -> GraphRefTransactionMarker -> Bool
forall a. Eq a => a -> a -> Bool
== GraphRefTransactionMarker
sB -> GraphRefRelationalExpr
-> GraphRefSOptRelationalExprM GraphRefRelationalExpr
forall (f :: * -> *) a. Applicative f => a -> f a
pure (RestrictionPredicateExprBase GraphRefTransactionMarker
-> GraphRefRelationalExpr -> GraphRefRelationalExpr
forall a.
RestrictionPredicateExprBase a
-> RelationalExprBase a -> RelationalExprBase a
Restrict  (RestrictionPredicateExprBase GraphRefTransactionMarker
-> RestrictionPredicateExprBase GraphRefTransactionMarker
-> RestrictionPredicateExprBase GraphRefTransactionMarker
forall a.
RestrictionPredicateExprBase a
-> RestrictionPredicateExprBase a -> RestrictionPredicateExprBase a
AndPredicate RestrictionPredicateExprBase GraphRefTransactionMarker
predA RestrictionPredicateExprBase GraphRefTransactionMarker
predB) (RelVarName -> GraphRefTransactionMarker -> GraphRefRelationalExpr
forall a. RelVarName -> a -> RelationalExprBase a
RelationVariable RelVarName
nameA GraphRefTransactionMarker
sA))
          (GraphRefRelationalExpr, GraphRefRelationalExpr)
_ -> if GraphRefRelationalExpr
optExprA GraphRefRelationalExpr -> GraphRefRelationalExpr -> Bool
forall a. Eq a => a -> a -> Bool
== GraphRefRelationalExpr
optExprB then --A join A == A
                           GraphRefRelationalExpr
-> GraphRefSOptRelationalExprM GraphRefRelationalExpr
forall (f :: * -> *) a. Applicative f => a -> f a
pure GraphRefRelationalExpr
optExprA
                         else
                           GraphRefRelationalExpr
-> GraphRefSOptRelationalExprM GraphRefRelationalExpr
forall (f :: * -> *) a. Applicative f => a -> f a
pure (GraphRefRelationalExpr
-> GraphRefRelationalExpr -> GraphRefRelationalExpr
forall a.
RelationalExprBase a
-> RelationalExprBase a -> RelationalExprBase a
Join GraphRefRelationalExpr
optExprA GraphRefRelationalExpr
optExprB)
                           
optimizeGraphRefRelationalExpr (Difference GraphRefRelationalExpr
exprA GraphRefRelationalExpr
exprB) = do
  TransactionGraph
graph <- ReaderT
  GraphRefSOptRelationalExprEnv
  (ExceptT RelationalError Identity)
  TransactionGraph
forall (m :: * -> *). AskGraphContext m => m TransactionGraph
askGraph
  Maybe DatabaseContext
context <- ReaderT
  GraphRefSOptRelationalExprEnv
  (ExceptT RelationalError Identity)
  (Maybe DatabaseContext)
askMaybeContext
  GraphRefRelationalExpr
optExprA <- GraphRefRelationalExpr
-> GraphRefSOptRelationalExprM GraphRefRelationalExpr
optimizeGraphRefRelationalExpr GraphRefRelationalExpr
exprA
  GraphRefRelationalExpr
optExprB <- GraphRefRelationalExpr
-> GraphRefSOptRelationalExprM GraphRefRelationalExpr
optimizeGraphRefRelationalExpr GraphRefRelationalExpr
exprB
  if GraphRefRelationalExpr
optExprA GraphRefRelationalExpr -> GraphRefRelationalExpr -> Bool
forall a. Eq a => a -> a -> Bool
== GraphRefRelationalExpr
optExprB then do --A difference A == A where false
    let eEmptyRel :: Either RelationalError Relation
eEmptyRel = GraphRefRelationalExprEnv
-> GraphRefRelationalExprM Relation
-> Either RelationalError Relation
forall a.
GraphRefRelationalExprEnv
-> GraphRefRelationalExprM a -> Either RelationalError a
runGraphRefRelationalExprM GraphRefRelationalExprEnv
gfEnv (GraphRefRelationalExpr -> GraphRefRelationalExprM Relation
typeForGraphRefRelationalExpr GraphRefRelationalExpr
optExprA)
        gfEnv :: GraphRefRelationalExprEnv
gfEnv = Maybe DatabaseContext
-> TransactionGraph -> GraphRefRelationalExprEnv
freshGraphRefRelationalExprEnv Maybe DatabaseContext
context TransactionGraph
graph
    case Either RelationalError Relation
eEmptyRel of
      Left RelationalError
err -> RelationalError
-> GraphRefSOptRelationalExprM GraphRefRelationalExpr
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError RelationalError
err
      Right Relation
emptyRel -> GraphRefRelationalExpr
-> GraphRefSOptRelationalExprM GraphRefRelationalExpr
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Relation -> GraphRefRelationalExpr
forall a. Relation -> RelationalExprBase a
ExistingRelation Relation
emptyRel)
    else
    GraphRefRelationalExpr
-> GraphRefSOptRelationalExprM GraphRefRelationalExpr
forall (f :: * -> *) a. Applicative f => a -> f a
pure (GraphRefRelationalExpr
-> GraphRefRelationalExpr -> GraphRefRelationalExpr
forall a.
RelationalExprBase a
-> RelationalExprBase a -> RelationalExprBase a
Difference GraphRefRelationalExpr
optExprA GraphRefRelationalExpr
optExprB)
                           
optimizeGraphRefRelationalExpr e :: GraphRefRelationalExpr
e@Rename{} = GraphRefRelationalExpr
-> GraphRefSOptRelationalExprM GraphRefRelationalExpr
forall (f :: * -> *) a. Applicative f => a -> f a
pure GraphRefRelationalExpr
e

optimizeGraphRefRelationalExpr (Group AttributeNamesBase GraphRefTransactionMarker
oldAttrNames RelVarName
newAttrName GraphRefRelationalExpr
expr) =
  GraphRefRelationalExpr
-> GraphRefSOptRelationalExprM GraphRefRelationalExpr
forall (f :: * -> *) a. Applicative f => a -> f a
pure (GraphRefRelationalExpr
 -> GraphRefSOptRelationalExprM GraphRefRelationalExpr)
-> GraphRefRelationalExpr
-> GraphRefSOptRelationalExprM GraphRefRelationalExpr
forall a b. (a -> b) -> a -> b
$ AttributeNamesBase GraphRefTransactionMarker
-> RelVarName -> GraphRefRelationalExpr -> GraphRefRelationalExpr
forall a.
AttributeNamesBase a
-> RelVarName -> RelationalExprBase a -> RelationalExprBase a
Group AttributeNamesBase GraphRefTransactionMarker
oldAttrNames RelVarName
newAttrName GraphRefRelationalExpr
expr
  
optimizeGraphRefRelationalExpr (Ungroup RelVarName
attrName GraphRefRelationalExpr
expr) =
  GraphRefRelationalExpr
-> GraphRefSOptRelationalExprM GraphRefRelationalExpr
forall (f :: * -> *) a. Applicative f => a -> f a
pure (GraphRefRelationalExpr
 -> GraphRefSOptRelationalExprM GraphRefRelationalExpr)
-> GraphRefRelationalExpr
-> GraphRefSOptRelationalExprM GraphRefRelationalExpr
forall a b. (a -> b) -> a -> b
$ RelVarName -> GraphRefRelationalExpr -> GraphRefRelationalExpr
forall a.
RelVarName -> RelationalExprBase a -> RelationalExprBase a
Ungroup RelVarName
attrName GraphRefRelationalExpr
expr
  
--remove restriction of nothing
optimizeGraphRefRelationalExpr (Restrict RestrictionPredicateExprBase GraphRefTransactionMarker
predicate GraphRefRelationalExpr
expr) = do
  TransactionGraph
graph <- ReaderT
  GraphRefSOptRelationalExprEnv
  (ExceptT RelationalError Identity)
  TransactionGraph
forall (m :: * -> *). AskGraphContext m => m TransactionGraph
askGraph
  Maybe DatabaseContext
mctx <- ReaderT
  GraphRefSOptRelationalExprEnv
  (ExceptT RelationalError Identity)
  (Maybe DatabaseContext)
askMaybeContext
  RestrictionPredicateExprBase GraphRefTransactionMarker
optimizedPredicate <- RestrictionPredicateExprBase GraphRefTransactionMarker
-> GraphRefSOptRelationalExprM
     (RestrictionPredicateExprBase GraphRefTransactionMarker)
applyStaticPredicateOptimization RestrictionPredicateExprBase GraphRefTransactionMarker
predicate
  case RestrictionPredicateExprBase GraphRefTransactionMarker
optimizedPredicate of
    RestrictionPredicateExprBase GraphRefTransactionMarker
optimizedPredicate' | RestrictionPredicateExprBase GraphRefTransactionMarker -> Bool
forall a. RestrictionPredicateExprBase a -> Bool
isTrueExpr RestrictionPredicateExprBase GraphRefTransactionMarker
optimizedPredicate' -> GraphRefRelationalExpr
-> GraphRefSOptRelationalExprM GraphRefRelationalExpr
optimizeGraphRefRelationalExpr GraphRefRelationalExpr
expr -- remove predicate entirely
    RestrictionPredicateExprBase GraphRefTransactionMarker
optimizedPredicate' | RestrictionPredicateExprBase GraphRefTransactionMarker -> Bool
forall a. RestrictionPredicateExprBase a -> Bool
isFalseExpr RestrictionPredicateExprBase GraphRefTransactionMarker
optimizedPredicate' -> do -- replace where false predicate with empty relation with attributes from relexpr
        let attributesRel :: Either RelationalError Relation
attributesRel = GraphRefRelationalExprEnv
-> GraphRefRelationalExprM Relation
-> Either RelationalError Relation
forall a.
GraphRefRelationalExprEnv
-> GraphRefRelationalExprM a -> Either RelationalError a
runGraphRefRelationalExprM GraphRefRelationalExprEnv
gfEnv (GraphRefRelationalExpr -> GraphRefRelationalExprM Relation
typeForGraphRefRelationalExpr GraphRefRelationalExpr
expr)
            gfEnv :: GraphRefRelationalExprEnv
gfEnv = Maybe DatabaseContext
-> TransactionGraph -> GraphRefRelationalExprEnv
freshGraphRefRelationalExprEnv Maybe DatabaseContext
mctx TransactionGraph
graph
        case Either RelationalError Relation
attributesRel of 
          Left RelationalError
err -> RelationalError
-> GraphRefSOptRelationalExprM GraphRefRelationalExpr
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError RelationalError
err
          Right Relation
attributesRelA -> GraphRefRelationalExpr
-> GraphRefSOptRelationalExprM GraphRefRelationalExpr
forall (f :: * -> *) a. Applicative f => a -> f a
pure (GraphRefRelationalExpr
 -> GraphRefSOptRelationalExprM GraphRefRelationalExpr)
-> GraphRefRelationalExpr
-> GraphRefSOptRelationalExprM GraphRefRelationalExpr
forall a b. (a -> b) -> a -> b
$ Attributes -> RelationTupleSet -> GraphRefRelationalExpr
forall a. Attributes -> RelationTupleSet -> RelationalExprBase a
MakeStaticRelation (Relation -> Attributes
attributes Relation
attributesRelA) RelationTupleSet
emptyTupleSet
      | Bool
otherwise -> do
        GraphRefRelationalExpr
optSubExpr <- GraphRefRelationalExpr
-> GraphRefSOptRelationalExprM GraphRefRelationalExpr
optimizeGraphRefRelationalExpr GraphRefRelationalExpr
expr
        GraphRefRelationalExpr
-> GraphRefSOptRelationalExprM GraphRefRelationalExpr
forall (f :: * -> *) a. Applicative f => a -> f a
pure (GraphRefRelationalExpr
 -> GraphRefSOptRelationalExprM GraphRefRelationalExpr)
-> GraphRefRelationalExpr
-> GraphRefSOptRelationalExprM GraphRefRelationalExpr
forall a b. (a -> b) -> a -> b
$ RestrictionPredicateExprBase GraphRefTransactionMarker
-> GraphRefRelationalExpr -> GraphRefRelationalExpr
forall a.
RestrictionPredicateExprBase a
-> RelationalExprBase a -> RelationalExprBase a
Restrict RestrictionPredicateExprBase GraphRefTransactionMarker
optimizedPredicate' GraphRefRelationalExpr
optSubExpr
  
optimizeGraphRefRelationalExpr e :: GraphRefRelationalExpr
e@(Equals GraphRefRelationalExpr
_ GraphRefRelationalExpr
_) = GraphRefRelationalExpr
-> GraphRefSOptRelationalExprM GraphRefRelationalExpr
forall (f :: * -> *) a. Applicative f => a -> f a
pure GraphRefRelationalExpr
e 

optimizeGraphRefRelationalExpr e :: GraphRefRelationalExpr
e@(NotEquals GraphRefRelationalExpr
_ GraphRefRelationalExpr
_) = GraphRefRelationalExpr
-> GraphRefSOptRelationalExprM GraphRefRelationalExpr
forall (f :: * -> *) a. Applicative f => a -> f a
pure GraphRefRelationalExpr
e 
  
optimizeGraphRefRelationalExpr e :: GraphRefRelationalExpr
e@(Extend ExtendTupleExprBase GraphRefTransactionMarker
_ GraphRefRelationalExpr
_) = GraphRefRelationalExpr
-> GraphRefSOptRelationalExprM GraphRefRelationalExpr
forall (f :: * -> *) a. Applicative f => a -> f a
pure GraphRefRelationalExpr
e  

optimizeGraphRefRelationalExpr e :: GraphRefRelationalExpr
e@(With [(WithNameExprBase GraphRefTransactionMarker,
  GraphRefRelationalExpr)]
_ GraphRefRelationalExpr
_) = GraphRefRelationalExpr
-> GraphRefSOptRelationalExprM GraphRefRelationalExpr
forall (f :: * -> *) a. Applicative f => a -> f a
pure GraphRefRelationalExpr
e  

-- database context expr
optimizeGraphRefDatabaseContextExpr :: GraphRefDatabaseContextExpr -> GraphRefSOptDatabaseContextExprM GraphRefDatabaseContextExpr
optimizeGraphRefDatabaseContextExpr :: GraphRefDatabaseContextExpr
-> GraphRefSOptDatabaseContextExprM GraphRefDatabaseContextExpr
optimizeGraphRefDatabaseContextExpr x :: GraphRefDatabaseContextExpr
x@GraphRefDatabaseContextExpr
NoOperation = GraphRefDatabaseContextExpr
-> GraphRefSOptDatabaseContextExprM GraphRefDatabaseContextExpr
forall (f :: * -> *) a. Applicative f => a -> f a
pure GraphRefDatabaseContextExpr
x
optimizeGraphRefDatabaseContextExpr x :: GraphRefDatabaseContextExpr
x@(Define RelVarName
_ [AttributeExprBase GraphRefTransactionMarker]
_) = GraphRefDatabaseContextExpr
-> GraphRefSOptDatabaseContextExprM GraphRefDatabaseContextExpr
forall (f :: * -> *) a. Applicative f => a -> f a
pure GraphRefDatabaseContextExpr
x

optimizeGraphRefDatabaseContextExpr x :: GraphRefDatabaseContextExpr
x@(Undefine RelVarName
_) = GraphRefDatabaseContextExpr
-> GraphRefSOptDatabaseContextExprM GraphRefDatabaseContextExpr
forall (f :: * -> *) a. Applicative f => a -> f a
pure GraphRefDatabaseContextExpr
x

optimizeGraphRefDatabaseContextExpr (Assign RelVarName
name GraphRefRelationalExpr
expr) = do
  GraphRefRelationalExpr
optExpr <- GraphRefSOptRelationalExprM GraphRefRelationalExpr
-> GraphRefSOptDatabaseContextExprM GraphRefRelationalExpr
forall a.
GraphRefSOptRelationalExprM a -> GraphRefSOptDatabaseContextExprM a
liftGraphRefRelExpr (GraphRefRelationalExpr
-> GraphRefSOptRelationalExprM GraphRefRelationalExpr
fullOptimizeGraphRefRelationalExpr GraphRefRelationalExpr
expr)
  GraphRefDatabaseContextExpr
-> GraphRefSOptDatabaseContextExprM GraphRefDatabaseContextExpr
forall (f :: * -> *) a. Applicative f => a -> f a
pure (GraphRefDatabaseContextExpr
 -> GraphRefSOptDatabaseContextExprM GraphRefDatabaseContextExpr)
-> GraphRefDatabaseContextExpr
-> GraphRefSOptDatabaseContextExprM GraphRefDatabaseContextExpr
forall a b. (a -> b) -> a -> b
$ RelVarName -> GraphRefRelationalExpr -> GraphRefDatabaseContextExpr
forall a.
RelVarName -> RelationalExprBase a -> DatabaseContextExprBase a
Assign RelVarName
name GraphRefRelationalExpr
optExpr
    
optimizeGraphRefDatabaseContextExpr (Insert RelVarName
targetName GraphRefRelationalExpr
expr) = do
  GraphRefRelationalExpr
optimizedExpr <- GraphRefSOptRelationalExprM GraphRefRelationalExpr
-> GraphRefSOptDatabaseContextExprM GraphRefRelationalExpr
forall a.
GraphRefSOptRelationalExprM a -> GraphRefSOptDatabaseContextExprM a
liftGraphRefRelExpr (GraphRefRelationalExpr
-> GraphRefSOptRelationalExprM GraphRefRelationalExpr
fullOptimizeGraphRefRelationalExpr GraphRefRelationalExpr
expr)
  if GraphRefRelationalExpr -> Bool
forall a. RelationalExprBase a -> Bool
isEmptyRelationExpr GraphRefRelationalExpr
optimizedExpr then -- if we are trying to insert an empty relation, do nothing
    GraphRefDatabaseContextExpr
-> GraphRefSOptDatabaseContextExprM GraphRefDatabaseContextExpr
forall (f :: * -> *) a. Applicative f => a -> f a
pure GraphRefDatabaseContextExpr
forall a. DatabaseContextExprBase a
NoOperation
    else 
    case GraphRefRelationalExpr
optimizedExpr of 
      -- if the target relvar and the insert relvar are the same, there is nothing to do
      -- insert s s -> NoOperation
      RelationVariable RelVarName
insName GraphRefTransactionMarker
_ | RelVarName
insName RelVarName -> RelVarName -> Bool
forall a. Eq a => a -> a -> Bool
== RelVarName
targetName -> GraphRefDatabaseContextExpr
-> GraphRefSOptDatabaseContextExprM GraphRefDatabaseContextExpr
forall (f :: * -> *) a. Applicative f => a -> f a
pure GraphRefDatabaseContextExpr
forall a. DatabaseContextExprBase a
NoOperation
      GraphRefRelationalExpr
_ -> GraphRefDatabaseContextExpr
-> GraphRefSOptDatabaseContextExprM GraphRefDatabaseContextExpr
forall (f :: * -> *) a. Applicative f => a -> f a
pure (RelVarName -> GraphRefRelationalExpr -> GraphRefDatabaseContextExpr
forall a.
RelVarName -> RelationalExprBase a -> DatabaseContextExprBase a
Insert RelVarName
targetName GraphRefRelationalExpr
optimizedExpr)
  
optimizeGraphRefDatabaseContextExpr (Delete RelVarName
name RestrictionPredicateExprBase GraphRefTransactionMarker
predicate) =
  RelVarName
-> RestrictionPredicateExprBase GraphRefTransactionMarker
-> GraphRefDatabaseContextExpr
forall a.
RelVarName
-> RestrictionPredicateExprBase a -> DatabaseContextExprBase a
Delete RelVarName
name (RestrictionPredicateExprBase GraphRefTransactionMarker
 -> GraphRefDatabaseContextExpr)
-> ReaderT
     GraphRefSOptDatabaseContextExprEnv
     (ExceptT RelationalError Identity)
     (RestrictionPredicateExprBase GraphRefTransactionMarker)
-> GraphRefSOptDatabaseContextExprM GraphRefDatabaseContextExpr
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> GraphRefSOptRelationalExprM
  (RestrictionPredicateExprBase GraphRefTransactionMarker)
-> ReaderT
     GraphRefSOptDatabaseContextExprEnv
     (ExceptT RelationalError Identity)
     (RestrictionPredicateExprBase GraphRefTransactionMarker)
forall a.
GraphRefSOptRelationalExprM a -> GraphRefSOptDatabaseContextExprM a
liftGraphRefRelExpr (RestrictionPredicateExprBase GraphRefTransactionMarker
-> GraphRefSOptRelationalExprM
     (RestrictionPredicateExprBase GraphRefTransactionMarker)
applyStaticPredicateOptimization RestrictionPredicateExprBase GraphRefTransactionMarker
predicate)

optimizeGraphRefDatabaseContextExpr (Update RelVarName
name AttributeNameAtomExprMap
upmap RestrictionPredicateExprBase GraphRefTransactionMarker
predicate) =
  RelVarName
-> AttributeNameAtomExprMap
-> RestrictionPredicateExprBase GraphRefTransactionMarker
-> GraphRefDatabaseContextExpr
forall a.
RelVarName
-> AttributeNameAtomExprMap
-> RestrictionPredicateExprBase a
-> DatabaseContextExprBase a
Update RelVarName
name AttributeNameAtomExprMap
upmap (RestrictionPredicateExprBase GraphRefTransactionMarker
 -> GraphRefDatabaseContextExpr)
-> ReaderT
     GraphRefSOptDatabaseContextExprEnv
     (ExceptT RelationalError Identity)
     (RestrictionPredicateExprBase GraphRefTransactionMarker)
-> GraphRefSOptDatabaseContextExprM GraphRefDatabaseContextExpr
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> GraphRefSOptRelationalExprM
  (RestrictionPredicateExprBase GraphRefTransactionMarker)
-> ReaderT
     GraphRefSOptDatabaseContextExprEnv
     (ExceptT RelationalError Identity)
     (RestrictionPredicateExprBase GraphRefTransactionMarker)
forall a.
GraphRefSOptRelationalExprM a -> GraphRefSOptDatabaseContextExprM a
liftGraphRefRelExpr (RestrictionPredicateExprBase GraphRefTransactionMarker
-> GraphRefSOptRelationalExprM
     (RestrictionPredicateExprBase GraphRefTransactionMarker)
applyStaticPredicateOptimization RestrictionPredicateExprBase GraphRefTransactionMarker
predicate)
      
optimizeGraphRefDatabaseContextExpr dep :: GraphRefDatabaseContextExpr
dep@(AddInclusionDependency RelVarName
_ InclusionDependency
_) = GraphRefDatabaseContextExpr
-> GraphRefSOptDatabaseContextExprM GraphRefDatabaseContextExpr
forall (f :: * -> *) a. Applicative f => a -> f a
pure GraphRefDatabaseContextExpr
dep

optimizeGraphRefDatabaseContextExpr (RemoveInclusionDependency RelVarName
name) = GraphRefDatabaseContextExpr
-> GraphRefSOptDatabaseContextExprM GraphRefDatabaseContextExpr
forall (f :: * -> *) a. Applicative f => a -> f a
pure (RelVarName -> GraphRefDatabaseContextExpr
forall a. RelVarName -> DatabaseContextExprBase a
RemoveInclusionDependency RelVarName
name)

optimizeGraphRefDatabaseContextExpr (AddNotification RelVarName
name RelationalExpr
triggerExpr RelationalExpr
resultOldExpr RelationalExpr
resultNewExpr) = 
  --we can't optimize these expressions until they run
  GraphRefDatabaseContextExpr
-> GraphRefSOptDatabaseContextExprM GraphRefDatabaseContextExpr
forall (f :: * -> *) a. Applicative f => a -> f a
pure (RelVarName
-> RelationalExpr
-> RelationalExpr
-> RelationalExpr
-> GraphRefDatabaseContextExpr
forall a.
RelVarName
-> RelationalExpr
-> RelationalExpr
-> RelationalExpr
-> DatabaseContextExprBase a
AddNotification RelVarName
name RelationalExpr
triggerExpr RelationalExpr
resultOldExpr RelationalExpr
resultNewExpr)

optimizeGraphRefDatabaseContextExpr notif :: GraphRefDatabaseContextExpr
notif@(RemoveNotification RelVarName
_) = GraphRefDatabaseContextExpr
-> GraphRefSOptDatabaseContextExprM GraphRefDatabaseContextExpr
forall (f :: * -> *) a. Applicative f => a -> f a
pure GraphRefDatabaseContextExpr
notif

optimizeGraphRefDatabaseContextExpr c :: GraphRefDatabaseContextExpr
c@(AddTypeConstructor TypeConstructorDef
_ [DataConstructorDef]
_) = GraphRefDatabaseContextExpr
-> GraphRefSOptDatabaseContextExprM GraphRefDatabaseContextExpr
forall (f :: * -> *) a. Applicative f => a -> f a
pure GraphRefDatabaseContextExpr
c
optimizeGraphRefDatabaseContextExpr c :: GraphRefDatabaseContextExpr
c@(RemoveTypeConstructor RelVarName
_) = GraphRefDatabaseContextExpr
-> GraphRefSOptDatabaseContextExprM GraphRefDatabaseContextExpr
forall (f :: * -> *) a. Applicative f => a -> f a
pure GraphRefDatabaseContextExpr
c
optimizeGraphRefDatabaseContextExpr c :: GraphRefDatabaseContextExpr
c@(RemoveAtomFunction RelVarName
_) = GraphRefDatabaseContextExpr
-> GraphRefSOptDatabaseContextExprM GraphRefDatabaseContextExpr
forall (f :: * -> *) a. Applicative f => a -> f a
pure GraphRefDatabaseContextExpr
c
optimizeGraphRefDatabaseContextExpr c :: GraphRefDatabaseContextExpr
c@(RemoveDatabaseContextFunction RelVarName
_) = GraphRefDatabaseContextExpr
-> GraphRefSOptDatabaseContextExprM GraphRefDatabaseContextExpr
forall (f :: * -> *) a. Applicative f => a -> f a
pure GraphRefDatabaseContextExpr
c
optimizeGraphRefDatabaseContextExpr c :: GraphRefDatabaseContextExpr
c@(ExecuteDatabaseContextFunction RelVarName
_ [AtomExprBase GraphRefTransactionMarker]
_) = GraphRefDatabaseContextExpr
-> GraphRefSOptDatabaseContextExprM GraphRefDatabaseContextExpr
forall (f :: * -> *) a. Applicative f => a -> f a
pure GraphRefDatabaseContextExpr
c

--optimization: from pgsql lists- check for join condition referencing foreign key- if join projection project away the referenced table, then it does not need to be scanned

--applyStaticDatabaseOptimization (MultipleExpr exprs) = pure $ Right $ MultipleExpr exprs
--for multiple expressions, we must evaluate
optimizeGraphRefDatabaseContextExpr (MultipleExpr [GraphRefDatabaseContextExpr]
exprs) = do
  --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
  DatabaseContext
context <- ReaderT
  GraphRefSOptDatabaseContextExprEnv
  (ExceptT RelationalError Identity)
  DatabaseContext
forall (m :: * -> *). AskGraphContext m => m DatabaseContext
askContext
  TransactionGraph
graph <- ReaderT
  GraphRefSOptDatabaseContextExprEnv
  (ExceptT RelationalError Identity)
  TransactionGraph
forall (m :: * -> *). AskGraphContext m => m TransactionGraph
askGraph
  TransactionId
parentId <- GraphRefSOptDatabaseContextExprM TransactionId
askTransId
  
  let emptyRvs :: DatabaseContext -> DatabaseContext
emptyRvs DatabaseContext
ctx = DatabaseContext
ctx { relationVariables :: RelationVariables
relationVariables = RelationVariables -> RelationVariables
mkEmptyRelVars (DatabaseContext -> RelationVariables
relationVariables DatabaseContext
ctx) }
      dbcEnv :: DatabaseContextEvalEnv
dbcEnv = TransactionId -> TransactionGraph -> DatabaseContextEvalEnv
mkDatabaseContextEvalEnv TransactionId
parentId TransactionGraph
graph
      folder :: (DatabaseContext, [GraphRefDatabaseContextExpr])
-> GraphRefDatabaseContextExpr
-> m (DatabaseContext, [GraphRefDatabaseContextExpr])
folder (DatabaseContext
ctx, [GraphRefDatabaseContextExpr]
expracc) GraphRefDatabaseContextExpr
expr = do
        --optimize the expr and run it against empty relvars to add it to the context
        case TransactionId
-> DatabaseContext
-> TransactionGraph
-> GraphRefSOptDatabaseContextExprM GraphRefDatabaseContextExpr
-> Either RelationalError GraphRefDatabaseContextExpr
forall a.
TransactionId
-> DatabaseContext
-> TransactionGraph
-> GraphRefSOptDatabaseContextExprM a
-> Either RelationalError a
runGraphRefSOptDatabaseContextExprM TransactionId
parentId DatabaseContext
ctx TransactionGraph
graph (GraphRefDatabaseContextExpr
-> GraphRefSOptDatabaseContextExprM GraphRefDatabaseContextExpr
optimizeGraphRefDatabaseContextExpr GraphRefDatabaseContextExpr
expr) of
          Left RelationalError
err -> RelationalError
-> m (DatabaseContext, [GraphRefDatabaseContextExpr])
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError RelationalError
err
          Right GraphRefDatabaseContextExpr
optExpr ->
            case DatabaseContext
-> DatabaseContextEvalEnv
-> DatabaseContextEvalMonad ()
-> Either RelationalError DatabaseContextEvalState
runDatabaseContextEvalMonad DatabaseContext
ctx DatabaseContextEvalEnv
dbcEnv (GraphRefDatabaseContextExpr -> DatabaseContextEvalMonad ()
evalGraphRefDatabaseContextExpr GraphRefDatabaseContextExpr
optExpr) of
              Left RelationalError
err -> RelationalError
-> m (DatabaseContext, [GraphRefDatabaseContextExpr])
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError RelationalError
err
              Right DatabaseContextEvalState
dbcState ->
                (DatabaseContext, [GraphRefDatabaseContextExpr])
-> m (DatabaseContext, [GraphRefDatabaseContextExpr])
forall (f :: * -> *) a. Applicative f => a -> f a
pure (DatabaseContext -> DatabaseContext
emptyRvs (DatabaseContext -> DatabaseContext)
-> DatabaseContext -> DatabaseContext
forall a b. (a -> b) -> a -> b
$ DatabaseContextEvalState -> DatabaseContext
dbc_context DatabaseContextEvalState
dbcState, [GraphRefDatabaseContextExpr]
expracc [GraphRefDatabaseContextExpr]
-> [GraphRefDatabaseContextExpr] -> [GraphRefDatabaseContextExpr]
forall a. [a] -> [a] -> [a]
++ [GraphRefDatabaseContextExpr
optExpr])

  (DatabaseContext
_, [GraphRefDatabaseContextExpr]
exprs') <- ((DatabaseContext, [GraphRefDatabaseContextExpr])
 -> GraphRefDatabaseContextExpr
 -> ReaderT
      GraphRefSOptDatabaseContextExprEnv
      (ExceptT RelationalError Identity)
      (DatabaseContext, [GraphRefDatabaseContextExpr]))
-> (DatabaseContext, [GraphRefDatabaseContextExpr])
-> [GraphRefDatabaseContextExpr]
-> ReaderT
     GraphRefSOptDatabaseContextExprEnv
     (ExceptT RelationalError Identity)
     (DatabaseContext, [GraphRefDatabaseContextExpr])
forall (t :: * -> *) (m :: * -> *) b a.
(Foldable t, Monad m) =>
(b -> a -> m b) -> b -> t a -> m b
foldM (DatabaseContext, [GraphRefDatabaseContextExpr])
-> GraphRefDatabaseContextExpr
-> ReaderT
     GraphRefSOptDatabaseContextExprEnv
     (ExceptT RelationalError Identity)
     (DatabaseContext, [GraphRefDatabaseContextExpr])
forall (m :: * -> *).
MonadError RelationalError m =>
(DatabaseContext, [GraphRefDatabaseContextExpr])
-> GraphRefDatabaseContextExpr
-> m (DatabaseContext, [GraphRefDatabaseContextExpr])
folder (DatabaseContext
context,[]) [GraphRefDatabaseContextExpr]
exprs
  GraphRefDatabaseContextExpr
-> GraphRefSOptDatabaseContextExprM GraphRefDatabaseContextExpr
forall (f :: * -> *) a. Applicative f => a -> f a
pure ([GraphRefDatabaseContextExpr] -> GraphRefDatabaseContextExpr
forall a. [DatabaseContextExprBase a] -> DatabaseContextExprBase a
MultipleExpr [GraphRefDatabaseContextExpr]
exprs')

applyStaticPredicateOptimization :: GraphRefRestrictionPredicateExpr -> GraphRefSOptRelationalExprM GraphRefRestrictionPredicateExpr
applyStaticPredicateOptimization :: RestrictionPredicateExprBase GraphRefTransactionMarker
-> GraphRefSOptRelationalExprM
     (RestrictionPredicateExprBase GraphRefTransactionMarker)
applyStaticPredicateOptimization RestrictionPredicateExprBase GraphRefTransactionMarker
predi = do
  RestrictionPredicateExprBase GraphRefTransactionMarker
optPred <- case RestrictionPredicateExprBase GraphRefTransactionMarker
predi of 
-- where x and x => where x
    AndPredicate RestrictionPredicateExprBase GraphRefTransactionMarker
pred1 RestrictionPredicateExprBase GraphRefTransactionMarker
pred2 -> do
      RestrictionPredicateExprBase GraphRefTransactionMarker
optPredA <- RestrictionPredicateExprBase GraphRefTransactionMarker
-> GraphRefSOptRelationalExprM
     (RestrictionPredicateExprBase GraphRefTransactionMarker)
applyStaticPredicateOptimization RestrictionPredicateExprBase GraphRefTransactionMarker
pred1
      RestrictionPredicateExprBase GraphRefTransactionMarker
optPredB <- RestrictionPredicateExprBase GraphRefTransactionMarker
-> GraphRefSOptRelationalExprM
     (RestrictionPredicateExprBase GraphRefTransactionMarker)
applyStaticPredicateOptimization RestrictionPredicateExprBase GraphRefTransactionMarker
pred2
      if RestrictionPredicateExprBase GraphRefTransactionMarker
optPredA RestrictionPredicateExprBase GraphRefTransactionMarker
-> RestrictionPredicateExprBase GraphRefTransactionMarker -> Bool
forall a. Eq a => a -> a -> Bool
== RestrictionPredicateExprBase GraphRefTransactionMarker
optPredB then
        RestrictionPredicateExprBase GraphRefTransactionMarker
-> GraphRefSOptRelationalExprM
     (RestrictionPredicateExprBase GraphRefTransactionMarker)
forall (f :: * -> *) a. Applicative f => a -> f a
pure RestrictionPredicateExprBase GraphRefTransactionMarker
optPredA
        else
        RestrictionPredicateExprBase GraphRefTransactionMarker
-> GraphRefSOptRelationalExprM
     (RestrictionPredicateExprBase GraphRefTransactionMarker)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (RestrictionPredicateExprBase GraphRefTransactionMarker
-> RestrictionPredicateExprBase GraphRefTransactionMarker
-> RestrictionPredicateExprBase GraphRefTransactionMarker
forall a.
RestrictionPredicateExprBase a
-> RestrictionPredicateExprBase a -> RestrictionPredicateExprBase a
AndPredicate RestrictionPredicateExprBase GraphRefTransactionMarker
optPredA RestrictionPredicateExprBase GraphRefTransactionMarker
optPredB)
-- where x or x => where x    
    OrPredicate RestrictionPredicateExprBase GraphRefTransactionMarker
pred1 RestrictionPredicateExprBase GraphRefTransactionMarker
pred2 -> do
      RestrictionPredicateExprBase GraphRefTransactionMarker
optPredA <- RestrictionPredicateExprBase GraphRefTransactionMarker
-> GraphRefSOptRelationalExprM
     (RestrictionPredicateExprBase GraphRefTransactionMarker)
applyStaticPredicateOptimization RestrictionPredicateExprBase GraphRefTransactionMarker
pred1
      RestrictionPredicateExprBase GraphRefTransactionMarker
optPredB <- RestrictionPredicateExprBase GraphRefTransactionMarker
-> GraphRefSOptRelationalExprM
     (RestrictionPredicateExprBase GraphRefTransactionMarker)
applyStaticPredicateOptimization RestrictionPredicateExprBase GraphRefTransactionMarker
pred2
      if (RestrictionPredicateExprBase GraphRefTransactionMarker
optPredA RestrictionPredicateExprBase GraphRefTransactionMarker
-> RestrictionPredicateExprBase GraphRefTransactionMarker -> Bool
forall a. Eq a => a -> a -> Bool
== RestrictionPredicateExprBase GraphRefTransactionMarker
optPredB) Bool -> Bool -> Bool
|| RestrictionPredicateExprBase GraphRefTransactionMarker -> Bool
forall a. RestrictionPredicateExprBase a -> Bool
isTrueExpr RestrictionPredicateExprBase GraphRefTransactionMarker
optPredA then
        RestrictionPredicateExprBase GraphRefTransactionMarker
-> GraphRefSOptRelationalExprM
     (RestrictionPredicateExprBase GraphRefTransactionMarker)
forall (f :: * -> *) a. Applicative f => a -> f a
pure RestrictionPredicateExprBase GraphRefTransactionMarker
optPredA
        else if RestrictionPredicateExprBase GraphRefTransactionMarker -> Bool
forall a. RestrictionPredicateExprBase a -> Bool
isTrueExpr RestrictionPredicateExprBase GraphRefTransactionMarker
optPredB then
               RestrictionPredicateExprBase GraphRefTransactionMarker
-> GraphRefSOptRelationalExprM
     (RestrictionPredicateExprBase GraphRefTransactionMarker)
forall (f :: * -> *) a. Applicative f => a -> f a
pure RestrictionPredicateExprBase GraphRefTransactionMarker
optPredB
             else
               RestrictionPredicateExprBase GraphRefTransactionMarker
-> GraphRefSOptRelationalExprM
     (RestrictionPredicateExprBase GraphRefTransactionMarker)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (RestrictionPredicateExprBase GraphRefTransactionMarker
-> RestrictionPredicateExprBase GraphRefTransactionMarker
-> RestrictionPredicateExprBase GraphRefTransactionMarker
forall a.
RestrictionPredicateExprBase a
-> RestrictionPredicateExprBase a -> RestrictionPredicateExprBase a
OrPredicate RestrictionPredicateExprBase GraphRefTransactionMarker
optPredA RestrictionPredicateExprBase GraphRefTransactionMarker
optPredB)
    AttributeEqualityPredicate RelVarName
attrNameA (AttributeAtomExpr RelVarName
attrNameB) ->
      if RelVarName
attrNameA RelVarName -> RelVarName -> Bool
forall a. Eq a => a -> a -> Bool
== RelVarName
attrNameB then
        RestrictionPredicateExprBase GraphRefTransactionMarker
-> GraphRefSOptRelationalExprM
     (RestrictionPredicateExprBase GraphRefTransactionMarker)
forall (f :: * -> *) a. Applicative f => a -> f a
pure RestrictionPredicateExprBase GraphRefTransactionMarker
forall a. RestrictionPredicateExprBase a
TruePredicate
      else
        RestrictionPredicateExprBase GraphRefTransactionMarker
-> GraphRefSOptRelationalExprM
     (RestrictionPredicateExprBase GraphRefTransactionMarker)
forall (f :: * -> *) a. Applicative f => a -> f a
pure RestrictionPredicateExprBase GraphRefTransactionMarker
predi
    AttributeEqualityPredicate{} -> RestrictionPredicateExprBase GraphRefTransactionMarker
-> GraphRefSOptRelationalExprM
     (RestrictionPredicateExprBase GraphRefTransactionMarker)
forall (f :: * -> *) a. Applicative f => a -> f a
pure RestrictionPredicateExprBase GraphRefTransactionMarker
predi
    RestrictionPredicateExprBase GraphRefTransactionMarker
TruePredicate -> RestrictionPredicateExprBase GraphRefTransactionMarker
-> GraphRefSOptRelationalExprM
     (RestrictionPredicateExprBase GraphRefTransactionMarker)
forall (f :: * -> *) a. Applicative f => a -> f a
pure RestrictionPredicateExprBase GraphRefTransactionMarker
predi
    NotPredicate{} -> RestrictionPredicateExprBase GraphRefTransactionMarker
-> GraphRefSOptRelationalExprM
     (RestrictionPredicateExprBase GraphRefTransactionMarker)
forall (f :: * -> *) a. Applicative f => a -> f a
pure RestrictionPredicateExprBase GraphRefTransactionMarker
predi
    RelationalExprPredicate{} -> RestrictionPredicateExprBase GraphRefTransactionMarker
-> GraphRefSOptRelationalExprM
     (RestrictionPredicateExprBase GraphRefTransactionMarker)
forall (f :: * -> *) a. Applicative f => a -> f a
pure RestrictionPredicateExprBase GraphRefTransactionMarker
predi
    AtomExprPredicate{} -> RestrictionPredicateExprBase GraphRefTransactionMarker
-> GraphRefSOptRelationalExprM
     (RestrictionPredicateExprBase GraphRefTransactionMarker)
forall (f :: * -> *) a. Applicative f => a -> f a
pure RestrictionPredicateExprBase GraphRefTransactionMarker
predi
  let attrMap :: Map RelVarName (AtomExprBase GraphRefTransactionMarker)
attrMap = RestrictionPredicateExprBase GraphRefTransactionMarker
-> Map RelVarName (AtomExprBase GraphRefTransactionMarker)
findStaticRestrictionPredicates RestrictionPredicateExprBase GraphRefTransactionMarker
optPred
  RestrictionPredicateExprBase GraphRefTransactionMarker
-> GraphRefSOptRelationalExprM
     (RestrictionPredicateExprBase GraphRefTransactionMarker)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (RestrictionPredicateExprBase GraphRefTransactionMarker
-> Map RelVarName (AtomExprBase GraphRefTransactionMarker)
-> RestrictionPredicateExprBase GraphRefTransactionMarker
replaceStaticAtomExprs RestrictionPredicateExprBase GraphRefTransactionMarker
optPred Map RelVarName (AtomExprBase GraphRefTransactionMarker)
attrMap)

--determines if an atom expression is tautologically true
isTrueExpr :: RestrictionPredicateExprBase a -> Bool
isTrueExpr :: RestrictionPredicateExprBase a -> Bool
isTrueExpr RestrictionPredicateExprBase a
TruePredicate = Bool
True
isTrueExpr (AtomExprPredicate (NakedAtomExpr (BoolAtom Bool
True))) = Bool
True
isTrueExpr RestrictionPredicateExprBase a
_ = Bool
False

--determines if an atom expression is tautologically false
isFalseExpr :: RestrictionPredicateExprBase a -> Bool
isFalseExpr :: RestrictionPredicateExprBase a -> Bool
isFalseExpr (NotPredicate RestrictionPredicateExprBase a
expr) = RestrictionPredicateExprBase a -> Bool
forall a. RestrictionPredicateExprBase a -> Bool
isTrueExpr RestrictionPredicateExprBase a
expr
isFalseExpr (AtomExprPredicate (NakedAtomExpr (BoolAtom Bool
False))) = Bool
True
isFalseExpr RestrictionPredicateExprBase a
_ = Bool
False

-- determine if the created relation can statically be determined to be empty
isEmptyRelationExpr :: RelationalExprBase a -> Bool    
isEmptyRelationExpr :: RelationalExprBase a -> Bool
isEmptyRelationExpr (MakeRelationFromExprs Maybe [AttributeExprBase a]
_ (TupleExprs a
_ [])) = Bool
True
isEmptyRelationExpr (MakeStaticRelation Attributes
_ RelationTupleSet
tupSet) = [RelationTuple] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null (RelationTupleSet -> [RelationTuple]
asList RelationTupleSet
tupSet)
isEmptyRelationExpr (ExistingRelation Relation
rel) = Relation
rel Relation -> Relation -> Bool
forall a. Eq a => a -> a -> Bool
== Attributes -> Relation
emptyRelationWithAttrs (Relation -> Attributes
attributes Relation
rel)
isEmptyRelationExpr RelationalExprBase a
_ = Bool
False
    
--transitive static variable optimization                        
replaceStaticAtomExprs :: GraphRefRestrictionPredicateExpr -> M.Map AttributeName GraphRefAtomExpr -> GraphRefRestrictionPredicateExpr
replaceStaticAtomExprs :: RestrictionPredicateExprBase GraphRefTransactionMarker
-> Map RelVarName (AtomExprBase GraphRefTransactionMarker)
-> RestrictionPredicateExprBase GraphRefTransactionMarker
replaceStaticAtomExprs RestrictionPredicateExprBase GraphRefTransactionMarker
predIn Map RelVarName (AtomExprBase GraphRefTransactionMarker)
replaceMap = case RestrictionPredicateExprBase GraphRefTransactionMarker
predIn of
  AttributeEqualityPredicate RelVarName
newAttrName (AttributeAtomExpr RelVarName
matchName) -> case RelVarName
-> Map RelVarName (AtomExprBase GraphRefTransactionMarker)
-> Maybe (AtomExprBase GraphRefTransactionMarker)
forall k a. Ord k => k -> Map k a -> Maybe a
M.lookup RelVarName
matchName Map RelVarName (AtomExprBase GraphRefTransactionMarker)
replaceMap of
    Maybe (AtomExprBase GraphRefTransactionMarker)
Nothing -> RestrictionPredicateExprBase GraphRefTransactionMarker
predIn
    Just AtomExprBase GraphRefTransactionMarker
newVal -> RelVarName
-> AtomExprBase GraphRefTransactionMarker
-> RestrictionPredicateExprBase GraphRefTransactionMarker
forall a.
RelVarName -> AtomExprBase a -> RestrictionPredicateExprBase a
AttributeEqualityPredicate RelVarName
newAttrName AtomExprBase GraphRefTransactionMarker
newVal
  AttributeEqualityPredicate{} -> RestrictionPredicateExprBase GraphRefTransactionMarker
predIn
  AndPredicate RestrictionPredicateExprBase GraphRefTransactionMarker
pred1 RestrictionPredicateExprBase GraphRefTransactionMarker
pred2 -> RestrictionPredicateExprBase GraphRefTransactionMarker
-> RestrictionPredicateExprBase GraphRefTransactionMarker
-> RestrictionPredicateExprBase GraphRefTransactionMarker
forall a.
RestrictionPredicateExprBase a
-> RestrictionPredicateExprBase a -> RestrictionPredicateExprBase a
AndPredicate (RestrictionPredicateExprBase GraphRefTransactionMarker
-> Map RelVarName (AtomExprBase GraphRefTransactionMarker)
-> RestrictionPredicateExprBase GraphRefTransactionMarker
replaceStaticAtomExprs RestrictionPredicateExprBase GraphRefTransactionMarker
pred1 Map RelVarName (AtomExprBase GraphRefTransactionMarker)
replaceMap) (RestrictionPredicateExprBase GraphRefTransactionMarker
-> Map RelVarName (AtomExprBase GraphRefTransactionMarker)
-> RestrictionPredicateExprBase GraphRefTransactionMarker
replaceStaticAtomExprs RestrictionPredicateExprBase GraphRefTransactionMarker
pred2 Map RelVarName (AtomExprBase GraphRefTransactionMarker)
replaceMap)
  OrPredicate RestrictionPredicateExprBase GraphRefTransactionMarker
pred1 RestrictionPredicateExprBase GraphRefTransactionMarker
pred2 -> RestrictionPredicateExprBase GraphRefTransactionMarker
-> RestrictionPredicateExprBase GraphRefTransactionMarker
-> RestrictionPredicateExprBase GraphRefTransactionMarker
forall a.
RestrictionPredicateExprBase a
-> RestrictionPredicateExprBase a -> RestrictionPredicateExprBase a
OrPredicate (RestrictionPredicateExprBase GraphRefTransactionMarker
-> Map RelVarName (AtomExprBase GraphRefTransactionMarker)
-> RestrictionPredicateExprBase GraphRefTransactionMarker
replaceStaticAtomExprs RestrictionPredicateExprBase GraphRefTransactionMarker
pred1 Map RelVarName (AtomExprBase GraphRefTransactionMarker)
replaceMap) (RestrictionPredicateExprBase GraphRefTransactionMarker
-> Map RelVarName (AtomExprBase GraphRefTransactionMarker)
-> RestrictionPredicateExprBase GraphRefTransactionMarker
replaceStaticAtomExprs RestrictionPredicateExprBase GraphRefTransactionMarker
pred2 Map RelVarName (AtomExprBase GraphRefTransactionMarker)
replaceMap)
  NotPredicate RestrictionPredicateExprBase GraphRefTransactionMarker
pred1 -> RestrictionPredicateExprBase GraphRefTransactionMarker
-> RestrictionPredicateExprBase GraphRefTransactionMarker
forall a.
RestrictionPredicateExprBase a -> RestrictionPredicateExprBase a
NotPredicate (RestrictionPredicateExprBase GraphRefTransactionMarker
-> Map RelVarName (AtomExprBase GraphRefTransactionMarker)
-> RestrictionPredicateExprBase GraphRefTransactionMarker
replaceStaticAtomExprs RestrictionPredicateExprBase GraphRefTransactionMarker
pred1 Map RelVarName (AtomExprBase GraphRefTransactionMarker)
replaceMap)
  RestrictionPredicateExprBase GraphRefTransactionMarker
TruePredicate -> RestrictionPredicateExprBase GraphRefTransactionMarker
predIn
  RelationalExprPredicate{} -> RestrictionPredicateExprBase GraphRefTransactionMarker
predIn
  AtomExprPredicate{} -> RestrictionPredicateExprBase GraphRefTransactionMarker
predIn
-- used for transitive attribute optimization- only works on statically-determined atoms for now- in the future, this could work for all AtomExprs which don't reference attributes
findStaticRestrictionPredicates :: GraphRefRestrictionPredicateExpr -> M.Map AttributeName GraphRefAtomExpr
findStaticRestrictionPredicates :: RestrictionPredicateExprBase GraphRefTransactionMarker
-> Map RelVarName (AtomExprBase GraphRefTransactionMarker)
findStaticRestrictionPredicates (AttributeEqualityPredicate RelVarName
attrName AtomExprBase GraphRefTransactionMarker
atomExpr) = 
  case AtomExprBase GraphRefTransactionMarker
atomExpr of
    val :: AtomExprBase GraphRefTransactionMarker
val@NakedAtomExpr{} -> RelVarName
-> AtomExprBase GraphRefTransactionMarker
-> Map RelVarName (AtomExprBase GraphRefTransactionMarker)
forall k a. k -> a -> Map k a
M.singleton RelVarName
attrName AtomExprBase GraphRefTransactionMarker
val
    val :: AtomExprBase GraphRefTransactionMarker
val@ConstructedAtomExpr{} -> RelVarName
-> AtomExprBase GraphRefTransactionMarker
-> Map RelVarName (AtomExprBase GraphRefTransactionMarker)
forall k a. k -> a -> Map k a
M.singleton RelVarName
attrName AtomExprBase GraphRefTransactionMarker
val
    AtomExprBase GraphRefTransactionMarker
_ -> Map RelVarName (AtomExprBase GraphRefTransactionMarker)
forall k a. Map k a
M.empty

findStaticRestrictionPredicates (AndPredicate RestrictionPredicateExprBase GraphRefTransactionMarker
pred1 RestrictionPredicateExprBase GraphRefTransactionMarker
pred2) = 
  Map RelVarName (AtomExprBase GraphRefTransactionMarker)
-> Map RelVarName (AtomExprBase GraphRefTransactionMarker)
-> Map RelVarName (AtomExprBase GraphRefTransactionMarker)
forall k a. Ord k => Map k a -> Map k a -> Map k a
M.union (RestrictionPredicateExprBase GraphRefTransactionMarker
-> Map RelVarName (AtomExprBase GraphRefTransactionMarker)
findStaticRestrictionPredicates RestrictionPredicateExprBase GraphRefTransactionMarker
pred1) (RestrictionPredicateExprBase GraphRefTransactionMarker
-> Map RelVarName (AtomExprBase GraphRefTransactionMarker)
findStaticRestrictionPredicates RestrictionPredicateExprBase GraphRefTransactionMarker
pred2) 
findStaticRestrictionPredicates (OrPredicate RestrictionPredicateExprBase GraphRefTransactionMarker
pred1 RestrictionPredicateExprBase GraphRefTransactionMarker
pred2) =
  Map RelVarName (AtomExprBase GraphRefTransactionMarker)
-> Map RelVarName (AtomExprBase GraphRefTransactionMarker)
-> Map RelVarName (AtomExprBase GraphRefTransactionMarker)
forall k a. Ord k => Map k a -> Map k a -> Map k a
M.union (RestrictionPredicateExprBase GraphRefTransactionMarker
-> Map RelVarName (AtomExprBase GraphRefTransactionMarker)
findStaticRestrictionPredicates RestrictionPredicateExprBase GraphRefTransactionMarker
pred1) (RestrictionPredicateExprBase GraphRefTransactionMarker
-> Map RelVarName (AtomExprBase GraphRefTransactionMarker)
findStaticRestrictionPredicates RestrictionPredicateExprBase GraphRefTransactionMarker
pred2)
findStaticRestrictionPredicates (NotPredicate RestrictionPredicateExprBase GraphRefTransactionMarker
predi) = RestrictionPredicateExprBase GraphRefTransactionMarker
-> Map RelVarName (AtomExprBase GraphRefTransactionMarker)
findStaticRestrictionPredicates RestrictionPredicateExprBase GraphRefTransactionMarker
predi
findStaticRestrictionPredicates RestrictionPredicateExprBase GraphRefTransactionMarker
TruePredicate = Map RelVarName (AtomExprBase GraphRefTransactionMarker)
forall k a. Map k a
M.empty
findStaticRestrictionPredicates RelationalExprPredicate{} = Map RelVarName (AtomExprBase GraphRefTransactionMarker)
forall k a. Map k a
M.empty
findStaticRestrictionPredicates AtomExprPredicate{} = Map RelVarName (AtomExprBase GraphRefTransactionMarker)
forall k a. Map k a
M.empty

isStaticAtomExpr :: AtomExpr -> Bool
isStaticAtomExpr :: AtomExpr -> Bool
isStaticAtomExpr NakedAtomExpr{} = Bool
True
isStaticAtomExpr ConstructedAtomExpr{} = Bool
True
isStaticAtomExpr AttributeAtomExpr{} = Bool
False
isStaticAtomExpr FunctionAtomExpr{} = Bool
False
isStaticAtomExpr RelationAtomExpr{} = Bool
False

--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
applyStaticJoinElimination :: GraphRefRelationalExpr -> GraphRefSOptRelationalExprM GraphRefRelationalExpr
applyStaticJoinElimination :: GraphRefRelationalExpr
-> GraphRefSOptRelationalExprM GraphRefRelationalExpr
applyStaticJoinElimination expr :: GraphRefRelationalExpr
expr@(Project AttributeNamesBase GraphRefTransactionMarker
attrNameSet (Join GraphRefRelationalExpr
exprA GraphRefRelationalExpr
exprB)) = do
  TransactionGraph
graph <- ReaderT
  GraphRefSOptRelationalExprEnv
  (ExceptT RelationalError Identity)
  TransactionGraph
forall (m :: * -> *). AskGraphContext m => m TransactionGraph
askGraph
  case GraphRefRelationalExpr
-> GraphRefRelationalExpr -> Maybe GraphRefTransactionMarker
inSameTransaction GraphRefRelationalExpr
exprA GraphRefRelationalExpr
exprB of
    -- the sub exprs are in different transactions or none at all, so we cannot extract inclusion dependencies across transaction boundaries
    Maybe GraphRefTransactionMarker
Nothing -> GraphRefRelationalExpr
-> GraphRefSOptRelationalExprM GraphRefRelationalExpr
forall (f :: * -> *) a. Applicative f => a -> f a
pure GraphRefRelationalExpr
expr
    Just GraphRefTransactionMarker
marker -> do
      DatabaseContext
commonContext <- case GraphRefTransactionMarker
marker of
                         GraphRefTransactionMarker
UncommittedContextMarker -> ReaderT
  GraphRefSOptRelationalExprEnv
  (ExceptT RelationalError Identity)
  DatabaseContext
forall (m :: * -> *). AskGraphContext m => m DatabaseContext
askContext
                         TransactionMarker TransactionId
tid -> Transaction -> DatabaseContext
concreteDatabaseContext (Transaction -> DatabaseContext)
-> ReaderT
     GraphRefSOptRelationalExprEnv
     (ExceptT RelationalError Identity)
     Transaction
-> ReaderT
     GraphRefSOptRelationalExprEnv
     (ExceptT RelationalError Identity)
     DatabaseContext
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ExceptT RelationalError Identity Transaction
-> ReaderT
     GraphRefSOptRelationalExprEnv
     (ExceptT RelationalError Identity)
     Transaction
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (Either RelationalError Transaction
-> ExceptT RelationalError Identity Transaction
forall (m :: * -> *) e a. Monad m => Either e a -> ExceptT e m a
except (TransactionId
-> TransactionGraph -> Either RelationalError Transaction
transactionForId TransactionId
tid TransactionGraph
graph))
      let typeForExpr :: GraphRefRelationalExpr -> t (ExceptT RelationalError m) Relation
typeForExpr GraphRefRelationalExpr
e = ExceptT RelationalError m Relation
-> t (ExceptT RelationalError m) Relation
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (ExceptT RelationalError m Relation
 -> t (ExceptT RelationalError m) Relation)
-> ExceptT RelationalError m Relation
-> t (ExceptT RelationalError m) Relation
forall a b. (a -> b) -> a -> b
$ Either RelationalError Relation
-> ExceptT RelationalError m Relation
forall (m :: * -> *) e a. Monad m => Either e a -> ExceptT e m a
except (Either RelationalError Relation
 -> ExceptT RelationalError m Relation)
-> Either RelationalError Relation
-> ExceptT RelationalError m Relation
forall a b. (a -> b) -> a -> b
$ GraphRefRelationalExprEnv
-> GraphRefRelationalExprM Relation
-> Either RelationalError Relation
forall a.
GraphRefRelationalExprEnv
-> GraphRefRelationalExprM a -> Either RelationalError a
runGraphRefRelationalExprM GraphRefRelationalExprEnv
gfEnv (GraphRefRelationalExpr -> GraphRefRelationalExprM Relation
typeForGraphRefRelationalExpr GraphRefRelationalExpr
e)
          gfEnv :: GraphRefRelationalExprEnv
gfEnv = Maybe DatabaseContext
-> TransactionGraph -> GraphRefRelationalExprEnv
freshGraphRefRelationalExprEnv (DatabaseContext -> Maybe DatabaseContext
forall a. a -> Maybe a
Just DatabaseContext
commonContext) TransactionGraph
graph
        
      Relation
projType <- GraphRefRelationalExpr
-> ReaderT
     GraphRefSOptRelationalExprEnv
     (ExceptT RelationalError Identity)
     Relation
forall (t :: (* -> *) -> * -> *) (m :: * -> *).
(MonadTrans t, Monad m) =>
GraphRefRelationalExpr -> t (ExceptT RelationalError m) Relation
typeForExpr GraphRefRelationalExpr
expr
      Relation
typeA <- GraphRefRelationalExpr
-> ReaderT
     GraphRefSOptRelationalExprEnv
     (ExceptT RelationalError Identity)
     Relation
forall (t :: (* -> *) -> * -> *) (m :: * -> *).
(MonadTrans t, Monad m) =>
GraphRefRelationalExpr -> t (ExceptT RelationalError m) Relation
typeForExpr GraphRefRelationalExpr
exprA
      Relation
typeB <- GraphRefRelationalExpr
-> ReaderT
     GraphRefSOptRelationalExprEnv
     (ExceptT RelationalError Identity)
     Relation
forall (t :: (* -> *) -> * -> *) (m :: * -> *).
(MonadTrans t, Monad m) =>
GraphRefRelationalExpr -> t (ExceptT RelationalError m) Relation
typeForExpr GraphRefRelationalExpr
exprB
      let matchesProjectionAttributes :: Maybe
  ((GraphRefRelationalExpr, Relation),
   (GraphRefRelationalExpr, Relation))
matchesProjectionAttributes 
            | Relation -> Set RelVarName
attrNames Relation
projType Set RelVarName -> Set RelVarName -> Bool
forall a. Ord a => Set a -> Set a -> Bool
`S.isSubsetOf` Relation -> Set RelVarName
attrNames Relation
typeA =
                ((GraphRefRelationalExpr, Relation),
 (GraphRefRelationalExpr, Relation))
-> Maybe
     ((GraphRefRelationalExpr, Relation),
      (GraphRefRelationalExpr, Relation))
forall a. a -> Maybe a
Just ((GraphRefRelationalExpr
exprA, Relation
typeA), (GraphRefRelationalExpr
exprB, Relation
typeB))
            | Relation -> Set RelVarName
attrNames Relation
projType Set RelVarName -> Set RelVarName -> Bool
forall a. Ord a => Set a -> Set a -> Bool
`S.isSubsetOf` Relation -> Set RelVarName
attrNames Relation
typeB =
                ((GraphRefRelationalExpr, Relation),
 (GraphRefRelationalExpr, Relation))
-> Maybe
     ((GraphRefRelationalExpr, Relation),
      (GraphRefRelationalExpr, Relation))
forall a. a -> Maybe a
Just ((GraphRefRelationalExpr
exprB, Relation
typeB), (GraphRefRelationalExpr
exprA, Relation
typeA))
            | Bool
otherwise =
                Maybe
  ((GraphRefRelationalExpr, Relation),
   (GraphRefRelationalExpr, Relation))
forall a. Maybe a
Nothing
          attrNames :: Relation -> Set RelVarName
attrNames = Attributes -> Set RelVarName
A.attributeNameSet (Attributes -> Set RelVarName)
-> (Relation -> Attributes) -> Relation -> Set RelVarName
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Relation -> Attributes
attributes
      case Maybe
  ((GraphRefRelationalExpr, Relation),
   (GraphRefRelationalExpr, Relation))
matchesProjectionAttributes of
        Maybe
  ((GraphRefRelationalExpr, Relation),
   (GraphRefRelationalExpr, Relation))
Nothing ->  -- this optimization does not apply
          GraphRefRelationalExpr
-> GraphRefSOptRelationalExprM GraphRefRelationalExpr
forall (f :: * -> *) a. Applicative f => a -> f a
pure GraphRefRelationalExpr
expr
        Just ((GraphRefRelationalExpr
joinedExpr, Relation
joinedType), (GraphRefRelationalExpr
unjoinedExpr, Relation
_)) -> do
        --lookup transaction
        --scan inclusion dependencies for a foreign key relationship
         let incDeps :: InclusionDependencies
incDeps = DatabaseContext -> InclusionDependencies
inclusionDependencies DatabaseContext
commonContext
             fkConstraint :: Either RelationalError Bool
fkConstraint = (Bool -> InclusionDependency -> Either RelationalError Bool)
-> Bool -> InclusionDependencies -> Either RelationalError Bool
forall (t :: * -> *) (m :: * -> *) b a.
(Foldable t, Monad m) =>
(b -> a -> m b) -> b -> t a -> m b
foldM Bool -> InclusionDependency -> Either RelationalError Bool
forall (f :: * -> *).
Applicative f =>
Bool -> InclusionDependency -> f Bool
isFkConstraint Bool
False InclusionDependencies
incDeps
            --search for matching fk constraint
             isFkConstraint :: Bool -> InclusionDependency -> f Bool
isFkConstraint Bool
acc (InclusionDependency (Project AttributeNamesBase ()
subAttrNames RelationalExpr
subrv) (Project AttributeNamesBase ()
_ RelationalExpr
superrv)) = do
               let gfSubAttrNames :: AttributeNamesBase GraphRefTransactionMarker
gfSubAttrNames = ProcessExprM (AttributeNamesBase GraphRefTransactionMarker)
-> AttributeNamesBase GraphRefTransactionMarker
forall a. ProcessExprM a -> a
processM (AttributeNamesBase ()
-> ProcessExprM (AttributeNamesBase GraphRefTransactionMarker)
processAttributeNames AttributeNamesBase ()
subAttrNames)
                   gfSubRv :: GraphRefRelationalExpr
gfSubRv = ProcessExprM GraphRefRelationalExpr -> GraphRefRelationalExpr
forall a. ProcessExprM a -> a
processM (RelationalExpr -> ProcessExprM GraphRefRelationalExpr
processRelationalExpr RelationalExpr
subrv)
                   gfSuperRv :: GraphRefRelationalExpr
gfSuperRv = ProcessExprM GraphRefRelationalExpr -> GraphRefRelationalExpr
forall a. ProcessExprM a -> a
processM (RelationalExpr -> ProcessExprM GraphRefRelationalExpr
processRelationalExpr RelationalExpr
superrv)
                   processM :: ProcessExprM a -> a
processM = GraphRefTransactionMarker -> ProcessExprM a -> a
forall a. GraphRefTransactionMarker -> ProcessExprM a -> a
runProcessExprM GraphRefTransactionMarker
marker
               case GraphRefRelationalExprEnv
-> GraphRefRelationalExprM (Set RelVarName)
-> Either RelationalError (Set RelVarName)
forall a.
GraphRefRelationalExprEnv
-> GraphRefRelationalExprM a -> Either RelationalError a
runGraphRefRelationalExprM GraphRefRelationalExprEnv
gfEnv (AttributeNamesBase GraphRefTransactionMarker
-> GraphRefRelationalExpr
-> GraphRefRelationalExprM (Set RelVarName)
evalGraphRefAttributeNames AttributeNamesBase GraphRefTransactionMarker
gfSubAttrNames GraphRefRelationalExpr
expr) of
                 Left RelationalError
_ -> Bool -> f Bool
forall (f :: * -> *) a. Applicative f => a -> f a
pure Bool
acc
                 Right Set RelVarName
subAttrNameSet -> 
                   Bool -> f Bool
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Bool
acc Bool -> Bool -> Bool
|| (GraphRefRelationalExpr
joinedExpr GraphRefRelationalExpr -> GraphRefRelationalExpr -> Bool
forall a. Eq a => a -> a -> Bool
== GraphRefRelationalExpr
gfSubRv Bool -> Bool -> Bool
&&
                                 GraphRefRelationalExpr
unjoinedExpr GraphRefRelationalExpr -> GraphRefRelationalExpr -> Bool
forall a. Eq a => a -> a -> Bool
== GraphRefRelationalExpr
gfSuperRv Bool -> Bool -> Bool
&& 
                                 -- the fk attribute is one of the projection attributes
                                 Set RelVarName -> Set RelVarName -> Bool
A.attributeNamesContained Set RelVarName
subAttrNameSet (Attributes -> Set RelVarName
A.attributeNameSet (Relation -> Attributes
attributes Relation
joinedType))
                                ))
             isFkConstraint Bool
acc InclusionDependency
_ = Bool -> f Bool
forall (f :: * -> *) a. Applicative f => a -> f a
pure Bool
acc
         case Either RelationalError Bool
fkConstraint of
           Right Bool
True -> --join elimination optimization applies
             GraphRefRelationalExpr
-> GraphRefSOptRelationalExprM GraphRefRelationalExpr
optimizeGraphRefRelationalExpr (AttributeNamesBase GraphRefTransactionMarker
-> GraphRefRelationalExpr -> GraphRefRelationalExpr
forall a.
AttributeNamesBase a
-> RelationalExprBase a -> RelationalExprBase a
Project AttributeNamesBase GraphRefTransactionMarker
attrNameSet GraphRefRelationalExpr
joinedExpr)
           Right Bool
False -> --join elimination optimization does not apply
             GraphRefRelationalExpr
-> GraphRefSOptRelationalExprM GraphRefRelationalExpr
forall (f :: * -> *) a. Applicative f => a -> f a
pure GraphRefRelationalExpr
expr
           Left RelationalError
err -> RelationalError
-> GraphRefSOptRelationalExprM GraphRefRelationalExpr
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError RelationalError
err
          
applyStaticJoinElimination GraphRefRelationalExpr
expr = GraphRefRelationalExpr
-> GraphRefSOptRelationalExprM GraphRefRelationalExpr
forall (f :: * -> *) a. Applicative f => a -> f a
pure GraphRefRelationalExpr
expr
                                                                              
--restriction collapse converts chained restrictions into (Restrict (And pred1 pred2 pred3...))
  --this optimization should be fairly uncontroversial- performing a tuple scan once is cheaper than twice- parallelization can still take place
applyStaticRestrictionCollapse :: GraphRefRelationalExpr -> GraphRefRelationalExpr
applyStaticRestrictionCollapse :: GraphRefRelationalExpr -> GraphRefRelationalExpr
applyStaticRestrictionCollapse GraphRefRelationalExpr
expr = 
  case GraphRefRelationalExpr
expr of
    MakeRelationFromExprs Maybe [AttributeExprBase GraphRefTransactionMarker]
_ TupleExprsBase GraphRefTransactionMarker
_ -> GraphRefRelationalExpr
expr
    MakeStaticRelation Attributes
_ RelationTupleSet
_ -> GraphRefRelationalExpr
expr
    ExistingRelation Relation
_ -> GraphRefRelationalExpr
expr
    RelationVariable RelVarName
_ GraphRefTransactionMarker
_ -> GraphRefRelationalExpr
expr
    With [(WithNameExprBase GraphRefTransactionMarker,
  GraphRefRelationalExpr)]
_ GraphRefRelationalExpr
_ -> GraphRefRelationalExpr
expr
    Project AttributeNamesBase GraphRefTransactionMarker
attrs GraphRefRelationalExpr
subexpr -> 
      AttributeNamesBase GraphRefTransactionMarker
-> GraphRefRelationalExpr -> GraphRefRelationalExpr
forall a.
AttributeNamesBase a
-> RelationalExprBase a -> RelationalExprBase a
Project AttributeNamesBase GraphRefTransactionMarker
attrs (GraphRefRelationalExpr -> GraphRefRelationalExpr
applyStaticRestrictionCollapse GraphRefRelationalExpr
subexpr)
    Union GraphRefRelationalExpr
sub1 GraphRefRelationalExpr
sub2 ->
      GraphRefRelationalExpr
-> GraphRefRelationalExpr -> GraphRefRelationalExpr
forall a.
RelationalExprBase a
-> RelationalExprBase a -> RelationalExprBase a
Union (GraphRefRelationalExpr -> GraphRefRelationalExpr
applyStaticRestrictionCollapse GraphRefRelationalExpr
sub1) (GraphRefRelationalExpr -> GraphRefRelationalExpr
applyStaticRestrictionCollapse GraphRefRelationalExpr
sub2)    
    Join GraphRefRelationalExpr
sub1 GraphRefRelationalExpr
sub2 ->
      GraphRefRelationalExpr
-> GraphRefRelationalExpr -> GraphRefRelationalExpr
forall a.
RelationalExprBase a
-> RelationalExprBase a -> RelationalExprBase a
Join (GraphRefRelationalExpr -> GraphRefRelationalExpr
applyStaticRestrictionCollapse GraphRefRelationalExpr
sub1) (GraphRefRelationalExpr -> GraphRefRelationalExpr
applyStaticRestrictionCollapse GraphRefRelationalExpr
sub2)
    Rename RelVarName
n1 RelVarName
n2 GraphRefRelationalExpr
sub -> 
      RelVarName
-> RelVarName -> GraphRefRelationalExpr -> GraphRefRelationalExpr
forall a.
RelVarName
-> RelVarName -> RelationalExprBase a -> RelationalExprBase a
Rename RelVarName
n1 RelVarName
n2 (GraphRefRelationalExpr -> GraphRefRelationalExpr
applyStaticRestrictionCollapse GraphRefRelationalExpr
sub)
    Difference GraphRefRelationalExpr
sub1 GraphRefRelationalExpr
sub2 -> 
      GraphRefRelationalExpr
-> GraphRefRelationalExpr -> GraphRefRelationalExpr
forall a.
RelationalExprBase a
-> RelationalExprBase a -> RelationalExprBase a
Difference (GraphRefRelationalExpr -> GraphRefRelationalExpr
applyStaticRestrictionCollapse GraphRefRelationalExpr
sub1) (GraphRefRelationalExpr -> GraphRefRelationalExpr
applyStaticRestrictionCollapse GraphRefRelationalExpr
sub2)
    Group AttributeNamesBase GraphRefTransactionMarker
n1 RelVarName
n2 GraphRefRelationalExpr
sub ->
      AttributeNamesBase GraphRefTransactionMarker
-> RelVarName -> GraphRefRelationalExpr -> GraphRefRelationalExpr
forall a.
AttributeNamesBase a
-> RelVarName -> RelationalExprBase a -> RelationalExprBase a
Group AttributeNamesBase GraphRefTransactionMarker
n1 RelVarName
n2 (GraphRefRelationalExpr -> GraphRefRelationalExpr
applyStaticRestrictionCollapse GraphRefRelationalExpr
sub)
    Ungroup RelVarName
n1 GraphRefRelationalExpr
sub ->
      RelVarName -> GraphRefRelationalExpr -> GraphRefRelationalExpr
forall a.
RelVarName -> RelationalExprBase a -> RelationalExprBase a
Ungroup RelVarName
n1 (GraphRefRelationalExpr -> GraphRefRelationalExpr
applyStaticRestrictionCollapse GraphRefRelationalExpr
sub)
    Equals GraphRefRelationalExpr
sub1 GraphRefRelationalExpr
sub2 -> 
      GraphRefRelationalExpr
-> GraphRefRelationalExpr -> GraphRefRelationalExpr
forall a.
RelationalExprBase a
-> RelationalExprBase a -> RelationalExprBase a
Equals (GraphRefRelationalExpr -> GraphRefRelationalExpr
applyStaticRestrictionCollapse GraphRefRelationalExpr
sub1) (GraphRefRelationalExpr -> GraphRefRelationalExpr
applyStaticRestrictionCollapse GraphRefRelationalExpr
sub2)
    NotEquals GraphRefRelationalExpr
sub1 GraphRefRelationalExpr
sub2 ->
      GraphRefRelationalExpr
-> GraphRefRelationalExpr -> GraphRefRelationalExpr
forall a.
RelationalExprBase a
-> RelationalExprBase a -> RelationalExprBase a
NotEquals (GraphRefRelationalExpr -> GraphRefRelationalExpr
applyStaticRestrictionCollapse GraphRefRelationalExpr
sub1) (GraphRefRelationalExpr -> GraphRefRelationalExpr
applyStaticRestrictionCollapse GraphRefRelationalExpr
sub2)
    Extend ExtendTupleExprBase GraphRefTransactionMarker
n GraphRefRelationalExpr
sub ->
      ExtendTupleExprBase GraphRefTransactionMarker
-> GraphRefRelationalExpr -> GraphRefRelationalExpr
forall a.
ExtendTupleExprBase a
-> RelationalExprBase a -> RelationalExprBase a
Extend ExtendTupleExprBase GraphRefTransactionMarker
n (GraphRefRelationalExpr -> GraphRefRelationalExpr
applyStaticRestrictionCollapse GraphRefRelationalExpr
sub)
    Restrict RestrictionPredicateExprBase GraphRefTransactionMarker
firstPred GraphRefRelationalExpr
_ ->
      let restrictions :: [GraphRefRelationalExpr]
restrictions = GraphRefRelationalExpr -> [GraphRefRelationalExpr]
forall a. RelationalExprBase a -> [RelationalExprBase a]
sequentialRestrictions GraphRefRelationalExpr
expr
          finalExpr :: GraphRefRelationalExpr
finalExpr = [GraphRefRelationalExpr] -> GraphRefRelationalExpr
forall a. [a] -> a
last [GraphRefRelationalExpr]
restrictions
          optFinalExpr :: GraphRefRelationalExpr
optFinalExpr = case GraphRefRelationalExpr
finalExpr of
                              Restrict RestrictionPredicateExprBase GraphRefTransactionMarker
_ GraphRefRelationalExpr
subexpr -> GraphRefRelationalExpr -> GraphRefRelationalExpr
applyStaticRestrictionCollapse GraphRefRelationalExpr
subexpr
                              GraphRefRelationalExpr
otherExpr -> GraphRefRelationalExpr
otherExpr
          andPreds :: RestrictionPredicateExprBase GraphRefTransactionMarker
andPreds = (GraphRefRelationalExpr
 -> RestrictionPredicateExprBase GraphRefTransactionMarker
 -> RestrictionPredicateExprBase GraphRefTransactionMarker)
-> RestrictionPredicateExprBase GraphRefTransactionMarker
-> [GraphRefRelationalExpr]
-> RestrictionPredicateExprBase GraphRefTransactionMarker
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr (\(Restrict RestrictionPredicateExprBase GraphRefTransactionMarker
subpred GraphRefRelationalExpr
_) RestrictionPredicateExprBase GraphRefTransactionMarker
acc -> RestrictionPredicateExprBase GraphRefTransactionMarker
-> RestrictionPredicateExprBase GraphRefTransactionMarker
-> RestrictionPredicateExprBase GraphRefTransactionMarker
forall a.
RestrictionPredicateExprBase a
-> RestrictionPredicateExprBase a -> RestrictionPredicateExprBase a
AndPredicate RestrictionPredicateExprBase GraphRefTransactionMarker
acc RestrictionPredicateExprBase GraphRefTransactionMarker
subpred) RestrictionPredicateExprBase GraphRefTransactionMarker
firstPred ([GraphRefRelationalExpr] -> [GraphRefRelationalExpr]
forall a. [a] -> [a]
tail [GraphRefRelationalExpr]
restrictions) in
      RestrictionPredicateExprBase GraphRefTransactionMarker
-> GraphRefRelationalExpr -> GraphRefRelationalExpr
forall a.
RestrictionPredicateExprBase a
-> RelationalExprBase a -> RelationalExprBase a
Restrict RestrictionPredicateExprBase GraphRefTransactionMarker
andPreds GraphRefRelationalExpr
optFinalExpr
      
sequentialRestrictions :: RelationalExprBase a -> [RelationalExprBase a]
sequentialRestrictions :: RelationalExprBase a -> [RelationalExprBase a]
sequentialRestrictions expr :: RelationalExprBase a
expr@(Restrict RestrictionPredicateExprBase a
_ RelationalExprBase a
subexpr) = RelationalExprBase a
exprRelationalExprBase a
-> [RelationalExprBase a] -> [RelationalExprBase a]
forall a. a -> [a] -> [a]
:RelationalExprBase a -> [RelationalExprBase a]
forall a. RelationalExprBase a -> [RelationalExprBase a]
sequentialRestrictions RelationalExprBase a
subexpr
sequentialRestrictions RelationalExprBase a
_ = []

--restriction pushdown only really makes sense for tuple-oriented storage schemes where performing a restriction before projection can cut down on the intermediate storage needed to store the data before the projection
-- x{proj} where c1 -> (x where c1){proj} #project on fewer tuples
-- (x union y) where c -> (x where c) union (y where c) #with a selective restriction, fewer tuples will need to be joined
applyStaticRestrictionPushdown :: GraphRefRelationalExpr -> GraphRefRelationalExpr
applyStaticRestrictionPushdown :: GraphRefRelationalExpr -> GraphRefRelationalExpr
applyStaticRestrictionPushdown GraphRefRelationalExpr
expr = case GraphRefRelationalExpr
expr of
  MakeRelationFromExprs Maybe [AttributeExprBase GraphRefTransactionMarker]
_ TupleExprsBase GraphRefTransactionMarker
_ -> GraphRefRelationalExpr
expr
  MakeStaticRelation Attributes
_ RelationTupleSet
_ -> GraphRefRelationalExpr
expr
  ExistingRelation Relation
_ -> GraphRefRelationalExpr
expr
  RelationVariable RelVarName
_ GraphRefTransactionMarker
_ -> GraphRefRelationalExpr
expr
  With [(WithNameExprBase GraphRefTransactionMarker,
  GraphRefRelationalExpr)]
_ GraphRefRelationalExpr
_ -> GraphRefRelationalExpr
expr
  Project AttributeNamesBase GraphRefTransactionMarker
_ GraphRefRelationalExpr
_ -> GraphRefRelationalExpr
expr
  --this transformation cannot be inverted because the projection attributes might not exist in the inverted version
  Restrict RestrictionPredicateExprBase GraphRefTransactionMarker
restrictAttrs (Project AttributeNamesBase GraphRefTransactionMarker
projAttrs GraphRefRelationalExpr
subexpr) -> 
    AttributeNamesBase GraphRefTransactionMarker
-> GraphRefRelationalExpr -> GraphRefRelationalExpr
forall a.
AttributeNamesBase a
-> RelationalExprBase a -> RelationalExprBase a
Project AttributeNamesBase GraphRefTransactionMarker
projAttrs (RestrictionPredicateExprBase GraphRefTransactionMarker
-> GraphRefRelationalExpr -> GraphRefRelationalExpr
forall a.
RestrictionPredicateExprBase a
-> RelationalExprBase a -> RelationalExprBase a
Restrict RestrictionPredicateExprBase GraphRefTransactionMarker
restrictAttrs (GraphRefRelationalExpr -> GraphRefRelationalExpr
applyStaticRestrictionPushdown GraphRefRelationalExpr
subexpr))
  Restrict RestrictionPredicateExprBase GraphRefTransactionMarker
restrictAttrs (Union GraphRefRelationalExpr
subexpr1 GraphRefRelationalExpr
subexpr2) ->
    let optSub1 :: GraphRefRelationalExpr
optSub1 = GraphRefRelationalExpr -> GraphRefRelationalExpr
applyStaticRestrictionPushdown GraphRefRelationalExpr
subexpr1
        optSub2 :: GraphRefRelationalExpr
optSub2 = GraphRefRelationalExpr -> GraphRefRelationalExpr
applyStaticRestrictionPushdown GraphRefRelationalExpr
subexpr2 in
    GraphRefRelationalExpr
-> GraphRefRelationalExpr -> GraphRefRelationalExpr
forall a.
RelationalExprBase a
-> RelationalExprBase a -> RelationalExprBase a
Union (RestrictionPredicateExprBase GraphRefTransactionMarker
-> GraphRefRelationalExpr -> GraphRefRelationalExpr
forall a.
RestrictionPredicateExprBase a
-> RelationalExprBase a -> RelationalExprBase a
Restrict RestrictionPredicateExprBase GraphRefTransactionMarker
restrictAttrs GraphRefRelationalExpr
optSub1) (RestrictionPredicateExprBase GraphRefTransactionMarker
-> GraphRefRelationalExpr -> GraphRefRelationalExpr
forall a.
RestrictionPredicateExprBase a
-> RelationalExprBase a -> RelationalExprBase a
Restrict RestrictionPredicateExprBase GraphRefTransactionMarker
restrictAttrs GraphRefRelationalExpr
optSub2)
  Restrict RestrictionPredicateExprBase GraphRefTransactionMarker
attrs GraphRefRelationalExpr
subexpr -> 
    RestrictionPredicateExprBase GraphRefTransactionMarker
-> GraphRefRelationalExpr -> GraphRefRelationalExpr
forall a.
RestrictionPredicateExprBase a
-> RelationalExprBase a -> RelationalExprBase a
Restrict RestrictionPredicateExprBase GraphRefTransactionMarker
attrs (GraphRefRelationalExpr -> GraphRefRelationalExpr
applyStaticRestrictionPushdown GraphRefRelationalExpr
subexpr)
    
  Union GraphRefRelationalExpr
sub1 GraphRefRelationalExpr
sub2 -> 
    GraphRefRelationalExpr
-> GraphRefRelationalExpr -> GraphRefRelationalExpr
forall a.
RelationalExprBase a
-> RelationalExprBase a -> RelationalExprBase a
Union (GraphRefRelationalExpr -> GraphRefRelationalExpr
applyStaticRestrictionPushdown GraphRefRelationalExpr
sub1) (GraphRefRelationalExpr -> GraphRefRelationalExpr
applyStaticRestrictionPushdown GraphRefRelationalExpr
sub2)
  Join GraphRefRelationalExpr
sub1 GraphRefRelationalExpr
sub2 ->
    GraphRefRelationalExpr
-> GraphRefRelationalExpr -> GraphRefRelationalExpr
forall a.
RelationalExprBase a
-> RelationalExprBase a -> RelationalExprBase a
Join (GraphRefRelationalExpr -> GraphRefRelationalExpr
applyStaticRestrictionPushdown GraphRefRelationalExpr
sub1) (GraphRefRelationalExpr -> GraphRefRelationalExpr
applyStaticRestrictionPushdown GraphRefRelationalExpr
sub2)
  Rename RelVarName
n1 RelVarName
n2 GraphRefRelationalExpr
sub ->
    RelVarName
-> RelVarName -> GraphRefRelationalExpr -> GraphRefRelationalExpr
forall a.
RelVarName
-> RelVarName -> RelationalExprBase a -> RelationalExprBase a
Rename RelVarName
n1 RelVarName
n2 (GraphRefRelationalExpr -> GraphRefRelationalExpr
applyStaticRestrictionPushdown GraphRefRelationalExpr
sub)
  Difference GraphRefRelationalExpr
sub1 GraphRefRelationalExpr
sub2 -> 
    GraphRefRelationalExpr
-> GraphRefRelationalExpr -> GraphRefRelationalExpr
forall a.
RelationalExprBase a
-> RelationalExprBase a -> RelationalExprBase a
Difference (GraphRefRelationalExpr -> GraphRefRelationalExpr
applyStaticRestrictionPushdown GraphRefRelationalExpr
sub1) (GraphRefRelationalExpr -> GraphRefRelationalExpr
applyStaticRestrictionPushdown GraphRefRelationalExpr
sub2)
  Group AttributeNamesBase GraphRefTransactionMarker
n1 RelVarName
n2 GraphRefRelationalExpr
sub ->
    AttributeNamesBase GraphRefTransactionMarker
-> RelVarName -> GraphRefRelationalExpr -> GraphRefRelationalExpr
forall a.
AttributeNamesBase a
-> RelVarName -> RelationalExprBase a -> RelationalExprBase a
Group AttributeNamesBase GraphRefTransactionMarker
n1 RelVarName
n2 (GraphRefRelationalExpr -> GraphRefRelationalExpr
applyStaticRestrictionPushdown GraphRefRelationalExpr
sub)
  Ungroup RelVarName
n1 GraphRefRelationalExpr
sub ->
    RelVarName -> GraphRefRelationalExpr -> GraphRefRelationalExpr
forall a.
RelVarName -> RelationalExprBase a -> RelationalExprBase a
Ungroup RelVarName
n1 (GraphRefRelationalExpr -> GraphRefRelationalExpr
applyStaticRestrictionPushdown GraphRefRelationalExpr
sub)
  Equals GraphRefRelationalExpr
sub1 GraphRefRelationalExpr
sub2 -> 
    GraphRefRelationalExpr
-> GraphRefRelationalExpr -> GraphRefRelationalExpr
forall a.
RelationalExprBase a
-> RelationalExprBase a -> RelationalExprBase a
Equals (GraphRefRelationalExpr -> GraphRefRelationalExpr
applyStaticRestrictionPushdown GraphRefRelationalExpr
sub1) (GraphRefRelationalExpr -> GraphRefRelationalExpr
applyStaticRestrictionPushdown GraphRefRelationalExpr
sub2)
  NotEquals GraphRefRelationalExpr
sub1 GraphRefRelationalExpr
sub2 ->
    GraphRefRelationalExpr
-> GraphRefRelationalExpr -> GraphRefRelationalExpr
forall a.
RelationalExprBase a
-> RelationalExprBase a -> RelationalExprBase a
NotEquals (GraphRefRelationalExpr -> GraphRefRelationalExpr
applyStaticRestrictionPushdown GraphRefRelationalExpr
sub1) (GraphRefRelationalExpr -> GraphRefRelationalExpr
applyStaticRestrictionPushdown GraphRefRelationalExpr
sub2)
  Extend ExtendTupleExprBase GraphRefTransactionMarker
n GraphRefRelationalExpr
sub ->
    ExtendTupleExprBase GraphRefTransactionMarker
-> GraphRefRelationalExpr -> GraphRefRelationalExpr
forall a.
ExtendTupleExprBase a
-> RelationalExprBase a -> RelationalExprBase a
Extend ExtendTupleExprBase GraphRefTransactionMarker
n (GraphRefRelationalExpr -> GraphRefRelationalExpr
applyStaticRestrictionPushdown GraphRefRelationalExpr
sub)
    
-- no optimizations available  
optimizeDatabaseContextIOExpr :: GraphRefDatabaseContextIOExpr -> GraphRefSOptDatabaseContextExprM GraphRefDatabaseContextIOExpr
optimizeDatabaseContextIOExpr :: GraphRefDatabaseContextIOExpr
-> GraphRefSOptDatabaseContextExprM GraphRefDatabaseContextIOExpr
optimizeDatabaseContextIOExpr = GraphRefDatabaseContextIOExpr
-> GraphRefSOptDatabaseContextExprM GraphRefDatabaseContextIOExpr
forall (f :: * -> *) a. Applicative f => a -> f a
pure