Skip to content

Commit 56c26cc

Browse files
Merge/v1.5 variegata into main (#507)
2 parents 01cf1f1 + 3d73752 commit 56c26cc

14 files changed

Lines changed: 591 additions & 378 deletions

File tree

.github/workflows/packaging_wheels.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ jobs:
3232
matrix:
3333
python: [ cp314 ]
3434
platform:
35-
- { os: windows-2025, arch: amd64, cibw_system: win }
35+
- { os: windows-2022, arch: amd64, cibw_system: win }
3636
- { os: windows-11-arm, arch: ARM64, cibw_system: win }
3737
- { os: ubuntu-24.04, arch: x86_64, cibw_system: manylinux }
3838
- { os: ubuntu-24.04-arm, arch: aarch64, cibw_system: manylinux }

.github/workflows/targeted_test.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ on:
88
required: true
99
type: choice
1010
options:
11-
- 'windows-2025'
11+
- 'windows-2022'
1212
- 'windows-11-arm'
1313
- 'ubuntu-24.04'
1414
- 'ubuntu-24.04-arm'

external/duckdb

Submodule duckdb updated 297 files

src/duckdb_py/arrow/arrow_array_stream.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,11 @@
1414

1515
namespace duckdb {
1616

17-
void TransformDuckToArrowChunk(ArrowSchema &arrow_schema, ArrowArray &data, py::list &batches) {
17+
void TransformDuckToArrowChunk(py::object pyarrow_schema, ArrowArray &data, py::list &batches) {
1818
py::gil_assert();
1919
auto pyarrow_lib_module = py::module::import("pyarrow").attr("lib");
2020
auto batch_import_func = pyarrow_lib_module.attr("RecordBatch").attr("_import_from_c");
21-
batches.append(batch_import_func(reinterpret_cast<uint64_t>(&data), reinterpret_cast<uint64_t>(&arrow_schema)));
21+
batches.append(batch_import_func(reinterpret_cast<uint64_t>(&data), pyarrow_schema));
2222
}
2323

2424
void VerifyArrowDatasetLoaded() {

src/duckdb_py/arrow/arrow_export_utils.cpp

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,18 +17,28 @@ namespace duckdb {
1717

1818
namespace pyarrow {
1919

20-
py::object ToArrowTable(const vector<LogicalType> &types, const vector<string> &names, const py::list &batches,
21-
ClientProperties &options) {
20+
py::object ToPyArrowSchema(const ArrowSchema &schema) {
2221
py::gil_scoped_acquire acquire;
2322

2423
auto pyarrow_lib_module = py::module::import("pyarrow").attr("lib");
25-
auto from_batches_func = pyarrow_lib_module.attr("Table").attr("from_batches");
2624
auto schema_import_func = pyarrow_lib_module.attr("Schema").attr("_import_from_c");
25+
return schema_import_func(reinterpret_cast<uint64_t>(&schema));
26+
}
27+
28+
py::object ToArrowTable(const py::list &batches, py::object pyarrow_schema) {
29+
py::gil_scoped_acquire acquire;
30+
31+
auto pyarrow_lib_module = py::module::import("pyarrow").attr("lib");
32+
auto from_batches_func = pyarrow_lib_module.attr("Table").attr("from_batches");
33+
34+
return py::cast<duckdb::pyarrow::Table>(from_batches_func(batches, pyarrow_schema));
35+
}
36+
37+
py::object ToArrowTable(const vector<LogicalType> &types, const vector<string> &names, const py::list &batches,
38+
ClientProperties &options) {
2739
ArrowSchema schema;
2840
ArrowConverter::ToArrowSchema(&schema, types, names, options);
29-
auto schema_obj = schema_import_func(reinterpret_cast<uint64_t>(&schema));
30-
31-
return py::cast<duckdb::pyarrow::Table>(from_batches_func(batches, schema_obj));
41+
return ToArrowTable(batches, ToPyArrowSchema(schema));
3242
}
3343

3444
} // namespace pyarrow

src/duckdb_py/include/duckdb_python/arrow/arrow_array_stream.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ enum class PyArrowObjectType {
6262
PolarsLazyFrame
6363
};
6464

65-
void TransformDuckToArrowChunk(ArrowSchema &arrow_schema, ArrowArray &data, py::list &batches);
65+
void TransformDuckToArrowChunk(py::object pyarrow_schema, ArrowArray &data, py::list &batches);
6666

6767
PyArrowObjectType GetArrowType(const py::handle &obj);
6868

src/duckdb_py/include/duckdb_python/arrow/arrow_export_utils.hpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,13 @@ namespace duckdb {
66

77
namespace pyarrow {
88

9+
py::object ToPyArrowSchema(const ArrowSchema &schema);
10+
911
py::object ToArrowTable(const vector<LogicalType> &types, const vector<string> &names, const py::list &batches,
1012
ClientProperties &options);
1113

14+
py::object ToArrowTable(const py::list &batches, py::object pyarrow_schema);
15+
1216
} // namespace pyarrow
1317

1418
} // namespace duckdb

src/duckdb_py/include/duckdb_python/pyresult.hpp

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,15 +36,13 @@ struct DuckDBPyResult {
3636

3737
PandasDataFrame FetchDF(bool date_as_object);
3838

39-
duckdb::pyarrow::Table FetchArrowTable(idx_t rows_per_batch, bool to_polars);
40-
4139
PandasDataFrame FetchDFChunk(const idx_t vectors_per_chunk = 1, bool date_as_object = false);
4240

4341
py::dict FetchPyTorch();
4442

4543
py::dict FetchTF();
4644

47-
ArrowArrayStream FetchArrowArrayStream(idx_t rows_per_batch = 1000000);
45+
duckdb::pyarrow::Table FetchArrowTable(idx_t rows_per_batch, bool to_polars);
4846
duckdb::pyarrow::RecordBatchReader FetchRecordBatchReader(idx_t rows_per_batch = 1000000);
4947
py::object FetchArrowCapsule(idx_t rows_per_batch = 1000000);
5048

@@ -71,6 +69,19 @@ struct DuckDBPyResult {
7169
unique_ptr<DataChunk> FetchNextRaw(QueryResult &result);
7270
unique_ptr<NumpyResultConversion> InitializeNumpyConversion(bool pandas = false);
7371

72+
//! Re-feed an already-MATERIALIZED result (a ColumnDataCollection, e.g. from
73+
//! rel.execute()) back through the engine on the user's own context. The eager
74+
//! variant installs a PhysicalArrowCollector to produce an ArrowQueryResult
75+
//! (parallel); the stream variant produces a lazy StreamQueryResult that co-owns
76+
//! the context (so it survives `del conn`). Never call these on a StreamQueryResult:
77+
//! a lazy result already has a live context and is converted/wrapped directly.
78+
void PromoteMaterializedToArrow(idx_t batch_size);
79+
80+
template <typename T>
81+
T RunWithArrowSchema(const std::function<T(const ArrowSchema &)> &fun, bool dedup_col_names);
82+
duckdb::pyarrow::Table MaterializedResultToArrowTable(const ArrowSchema &arrow_schema, idx_t rows_per_batch);
83+
ArrowArrayStream FetchArrowArrayStream(idx_t rows_per_batch);
84+
7485
private:
7586
idx_t chunk_offset = 0;
7687

src/duckdb_py/pyconnection.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -413,7 +413,7 @@ shared_ptr<DuckDBPyConnection> DuckDBPyConnection::UnregisterUDF(const string &n
413413
auto &catalog = Catalog::GetCatalog(context, SYSTEM_CATALOG);
414414
DropInfo info;
415415
info.type = CatalogType::SCALAR_FUNCTION_ENTRY;
416-
info.name = Identifier(name);
416+
info.NameMutable() = Identifier(name);
417417
info.allow_drop_internal = true;
418418
info.cascade = false;
419419
info.if_not_found = OnEntryNotFound::THROW_EXCEPTION;
@@ -1651,11 +1651,12 @@ unique_ptr<DuckDBPyRelation> DuckDBPyConnection::RunQuery(const py::object &quer
16511651
unique_ptr<DuckDBPyRelation> DuckDBPyConnection::Table(const string &tname) {
16521652
auto &connection = con.GetConnection();
16531653
auto qualified_name = QualifiedName::Parse(tname);
1654-
if (qualified_name.schema.empty()) {
1655-
qualified_name.schema = DEFAULT_SCHEMA;
1654+
if (qualified_name.Schema().empty()) {
1655+
qualified_name.SchemaMutable() = DEFAULT_SCHEMA;
16561656
}
16571657
try {
1658-
return CreateRelation(connection.Table(qualified_name.catalog, qualified_name.schema, qualified_name.name));
1658+
return CreateRelation(
1659+
connection.Table(qualified_name.Catalog(), qualified_name.Schema(), qualified_name.Name()));
16591660
} catch (const CatalogException &) {
16601661
// CatalogException will be of the type '... is not a table'
16611662
// Not a table in the database, make a query relation that can perform replacement scans

src/duckdb_py/pyexpression.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -325,13 +325,13 @@ shared_ptr<DuckDBPyExpression> DuckDBPyExpression::ColumnExpression(const py::ar
325325
}
326326

327327
auto qualified_name = QualifiedName::Parse(column_name);
328-
if (!qualified_name.catalog.empty()) {
329-
column_names.push_back(qualified_name.catalog);
328+
if (!qualified_name.Catalog().empty()) {
329+
column_names.push_back(qualified_name.Catalog());
330330
}
331-
if (!qualified_name.schema.empty()) {
332-
column_names.push_back(qualified_name.schema);
331+
if (!qualified_name.Schema().empty()) {
332+
column_names.push_back(qualified_name.Schema());
333333
}
334-
column_names.push_back(qualified_name.name);
334+
column_names.push_back(qualified_name.Name());
335335
} else {
336336
for (auto &part : names) {
337337
column_names.push_back(Identifier(py::str(part)));

0 commit comments

Comments
 (0)