Skip to content

Commit

Permalink
cleaning
Browse files Browse the repository at this point in the history
  • Loading branch information
andicuko committed Sep 27, 2024
1 parent cb866dc commit 4d99bc3
Show file tree
Hide file tree
Showing 7 changed files with 149 additions and 6,340 deletions.
34 changes: 17 additions & 17 deletions examples/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -110,32 +110,32 @@ fn print_ast(query: &str) -> Result<(), &'static str> {
fn main() -> Result<(), &'static str> {
build_ast()?;

// // Print an AST with a subquery
// // print_ast("select * from (select count(a) as c from sch.tbl)");
// Print an AST with a subquery
// print_ast("select * from (select count(a) as c from sch.tbl)");

// // Print an AST with a JOIN
// print_ast("select * from sch.tbl1 LEFT OUTER JOIN sch.tbl2 ON tbl1.id = tbl2.id LIMIT 100")?;
// Print an AST with a JOIN
print_ast("select * from sch.tbl1 LEFT OUTER JOIN sch.tbl2 ON tbl1.id = tbl2.id LIMIT 100")?;

// // Print an AST with CTEs
// // print_ast("WITH cte_tbl AS (select a, b FROM sch.tbl1) select * from cte_tbl");
// Print an AST with CTEs
// print_ast("WITH cte_tbl AS (select a, b FROM sch.tbl1) select * from cte_tbl");

// // Print an AST with Insert
// print_ast("INSERT INTO person (name, data) VALUES (?1, ?2)")?;
// Print an AST with Insert
print_ast("INSERT INTO person (name, data) VALUES (?1, ?2)")?;

// // Print a UNION
// print_ast("SELECT * FROM table_1 10 UNION SELECT * FROM table_2")?;
// Print a UNION
print_ast("SELECT * FROM table_1 10 UNION SELECT * FROM table_2")?;

// // Print an expression with nesting
// print_ast("SELECT (a+b)*(c+d) FROM table_1")?;
// Print an expression with nesting
print_ast("SELECT (a+b)*(c+d) FROM table_1")?;

// // Print an AST with Values
// print_ast("SELECT a FROM (VALUES (1), (2), (3)) AS t1 (possible_values);")?;
// Print an AST with Values
print_ast("SELECT a FROM (VALUES (1), (2), (3)) AS t1 (possible_values);")?;

// // Print an AST with Values
// print_ast("(VALUES (1), (2), (3)) AS t1")?;
// Print an AST with Values
print_ast("(VALUES (1), (2), (3)) AS t1")?;

// Print an AST with count(*)
print_ast(r#"SELECT NOT ("field_vzkb" IS NULL) FROM table_1"#)?;
print_ast("SELECT COUNT(*) FROM table_1")?;

Ok(())
}
103 changes: 76 additions & 27 deletions src/dialect_translation/hive.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,34 @@
use super::{function_builder, QueryToRelationTranslator, RelationToQueryTranslator};
use crate::expr::{self};
use crate::{
expr::{self},
relation::{Join, Variant as _},
};
use sqlparser::{ast, dialect::HiveDialect};

#[derive(Clone, Copy)]
pub struct HiveTranslator;

