Skip to content

Commit ab2d2a3

Browse files
committed
check conversion errors in time
1 parent 9861312 commit ab2d2a3

2 files changed

Lines changed: 24 additions & 19 deletions

File tree

src/duckdb_py/native/python_conversion.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -953,18 +953,18 @@ void TransformPythonObjectInternal(py::handle ele, A &result, const B &param, bo
953953
default:
954954
break;
955955
}
956-
if (overflow == 1) {
956+
if (overflow == 1) { // value is > LLONG_MAX
957957
uint64_t unsigned_value = PyLong_AsUnsignedLongLong(ptr);
958958
if (!PyErr_Occurred()) {
959959
// value does not fit within an int64, but it fits within a uint64
960960
OP::HandleUnsignedBigint(result, param, unsigned_value);
961961
break;
962962
}
963+
PyErr_Clear();
963964
if (conversion_target.id() == LogicalTypeId::UBIGINT) {
964965
throw InvalidInputException("Python Conversion Failure: Value out of range for type %s",
965966
conversion_target);
966967
}
967-
PyErr_Clear();
968968
}
969969
double number = PyLong_AsDouble(ele.ptr());
970970
if (number == -1.0 && PyErr_Occurred()) {

src/duckdb_py/python_udf.cpp

Lines changed: 22 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -307,26 +307,31 @@ static scalar_function_t CreateNativeFunction(PyObject *function, PythonExceptio
307307

308308
for (idx_t row = 0; row < input.size(); row++) {
309309

310-
auto bundled_parameters = py::tuple((int)input.ColumnCount());
311-
bool contains_null = false;
312-
for (idx_t i = 0; i < input.ColumnCount(); i++) {
313-
// Fill the tuple with the arguments for this row
314-
auto &column = input.data[i];
315-
auto value = column.GetValue(row);
316-
if (value.IsNull() && default_null_handling) {
317-
contains_null = true;
318-
break;
310+
py::object ret;
311+
if (input.ColumnCount() > 0) {
312+
auto bundled_parameters = py::tuple((int)input.ColumnCount());
313+
bool contains_null = false;
314+
for (idx_t i = 0; i < input.ColumnCount(); i++) {
315+
// Fill the tuple with the arguments for this row
316+
auto &column = input.data[i];
317+
auto value = column.GetValue(row);
318+
if (value.IsNull() && default_null_handling) {
319+
contains_null = true;
320+
break;
321+
}
322+
bundled_parameters[i] = PythonObject::FromValue(value, column.GetType(), client_properties);
319323
}
320-
bundled_parameters[i] = PythonObject::FromValue(value, column.GetType(), client_properties);
321-
}
322-
if (contains_null) {
323-
// Immediately insert None, no need to call the function
324-
FlatVector::SetNull(result, row, true);
325-
continue;
324+
if (contains_null) {
325+
// Immediately insert None, no need to call the function
326+
FlatVector::SetNull(result, row, true);
327+
continue;
328+
}
329+
// Call the function
330+
ret = py::reinterpret_steal<py::object>(PyObject_CallObject(function, bundled_parameters.ptr()));
331+
} else {
332+
ret = py::reinterpret_steal<py::object>(PyObject_CallObject(function, nullptr));
326333
}
327334

328-
// Call the function
329-
auto ret = py::reinterpret_steal<py::object>(PyObject_CallObject(function, bundled_parameters.ptr()));
330335
if (ret == nullptr && PyErr_Occurred()) {
331336
if (exception_handling == PythonExceptionHandling::FORWARD_ERROR) {
332337
auto exception = py::error_already_set();

0 commit comments

Comments
 (0)