File tree 2 files changed +33
-7
lines changed
2 files changed +33
-7
lines changed Original file line number Diff line number Diff line change @@ -1735,22 +1735,20 @@ def _register_udfs(self, expr: ir.Expr) -> None:
1735
1735
registration_func (con )
1736
1736
1737
1737
def _register_udf (self , udf_node : ops .ScalarUDF ):
1738
- func = udf_node .__func__
1739
- name = type (udf_node ).__name__
1740
1738
type_mapper = self .compiler .type_mapper
1741
1739
input_types = [
1742
1740
type_mapper .to_string (param .annotation .pattern .dtype )
1743
1741
for param in udf_node .__signature__ .parameters .values ()
1744
1742
]
1745
- output_type = type_mapper .to_string (udf_node .dtype )
1746
1743
1747
1744
def register_udf (con ):
1748
1745
return con .create_function (
1749
- name ,
1750
- func ,
1751
- input_types ,
1752
- output_type ,
1746
+ name = type ( udf_node ). __name__ ,
1747
+ function = udf_node . __func__ ,
1748
+ parameters = input_types ,
1749
+ return_type = type_mapper . to_string ( udf_node . dtype ) ,
1753
1750
type = _UDF_INPUT_TYPE_MAPPING [udf_node .__input_type__ ],
1751
+ ** udf_node .__config__ ,
1754
1752
)
1755
1753
1756
1754
return register_udf
Original file line number Diff line number Diff line change 1
1
from __future__ import annotations
2
2
3
+ import duckdb
3
4
import pytest
4
5
from pytest import param
5
6
7
+ import ibis
6
8
from ibis import udf
7
9
8
10
@@ -103,3 +105,29 @@ def dont_intercept_null(x: int) -> int:
103
105
)
104
106
def test_dont_intercept_null (con , expr , expected ):
105
107
assert con .execute (expr ) == expected
108
+
109
+
110
+ def test_kwargs_are_forwarded (con ):
111
+ def nullify_two (x : int ) -> int :
112
+ return None if x == 2 else x
113
+
114
+ @udf .scalar .python
115
+ def no_kwargs (x : int ) -> int :
116
+ return nullify_two (x )
117
+
118
+ @udf .scalar .python (null_handling = "special" )
119
+ def with_kwargs (x : int ) -> int :
120
+ return nullify_two (x )
121
+
122
+ # If we return go Non-NULL -> Non-NULL, then passing null_handling="special"
123
+ # will not change the result
124
+ assert con .execute (no_kwargs (ibis .literal (1 ))) == 1
125
+ assert con .execute (with_kwargs (ibis .literal (1 ))) == 1
126
+
127
+ # But, if our UDF ever goes Non-NULL -> NULL, then we NEED to pass
128
+ # null_handling="special", otherwise duckdb throws an error
129
+ assert con .execute (with_kwargs (ibis .literal (2 ))) is None
130
+
131
+ expr = no_kwargs (ibis .literal (2 ))
132
+ with pytest .raises (duckdb .InvalidInputException ):
133
+ con .execute (expr )
You can’t perform that action at this time.
0 commit comments