28 major breaking releases

38.0.0 May 10, 2024
37.1.0 Apr 22, 2024
36.0.0 Feb 19, 2024
35.0.0 Jan 25, 2024
9.0.0 Jun 13, 2022

#1 in #sql-parser

Download history 36756/week @ 2024-01-29 43178/week @ 2024-02-05 50472/week @ 2024-02-12 40454/week @ 2024-02-19 53871/week @ 2024-02-26 52784/week @ 2024-03-04 55742/week @ 2024-03-11 53400/week @ 2024-03-18 44379/week @ 2024-03-25 45858/week @ 2024-04-01 42406/week @ 2024-04-08 72074/week @ 2024-04-15 90358/week @ 2024-04-22 82317/week @ 2024-04-29 82617/week @ 2024-05-06 93270/week @ 2024-05-13

351,093 downloads per month
Used in 102 crates (9 directly)

Apache-2.0

2MB
42K SLoC

DataFusion SQL Query Planner

This crate provides a general purpose SQL query planner that can parse SQL and translate queries into logical plans. Although this crate is used by the DataFusion query engine, it was designed to be easily usable from any project that requires a SQL query planner and does not make any assumptions about how the resulting logical plan will be translated to a physical plan. For example, there is no concept of row-based versus columnar execution in the logical plan.

Example Usage

See the examples directory for fully working examples.

Here is an example of producing a logical plan from a SQL string.

fn main() {
    let sql = "SELECT \
            c.id, c.first_name, c.last_name, \
            COUNT(*) as num_orders, \
            SUM(o.price) AS total_price, \
            SUM(o.price * s.sales_tax) AS state_tax \
        FROM customer c \
        JOIN state s ON c.state = s.id \
        JOIN orders o ON c.id = o.customer_id \
        WHERE o.price > 0 \
        AND c.last_name LIKE 'G%' \
        GROUP BY 1, 2, 3 \
        ORDER BY state_tax DESC";

    // parse the SQL
    let dialect = GenericDialect {}; // or AnsiDialect, or your own dialect ...
    let ast = Parser::parse_sql(&dialect, sql).unwrap();
    let statement = &ast[0];

    // create a logical query plan
    let schema_provider = MySchemaProvider::new();
    let sql_to_rel = SqlToRel::new(&schema_provider);
    let plan = sql_to_rel.sql_statement_to_plan(statement.clone()).unwrap();

    // show the plan
    println!("{:?}", plan);
}

This is the logical plan that is produced from this example. Note that this is an unoptimized logical plan. The datafusion-optimizer crate provides a query optimizer that can be applied to plans produced by this crate.

Sort: state_tax DESC NULLS FIRST
  Projection: c.id, c.first_name, c.last_name, COUNT(Int64(1)) AS num_orders, SUM(o.price) AS total_price, SUM(o.price * s.sales_tax) AS state_tax
    Aggregate: groupBy=[[c.id, c.first_name, c.last_name]], aggr=[[COUNT(Int64(1)), SUM(o.price), SUM(o.price * s.sales_tax)]]
      Filter: o.price > Int64(0) AND c.last_name LIKE Utf8("G%")
        Inner Join: c.id = o.customer_id
          Inner Join: c.state = s.id
            SubqueryAlias: c
              TableScan: customer
            SubqueryAlias: s
              TableScan: state
          SubqueryAlias: o
            TableScan: orders

Dependencies

~14–24MB
~333K SLoC