module DataFrame.Lazy.Internal.PhysicalPlan where

import qualified Data.Text as T
import qualified DataFrame.Internal.DataFrame as D
import qualified DataFrame.Internal.Expression as E
import DataFrame.Internal.Schema (Schema)
import DataFrame.Lazy.Internal.LogicalPlan (DataSource, SortOrder)
import DataFrame.Operations.Join (JoinType)

-- | Scan-level configuration: batch size, separator, optional pushdowns.
data ScanConfig = ScanConfig
    { ScanConfig -> Int
scanBatchSize :: !Int
    , ScanConfig -> Char
scanSeparator :: !Char
    , ScanConfig -> Schema
scanSchema :: !Schema
    , ScanConfig -> Maybe (Expr Bool)
scanPushdownPredicate :: !(Maybe (E.Expr Bool))
    }
    deriving (Int -> ScanConfig -> ShowS
[ScanConfig] -> ShowS
ScanConfig -> String
(Int -> ScanConfig -> ShowS)
-> (ScanConfig -> String)
-> ([ScanConfig] -> ShowS)
-> Show ScanConfig
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> ScanConfig -> ShowS
showsPrec :: Int -> ScanConfig -> ShowS
$cshow :: ScanConfig -> String
show :: ScanConfig -> String
$cshowList :: [ScanConfig] -> ShowS
showList :: [ScanConfig] -> ShowS
Show)

{- | Physical plan: every node carries enough information for the executor
to allocate resources and choose algorithms without further analysis.
-}
data PhysicalPlan
    = PhysicalScan DataSource ScanConfig
    | PhysicalProject [T.Text] PhysicalPlan
    | PhysicalFilter (E.Expr Bool) PhysicalPlan
    | PhysicalDerive T.Text E.UExpr PhysicalPlan
    | PhysicalHashJoin JoinType T.Text T.Text PhysicalPlan PhysicalPlan
    | PhysicalSortMergeJoin JoinType T.Text T.Text PhysicalPlan PhysicalPlan
    | PhysicalHashAggregate [T.Text] [(T.Text, E.UExpr)] PhysicalPlan
    | PhysicalSort [(T.Text, SortOrder)] PhysicalPlan
    | PhysicalLimit Int PhysicalPlan
    | -- | Materialize child to a binary file on disk (used for build sides).
      PhysicalSpill PhysicalPlan FilePath
    | -- | Emit an already-loaded DataFrame as a stream of batches.
      PhysicalSourceDF D.DataFrame
    deriving (Int -> PhysicalPlan -> ShowS
[PhysicalPlan] -> ShowS
PhysicalPlan -> String
(Int -> PhysicalPlan -> ShowS)
-> (PhysicalPlan -> String)
-> ([PhysicalPlan] -> ShowS)
-> Show PhysicalPlan
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> PhysicalPlan -> ShowS
showsPrec :: Int -> PhysicalPlan -> ShowS
$cshow :: PhysicalPlan -> String
show :: PhysicalPlan -> String
$cshowList :: [PhysicalPlan] -> ShowS
showList :: [PhysicalPlan] -> ShowS
Show)