1616#include " pandas/pandas_scan.h"
1717#include " processor/result/factorized_table.h"
1818#include " pyarrow/pyarrow_scan.h"
19+ #include " storage/table/arrow_table_support.h"
1920#include < format>
2021
2122using namespace lbug ::common;
@@ -42,7 +43,10 @@ void PyConnection::initialize(py::handle& m) {
4243 .def (" create_function" , &PyConnection::createScalarFunction, py::arg (" name" ),
4344 py::arg (" udf" ), py::arg (" params_type" ), py::arg (" return_value" ),
4445 py::arg (" default_null" ), py::arg (" catch_exceptions" ))
45- .def (" remove_function" , &PyConnection::removeScalarFunction, py::arg (" name" ));
46+ .def (" remove_function" , &PyConnection::removeScalarFunction, py::arg (" name" ))
47+ .def (" create_arrow_table" , &PyConnection::createArrowTable, py::arg (" table_name" ),
48+ py::arg (" arrow_table" ))
49+ .def (" drop_arrow_table" , &PyConnection::dropArrowTable, py::arg (" table_name" ));
4650 PyDateTime_IMPORT;
4751}
4852
@@ -768,3 +772,48 @@ void PyConnection::createScalarFunction(const std::string& name, const py::funct
768772void PyConnection::removeScalarFunction (const std::string& name) {
769773 conn->removeUDFFunction (name);
770774}
775+
776+ std::unique_ptr<PyQueryResult> PyConnection::createArrowTable (const std::string& tableName,
777+ py::object arrowTable) {
778+ py::gil_scoped_acquire acquire;
779+
780+ // Convert pandas/polars to pyarrow if needed
781+ if (PyConnection::isPandasDataframe (arrowTable)) {
782+ arrowTable = importCache->pyarrow .lib .Table .from_pandas ()(arrowTable);
783+ } else if (PyConnection::isPolarsDataframe (arrowTable)) {
784+ arrowTable = arrowTable.attr (" to_arrow" )();
785+ }
786+
787+ // Ensure we have a pyarrow table
788+ if (!PyConnection::isPyArrowTable (arrowTable)) {
789+ throw RuntimeException (" Expected a pyarrow Table, polars DataFrame, or pandas DataFrame" );
790+ }
791+
792+ // Export Arrow table to C Data Interface
793+ // First, get the schema
794+ ArrowSchemaWrapper schema;
795+ arrowTable.attr (" schema" ).attr (" _export_to_c" )(reinterpret_cast <uint64_t >(&schema));
796+
797+ // Get the batches (arrays)
798+ std::vector<ArrowArrayWrapper> arrays;
799+ py::list batches = arrowTable.attr (" to_batches" )();
800+ for (auto & batch : batches) {
801+ arrays.emplace_back ();
802+ batch.attr (" _export_to_c" )(reinterpret_cast <uint64_t >(&arrays.back ()));
803+ }
804+
805+ // Convert wrappers to raw Arrow structs for the API
806+ std::vector<ArrowArray> rawArrays;
807+ for (auto & arr : arrays) {
808+ rawArrays.push_back (static_cast <ArrowArray>(arr));
809+ }
810+
811+ auto result = ArrowTableSupport::createViewFromArrowTable (*conn, tableName, schema, rawArrays);
812+
813+ return checkAndWrapQueryResult (result.queryResult );
814+ }
815+
816+ std::unique_ptr<PyQueryResult> PyConnection::dropArrowTable (const std::string& tableName) {
817+ auto result = ArrowTableSupport::unregisterArrowTable (*conn, tableName);
818+ return checkAndWrapQueryResult (result);
819+ }
0 commit comments