dataframe-expr-serializer 1.3.0.0 → 1.4.0.0
raw patch · 2 files changed
+105/−65 lines, 2 filesdep ~dataframe-coredep ~dataframe-operations
Dependency ranges changed: dataframe-core, dataframe-operations
Files
- dataframe-expr-serializer.cabal +3/−3
- src/DataFrame/IR/ExprJson.hs +102/−62
dataframe-expr-serializer.cabal view
@@ -1,6 +1,6 @@ cabal-version: 3.4 name: dataframe-expr-serializer-version: 1.3.0.0+version: 1.4.0.0 synopsis: Serialize and deserialize dataframe expressions and pipelines. description: Save fitted @Expr@ values and whole pipelines (ordered @[NamedExpr]@) to a@@ -39,8 +39,8 @@ build-depends: base >= 4 && < 5, aeson >= 0.11.0.0 && < 3, bytestring >= 0.11 && < 0.14,- dataframe-core >= 2.6 && < 2.7,- dataframe-operations >= 2.6 && < 2.7,+ dataframe-core >= 2.7 && < 2.8,+ dataframe-operations >= 2.7 && < 2.8, text >= 2.1 && < 3, vector >= 0.13 && < 0.15 hs-source-dirs: src
src/DataFrame/IR/ExprJson.hs view
@@ -53,10 +53,17 @@ import DataFrame.Internal.Column (Columnable) import DataFrame.Internal.Expression ( AggStrategy (..),- BinaryOp (binaryName),+ BinOpId (..),+ BinaryOp (binaryId), Expr (..),+ OpRef (..), SomeExpr (..),- UnaryOp (unaryName),+ UnOpId (..),+ UnaryOp (unaryId),+ aggName,+ aggStrategyId,+ binOpName,+ unOpName, ) import qualified DataFrame.Internal.Expression as F import DataFrame.Internal.Expression.Reflect (@@ -196,7 +203,7 @@ Unary op (arg :: Expr b) -> do outTag <- requireTypeTag @a argTag <- requireTypeTag @b- opTag <- recognizeUnary (unaryName op)+ opTag <- recognizeUnary (unaryId op) argEnc <- encodeExpr arg Right $ object@@ -209,7 +216,7 @@ Binary op (lhs :: Expr c) (rhs :: Expr b) -> do outTag <- requireTypeTag @a argTag <- requireTypeTag @c- opTag <- recognizeBinary (binaryName op)+ opTag <- recognizeBinary (binaryId op) lEnc <- encodeExpr lhs rEnc <- encodeExpr rhs Right $@@ -244,11 +251,12 @@ outTag <- requireTypeTag @a argTag <- requireTypeTag @b innerEnc <- encodeExpr inner+ aggTag <- aggStrategyName strat Right $ object [ "node" .= ("agg" :: T.Text) , "out_type" .= outTag- , "agg" .= aggStrategyName strat+ , "agg" .= aggTag , "arg_type" .= argTag , "arg" .= innerEnc ]@@ -271,10 +279,14 @@ "DataFrame.IR.ExprJson.encodeExpr: unsupported type: " <> show (typeRep @x) -- | Wire-format name for an aggregation strategy.-aggStrategyName :: AggStrategy a b -> T.Text-aggStrategyName (CollectAgg n _) = n-aggStrategyName (FoldAgg n _ _) = n-aggStrategyName (MergeAgg n _ _ _ _) = n+aggStrategyName :: AggStrategy a b -> Either String T.Text+aggStrategyName strat = case aggStrategyId strat of+ Builtin a -> Right (aggName a)+ Named n -> Right n+ Anonymous l ->+ Left $+ "DataFrame.IR.ExprJson: anonymous aggregation (cannot serialize): "+ <> T.unpack l -- | Encode an 'Expr' to a strict 'BS.ByteString' of JSON. encodeExprToBytes ::@@ -321,64 +333,81 @@ Left $ "DataFrame.IR.ExprJson.encodeLit: unsupported type: " <> show (typeRep @a) --- | Map a 'binaryName' string to a wire-format op name.-recognizeBinary :: T.Text -> Either String T.Text-recognizeBinary n = case n of- "add" -> Right "add"- "sub" -> Right "sub"- "mult" -> Right "mult"- "divide" -> Right "divide"- "eq" -> Right "eq"- "neq" -> Right "neq"- "lt" -> Right "lt"- "leq" -> Right "leq"- "gt" -> Right "gt"- "geq" -> Right "geq"- "and" -> Right "and"- "or" -> Right "or"- -- Nullable-aware aliases (lossless on non-null inputs)- "nulladd" -> Right "add"- "nullsub" -> Right "sub"- "nullmul" -> Right "mult"- "nulldiv" -> Right "divide"- "nulland" -> Right "and"- "nullor" -> Right "or"- "exponentiate" -> Right "exponentiate"- "logBase" -> Right "logBase"- "div" -> Right "div"- "mod" -> Right "mod"- "pow" -> Right "pow"- other ->+-- | Wire-format op name of a binary builtin.+recognizeBinary :: OpRef BinOpId -> Either String T.Text+recognizeBinary ident = case ident of+ Builtin op -> case op of+ BNullAdd -> Right "add"+ BNullSub -> Right "sub"+ BNullMul -> Right "mult"+ BNullDiv -> Right "divide"+ BNullAnd -> Right "and"+ BNullOr -> Right "or"+ BPowFrac -> Right "powFrac"+ _+ | op `elem` wireBinary -> Right (binOpName op)+ | otherwise -> unsupported (binOpName op)+ Named n -> unsupported n+ Anonymous l -> unsupported l+ where+ unsupported n = Left $ "DataFrame.IR.ExprJson: unsupported binary op (cannot serialize): "- <> T.unpack other+ <> T.unpack n+ wireBinary =+ [ BAdd+ , BSub+ , BMult+ , BDivide+ , BEq+ , BNeq+ , BLt+ , BLeq+ , BGt+ , BGeq+ , BAnd+ , BOr+ , BExponentiate+ , BLogBase+ , BDiv+ , BMod+ , BPow+ ] --- | Map a 'unaryName' string to a wire-format op name.-recognizeUnary :: T.Text -> Either String T.Text-recognizeUnary n = case n of- "not" -> Right "not"- "negate" -> Right "negate"- "abs" -> Right "abs"- "signum" -> Right "signum"- "exp" -> Right "exp"- "sqrt" -> Right "sqrt"- "log" -> Right "log"- "sin" -> Right "sin"- "cos" -> Right "cos"- "tan" -> Right "tan"- "asin" -> Right "asin"- "acos" -> Right "acos"- "atan" -> Right "atan"- "sinh" -> Right "sinh"- "cosh" -> Right "cosh"- "asinh" -> Right "asinh"- "acosh" -> Right "acosh"- "atanh" -> Right "atanh"- "toDouble" -> Right "toDouble"- other ->+-- | Wire-format op name of a unary builtin.+recognizeUnary :: OpRef UnOpId -> Either String T.Text+recognizeUnary ident = case ident of+ Builtin op+ | op `elem` wireUnary -> Right (unOpName op)+ | otherwise -> unsupported (unOpName op)+ Named n -> unsupported n+ Anonymous l -> unsupported l+ where+ unsupported n = Left $ "DataFrame.IR.ExprJson: unsupported unary op (cannot serialize): "- <> T.unpack other+ <> T.unpack n+ wireUnary =+ [ UNot+ , UNegate+ , UAbs+ , USignum+ , UExp+ , USqrt+ , ULog+ , USin+ , UCos+ , UTan+ , UAsin+ , UAcos+ , UAtan+ , USinh+ , UCosh+ , UAsinh+ , UAcosh+ , UAtanh+ , UToDouble+ ] -- | Decode a JSON value into a 'SomeExpr' using the root @out_type@. decodeExprAny :: Aeson.Value -> Either String SomeExpr@@ -644,6 +673,11 @@ l <- parseExprAt @a rawLhs r <- parseExprAt @a rawRhs return $ SomeExpr (l ** r)+ "logBase" -> withFloatingTypeTag outType $ \(_ :: Proxy a) -> do+ requireSame outType argType+ l <- parseExprAt @a rawLhs+ r <- parseExprAt @a rawRhs+ return $ SomeExpr (logBase l r) "nulladd" -> parseBinary "add" outType argType rawLhs rawRhs "nullsub" -> parseBinary "sub" outType argType rawLhs rawRhs "nullmul" -> parseBinary "mult" outType argType rawLhs rawRhs@@ -674,6 +708,12 @@ return $ SomeExpr (F.mean arg) "variance" -> realUnboxAgg F.variance "median" -> realUnboxAgg F.median+ "stddev" -> realUnboxAgg F.stddev+ "countDistinct" -> do+ requireTag outType "int"+ withOrdTypeTag argType $ \(_ :: Proxy a) -> do+ arg <- parseExprAt @a rawArg+ return $ SomeExpr (F.countDistinct arg) "collect" -> fail "DataFrame.IR.ExprJson: 'collect' is not supported in the wire format \