Skip to content
This repository was archived by the owner on Oct 21, 2024. It is now read-only.

Commit ad2e3b0

Browse files
committed
send schema before batches
1 parent 260f9ca commit ad2e3b0

File tree

3 files changed

+35
-6
lines changed

3 files changed

+35
-6
lines changed

rust/arrow/src/flight/mod.rs

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,11 @@
1919
2020
use flight::FlightData;
2121

22+
use crate::datatypes::Schema;
2223
use crate::ipc::writer;
2324
use crate::record_batch::RecordBatch;
2425

25-
/// Convert a `RecordBatch` to `FlightData by getting the header and body as bytes
26+
/// Convert a `RecordBatch` to `FlightData` by getting the header and body as bytes
2627
impl From<&RecordBatch> for FlightData {
2728
fn from(batch: &RecordBatch) -> Self {
2829
let (header, body) = writer::record_batch_to_bytes(batch);
@@ -35,4 +36,17 @@ impl From<&RecordBatch> for FlightData {
3536
}
3637
}
3738

39+
/// Convert a `Schema` to `FlightData` by converting to an IPC message
40+
impl From<&Schema> for FlightData {
41+
fn from(schema: &Schema) -> Self {
42+
let schema = writer::schema_to_bytes(schema);
43+
Self {
44+
flight_descriptor: None,
45+
app_metadata: vec![],
46+
data_header: schema,
47+
data_body: vec![],
48+
}
49+
}
50+
}
51+
3852
// TODO: add more explicit conversion that expoess flight descriptor and metadata options

rust/arrow/src/ipc/writer.rs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -209,8 +209,7 @@ impl<W: Write> Drop for StreamWriter<W> {
209209
}
210210
}
211211

212-
/// Convert the schema to its IPC representation, and write it to the `writer`
213-
fn write_schema<R: Write>(writer: &mut BufWriter<R>, schema: &Schema) -> Result<usize> {
212+
pub(crate) fn schema_to_bytes(schema: &Schema) -> Vec<u8> {
214213
let mut fbb = FlatBufferBuilder::new();
215214
let schema = {
216215
let fb = ipc::convert::schema_to_fb_offset(&mut fbb, schema);
@@ -227,9 +226,13 @@ fn write_schema<R: Write>(writer: &mut BufWriter<R>, schema: &Schema) -> Result<
227226
fbb.finish(data, None);
228227

229228
let data = fbb.finished_data();
230-
let written = write_padded_data(writer, data, WriteDataType::Header);
229+
data.to_vec()
230+
}
231231

232-
written
232+
/// Convert the schema to its IPC representation, and write it to the `writer`
233+
fn write_schema<R: Write>(writer: &mut BufWriter<R>, schema: &Schema) -> Result<usize> {
234+
let data = schema_to_bytes(schema);
235+
write_padded_data(writer, &data[..], WriteDataType::Header)
233236
}
234237

235238
/// The message type being written. This determines whether to write the data length or not.

rust/datafusion/examples/flight-server.rs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,12 +77,24 @@ impl FlightService for FlightServiceImpl {
7777

7878
// execute the query
7979
let results = ctx.collect(plan.as_ref()).map_err(|e| to_tonic_err(&e))?;
80+
if results.is_empty() {
81+
return Err(Status::internal("There were no results from ticket"));
82+
}
8083

81-
let flights: Vec<Result<FlightData, Status>> = results
84+
// add an initial FlightData message that sends schema
85+
// TODO: find a more ergonomic way of doing this
86+
let schema = results[0].schema();
87+
let mut flights: Vec<Result<FlightData, Status>> =
88+
vec![Ok(FlightData::from(schema.as_ref()))];
89+
90+
let mut batches: Vec<Result<FlightData, Status>> = results
8291
.iter()
8392
.map(|batch| Ok(FlightData::from(batch)))
8493
.collect();
8594

95+
// append batch vector to schema vector, so that the first message sent is the schema
96+
flights.append(&mut batches);
97+
8698
let output = futures::stream::iter(flights);
8799

88100
Ok(Response::new(Box::pin(output) as Self::DoGetStream))

0 commit comments

Comments
 (0)