Skip to content

Commit fc547d8

Browse files
make main compile again (duckdb#519)
2 parents 664d7e4 + a9d6436 commit fc547d8

12 files changed

Lines changed: 33 additions & 31 deletions

File tree

_duckdb-stubs/_typing.pyi

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ Note:
133133
We use lowercase here to be able to reuse this `Literal` in the `DTypeIdentifiers` `Literal`.
134134
"""
135135

136-
NestedIds: TypeAlias = Literal["list", "struct", "array", "enum", "map", "decimal", "union"]
136+
NestedIds: TypeAlias = Literal["list", "struct", "tuple", "array", "enum", "map", "decimal", "union"]
137137
"""Identifiers for nested types in `DuckDBPyType.id`."""
138138

139139
PyTypeIds: TypeAlias = Builtins | NestedIds

duckdb/experimental/spark/sql/type_utils.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ def convert_nested_type(dtype: DuckDBPyType) -> DataType: # noqa: D103
9494
"DuckDB union types cannot be directly mapped to PySpark types."
9595
)
9696
raise ContributionsAcceptedError(msg)
97-
if id == "struct":
97+
if id == "struct" or id == "tuple":
9898
children: list[tuple[str, DuckDBPyType]] = dtype.children
9999
fields = [StructField(x[0], convert_type(x[1])) for x in children]
100100
return StructType(fields)
@@ -105,7 +105,7 @@ def convert_nested_type(dtype: DuckDBPyType) -> DataType: # noqa: D103
105105

106106
def convert_type(dtype: DuckDBPyType) -> DataType: # noqa: D103
107107
id = dtype.id
108-
if id in ["list", "struct", "map", "array"]:
108+
if id in ["list", "struct", "tuple", "map", "array"]:
109109
return convert_nested_type(dtype)
110110
if id == "decimal":
111111
children: list[tuple[str, DuckDBPyType]] = dtype.children

external/duckdb

Submodule duckdb updated 809 files

src/duckdb_py/arrow/pyarrow_filter_pushdown.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -79,10 +79,9 @@ py::object MakePyArrowScalar(const Value &constant, const string &timezone_confi
7979
// Cast::Operation<dtime_ns_t, int64_t> for which no specialization exists, and
8080
// throws "Unimplemented type for cast (INT64 -> INT64)". Use the type-strong
8181
// GetValueUnsafe<dtime_ns_t>() which reads `value_.time_ns` from the union
82-
// directly. The `dtime_ns_t.micros` field name is a misnomer — it actually holds
83-
// nanoseconds (see arrow_conversion.cpp:432).
82+
// directly. dtime_ns_t.value holds nanoseconds (see arrow_conversion.cpp:432).
8483
py::handle date_type = import_cache.pyarrow.time64();
85-
return dataset_scalar(scalar(constant.GetValueUnsafe<dtime_ns_t>().micros, date_type("ns")));
84+
return dataset_scalar(scalar(constant.GetValueUnsafe<dtime_ns_t>().value, date_type("ns")));
8685
}
8786
case LogicalTypeId::TIMESTAMP: {
8887
py::handle date_type = import_cache.pyarrow.timestamp();

src/duckdb_py/native/python_conversion.cpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ Value TransformDictionaryToStruct(optional_ptr<ClientContext> context, const PyD
117117
const LogicalType &target_type = LogicalType::UNKNOWN) {
118118
auto struct_keys = TransformStructKeys(dict.keys, dict.len, target_type);
119119

120-
bool struct_target = target_type.id() == LogicalTypeId::STRUCT;
120+
bool struct_target = target_type.id() == LogicalTypeId::STRUCT || target_type.id() == LogicalTypeId::TUPLE;
121121
if (struct_target && dict.len != StructType::GetChildCount(target_type)) {
122122
throw InvalidInputException("We could not convert the object %s to the desired target type (%s)",
123123
dict.ToString(), target_type.ToString());
@@ -252,7 +252,7 @@ Value TransformTupleToStruct(optional_ptr<ClientContext> context, py::handle ele
252252
auto tuple = py::cast<py::tuple>(ele);
253253
auto size = py::len(tuple);
254254

255-
D_ASSERT(target_type.id() == LogicalTypeId::STRUCT);
255+
D_ASSERT(target_type.id() == LogicalTypeId::STRUCT || target_type.id() == LogicalTypeId::TUPLE);
256256
auto child_types = StructType::GetChildTypes(target_type);
257257
auto child_count = child_types.size();
258258
if (size != child_count) {
@@ -558,7 +558,7 @@ struct PythonValueConversion {
558558

559559
static void HandleTuple(optional_ptr<ClientContext> context, Value &result, const LogicalType &target_type,
560560
py::handle ele, idx_t list_size) {
561-
if (target_type.id() == LogicalTypeId::STRUCT) {
561+
if (target_type.id() == LogicalTypeId::STRUCT || target_type.id() == LogicalTypeId::TUPLE) {
562562
result = TransformTupleToStruct(context, ele, target_type);
563563
return;
564564
}
@@ -584,6 +584,7 @@ struct PythonValueConversion {
584584
PyDictionary dict = PyDictionary(py::reinterpret_borrow<py::object>(ele));
585585
switch (target_type.id()) {
586586
case LogicalTypeId::STRUCT:
587+
case LogicalTypeId::TUPLE:
587588
return TransformDictionaryToStruct(context, dict, target_type);
588589
case LogicalTypeId::MAP:
589590
return TransformDictionaryToMap(context, dict, target_type);
@@ -886,6 +887,7 @@ struct PythonVectorConversion {
886887
auto &result_type = result.GetType();
887888
switch (result_type.id()) {
888889
case LogicalTypeId::STRUCT:
890+
case LogicalTypeId::TUPLE:
889891
ConvertTupleToStruct(context, result, result_offset, ele, tuple_size);
890892
break;
891893
case LogicalTypeId::ARRAY:
@@ -981,6 +983,7 @@ void TransformPythonObjectInternal(optional_ptr<ClientContext> context, py::hand
981983
auto &conversion_target = OP::ConversionTarget(result, param);
982984
switch (conversion_target.id()) {
983985
case LogicalTypeId::STRUCT:
986+
case LogicalTypeId::TUPLE:
984987
case LogicalTypeId::UNKNOWN:
985988
case LogicalTypeId::LIST:
986989
case LogicalTypeId::ARRAY:

src/duckdb_py/native/python_objects.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -461,6 +461,7 @@ static bool KeyIsHashable(const LogicalType &type) {
461461
return true;
462462
}
463463
case LogicalTypeId::STRUCT:
464+
case LogicalTypeId::TUPLE:
464465
return false;
465466
case LogicalTypeId::SQLNULL:
466467
// A SQLNULL key is always NULL, and Python's None is hashable.
@@ -603,7 +604,7 @@ py::object PythonObject::FromValue(const Value &val, const LogicalType &type,
603604
time = val.GetValueUnsafe<dtime_t>();
604605
} else {
605606
// Python's datetime doesn't support nanoseconds, we convert to micros.
606-
time = val.GetValueUnsafe<dtime_ns_t>().time();
607+
time = dtime_t(val.GetValueUnsafe<dtime_ns_t>().value / 1000);
607608
}
608609
duckdb::Time::Convert(time, hour, min, sec, usec);
609610
try {
@@ -692,7 +693,8 @@ py::object PythonObject::FromValue(const Value &val, const LogicalType &type,
692693
}
693694
return std::move(py_struct);
694695
}
695-
case LogicalTypeId::STRUCT: {
696+
case LogicalTypeId::STRUCT:
697+
case LogicalTypeId::TUPLE: {
696698
return FromStruct(val, type, client_properties);
697699
}
698700
case LogicalTypeId::UUID: {

src/duckdb_py/numpy/array_wrapper.cpp

Lines changed: 4 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -295,21 +295,10 @@ struct ArrayConvert {
295295
};
296296

297297
struct StructConvert {
298-
static py::dict ConvertValue(Vector &input, idx_t chunk_offset, NumpyAppendData &append_data) {
299-
auto &client_properties = append_data.client_properties;
300-
301-
py::dict py_struct;
298+
// Delegate to FromStruct so unnamed structs / TUPLE values become Python tuples (named ones stay dicts).
299+
static py::object ConvertValue(Vector &input, idx_t chunk_offset, NumpyAppendData &append_data) {
302300
auto val = input.GetValue(chunk_offset);
303-
auto &child_types = StructType::GetChildTypes(input.GetType());
304-
auto &struct_children = StructValue::GetChildren(val);
305-
306-
for (idx_t i = 0; i < struct_children.size(); i++) {
307-
auto &child_entry = child_types[i];
308-
auto &child_name = child_entry.first;
309-
auto &child_type = child_entry.second;
310-
py_struct[child_name.c_str()] = PythonObject::FromValue(struct_children[i], child_type, client_properties);
311-
}
312-
return py_struct;
301+
return PythonObject::FromStruct(val, input.GetType(), append_data.client_properties);
313302
}
314303
};
315304

@@ -714,6 +703,7 @@ void ArrayWrapper::Append(idx_t current_offset, Vector &input, idx_t source_size
714703
may_have_null = ConvertNested<py::object, duckdb_py_convert::UnionConvert>(append_data);
715704
break;
716705
case LogicalTypeId::STRUCT:
706+
case LogicalTypeId::TUPLE:
717707
may_have_null = ConvertNested<py::object, duckdb_py_convert::StructConvert>(append_data);
718708
break;
719709
case LogicalTypeId::VARIANT:

src/duckdb_py/numpy/raw_array_wrapper.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ static idx_t GetNumpyTypeWidth(const LogicalType &type) {
5858
case LogicalTypeId::LIST:
5959
case LogicalTypeId::MAP:
6060
case LogicalTypeId::STRUCT:
61+
case LogicalTypeId::TUPLE:
6162
case LogicalTypeId::UNION:
6263
case LogicalTypeId::UUID:
6364
case LogicalTypeId::ARRAY:
@@ -124,6 +125,7 @@ string RawArrayWrapper::DuckDBToNumpyDtype(const LogicalType &type) {
124125
case LogicalTypeId::LIST:
125126
case LogicalTypeId::MAP:
126127
case LogicalTypeId::STRUCT:
128+
case LogicalTypeId::TUPLE:
127129
case LogicalTypeId::UNION:
128130
case LogicalTypeId::UUID:
129131
case LogicalTypeId::ARRAY:

src/duckdb_py/pyconnection.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -424,7 +424,7 @@ std::shared_ptr<DuckDBPyConnection> DuckDBPyConnection::UnregisterUDF(const stri
424424
auto &catalog = Catalog::GetCatalog(context, SYSTEM_CATALOG);
425425
DropInfo info;
426426
info.type = CatalogType::SCALAR_FUNCTION_ENTRY;
427-
info.NameMutable() = Identifier(name);
427+
info.SetName(Identifier(name));
428428
info.allow_drop_internal = true;
429429
info.cascade = false;
430430
info.if_not_found = OnEntryNotFound::THROW_EXCEPTION;
@@ -1664,7 +1664,7 @@ std::unique_ptr<DuckDBPyRelation> DuckDBPyConnection::Table(const string &tname)
16641664
auto &connection = con.GetConnection();
16651665
auto qualified_name = QualifiedName::Parse(tname);
16661666
if (qualified_name.Schema().empty()) {
1667-
qualified_name.SchemaMutable() = DEFAULT_SCHEMA;
1667+
qualified_name = QualifiedName(qualified_name.Catalog(), DEFAULT_SCHEMA, qualified_name.Name());
16681668
}
16691669
try {
16701670
return CreateRelation(

src/duckdb_py/typing/pytype.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ bool DuckDBPyType::EqualsString(const string &type_str) const {
5151

5252
std::shared_ptr<DuckDBPyType> DuckDBPyType::GetAttribute(const string &name) const {
5353
auto name_identifier = Identifier(name);
54-
if (type.id() == LogicalTypeId::STRUCT || type.id() == LogicalTypeId::UNION) {
54+
if (type.id() == LogicalTypeId::STRUCT || type.id() == LogicalTypeId::TUPLE || type.id() == LogicalTypeId::UNION) {
5555
auto &children = StructType::GetChildTypes(type);
5656
for (idx_t i = 0; i < children.size(); i++) {
5757
auto &child = children[i];
@@ -372,6 +372,7 @@ py::list DuckDBPyType::Children() const {
372372
switch (type.id()) {
373373
case LogicalTypeId::LIST:
374374
case LogicalTypeId::STRUCT:
375+
case LogicalTypeId::TUPLE:
375376
case LogicalTypeId::UNION:
376377
case LogicalTypeId::MAP:
377378
case LogicalTypeId::ARRAY:
@@ -403,7 +404,7 @@ py::list DuckDBPyType::Children() const {
403404
children.append(py::make_tuple("values", strings_list));
404405
return children;
405406
}
406-
if (id == LogicalTypeId::STRUCT || id == LogicalTypeId::UNION) {
407+
if (id == LogicalTypeId::STRUCT || id == LogicalTypeId::TUPLE || id == LogicalTypeId::UNION) {
407408
auto &struct_children = StructType::GetChildTypes(type);
408409
for (idx_t i = 0; i < struct_children.size(); i++) {
409410
auto &child = struct_children[i];

0 commit comments

Comments
 (0)