Skip to content

Commit 7624095

Browse files
committed
Support for joins
1 parent face972 commit 7624095

File tree

4 files changed

+409
-64
lines changed

4 files changed

+409
-64
lines changed

src/dialect/generic_sql.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@ impl Dialect for GenericSqlDialect {
1111
STORED, CSV, PARQUET, LOCATION, WITH, WITHOUT, HEADER, ROW, // SQL types
1212
CHAR, CHARACTER, VARYING, LARGE, OBJECT, VARCHAR, CLOB, BINARY, VARBINARY, BLOB, FLOAT,
1313
REAL, DOUBLE, PRECISION, INT, INTEGER, SMALLINT, BIGINT, NUMERIC, DECIMAL, DEC,
14-
BOOLEAN, DATE, TIME, TIMESTAMP, CASE, WHEN, THEN, ELSE, END,
14+
BOOLEAN, DATE, TIME, TIMESTAMP, CASE, WHEN, THEN, ELSE, END, JOIN, LEFT, RIGHT, FULL,
15+
CROSS, OUTER, INNER, NATURAL, ON, USING,
1516
];
1617
}
1718

src/sqlast/mod.rs

Lines changed: 84 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,8 @@ pub enum ASTNode {
7575
projection: Vec<ASTNode>,
7676
/// FROM
7777
relation: Option<Box<ASTNode>>,
78+
// JOIN
79+
joins: Vec<Join>,
7880
/// WHERE
7981
selection: Option<Box<ASTNode>>,
8082
/// ORDER BY
@@ -167,10 +169,16 @@ impl ToString for ASTNode {
167169
.collect::<Vec<String>>()
168170
.join(", ")
169171
),
170-
ASTNode::SQLCase { conditions, results, else_result } => {
172+
ASTNode::SQLCase {
173+
conditions,
174+
results,
175+
else_result,
176+
} => {
171177
let mut s = format!(
172178
"CASE {}",
173-
conditions.iter().zip(results)
179+
conditions
180+
.iter()
181+
.zip(results)
174182
.map(|(c, r)| format!("WHEN {} THEN {}", c.to_string(), r.to_string()))
175183
.collect::<Vec<String>>()
176184
.join(" ")
@@ -179,10 +187,11 @@ impl ToString for ASTNode {
179187
s += &format!(" ELSE {}", else_result.to_string())
180188
}
181189
s + " END"
182-
},
190+
}
183191
ASTNode::SQLSelect {
184192
projection,
185193
relation,
194+
joins,
186195
selection,
187196
order_by,
188197
group_by,
@@ -200,6 +209,9 @@ impl ToString for ASTNode {
200209
if let Some(relation) = relation {
201210
s += &format!(" FROM {}", relation.as_ref().to_string());
202211
}
212+
for join in joins {
213+
s += &join.to_string();
214+
}
203215
if let Some(selection) = selection {
204216
s += &format!(" WHERE {}", selection.as_ref().to_string());
205217
}
@@ -402,3 +414,72 @@ impl ToString for SQLColumnDef {
402414
s
403415
}
404416
}
417+
418+
#[derive(Debug, Clone, PartialEq)]
419+
pub struct Join {
420+
pub relation: ASTNode,
421+
pub join_operator: JoinOperator,
422+
}
423+
424+
impl ToString for Join {
425+
fn to_string(&self) -> String {
426+
fn prefix(constraint: &JoinConstraint) -> String {
427+
match constraint {
428+
JoinConstraint::Natural => "NATURAL ".to_string(),
429+
_ => "".to_string(),
430+
}
431+
}
432+
fn suffix(constraint: &JoinConstraint) -> String {
433+
match constraint {
434+
JoinConstraint::On(expr) => format!(" ON({})", expr.to_string()),
435+
JoinConstraint::Using(attrs) => format!(" USING({})", attrs.join(", ")),
436+
_ => "".to_string(),
437+
}
438+
}
439+
match &self.join_operator {
440+
JoinOperator::Inner(constraint) => format!(
441+
"{}INNER JOIN {}{}",
442+
prefix(constraint),
443+
self.relation.to_string(),
444+
prefix(constraint)
445+
),
446+
JoinOperator::Cross => format!("CROSS JOIN {}", self.relation.to_string()),
447+
JoinOperator::Implicit => format!(", {}", self.relation.to_string()),
448+
JoinOperator::LeftOuter(constraint) => format!(
449+
"{}LEFT OUTER JOIN {}{}",
450+
prefix(constraint),
451+
self.relation.to_string(),
452+
suffix(constraint)
453+
),
454+
JoinOperator::RightOuter(constraint) => format!(
455+
"{}RIGHT OUTER JOIN {}{}",
456+
prefix(constraint),
457+
self.relation.to_string(),
458+
suffix(constraint)
459+
),
460+
JoinOperator::FullOuter(constraint) => format!(
461+
"{}FULL OUTER JOIN {}{}",
462+
prefix(constraint),
463+
self.relation.to_string(),
464+
suffix(constraint)
465+
),
466+
}
467+
}
468+
}
469+
470+
#[derive(Debug, Clone, PartialEq)]
471+
pub enum JoinOperator {
472+
Inner(JoinConstraint),
473+
LeftOuter(JoinConstraint),
474+
RightOuter(JoinConstraint),
475+
FullOuter(JoinConstraint),
476+
Implicit,
477+
Cross,
478+
}
479+
480+
#[derive(Debug, Clone, PartialEq)]
481+
pub enum JoinConstraint {
482+
On(ASTNode),
483+
Using(Vec<String>),
484+
Natural,
485+
}

0 commit comments

Comments
 (0)