{-# LANGUAGE GADTs #-}

module DataFrame.Lazy.Internal.LogicalPlan where

import qualified Data.Text as T
import DataFrame.IO.CSV (CsvReader)
import qualified DataFrame.Internal.DataFrame as D
import qualified DataFrame.Internal.Expression as E
import DataFrame.Operations.Join (JoinType)
import DataFrame.Schema (Schema)

-- | Data source for a scan node.
data DataSource
    = -- | path, separator, CSV reader (e.g. attoparsec or SIMD)
      CsvSource FilePath Char CsvReader
    | CsvSourceStreaming FilePath Char CsvReader
    | ParquetSource FilePath

instance Show DataSource where
    show :: DataSource -> String
show (CsvSource String
path Char
sep CsvReader
_) =
        String
"CsvSource " String -> ShowS
forall a. [a] -> [a] -> [a]
++ ShowS
forall a. Show a => a -> String
show String
path String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
" " String -> ShowS
forall a. [a] -> [a] -> [a]
++ Char -> String
forall a. Show a => a -> String
show Char
sep String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
" <reader>"
    show (CsvSourceStreaming String
path Char
sep CsvReader
_) =
        String
"CsvSourceStreaming " String -> ShowS
forall a. [a] -> [a] -> [a]
++ ShowS
forall a. Show a => a -> String
show String
path String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
" " String -> ShowS
forall a. [a] -> [a] -> [a]
++ Char -> String
forall a. Show a => a -> String
show Char
sep String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
" <reader>"
    show (ParquetSource String
path) = String
"ParquetSource " String -> ShowS
forall a. [a] -> [a] -> [a]
++ ShowS
forall a. Show a => a -> String
show String
path

-- | Sort direction used in Sort nodes and the public API.
data SortOrder = Ascending | Descending
    deriving (Int -> SortOrder -> ShowS
[SortOrder] -> ShowS
SortOrder -> String
(Int -> SortOrder -> ShowS)
-> (SortOrder -> String)
-> ([SortOrder] -> ShowS)
-> Show SortOrder
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> SortOrder -> ShowS
showsPrec :: Int -> SortOrder -> ShowS
$cshow :: SortOrder -> String
show :: SortOrder -> String
$cshowList :: [SortOrder] -> ShowS
showList :: [SortOrder] -> ShowS
Show, SortOrder -> SortOrder -> Bool
(SortOrder -> SortOrder -> Bool)
-> (SortOrder -> SortOrder -> Bool) -> Eq SortOrder
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: SortOrder -> SortOrder -> Bool
== :: SortOrder -> SortOrder -> Bool
$c/= :: SortOrder -> SortOrder -> Bool
/= :: SortOrder -> SortOrder -> Bool
Eq, Eq SortOrder
Eq SortOrder =>
(SortOrder -> SortOrder -> Ordering)
-> (SortOrder -> SortOrder -> Bool)
-> (SortOrder -> SortOrder -> Bool)
-> (SortOrder -> SortOrder -> Bool)
-> (SortOrder -> SortOrder -> Bool)
-> (SortOrder -> SortOrder -> SortOrder)
-> (SortOrder -> SortOrder -> SortOrder)
-> Ord SortOrder
SortOrder -> SortOrder -> Bool
SortOrder -> SortOrder -> Ordering
SortOrder -> SortOrder -> SortOrder
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: SortOrder -> SortOrder -> Ordering
compare :: SortOrder -> SortOrder -> Ordering
$c< :: SortOrder -> SortOrder -> Bool
< :: SortOrder -> SortOrder -> Bool
$c<= :: SortOrder -> SortOrder -> Bool
<= :: SortOrder -> SortOrder -> Bool
$c> :: SortOrder -> SortOrder -> Bool
> :: SortOrder -> SortOrder -> Bool
$c>= :: SortOrder -> SortOrder -> Bool
>= :: SortOrder -> SortOrder -> Bool
$cmax :: SortOrder -> SortOrder -> SortOrder
max :: SortOrder -> SortOrder -> SortOrder
$cmin :: SortOrder -> SortOrder -> SortOrder
min :: SortOrder -> SortOrder -> SortOrder
Ord)

{- | Relational-algebra tree that represents what the query computes.
No physical decisions (batch size, join strategy) are made here.
-}
data LogicalPlan
    = -- | Read columns described by the schema from a source.
      Scan DataSource Schema
    | -- | Retain only the listed columns.
      Project [T.Text] LogicalPlan
    | -- | Keep rows matching the predicate.
      Filter (E.Expr Bool) LogicalPlan
    | -- | Add or overwrite a column via an expression.
      Derive T.Text E.UExpr LogicalPlan
    | -- | Join two sub-plans on the given key columns.
      Join JoinType T.Text T.Text LogicalPlan LogicalPlan
    | -- | Group then aggregate.
      Aggregate [T.Text] [(T.Text, E.UExpr)] LogicalPlan
    | -- | Sort by a list of (column, direction) pairs.
      Sort [(T.Text, SortOrder)] LogicalPlan
    | -- | Retain at most N rows.
      Limit Int LogicalPlan
    | -- | Lift an already-loaded DataFrame into the lazy plan.
      SourceDF D.DataFrame
    deriving (Int -> LogicalPlan -> ShowS
[LogicalPlan] -> ShowS
LogicalPlan -> String
(Int -> LogicalPlan -> ShowS)
-> (LogicalPlan -> String)
-> ([LogicalPlan] -> ShowS)
-> Show LogicalPlan
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> LogicalPlan -> ShowS
showsPrec :: Int -> LogicalPlan -> ShowS
$cshow :: LogicalPlan -> String
show :: LogicalPlan -> String
$cshowList :: [LogicalPlan] -> ShowS
showList :: [LogicalPlan] -> ShowS
Show)