Skip to content

Add nodes to convert between csp.Structs and Arrow RecordBatches#698

Merged
arhamchopra merged 6 commits into
mainfrom
ac/arrow_nodes_scalar_support
Apr 16, 2026
Merged

Add nodes to convert between csp.Structs and Arrow RecordBatches#698
arhamchopra merged 6 commits into
mainfrom
ac/arrow_nodes_scalar_support

Conversation

@arhamchopra

@arhamchopra arhamchopra commented Apr 6, 2026

Copy link
Copy Markdown
Collaborator

Arrow Batch Adapter: Scalar Type Support

Adds bidirectional conversion between Arrow RecordBatch and csp.Struct for all scalar types, with new CSP graph nodes for use in running graphs.

Motivation

CSP lacked a general-purpose way to move data between Arrow RecordBatches and csp Structs. The parquet adapter had its own bespoke conversion logic, and there was no reusable building block for other Arrow-based integrations (IPC, Flight, custom adapters). This PR introduces a shared, extensible Arrow ↔ Struct conversion layer that any adapter can use.

What's New

Core C++ Library (cpp/csp/adapters/arrow/)

  • ArrowTypeVisitor — Generic Arrow type → C++ type dispatch using template metaprogramming. Eliminates repetitive switch statements across the codebase.
  • ArrowFieldReader — Column-oriented extraction from Arrow arrays to CSP values. Supports scalar types, dictionary-encoded columns, enums, nested structs, and pluggable custom readers for extension types (e.g. numpy arrays).
  • ArrowFieldWriter — Mirror of FieldReader for serialization. Converts CSP struct fields to Arrow arrays via builders.
  • RecordBatchToStruct / StructToRecordBatch — Batch converters built on the readers/writers. Pre-allocate structs and use columnar readAll()/writeAll() for cache-friendly bulk conversion.

Python Graph Nodes (csp/adapters/arrow.py, ArrowCppNodes.cpp)

  • csp.adapters.arrow.record_batches_to_struct(data, cls, ...) — Converts ts[List[pa.RecordBatch]]ts[List[Struct]]
  • csp.adapters.arrow.struct_to_record_batches(data, cls, ...) — Converts ts[List[Struct]]ts[List[pa.RecordBatch]]
  • Data crosses the Python ↔ C++ boundary via the Arrow C Data Interface (zero-copy, ABI-stable PyCapsule exchange).
  • Optional field_map for column ↔ field renaming, optional max_batch_size for chunked output.

Build System

  • New csp_arrow_adapter static library with centralized Arrow dependency resolution (FindDepsArrowAdapter.cmake).
  • Simplified arrowadapterimpl Python extension — now links against csp_arrow_adapter instead of resolving Arrow directly.

Supported Types

CSP Type Arrow Types
bool BOOL
int INT8/16/32/64, UINT8/16/32/64
float FLOAT, DOUBLE, HALF_FLOAT
str STRING, LARGE_STRING, DICTIONARY
bytes BINARY, FIXED_SIZE_BINARY
datetime TIMESTAMP (ns/us/ms/s)
date DATE32, DATE64
time TIME32, TIME64
timedelta DURATION
Enum STRING, DICTIONARY
csp.Struct STRUCT (recursive)

Extensibility

The converters accept pluggable custom readers/writers for types not covered by the built-in scalar support (e.g. numpy list columns). Custom readers are passed at construction time and excluded from auto-detection — no core library changes needed to add new types.

This partially resolves #286

Add core Arrow adapter library with:
- ArrowTypeVisitor: visitArrowValueType maps arrow::Type to C++ types
- ArrowFieldReader: per-column value extraction from Arrow arrays
- ArrowFieldWriter: per-column value serialization to Arrow builders
- CMake build for csp_arrow_adapter static library
- Centralize Arrow link-target resolution in FindDepsArrowAdapter

Signed-off-by: Arham Chopra <arham.chopra@cubistsystematic.com>
Add RecordBatchToStruct and StructToRecordBatch converters for
bulk-converting between Arrow RecordBatches and csp::Struct vectors.
Support pluggable custom field readers/writers for extension types.

Signed-off-by: Arham Chopra <arham.chopra@cubistsystematic.com>
Add ArrowCppNodes with record_batches_to_struct and struct_to_record_batches
CppNode implementations. Make RecordBatchPullInputAdapter schema optional
(lazy extraction from first batch). Register graph functions in arrow.py.
Simplify arrowadapterimpl build to link against csp_arrow_adapter.

Signed-off-by: Arham Chopra <arham.chopra@cubistsystematic.com>
Add tests for record_batches_to_struct and struct_to_record_batches
covering all scalar types, nested structs, schema validation, and
round-trip conversion. Add RecordBatch pull input adapter tests.

Signed-off-by: Arham Chopra <arham.chopra@cubistsystematic.com>
@arhamchopra arhamchopra force-pushed the ac/arrow_nodes_scalar_support branch from 8920496 to 4068d0c Compare April 6, 2026 15:40
@arhamchopra arhamchopra changed the title Add nodes to convert between Add nodes to convert between csp.Structs and Arrow RecordBatches Apr 6, 2026
Comment thread cpp/csp/python/adapters/ArrowCppNodes.cpp Outdated
Comment thread cpp/csp/python/adapters/ArrowCppNodes.cpp Outdated
Comment thread cpp/csp/python/adapters/ArrowCppNodes.cpp Outdated
Comment thread cpp/csp/python/adapters/ArrowCppNodes.cpp Outdated
Comment thread cpp/csp/python/adapters/ArrowCppNodes.cpp Outdated
Comment thread csp/adapters/arrow.py
Comment thread csp/adapters/arrow.py Outdated
- Remove unnecessary ticked() checks on single-input nodes
- Remove extra blank line in START()
- Use PyList_GET_ITEM for faster unchecked access in loop
- Use typed TS_INPUT(vector<StructPtr>) instead of Generic for struct_to_record_batches
- Use standard @csp.node decorator instead of _node_internal_use

Signed-off-by: Arham Chopra <arham.chopra@cubistsystematic.com>
@arhamchopra arhamchopra force-pushed the ac/arrow_nodes_scalar_support branch from c2b253a to 506f5aa Compare April 16, 2026 05:08

@arhamchopra arhamchopra left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed all review feedback in commit 506f5aa:

@robambalu robambalu marked this pull request as ready for review April 16, 2026 13:16
@robambalu robambalu self-requested a review April 16, 2026 13:19
@robambalu robambalu self-requested a review April 16, 2026 16:55
@arhamchopra arhamchopra merged commit 83a96fc into main Apr 16, 2026
25 checks passed
@arhamchopra arhamchopra deleted the ac/arrow_nodes_scalar_support branch April 16, 2026 17:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add fast csp.Struct to Arrow record batch conversion

2 participants