//Is the same as MySql for now.
// Using the same translations as in bigquery since it should be similar.
// HiveTranslator is not tested at the moment.
impl RelationToQueryTranslator for HiveTranslator {
fn identifier(&self, value: &expr::Identifier) -> Vec<ast::Ident> {
value
.iter()
.map(|r| ast::Ident::with_quote('`', r))
.collect()
}

fn cte(&self, name: ast::Ident, _columns: Vec<ast::Ident>, query: ast::Query) -> ast::Cte {
ast::Cte {
alias: ast::TableAlias {
name,
columns: vec![],
},
query: Box::new(query),
from: None,
materialized: None,
}
}
fn first(&self, expr: ast::Expr) -> ast::Expr {
expr
}
Expand All @@ -22,43 +44,70 @@ impl RelationToQueryTranslator for HiveTranslator {
fn std(&self, expr: ast::Expr) -> ast::Expr {
function_builder("STDDEV", vec![expr], false)
}

fn identifier(&self, value: &expr::Identifier) -> Vec<ast::Ident> {
value
.iter()
.map(|r| ast::Ident::with_quote('`', r))
.collect()
}

fn random(&self) -> ast::Expr {
function_builder("RAND", vec![], false)
}
/// Converting LOG to LOG10
fn log(&self, expr: ast::Expr) -> ast::Expr {
function_builder("LOG10", vec![expr], false)
}
fn cast_as_text(&self, expr: ast::Expr) -> ast::Expr {
ast::Expr::Cast {
expr: Box::new(expr),
data_type: ast::DataType::Char(None),
data_type: ast::DataType::String(None),
format: None,
kind: ast::CastKind::Cast,
}
}
fn cast_as_float(&self, expr: ast::Expr) -> ast::Expr {
ast::Expr::Cast {
expr: Box::new(expr),
data_type: ast::DataType::Float64,
format: None,
kind: ast::CastKind::Cast,
}
}
fn substr(&self, exprs: Vec<ast::Expr>) -> ast::Expr {
assert!(exprs.len() == 2);
function_builder("SUBSTR", exprs, false)
}
fn substr_with_size(&self, exprs: Vec<ast::Expr>) -> ast::Expr {
assert!(exprs.len() == 3);
function_builder("SUBSTR", exprs, false)
}
/// Converting MD5(X) to TO_HEX(MD5(X))
fn md5(&self, expr: ast::Expr) -> ast::Expr {
let md5_function = function_builder("MD5", vec![expr], false);
function_builder("TO_HEX", vec![md5_function], false)
}
fn random(&self) -> ast::Expr {
function_builder("RAND", vec![], false)
}
fn join_projection(&self, join: &Join) -> Vec<ast::SelectItem> {
join.left()
.schema()
.iter()
.map(|f| self.expr(&expr::Expr::qcol(Join::left_name(), f.name())))
.chain(
join.right()
.schema()
.iter()
.map(|f| self.expr(&expr::Expr::qcol(Join::right_name(), f.name()))),
)
.zip(join.schema().iter())
.map(|(expr, field)| ast::SelectItem::ExprWithAlias {
expr,
alias: field.name().into(),
})
.collect()
}
/// It converts EXTRACT(epoch FROM column) into
/// UNIX_SECONDS(CAST(col AS TIMESTAMP))
fn extract_epoch(&self, expr: ast::Expr) -> ast::Expr {
function_builder("UNIX_TIMESTAMP", vec![expr], false)
}
/// For mysql CAST(expr AS INTEGER) should be converted to
/// CAST(expr AS SIGNED [INTEGER]) which produces a BigInt value.
/// CONVERT can be also used as CONVERT(expr, SIGNED)
/// however st::DataType doesn't support SIGNED [INTEGER].
/// We fix it by creating a function CONVERT(expr, SIGNED).
fn cast_as_integer(&self, expr: ast::Expr) -> ast::Expr {
let signed = ast::Expr::Identifier(ast::Ident {
value: "SIGNED".to_string(),
quote_style: None,
});
function_builder("CONVERT", vec![expr, signed], false)
let cast = ast::Expr::Cast {
expr: Box::new(expr),
data_type: ast::DataType::Timestamp(None, ast::TimezoneInfo::None),
format: None,
kind: ast::CastKind::Cast,
};
function_builder("UNIX_SECONDS", vec![cast], false)
}
}

Expand Down
40 changes: 32 additions & 8 deletions src/dialect_translation/mssql.rs
Original file line number Diff line number Diff line change
Expand Up @@ -270,7 +270,7 @@ impl QueryToRelationTranslator for MsSqlTranslator {
context: &Hierarchy<expr::Identifier>,
) -> Result<expr::Expr> {
let function_name: &str = &func.name.0.iter().next().unwrap().value.to_lowercase()[..];
println!("{}", function_name);

match function_name {
"log" => self.try_ln(func, context),
"log10" => self.try_log(func, context),
Expand Down Expand Up @@ -497,7 +497,7 @@ mod tests {
let mut database = mssql::test_database();
let relations = database.relations();

let query = "SELECT COALESCE(a, NULL) FROM table_1 LIMIT 30";
let query = "SELECT COALESCE(a) FROM table_1 LIMIT 30";

let relation = Relation::try_from(With::with(&parse(query).unwrap(), &relations)).unwrap();
relation.display_dot().unwrap();
Expand Down Expand Up @@ -525,7 +525,7 @@ mod tests {

#[test]
fn test_not() {
// let mut database = mssql::test_database();
let mut database = mssql::test_database();
let schema: Schema = vec![("a", DataType::optional(DataType::float()))]
.into_iter()
.collect();
Expand All @@ -539,18 +539,42 @@ mod tests {

let relations = Hierarchy::from([(vec!["table_2"], table)]);

let query = "WITH new_tab AS (SELECT NOT (a IS NULL) AS col FROM table_2) SELECT * FROM new_tab WHERE RANDOM()) < (0.9) ";
// let query = "SELECT DISTINCT a FROM table_2 LIMIT 10";
let query = "SELECT NOT (a IS NULL) AS col FROM table_2";

let relation = Relation::try_from(With::with(&parse(query).unwrap(), &relations)).unwrap();
relation.display_dot().unwrap();

let rel_with_traslator = RelationWithTranslator(&relation, MsSqlTranslator);
let translated_query = ast::Query::from(rel_with_traslator);
println!("{:?}", translated_query);
println!("\n{}\n", translated_query);
println!("{}", translated_query);
let _ = database.query(&translated_query.to_string()[..]).unwrap();
}

#[test]
fn test_where_rand() {
let mut database = mssql::test_database();
let schema: Schema = vec![("a", DataType::optional(DataType::float()))]
.into_iter()
.collect();
let table: Arc<Relation> = Arc::new(
Relation::table()
.name("table_2")
.schema(schema.clone())
.size(100)
.build(),
);

let relations = Hierarchy::from([(vec!["table_2"], table)]);

let query = "SELECT * FROM new_tab WHERE RANDOM()) < (0.5)";

// let _ = database.query(translated_query).unwrap();
let relation = Relation::try_from(With::with(&parse(query).unwrap(), &relations)).unwrap();
relation.display_dot().unwrap();

let rel_with_traslator = RelationWithTranslator(&relation, MsSqlTranslator);
let translated_query = ast::Query::from(rel_with_traslator);
println!("{}", translated_query);
let _ = database.query(&translated_query.to_string()).unwrap();
}

#[test]
Expand Down
2 changes: 1 addition & 1 deletion src/dialect_translation/mysql.rs
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ impl RelationToQueryTranslator for MySqlTranslator {
/// For mysql CAST(expr AS INTEGER) should be converted to
/// CAST(expr AS SIGNED [INTEGER]) which produces a BigInt value.
/// CONVERT can be also used as CONVERT(expr, SIGNED)
/// however st::DataType doesn't support SIGNED [INTEGER].
/// however ast::DataType doesn't support SIGNED [INTEGER].
/// We fix it by creating a function CONVERT(expr, SIGNED).
fn cast_as_integer(&self, expr: ast::Expr) -> ast::Expr {
let signed = ast::Expr::Identifier(ast::Ident {
Expand Down
Loading

0 comments on commit 4d99bc3

Please sign in to comment.