Skip to content

Commit 020bfdb

Browse files
committed
feat(api): add ops.StructColumn operation
1 parent a216c18 commit 020bfdb

File tree

2 files changed

+26
-1
lines changed

2 files changed

+26
-1
lines changed

ibis/expr/operations/generic.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -373,6 +373,23 @@ def has_resolved_name(self):
373373
return True
374374

375375

376+
@public
377+
class StructColumn(Value):
378+
names = rlz.tuple_of(rlz.instance_of(str), min_length=1)
379+
values = rlz.tuple_of(rlz.any, min_length=1)
380+
381+
output_shape = rlz.Shape.COLUMNAR
382+
383+
@immutable_property
384+
def output_dtype(self):
385+
return dt.Struct.from_tuples(
386+
zip(self.names, (value.type() for value in self.values))
387+
)
388+
389+
def root_tables(self):
390+
return distinct_roots(*self.values)
391+
392+
376393
@public
377394
class DecimalPrecision(Unary):
378395
arg = rlz.decimal

ibis/expr/types/structs.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,15 @@ def struct(
4646
Create a struct literal from a [`dict`][dict] with a specified type
4747
>>> t = ibis.struct(dict(a=1, b='foo'), type='struct<a: float, b: string>')
4848
"""
49-
return literal(collections.OrderedDict(value), type=type)
49+
import ibis.expr.operations as ops
50+
51+
items = dict(value)
52+
values = items.values()
53+
if any(isinstance(value, Value) for value in values):
54+
return ops.StructColumn(
55+
names=tuple(items.keys()), values=tuple(values)
56+
).to_expr()
57+
return literal(collections.OrderedDict(items), type=type)
5058

5159

5260
@public

0 commit comments

Comments
 (0)