This is an automated email from the ASF dual-hosted git repository.

alamb pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/arrow-rs.git


The following commit(s) were added to refs/heads/main by this push:
     new c87a4d9d5e Add `pretty_format_batches_with_schema` function (#7642)
c87a4d9d5e is described below

commit c87a4d9d5e67371eeed1b786b20d9dde32d3a918
Author: 张林伟 <[email protected]>
AuthorDate: Sat Jun 14 03:56:51 2025 +0800

    Add `pretty_format_batches_with_schema` function (#7642)
    
    # Which issue does this PR close?
    
    Closes #NNN.
    
    # Rationale for this change
    
    Improve empty batches format.
    
    # What changes are included in this PR?
    
    Add new `pretty_format_batches_with_schema` function.
    
    # Are there any user-facing changes?
    
    Yes.
    
    ---------
    
    Co-authored-by: Andrew Lamb <[email protected]>
---
 arrow-cast/src/pretty.rs | 82 +++++++++++++++++++++++++++++++++++++-----------
 1 file changed, 63 insertions(+), 19 deletions(-)

diff --git a/arrow-cast/src/pretty.rs b/arrow-cast/src/pretty.rs
index 1c0b7a5d44..c3fc00e4b9 100644
--- a/arrow-cast/src/pretty.rs
+++ b/arrow-cast/src/pretty.rs
@@ -27,7 +27,7 @@ use std::fmt::Display;
 use comfy_table::{Cell, Table};
 
 use arrow_array::{Array, ArrayRef, RecordBatch};
-use arrow_schema::ArrowError;
+use arrow_schema::{ArrowError, SchemaRef};
 
 use crate::display::{ArrayFormatter, FormatOptions};
 
@@ -65,6 +65,38 @@ pub fn pretty_format_batches(results: &[RecordBatch]) -> 
Result<impl Display, Ar
     pretty_format_batches_with_options(results, &options)
 }
 
+/// Create a visual representation of [`RecordBatch`]es with a provided schema.
+///
+/// Useful to display empty batches.
+///
+/// # Example
+/// ```
+/// # use std::sync::Arc;
+/// # use arrow_array::{ArrayRef, Int32Array, RecordBatch, StringArray};
+/// # use arrow_cast::pretty::pretty_format_batches_with_schema;
+/// # use arrow_schema::{DataType, Field, Schema};
+/// let schema = Arc::new(Schema::new(vec![
+///     Field::new("a", DataType::Int32, false),
+///     Field::new("b", DataType::Utf8, true),
+/// ]));
+/// // Note, returned object implements `Display`
+/// let pretty_table = pretty_format_batches_with_schema(schema, &[]).unwrap();
+/// let table_str = format!("Batches:\n{pretty_table}");
+/// assert_eq!(table_str,
+/// r#"Batches:
+/// +---+---+
+/// | a | b |
+/// +---+---+
+/// +---+---+"#);
+/// ```
+pub fn pretty_format_batches_with_schema(
+    schema: SchemaRef,
+    results: &[RecordBatch],
+) -> Result<impl Display, ArrowError> {
+    let options = FormatOptions::default().with_display_error(true);
+    create_table(Some(schema), results, &options)
+}
+
 /// Create a visual representation of [`RecordBatch`]es with formatting 
options.
 ///
 /// # Arguments
@@ -99,7 +131,7 @@ pub fn pretty_format_batches_with_options(
     results: &[RecordBatch],
     options: &FormatOptions,
 ) -> Result<impl Display, ArrowError> {
-    create_table(results, options)
+    create_table(None, results, options)
 }
 
 /// Create a visual representation of [`ArrayRef`]
@@ -139,29 +171,41 @@ pub fn print_columns(col_name: &str, results: 
&[ArrayRef]) -> Result<(), ArrowEr
 }
 
 /// Convert a series of record batches into a table
-fn create_table(results: &[RecordBatch], options: &FormatOptions) -> 
Result<Table, ArrowError> {
+fn create_table(
+    schema_opt: Option<SchemaRef>,
+    results: &[RecordBatch],
+    options: &FormatOptions,
+) -> Result<Table, ArrowError> {
     let mut table = Table::new();
     table.load_preset("||--+-++|    ++++++");
 
-    if results.is_empty() {
-        return Ok(table);
-    }
-
-    let schema = results[0].schema();
-
-    let mut header = Vec::new();
-    for field in schema.fields() {
-        if options.types_info() {
-            header.push(Cell::new(format!(
-                "{}\n{}",
-                field.name(),
-                field.data_type()
-            )))
+    let schema_opt = schema_opt.or_else(|| {
+        if results.is_empty() {
+            None
         } else {
-            header.push(Cell::new(field.name()));
+            Some(results[0].schema())
+        }
+    });
+
+    if let Some(schema) = schema_opt {
+        let mut header = Vec::new();
+        for field in schema.fields() {
+            if options.types_info() {
+                header.push(Cell::new(format!(
+                    "{}\n{}",
+                    field.name(),
+                    field.data_type()
+                )))
+            } else {
+                header.push(Cell::new(field.name()));
+            }
         }
+        table.set_header(header);
+    }
+
+    if results.is_empty() {
+        return Ok(table);
     }
-    table.set_header(header);
 
     for batch in results {
         let formatters = batch

Reply via email to