Skip to content

Commit

Permalink
Add an experimental transpile command
Browse files Browse the repository at this point in the history
This is still pretty basic.
  • Loading branch information
emk committed Oct 23, 2023
1 parent d46740a commit 5521d70
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 0 deletions.
1 change: 1 addition & 0 deletions src/cmd/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@
pub mod parse;
pub mod sql_test;
pub mod transpile;
50 changes: 50 additions & 0 deletions src/cmd/transpile.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
//! Transpile code to another dialect of SQL.
use std::path::PathBuf;

use clap::Parser;
use tracing::instrument;

use crate::{
ast::{parse_sql, Emit},
drivers,
errors::{Context, Result},
};

/// Run SQL tests from a directory.
#[derive(Debug, Parser)]
pub struct TranspileOpt {
/// An SQL file to transpile.
sql_path: PathBuf,

/// A database locator to run tests against. (For now, this must be a
/// an actual database locator, and not the name of a dialect.)
#[clap(long, visible_alias = "db", default_value = "sqlite3::memory:")]
database: String,
}

/// Run our SQL test suite.
#[instrument(skip(opt))]
pub async fn cmd_transpile(opt: &TranspileOpt) -> Result<()> {
// Get a database driver for our target.
let locator = opt.database.parse::<Box<dyn drivers::Locator>>()?;
let driver = locator.driver().await?;

// Parse our SQL.
let sql = tokio::fs::read_to_string(&opt.sql_path)
.await
.with_context(|| format!("could not read SQL file {}", opt.sql_path.display()))?;
let ast = parse_sql(&opt.sql_path, &sql)?;
let rewritten_ast = driver.rewrite_ast(&ast)?;

// Print our rewritten AST.
for statement in rewritten_ast.extra.native_setup_sql {
println!("{};", statement);
}
let transpiled_sql = rewritten_ast.ast.emit_to_string(locator.target());
println!("{}", transpiled_sql);
for statement in rewritten_ast.extra.native_teardown_sql {
println!("{};", statement);
}
Ok(())
}
4 changes: 4 additions & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ mod util;
use cmd::{
parse::{cmd_parse, ParseOpt},
sql_test::{cmd_sql_test, SqlTestOpt},
transpile::{cmd_transpile, TranspileOpt},
};
use tracing::info_span;

Expand All @@ -23,6 +24,8 @@ enum Opt {
Parse(ParseOpt),
/// Run SQL tests from a directory.
SqlTest(SqlTestOpt),
/// Transpile BigQuery SQL to another dialect.
Transpile(TranspileOpt),
}

#[tokio::main]
Expand All @@ -35,6 +38,7 @@ async fn main() {
let result = match opt {
Opt::Parse(parse_opt) => cmd_parse(&parse_opt),
Opt::SqlTest(sql_test_opt) => cmd_sql_test(&sql_test_opt).await,
Opt::Transpile(transpile_opt) => cmd_transpile(&transpile_opt).await,
};
if let Err(e) = result {
e.emit();
Expand Down

0 comments on commit 5521d70

Please sign in to comment.