You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@arrow.apache.org by al...@apache.org on 2023/06/02 11:06:49 UTC

[arrow-rs] branch master updated: Update FlightSQL metadata locations, names and docs (#4341)

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

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


The following commit(s) were added to refs/heads/master by this push:
     new 0a3259091 Update FlightSQL metadata locations, names and docs (#4341)
0a3259091 is described below

commit 0a3259091cc4e74b59fe22d40fc84474492112b4
Author: Andrew Lamb <an...@nerdnetworks.org>
AuthorDate: Fri Jun 2 07:06:44 2023 -0400

    Update FlightSQL metadata locations, names and docs (#4341)
    
    * Update FlightSQL metadata locations, names and docs
    
    * update
    
    * fix typo
    
    * fix CI, unify interface
---
 arrow-flight/examples/flight_sql_server.rs         |  20 ++--
 arrow-flight/src/sql/catalogs/mod.rs               | 123 ---------------------
 arrow-flight/src/sql/metadata/catalogs.rs          | 100 +++++++++++++++++
 .../src/sql/{catalogs => metadata}/db_schemas.rs   |  57 +++++-----
 arrow-flight/src/sql/metadata/mod.rs               |  55 +++++++++
 arrow-flight/src/sql/{ => metadata}/sql_info.rs    |   6 +-
 .../src/sql/{catalogs => metadata}/tables.rs       |  50 +++++----
 arrow-flight/src/sql/mod.rs                        |   8 +-
 8 files changed, 233 insertions(+), 186 deletions(-)

diff --git a/arrow-flight/examples/flight_sql_server.rs b/arrow-flight/examples/flight_sql_server.rs
index 6b92621a5..ecd8db76b 100644
--- a/arrow-flight/examples/flight_sql_server.rs
+++ b/arrow-flight/examples/flight_sql_server.rs
@@ -30,10 +30,7 @@ use tonic::{Request, Response, Status, Streaming};
 use arrow_array::builder::StringBuilder;
 use arrow_array::{ArrayRef, RecordBatch};
 use arrow_flight::encode::FlightDataEncoderBuilder;
-use arrow_flight::sql::catalogs::{
-    get_catalogs_schema, get_db_schemas_schema, get_tables_schema,
-};
-use arrow_flight::sql::sql_info::SqlInfoList;
+use arrow_flight::sql::metadata::SqlInfoList;
 use arrow_flight::sql::{
     server::FlightSqlService, ActionBeginSavepointRequest, ActionBeginSavepointResult,
     ActionBeginTransactionRequest, ActionBeginTransactionResult,
@@ -252,7 +249,7 @@ impl FlightSqlService for FlightSqlServiceImpl {
         let endpoint = FlightEndpoint::new().with_ticket(ticket);
 
         let flight_info = FlightInfo::new()
-            .try_with_schema(get_catalogs_schema())
+            .try_with_schema(&query.into_builder().schema())
             .map_err(|e| status!("Unable to encode schema", e))?
             .with_endpoint(endpoint)
             .with_descriptor(flight_descriptor);
@@ -272,7 +269,7 @@ impl FlightSqlService for FlightSqlServiceImpl {
         let endpoint = FlightEndpoint::new().with_ticket(ticket);
 
         let flight_info = FlightInfo::new()
-            .try_with_schema(get_db_schemas_schema().as_ref())
+            .try_with_schema(&query.into_builder().schema())
             .map_err(|e| status!("Unable to encode schema", e))?
             .with_endpoint(endpoint)
             .with_descriptor(flight_descriptor);
@@ -292,7 +289,7 @@ impl FlightSqlService for FlightSqlServiceImpl {
         let endpoint = FlightEndpoint::new().with_ticket(ticket);
 
         let flight_info = FlightInfo::new()
-            .try_with_schema(get_tables_schema(query.include_schema).as_ref())
+            .try_with_schema(&query.into_builder().schema())
             .map_err(|e| status!("Unable to encode schema", e))?
             .with_endpoint(endpoint)
             .with_descriptor(flight_descriptor);
@@ -410,9 +407,10 @@ impl FlightSqlService for FlightSqlServiceImpl {
         for catalog_name in catalog_names {
             builder.append(catalog_name);
         }
+        let schema = builder.schema();
         let batch = builder.build();
         let stream = FlightDataEncoderBuilder::new()
-            .with_schema(Arc::new(get_catalogs_schema().clone()))
+            .with_schema(schema)
             .build(futures::stream::once(async { batch }))
             .map_err(Status::from);
         Ok(Response::new(Box::pin(stream)))
@@ -436,9 +434,10 @@ impl FlightSqlService for FlightSqlServiceImpl {
             builder.append(catalog_name, schema_name);
         }
 
+        let schema = builder.schema();
         let batch = builder.build();
         let stream = FlightDataEncoderBuilder::new()
-            .with_schema(get_db_schemas_schema())
+            .with_schema(schema)
             .build(futures::stream::once(async { batch }))
             .map_err(Status::from);
         Ok(Response::new(Box::pin(stream)))
@@ -475,9 +474,10 @@ impl FlightSqlService for FlightSqlServiceImpl {
                 .map_err(Status::from)?;
         }
 
+        let schema = builder.schema();
         let batch = builder.build();
         let stream = FlightDataEncoderBuilder::new()
-            .with_schema(get_db_schemas_schema())
+            .with_schema(schema)
             .build(futures::stream::once(async { batch }))
             .map_err(Status::from);
         Ok(Response::new(Box::pin(stream)))
diff --git a/arrow-flight/src/sql/catalogs/mod.rs b/arrow-flight/src/sql/catalogs/mod.rs
deleted file mode 100644
index e4cbb6fed..000000000
--- a/arrow-flight/src/sql/catalogs/mod.rs
+++ /dev/null
@@ -1,123 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-
-//! Builders and function for building responses to information schema requests
-//!
-//! - [`get_catalogs_batch`] and [`get_catalogs_schema`] for building responses to [`CommandGetCatalogs`] queries.
-//! - [`GetSchemasBuilder`] and [`get_db_schemas_schema`] for building responses to [`CommandGetDbSchemas`] queries.
-//! - [`GetTablesBuilder`] and [`get_tables_schema`] for building responses to [`CommandGetTables`] queries.
-//!
-//! [`CommandGetCatalogs`]: crate::sql::CommandGetCatalogs
-//! [`CommandGetDbSchemas`]: crate::sql::CommandGetDbSchemas
-//! [`CommandGetTables`]: crate::sql::CommandGetTables
-
-use std::sync::Arc;
-
-use arrow_array::{ArrayRef, RecordBatch, StringArray, UInt32Array};
-use arrow_row::{RowConverter, SortField};
-use arrow_schema::{DataType, Field, Schema, SchemaRef};
-use once_cell::sync::Lazy;
-
-use crate::error::Result;
-use crate::sql::CommandGetCatalogs;
-
-pub use db_schemas::{get_db_schemas_schema, GetSchemasBuilder};
-pub use tables::{get_tables_schema, GetTablesBuilder};
-
-mod db_schemas;
-mod tables;
-
-pub struct GetCatalogsBuilder {
-    catalogs: Vec<String>,
-}
-
-impl CommandGetCatalogs {
-    pub fn into_builder(self) -> GetCatalogsBuilder {
-        self.into()
-    }
-}
-
-impl From<CommandGetCatalogs> for GetCatalogsBuilder {
-    fn from(_: CommandGetCatalogs) -> Self {
-        Self::new()
-    }
-}
-
-impl Default for GetCatalogsBuilder {
-    fn default() -> Self {
-        Self::new()
-    }
-}
-
-impl GetCatalogsBuilder {
-    /// Create a new instance of [`GetCatalogsBuilder`]
-    pub fn new() -> Self {
-        Self {
-            catalogs: Vec::new(),
-        }
-    }
-
-    /// Append a row
-    pub fn append(&mut self, catalog_name: impl Into<String>) {
-        self.catalogs.push(catalog_name.into());
-    }
-
-    /// builds a `RecordBatch` with the correct schema for a `CommandGetCatalogs` response
-    pub fn build(self) -> Result<RecordBatch> {
-        get_catalogs_batch(self.catalogs)
-    }
-}
-
-/// Returns the RecordBatch for `CommandGetCatalogs`
-pub fn get_catalogs_batch(mut catalog_names: Vec<String>) -> Result<RecordBatch> {
-    catalog_names.sort_unstable();
-
-    let batch = RecordBatch::try_new(
-        Arc::clone(&GET_CATALOG_SCHEMA),
-        vec![Arc::new(StringArray::from_iter_values(catalog_names)) as _],
-    )?;
-
-    Ok(batch)
-}
-
-/// Returns the schema that will result from [`CommandGetCatalogs`]
-///
-/// [`CommandGetCatalogs`]: crate::sql::CommandGetCatalogs
-pub fn get_catalogs_schema() -> &'static Schema {
-    &GET_CATALOG_SCHEMA
-}
-
-/// The schema for GetCatalogs
-static GET_CATALOG_SCHEMA: Lazy<SchemaRef> = Lazy::new(|| {
-    Arc::new(Schema::new(vec![Field::new(
-        "catalog_name",
-        DataType::Utf8,
-        false,
-    )]))
-});
-
-fn lexsort_to_indices(arrays: &[ArrayRef]) -> UInt32Array {
-    let fields = arrays
-        .iter()
-        .map(|a| SortField::new(a.data_type().clone()))
-        .collect();
-    let mut converter = RowConverter::new(fields).unwrap();
-    let rows = converter.convert_columns(arrays).unwrap();
-    let mut sort: Vec<_> = rows.iter().enumerate().collect();
-    sort.sort_unstable_by(|(_, a), (_, b)| a.cmp(b));
-    UInt32Array::from_iter_values(sort.iter().map(|(i, _)| *i as u32))
-}
diff --git a/arrow-flight/src/sql/metadata/catalogs.rs b/arrow-flight/src/sql/metadata/catalogs.rs
new file mode 100644
index 000000000..327fed810
--- /dev/null
+++ b/arrow-flight/src/sql/metadata/catalogs.rs
@@ -0,0 +1,100 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+use std::sync::Arc;
+
+use arrow_array::{RecordBatch, StringArray};
+use arrow_schema::{DataType, Field, Schema, SchemaRef};
+use once_cell::sync::Lazy;
+
+use crate::error::Result;
+use crate::sql::CommandGetCatalogs;
+
+/// A builder for a [`CommandGetCatalogs`] response.
+///
+/// Builds rows like this:
+///
+/// * catalog_name: utf8,
+pub struct GetCatalogsBuilder {
+    catalogs: Vec<String>,
+}
+
+impl CommandGetCatalogs {
+    /// Create a builder suitable for constructing a response
+    pub fn into_builder(self) -> GetCatalogsBuilder {
+        self.into()
+    }
+}
+
+impl From<CommandGetCatalogs> for GetCatalogsBuilder {
+    fn from(_: CommandGetCatalogs) -> Self {
+        Self::new()
+    }
+}
+
+impl Default for GetCatalogsBuilder {
+    fn default() -> Self {
+        Self::new()
+    }
+}
+
+impl GetCatalogsBuilder {
+    /// Create a new instance of [`GetCatalogsBuilder`]
+    pub fn new() -> Self {
+        Self {
+            catalogs: Vec::new(),
+        }
+    }
+
+    /// Append a row
+    pub fn append(&mut self, catalog_name: impl Into<String>) {
+        self.catalogs.push(catalog_name.into());
+    }
+
+    /// builds a `RecordBatch` with the correct schema for a
+    /// [`CommandGetCatalogs`] response
+    pub fn build(self) -> Result<RecordBatch> {
+        let Self { catalogs } = self;
+
+        let batch = RecordBatch::try_new(
+            Arc::clone(&GET_CATALOG_SCHEMA),
+            vec![Arc::new(StringArray::from_iter_values(catalogs)) as _],
+        )?;
+
+        Ok(batch)
+    }
+
+    /// Returns the schema that will result from [`CommandGetCatalogs`]
+    ///
+    /// [`CommandGetCatalogs`]: crate::sql::CommandGetCatalogs
+    pub fn schema(&self) -> SchemaRef {
+        get_catalogs_schema()
+    }
+}
+
+fn get_catalogs_schema() -> SchemaRef {
+    Arc::clone(&GET_CATALOG_SCHEMA)
+}
+
+/// The schema for GetCatalogs
+static GET_CATALOG_SCHEMA: Lazy<SchemaRef> = Lazy::new(|| {
+    Arc::new(Schema::new(vec![Field::new(
+        "catalog_name",
+        DataType::Utf8,
+        false,
+    )]))
+});
diff --git a/arrow-flight/src/sql/catalogs/db_schemas.rs b/arrow-flight/src/sql/metadata/db_schemas.rs
similarity index 89%
rename from arrow-flight/src/sql/catalogs/db_schemas.rs
rename to arrow-flight/src/sql/metadata/db_schemas.rs
index 76c5499c8..7b10e1c14 100644
--- a/arrow-flight/src/sql/catalogs/db_schemas.rs
+++ b/arrow-flight/src/sql/metadata/db_schemas.rs
@@ -15,7 +15,7 @@
 // specific language governing permissions and limitations
 // under the License.
 
-//! [`GetSchemasBuilder`] for building responses to [`CommandGetDbSchemas`] queries.
+//! [`GetDbSchemasBuilder`] for building responses to [`CommandGetDbSchemas`] queries.
 //!
 //! [`CommandGetDbSchemas`]: crate::sql::CommandGetDbSchemas
 
@@ -33,26 +33,13 @@ use super::lexsort_to_indices;
 use crate::error::*;
 use crate::sql::CommandGetDbSchemas;
 
-/// Return the schema of the RecordBatch that will be returned from [`CommandGetDbSchemas`]
+/// A builder for a [`CommandGetDbSchemas`] response.
 ///
-/// [`CommandGetDbSchemas`]: crate::sql::CommandGetDbSchemas
-pub fn get_db_schemas_schema() -> SchemaRef {
-    Arc::clone(&GET_DB_SCHEMAS_SCHEMA)
-}
-
-/// The schema for GetDbSchemas
-static GET_DB_SCHEMAS_SCHEMA: Lazy<SchemaRef> = Lazy::new(|| {
-    Arc::new(Schema::new(vec![
-        Field::new("catalog_name", DataType::Utf8, false),
-        Field::new("db_schema_name", DataType::Utf8, false),
-    ]))
-});
-
 /// Builds rows like this:
 ///
 /// * catalog_name: utf8,
 /// * db_schema_name: utf8,
-pub struct GetSchemasBuilder {
+pub struct GetDbSchemasBuilder {
     // Specifies the Catalog to search for the tables.
     // - An empty string retrieves those without a catalog.
     // - If omitted the catalog name is not used to narrow the search.
@@ -66,19 +53,20 @@ pub struct GetSchemasBuilder {
 }
 
 impl CommandGetDbSchemas {
-    pub fn into_builder(self) -> GetSchemasBuilder {
+    /// Create a builder suitable for constructing a response
+    pub fn into_builder(self) -> GetDbSchemasBuilder {
         self.into()
     }
 }
 
-impl From<CommandGetDbSchemas> for GetSchemasBuilder {
+impl From<CommandGetDbSchemas> for GetDbSchemasBuilder {
     fn from(value: CommandGetDbSchemas) -> Self {
         Self::new(value.catalog, value.db_schema_filter_pattern)
     }
 }
 
-impl GetSchemasBuilder {
-    /// Create a new instance of [`GetSchemasBuilder`]
+impl GetDbSchemasBuilder {
+    /// Create a new instance of [`GetDbSchemasBuilder`]
     ///
     /// # Parameters
     ///
@@ -118,6 +106,7 @@ impl GetSchemasBuilder {
 
     /// builds a `RecordBatch` with the correct schema for a `CommandGetDbSchemas` response
     pub fn build(self) -> Result<RecordBatch> {
+        let schema = self.schema();
         let Self {
             catalog_filter,
             db_schema_filter_pattern,
@@ -154,7 +143,7 @@ impl GetSchemasBuilder {
         }
 
         let batch = RecordBatch::try_new(
-            get_db_schemas_schema(),
+            schema,
             vec![
                 Arc::new(catalog_name) as ArrayRef,
                 Arc::new(db_schema_name) as ArrayRef,
@@ -176,10 +165,28 @@ impl GetSchemasBuilder {
             .map(|c| take(c, &indices, None))
             .collect::<std::result::Result<Vec<_>, _>>()?;
 
-        Ok(RecordBatch::try_new(get_db_schemas_schema(), columns)?)
+        Ok(RecordBatch::try_new(filtered_batch.schema(), columns)?)
     }
+
+    /// Return the schema of the RecordBatch that will be returned
+    /// from [`CommandGetDbSchemas`]
+    pub fn schema(&self) -> SchemaRef {
+        get_db_schemas_schema()
+    }
+}
+
+fn get_db_schemas_schema() -> SchemaRef {
+    Arc::clone(&GET_DB_SCHEMAS_SCHEMA)
 }
 
+/// The schema for GetDbSchemas
+static GET_DB_SCHEMAS_SCHEMA: Lazy<SchemaRef> = Lazy::new(|| {
+    Arc::new(Schema::new(vec![
+        Field::new("catalog_name", DataType::Utf8, false),
+        Field::new("db_schema_name", DataType::Utf8, false),
+    ]))
+});
+
 #[cfg(test)]
 mod tests {
     use super::*;
@@ -207,7 +214,7 @@ mod tests {
     fn test_schemas_are_filtered() {
         let ref_batch = get_ref_batch();
 
-        let mut builder = GetSchemasBuilder::new(None::<String>, None::<String>);
+        let mut builder = GetDbSchemasBuilder::new(None::<String>, None::<String>);
         builder.append("a_catalog", "a_schema");
         builder.append("a_catalog", "b_schema");
         builder.append("b_catalog", "a_schema");
@@ -216,7 +223,7 @@ mod tests {
 
         assert_eq!(schema_batch, ref_batch);
 
-        let mut builder = GetSchemasBuilder::new(None::<String>, Some("a%"));
+        let mut builder = GetDbSchemasBuilder::new(None::<String>, Some("a%"));
         builder.append("a_catalog", "a_schema");
         builder.append("a_catalog", "b_schema");
         builder.append("b_catalog", "a_schema");
@@ -242,7 +249,7 @@ mod tests {
     fn test_schemas_are_sorted() {
         let ref_batch = get_ref_batch();
 
-        let mut builder = GetSchemasBuilder::new(None::<String>, None::<String>);
+        let mut builder = GetDbSchemasBuilder::new(None::<String>, None::<String>);
         builder.append("a_catalog", "b_schema");
         builder.append("b_catalog", "a_schema");
         builder.append("a_catalog", "a_schema");
diff --git a/arrow-flight/src/sql/metadata/mod.rs b/arrow-flight/src/sql/metadata/mod.rs
new file mode 100644
index 000000000..9d3810806
--- /dev/null
+++ b/arrow-flight/src/sql/metadata/mod.rs
@@ -0,0 +1,55 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+//! Builders and function for building responses to FlightSQL metadata
+//! / information schema requests.
+//!
+//! - [`GetCatalogsBuilder`] for building responses to [`CommandGetCatalogs`] queries.
+//! - [`GetDbSchemasBuilder`] for building responses to [`CommandGetDbSchemas`] queries.
+//! - [`GetTablesBuilder`]for building responses to [`CommandGetTables`] queries.
+//!
+//! [`CommandGetCatalogs`]: crate::sql::CommandGetCatalogs
+//! [`CommandGetDbSchemas`]: crate::sql::CommandGetDbSchemas
+//! [`CommandGetTables`]: crate::sql::CommandGetTables
+
+mod catalogs;
+mod db_schemas;
+mod sql_info;
+mod tables;
+
+pub use catalogs::GetCatalogsBuilder;
+pub use db_schemas::GetDbSchemasBuilder;
+pub use sql_info::SqlInfoList;
+pub use tables::GetTablesBuilder;
+
+use arrow_array::ArrayRef;
+use arrow_array::UInt32Array;
+use arrow_row::RowConverter;
+use arrow_row::SortField;
+
+/// Helper function to sort all the columns in an array
+fn lexsort_to_indices(arrays: &[ArrayRef]) -> UInt32Array {
+    let fields = arrays
+        .iter()
+        .map(|a| SortField::new(a.data_type().clone()))
+        .collect();
+    let mut converter = RowConverter::new(fields).unwrap();
+    let rows = converter.convert_columns(arrays).unwrap();
+    let mut sort: Vec<_> = rows.iter().enumerate().collect();
+    sort.sort_unstable_by(|(_, a), (_, b)| a.cmp(b));
+    UInt32Array::from_iter_values(sort.iter().map(|(i, _)| *i as u32))
+}
diff --git a/arrow-flight/src/sql/sql_info.rs b/arrow-flight/src/sql/metadata/sql_info.rs
similarity index 99%
rename from arrow-flight/src/sql/sql_info.rs
rename to arrow-flight/src/sql/metadata/sql_info.rs
index f0d14ff8a..3dcee1e58 100644
--- a/arrow-flight/src/sql/sql_info.rs
+++ b/arrow-flight/src/sql/metadata/sql_info.rs
@@ -33,8 +33,8 @@ use arrow_data::ArrayData;
 use arrow_schema::{DataType, Field, Fields, Schema, UnionFields, UnionMode};
 use once_cell::sync::Lazy;
 
-use super::SqlInfo;
 use crate::error::Result;
+use crate::sql::SqlInfo;
 
 /// Represents a dynamic value
 #[derive(Debug, Clone, PartialEq)]
@@ -321,7 +321,7 @@ impl SqlInfoUnionBuilder {
     }
 }
 
-/// A list of FlightSQL server capabilties.
+/// A builder for [`CommandGetSqlInfo`] response.
 ///
 /// [`CommandGetSqlInfo`] are metadata requests used by a Flight SQL
 /// server to communicate supported capabilities to Flight SQL
@@ -334,7 +334,7 @@ impl SqlInfoUnionBuilder {
 ///
 /// # Example
 /// ```
-/// # use arrow_flight::sql::{SqlInfoList, SqlInfo, SqlSupportedTransaction};
+/// # use arrow_flight::sql::{metadata::SqlInfoList, SqlInfo, SqlSupportedTransaction};
 /// // Create the list of metadata describing the server
 /// let info_list = SqlInfoList::new()
 ///     .with_sql_info(SqlInfo::FlightSqlServerName, "server name")
diff --git a/arrow-flight/src/sql/catalogs/tables.rs b/arrow-flight/src/sql/metadata/tables.rs
similarity index 95%
rename from arrow-flight/src/sql/catalogs/tables.rs
rename to arrow-flight/src/sql/metadata/tables.rs
index fcdc0dbb7..67193969d 100644
--- a/arrow-flight/src/sql/catalogs/tables.rs
+++ b/arrow-flight/src/sql/metadata/tables.rs
@@ -35,19 +35,8 @@ use crate::error::*;
 use crate::sql::CommandGetTables;
 use crate::{IpcMessage, IpcWriteOptions, SchemaAsIpc};
 
-/// Return the schema of the RecordBatch that will be returned from [`CommandGetTables`]
+/// A builder for a [`CommandGetTables`] response.
 ///
-/// Note the schema differs based on the values of `include_schema
-///
-/// [`CommandGetTables`]: crate::sql::CommandGetTables
-pub fn get_tables_schema(include_schema: bool) -> SchemaRef {
-    if include_schema {
-        Arc::clone(&GET_TABLES_SCHEMA_WITH_TABLE_SCHEMA)
-    } else {
-        Arc::clone(&GET_TABLES_SCHEMA_WITHOUT_TABLE_SCHEMA)
-    }
-}
-
 /// Builds rows like this:
 ///
 /// * catalog_name: utf8,
@@ -76,6 +65,7 @@ pub struct GetTablesBuilder {
 }
 
 impl CommandGetTables {
+    /// Create a builder suitable for constructing a response
     pub fn into_builder(self) -> GetTablesBuilder {
         self.into()
     }
@@ -96,7 +86,7 @@ impl From<CommandGetTables> for GetTablesBuilder {
 impl GetTablesBuilder {
     /// Create a new instance of [`GetTablesBuilder`]
     ///
-    /// # Paramneters
+    /// # Parameters
     ///
     /// - `catalog`:  Specifies the Catalog to search for the tables.
     ///   - An empty string retrieves those without a catalog.
@@ -168,6 +158,7 @@ impl GetTablesBuilder {
 
     /// builds a `RecordBatch` for `CommandGetTables`
     pub fn build(self) -> Result<RecordBatch> {
+        let schema = self.schema();
         let Self {
             catalog_filter,
             table_types_filter,
@@ -220,10 +211,9 @@ impl GetTablesBuilder {
             filters.push(like_utf8_scalar(&table_name, &table_name_filter_pattern)?)
         }
 
-        let include_schema = table_schema.is_some();
         let batch = if let Some(table_schema) = table_schema {
             RecordBatch::try_new(
-                get_tables_schema(include_schema),
+                schema,
                 vec![
                     Arc::new(catalog_name) as ArrayRef,
                     Arc::new(db_schema_name) as ArrayRef,
@@ -234,7 +224,8 @@ impl GetTablesBuilder {
             )
         } else {
             RecordBatch::try_new(
-                get_tables_schema(include_schema),
+                // schema is different if table_schema is none
+                schema,
                 vec![
                     Arc::new(catalog_name) as ArrayRef,
                     Arc::new(db_schema_name) as ArrayRef,
@@ -271,10 +262,29 @@ impl GetTablesBuilder {
             .map(|c| take(c, &indices, None))
             .collect::<std::result::Result<Vec<_>, _>>()?;
 
-        Ok(RecordBatch::try_new(
-            get_tables_schema(include_schema),
-            columns,
-        )?)
+        Ok(RecordBatch::try_new(filtered_batch.schema(), columns)?)
+    }
+
+    /// Return the schema of the RecordBatch that will be returned from [`CommandGetTables`]
+    ///
+    /// Note the schema differs based on the values of `include_schema
+    ///
+    /// [`CommandGetTables`]: crate::sql::CommandGetTables
+    pub fn schema(&self) -> SchemaRef {
+        get_tables_schema(self.include_schema())
+    }
+
+    /// Should the "schema" column be included
+    pub fn include_schema(&self) -> bool {
+        self.table_schema.is_some()
+    }
+}
+
+fn get_tables_schema(include_schema: bool) -> SchemaRef {
+    if include_schema {
+        Arc::clone(&GET_TABLES_SCHEMA_WITH_TABLE_SCHEMA)
+    } else {
+        Arc::clone(&GET_TABLES_SCHEMA_WITHOUT_TABLE_SCHEMA)
     }
 }
 
diff --git a/arrow-flight/src/sql/mod.rs b/arrow-flight/src/sql/mod.rs
index 212655d66..4bb8ce8b3 100644
--- a/arrow-flight/src/sql/mod.rs
+++ b/arrow-flight/src/sql/mod.rs
@@ -27,7 +27,7 @@
 //! 2. Helpers for encoding and decoding FlightSQL messages: [`Any`] and [`Command`]
 //! 3. A [`FlightSqlServiceClient`] for interacting with FlightSQL servers.
 //! 4. A [`FlightSqlService`] to help building FlightSQL servers from [`FlightService`].
-//! 5. Structures to build responses for FlightSQL metadata APIs: [`SqlInfoList`]
+//! 5. Helpers to build responses for FlightSQL metadata APIs: [`metadata`]
 //!
 //! [Flight SQL]: https://arrow.apache.org/docs/format/FlightSql.html
 //! [Apache Arrow]: https://arrow.apache.org
@@ -37,6 +37,7 @@
 //! [`do_get`]: crate::flight_service_server::FlightService::do_get
 //! [`FlightSqlServiceClient`]: client::FlightSqlServiceClient
 //! [`FlightSqlService`]: server::FlightSqlService
+//! [`metadata`]: crate::sql::metadata
 use arrow_schema::ArrowError;
 use bytes::Bytes;
 use paste::paste;
@@ -98,12 +99,9 @@ pub use gen::UpdateDeleteRules;
 pub use gen::XdbcDataType;
 pub use gen::XdbcDatetimeSubcode;
 
-pub use sql_info::SqlInfoList;
-
-pub mod catalogs;
 pub mod client;
+pub mod metadata;
 pub mod server;
-pub mod sql_info;
 
 /// ProstMessageExt are useful utility methods for prost::Message types
 pub trait ProstMessageExt: prost::Message + Default {