Skip to content

Commit c52405d

Browse files
committed
Add support for try expressions
1 parent 89ed9a1 commit c52405d

File tree

5 files changed

+37
-0
lines changed

5 files changed

+37
-0
lines changed

_duckdb-stubs/__init__.pyi

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -884,6 +884,7 @@ class Expression:
884884
def otherwise(self, value: Expression) -> Expression: ...
885885
def show(self) -> None: ...
886886
def when(self, condition: Expression, value: Expression) -> Expression: ...
887+
def try_(self, condition: Expression, value: Expression) -> Expression: ...
887888

888889
class FatalException(DatabaseError): ...
889890

src/duckdb_py/include/duckdb_python/expression/pyexpression.hpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,10 @@ struct DuckDBPyExpression : public enable_shared_from_this<DuckDBPyExpression> {
8383
shared_ptr<DuckDBPyExpression> In(const py::args &args);
8484
shared_ptr<DuckDBPyExpression> NotIn(const py::args &args);
8585

86+
// TRY
87+
88+
shared_ptr<DuckDBPyExpression> Try();
89+
8690
// Order modifiers
8791

8892
shared_ptr<DuckDBPyExpression> Ascending();

src/duckdb_py/pyexpression.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,12 @@ shared_ptr<DuckDBPyExpression> DuckDBPyExpression::NotIn(const py::args &args) {
226226
return CreateCompareExpression(ExpressionType::COMPARE_NOT_IN, args);
227227
}
228228

229+
// TRY
230+
231+
shared_ptr<DuckDBPyExpression> DuckDBPyExpression::Try() {
232+
return DuckDBPyExpression::InternalUnaryOperator(ExpressionType::OPERATOR_TRY, *this);
233+
}
234+
229235
// COALESCE
230236

231237
shared_ptr<DuckDBPyExpression> DuckDBPyExpression::Coalesce(const py::args &args) {

src/duckdb_py/pyexpression/initialize.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -367,6 +367,14 @@ void DuckDBPyExpression::Initialize(py::module_ &m) {
367367
)";
368368
expression.def("isnotin", &DuckDBPyExpression::NotIn, docs);
369369

370+
docs = R"(
371+
Create a TRY expression from self
372+
373+
Returns:
374+
DuckDBPyExpression: TRY(self)
375+
)";
376+
expression.def("try_", &DuckDBPyExpression::Try, docs);
377+
370378
docs = R"(
371379
Return the stringified version of the expression.
372380

tests/fast/test_expression.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -928,6 +928,24 @@ def test_null(self):
928928
res2 = rel.filter(b.isnotnull()).fetchall()
929929
assert res2 == [(1, "a"), (2, "b"), (4, "c"), (5, "a")]
930930

931+
def test_try(self):
932+
con = duckdb.connect()
933+
rel = con.sql(
934+
"""
935+
select * from (VALUES
936+
(-1.0),
937+
(0.0),
938+
(1.0),
939+
(NULL),
940+
) tbl(a)
941+
"""
942+
)
943+
944+
expr = FunctionExpression("sqrt", ColumnExpression("a"))
945+
946+
res = rel.select(expr.try_()).fetchall()
947+
assert res == [(None,), (0.0,), (1.0,), (None,)]
948+
931949
def test_sort(self):
932950
con = duckdb.connect()
933951
rel = con.sql(

0 commit comments

Comments
 (0)