Skip to content

Commit 63d4c21

Browse files
committed
work on literals we don't want promoted into Polars literals
1 parent f4b7aff commit 63d4c21

File tree

2 files changed

+13
-5
lines changed

2 files changed

+13
-5
lines changed

data_algebra/polars_model.py

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ def __init__(
3737
collect_required: bool = False, # property of tree, not node
3838
one_constant_required: bool = False, # property of tree, not node
3939
inputs: Optional[List] = None,
40+
lit_value = None,
4041
) -> None:
4142
"""
4243
Carry a Polars expression term (polars_term) plus annotations.
@@ -46,13 +47,17 @@ def __init__(
4647
:param is_column: True if term is a column name
4748
:param collect_required: True if Polars frame collection required by this node or an input node
4849
:param one_constant_required: True one constant required by this node or an input node
50+
:param lit_value: original value for a literal
4951
:param inputs: inputs to expression node
5052
"""
5153
assert isinstance(is_literal, bool)
5254
assert isinstance(is_column, bool)
5355
assert isinstance(collect_required, bool)
5456
assert isinstance(one_constant_required, bool)
5557
assert (is_literal + is_column + (inputs is not None) + (polars_term is None)) == 1
58+
if lit_value is not None:
59+
assert is_literal
60+
self.lit_value = lit_value
5661
self.polars_term = polars_term
5762
self.is_literal = is_literal
5863
self.collect_required = collect_required
@@ -210,9 +215,9 @@ def _populate_expr_impl_map() -> Dict[int, Dict[str, Callable]]:
210215
# datetime parsing from https://stackoverflow.com/a/71759536/6901725
211216
# TODO: figure out why format is wrong type
212217
# TODO: wire up format
213-
"parse_date": lambda x, format : x.cast(str).str.strptime(pl.Date, fmt="%Y-%m-%d", strict=False).cast(pl.Date),
218+
"parse_date": lambda x, format : x.cast(str).str.strptime(pl.Date, fmt=format, strict=False).cast(pl.Date),
214219
# TODO: wire up format
215-
"parse_datetime": lambda x, format : x.cast(str).str.strptime(pl.Datetime, strict=False).cast(pl.Datetime),
220+
"parse_datetime": lambda x, format : x.cast(str).str.strptime(pl.Datetime, fmt=format, strict=False).cast(pl.Datetime),
216221
}
217222
impl_map_3 = {
218223
"if_else": lambda a, b, c: pl.when(a).then(b).otherwise(c),
@@ -265,6 +270,7 @@ def __init__(self, *, use_lazy_eval: bool = True):
265270
"TableDescription": self._table_step,
266271
}
267272
self._expr_impl_map = _populate_expr_impl_map()
273+
self._want_literals_unpacked = {"parse_date", "parse_datetime"}
268274
self._collect_required = set()
269275

270276
def data_frame(self, arg=None):
@@ -651,7 +657,7 @@ def act_on_literal(self, *, value):
651657
:return: converted result
652658
"""
653659
assert not isinstance(value, PolarsTerm)
654-
return PolarsTerm(polars_term=pl.lit(value), is_literal=True)
660+
return PolarsTerm(polars_term=pl.lit(value), is_literal=True, lit_value=value)
655661

656662
def act_on_column_name(self, *, arg, value):
657663
"""
@@ -679,7 +685,9 @@ def act_on_expression(self, *, arg, values: List, op):
679685
assert isinstance(v, PolarsTerm)
680686
f = self._expr_impl_map[len(values)][op.op]
681687
assert f is not None
682-
res = f(*[v.polars_term for v in values])
688+
want_literals_unpacked = op.op in self._want_literals_unpacked
689+
args = [v.lit_value if (want_literals_unpacked and v.is_literal) else v.polars_term for v in values]
690+
res = f(*args)
683691
return PolarsTerm(
684692
polars_term=res,
685693
inputs=values,

tests/test_polars.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -318,7 +318,7 @@ def test_polars_project_max_date():
318318
# d.with_columns([pl.col("v").cast(str).str.strptime(pl.Date, fmt="%Y-%m-%d", strict=False).cast(pl.Date).alias("v2")])
319319
ops = (
320320
data_algebra.descr(d=d)
321-
.extend({"v": "v.parse_date()"})
321+
.extend({"v": "v.parse_date('%Y-%m-%d')"})
322322
.project(
323323
{
324324
"min_v": "v.min()",

0 commit comments

Comments
 (0)