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

comphead pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/datafusion.git


The following commit(s) were added to refs/heads/main by this push:
     new a2a6458e42 Minor: improve documentation for sql unparsing (#11395)
a2a6458e42 is described below

commit a2a6458e420209c7125b08966c5726b5fd104195
Author: Andrew Lamb <[email protected]>
AuthorDate: Fri Jul 12 11:53:03 2024 -0400

    Minor: improve documentation for sql unparsing (#11395)
---
 datafusion/sql/src/lib.rs           |  6 +++-
 datafusion/sql/src/unparser/expr.rs | 29 ++++++++++++-----
 datafusion/sql/src/unparser/mod.rs  | 64 +++++++++++++++++++++++++++++++++++--
 datafusion/sql/src/unparser/plan.rs | 24 ++++++++++----
 4 files changed, 105 insertions(+), 18 deletions(-)

diff --git a/datafusion/sql/src/lib.rs b/datafusion/sql/src/lib.rs
index eb5fec7a3c..f53cab5df8 100644
--- a/datafusion/sql/src/lib.rs
+++ b/datafusion/sql/src/lib.rs
@@ -17,7 +17,7 @@
 // Make cheap clones clear: https://github.com/apache/datafusion/issues/11143
 #![deny(clippy::clone_on_ref_ptr)]
 
-//! This module provides:
+//! This crate provides:
 //!
 //! 1. A SQL parser, [`DFParser`], that translates SQL query text into
 //! an abstract syntax tree (AST), [`Statement`].
@@ -25,10 +25,14 @@
 //! 2. A SQL query planner [`SqlToRel`] that creates [`LogicalPlan`]s
 //! from [`Statement`]s.
 //!
+//! 3. A SQL [`unparser`] that converts [`Expr`]s and [`LogicalPlan`]s
+//! into SQL query text.
+//!
 //! [`DFParser`]: parser::DFParser
 //! [`Statement`]: parser::Statement
 //! [`SqlToRel`]: planner::SqlToRel
 //! [`LogicalPlan`]: datafusion_expr::logical_plan::LogicalPlan
+//! [`Expr`]: datafusion_expr::expr::Expr
 
 mod cte;
 mod expr;
diff --git a/datafusion/sql/src/unparser/expr.rs 
b/datafusion/sql/src/unparser/expr.rs
index e0d05c400c..eb149c819c 100644
--- a/datafusion/sql/src/unparser/expr.rs
+++ b/datafusion/sql/src/unparser/expr.rs
@@ -72,21 +72,34 @@ impl Display for Unparsed {
     }
 }
 
-/// Convert a DataFusion [`Expr`] to `sqlparser::ast::Expr`
+/// Convert a DataFusion [`Expr`] to [`ast::Expr`]
 ///
-/// This function is the opposite of `SqlToRel::sql_to_expr` and can
-/// be used to, among other things, convert [`Expr`]s to strings.
-/// Throws an error if [`Expr`] can not be represented by an 
`sqlparser::ast::Expr`
+/// This function is the opposite of [`SqlToRel::sql_to_expr`] and can be used
+/// to, among other things, convert [`Expr`]s to SQL strings. Such strings 
could
+/// be used to pass filters or other expressions to another SQL engine.
+///
+/// # Errors
+///
+/// Throws an error if [`Expr`] can not be represented by an [`ast::Expr`]
+///
+/// # See Also
+///
+/// * [`Unparser`] for more control over the conversion to SQL
+/// * [`plan_to_sql`] for converting a [`LogicalPlan`] to SQL
 ///
 /// # Example
 /// ```
 /// use datafusion_expr::{col, lit};
 /// use datafusion_sql::unparser::expr_to_sql;
-/// let expr = col("a").gt(lit(4));
-/// let sql = expr_to_sql(&expr).unwrap();
-///
-/// assert_eq!(format!("{}", sql), "(a > 4)")
+/// let expr = col("a").gt(lit(4)); // form an expression `a > 4`
+/// let sql = expr_to_sql(&expr).unwrap(); // convert to ast::Expr
+/// // use the Display impl to convert to SQL text
+/// assert_eq!(sql.to_string(), "(a > 4)")
 /// ```
+///
+/// [`SqlToRel::sql_to_expr`]: crate::planner::SqlToRel::sql_to_expr
+/// [`plan_to_sql`]: crate::unparser::plan_to_sql
+/// [`LogicalPlan`]: datafusion_expr::logical_plan::LogicalPlan
 pub fn expr_to_sql(expr: &Expr) -> Result<ast::Expr> {
     let unparser = Unparser::default();
     unparser.expr_to_sql(expr)
diff --git a/datafusion/sql/src/unparser/mod.rs 
b/datafusion/sql/src/unparser/mod.rs
index e5ffbc8a21..83ae64ba23 100644
--- a/datafusion/sql/src/unparser/mod.rs
+++ b/datafusion/sql/src/unparser/mod.rs
@@ -15,6 +15,8 @@
 // specific language governing permissions and limitations
 // under the License.
 
+//! [`Unparser`] for converting `Expr` to SQL text
+
 mod ast;
 mod expr;
 mod plan;
@@ -27,6 +29,29 @@ pub use plan::plan_to_sql;
 use self::dialect::{DefaultDialect, Dialect};
 pub mod dialect;
 
+/// Convert a DataFusion [`Expr`] to [`sqlparser::ast::Expr`]
+///
+/// See [`expr_to_sql`] for background. `Unparser` allows greater control of
+/// the conversion, but with a more complicated API.
+///
+/// To get more human-readable output, see [`Self::with_pretty`]
+///
+/// # Example
+/// ```
+/// use datafusion_expr::{col, lit};
+/// use datafusion_sql::unparser::Unparser;
+/// let expr = col("a").gt(lit(4)); // form an expression `a > 4`
+/// let unparser = Unparser::default();
+/// let sql = unparser.expr_to_sql(&expr).unwrap();// convert to AST
+/// // use the Display impl to convert to SQL text
+/// assert_eq!(sql.to_string(), "(a > 4)");
+/// // now convert to pretty sql
+/// let unparser = unparser.with_pretty(true);
+/// let sql = unparser.expr_to_sql(&expr).unwrap();
+/// assert_eq!(sql.to_string(), "a > 4"); // note lack of parenthesis
+/// ```
+///
+/// [`Expr`]: datafusion_expr::Expr
 pub struct Unparser<'a> {
     dialect: &'a dyn Dialect,
     pretty: bool,
@@ -40,9 +65,42 @@ impl<'a> Unparser<'a> {
         }
     }
 
-    /// Allow unparser to remove parenthesis according to the precedence rules 
of DataFusion.
-    /// This might make it invalid SQL for other SQL query engines with 
different precedence
-    /// rules, even if its valid for DataFusion.
+    /// Create pretty SQL output, better suited for human consumption
+    ///
+    /// See example on the struct level documentation
+    ///
+    /// # Pretty Output
+    ///
+    /// By default, `Unparser` generates SQL text that will parse back to the
+    /// same parsed [`Expr`], which is useful for creating machine readable
+    /// expressions to send to other systems. However, the resulting 
expressions are
+    /// not always nice to read for humans.
+    ///
+    /// For example
+    ///
+    /// ```sql
+    /// ((a + 4) > 5)
+    /// ```
+    ///
+    /// This method removes parenthesis using to the precedence rules of
+    /// DataFusion. If the output is reparsed, the resulting [`Expr`] produces
+    /// same value as the original in DataFusion, but with a potentially
+    /// different order of operations.
+    ///
+    /// Note that this setting may create invalid SQL for other SQL query
+    /// engines with different precedence rules
+    ///
+    /// # Example
+    /// ```
+    /// use datafusion_expr::{col, lit};
+    /// use datafusion_sql::unparser::Unparser;
+    /// let expr = col("a").gt(lit(4)).and(col("b").lt(lit(5))); // form an 
expression `a > 4 AND b < 5`
+    /// let unparser = Unparser::default().with_pretty(true);
+    /// let sql = unparser.expr_to_sql(&expr).unwrap();
+    /// assert_eq!(sql.to_string(), "a > 4 AND b < 5"); // note lack of 
parenthesis
+    /// ```
+    ///
+    /// [`Expr`]: datafusion_expr::Expr
     pub fn with_pretty(mut self, pretty: bool) -> Self {
         self.pretty = pretty;
         self
diff --git a/datafusion/sql/src/unparser/plan.rs 
b/datafusion/sql/src/unparser/plan.rs
index 15137403c5..41a8c96884 100644
--- a/datafusion/sql/src/unparser/plan.rs
+++ b/datafusion/sql/src/unparser/plan.rs
@@ -33,10 +33,18 @@ use super::{
     Unparser,
 };
 
-/// Convert a DataFusion [`LogicalPlan`] to `sqlparser::ast::Statement`
+/// Convert a DataFusion [`LogicalPlan`] to [`ast::Statement`]
 ///
-/// This function is the opposite of `SqlToRel::sql_statement_to_plan` and can
-/// be used to, among other things, convert `LogicalPlan`s to strings.
+/// This function is the opposite of [`SqlToRel::sql_statement_to_plan`] and 
can
+/// be used to, among other things, to convert `LogicalPlan`s to SQL strings.
+///
+/// # Errors
+///
+/// This function returns an error if the plan cannot be converted to SQL.
+///
+/// # See Also
+///
+/// * [`expr_to_sql`] for converting [`Expr`], a single expression to SQL
 ///
 /// # Example
 /// ```
@@ -47,16 +55,20 @@ use super::{
 ///     Field::new("id", DataType::Utf8, false),
 ///     Field::new("value", DataType::Utf8, false),
 /// ]);
+/// // Scan 'table' and select columns 'id' and 'value'
 /// let plan = table_scan(Some("table"), &schema, None)
 ///     .unwrap()
 ///     .project(vec![col("id"), col("value")])
 ///     .unwrap()
 ///     .build()
 ///     .unwrap();
-/// let sql = plan_to_sql(&plan).unwrap();
-///
-/// assert_eq!(format!("{}", sql), "SELECT \"table\".id, \"table\".\"value\" 
FROM \"table\"")
+/// let sql = plan_to_sql(&plan).unwrap(); // convert to AST
+/// // use the Display impl to convert to SQL text
+/// assert_eq!(sql.to_string(), "SELECT \"table\".id, \"table\".\"value\" FROM 
\"table\"")
 /// ```
+///
+/// [`SqlToRel::sql_statement_to_plan`]: 
crate::planner::SqlToRel::sql_statement_to_plan
+/// [`expr_to_sql`]: crate::unparser::expr_to_sql
 pub fn plan_to_sql(plan: &LogicalPlan) -> Result<ast::Statement> {
     let unparser = Unparser::default();
     unparser.plan_to_sql(plan)


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to