Skip to content

Commit

Permalink
Use the arrow only for nodes, make timing optional
Browse files Browse the repository at this point in the history
  • Loading branch information
mamcx committed Jan 27, 2025
1 parent 19a2259 commit 1aeeae9
Show file tree
Hide file tree
Showing 6 changed files with 70 additions and 78 deletions.
2 changes: 1 addition & 1 deletion crates/core/src/sql/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -977,7 +977,7 @@ pub(crate) fn compile_to_ast<T: TableSchemaView + StateView>(
) -> Result<Vec<SqlAst>, DBError> {
// NOTE: The following ensures compliance with the 1.0 sql api.
// Come 1.0, it will have replaced the current compilation stack.
compile_sql_stmt(sql_text, &SchemaViewer::new(tx, auth))?;
compile_sql_stmt(sql_text, &SchemaViewer::new(tx, auth), false)?;

let dialect = PostgreSqlDialect {};
let ast = Parser::parse_sql(&dialect, sql_text).map_err(|error| DBError::SqlParser {
Expand Down
10 changes: 7 additions & 3 deletions crates/expr/src/check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -165,13 +165,17 @@ pub fn type_subscription(ast: SqlSelect, tx: &impl SchemaView) -> TypingResult<P
}

/// Parse and type check a *subscription* query into a `StatementCtx`
pub fn compile_sql_sub<'a>(sql: &'a str, tx: &impl SchemaView) -> TypingResult<StatementCtx<'a>> {
let planning_time = std::time::Instant::now();
pub fn compile_sql_sub<'a>(sql: &'a str, tx: &impl SchemaView, with_timings: bool) -> TypingResult<StatementCtx<'a>> {
let planning_time = if with_timings {
Some(std::time::Instant::now())
} else {
None
};
Ok(StatementCtx {
statement: Statement::Select(ProjectList::Name(parse_and_type_sub(sql, tx)?)),
sql,
source: StatementSource::Subscription,
planning_time: planning_time.elapsed(),
planning_time: planning_time.map(|t| t.elapsed()),
})
}

Expand Down
2 changes: 1 addition & 1 deletion crates/expr/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -188,5 +188,5 @@ pub struct StatementCtx<'a> {
pub statement: Statement,
pub sql: &'a str,
pub source: StatementSource,
pub planning_time: std::time::Duration,
pub planning_time: Option<std::time::Duration>,
}
10 changes: 7 additions & 3 deletions crates/expr/src/statement.rs
Original file line number Diff line number Diff line change
Expand Up @@ -278,14 +278,18 @@ fn parse_and_type_sql(sql: &str, tx: &impl SchemaView) -> TypingResult<Statement
}

/// Parse and type check a *general* query into a [StatementCtx].
pub fn compile_sql_stmt<'a>(sql: &'a str, tx: &impl SchemaView) -> TypingResult<StatementCtx<'a>> {
let planning_time = std::time::Instant::now();
pub fn compile_sql_stmt<'a>(sql: &'a str, tx: &impl SchemaView, with_timings: bool) -> TypingResult<StatementCtx<'a>> {
let planning_time = if with_timings {
Some(std::time::Instant::now())
} else {
None
};
let statement = parse_and_type_sql(sql, tx)?;
Ok(StatementCtx {
statement,
sql,
source: StatementSource::Query,
planning_time: planning_time.elapsed(),
planning_time: planning_time.map(|t| t.elapsed()),
})
}

Expand Down
62 changes: 30 additions & 32 deletions crates/physical-plan/src/plan.rs
Original file line number Diff line number Diff line change
Expand Up @@ -965,7 +965,7 @@ pub struct PhysicalCtx<'a> {
// A map from table names to their labels
pub vars: HashMap<String, usize>,
pub source: StatementSource,
pub planning_time: std::time::Duration,
pub planning_time: Option<std::time::Duration>,
}

impl<'a> PhysicalCtx<'a> {
Expand All @@ -986,12 +986,12 @@ pub mod tests_utils {
use spacetimedb_expr::statement::compile_sql_stmt;

fn sub<'a>(db: &'a impl SchemaView, sql: &'a str) -> PhysicalCtx<'a> {
let plan = compile_sql_sub(sql, db).unwrap();
let plan = compile_sql_sub(sql, db, true).unwrap();
compile(plan)
}

fn query<'a>(db: &'a impl SchemaView, sql: &'a str) -> PhysicalCtx<'a> {
let plan = compile_sql_stmt(sql, db).unwrap();
let plan = compile_sql_stmt(sql, db, true).unwrap();
compile(plan)
}

Expand Down Expand Up @@ -1155,18 +1155,16 @@ Seq Scan on t
/// No rewrites applied to a table scan + filter
#[test]
fn filter_noop() {
let t_id = TableId(1);

let t = Arc::new(schema(
t_id,
TableId(1),
"t",
&[("id", AlgebraicType::U64), ("x", AlgebraicType::U64)],
&[&[0]],
&[&[0]],
Some(0),
));

let db = SchemaViewer::new(vec![t.clone()]);
let db = SchemaViewer::new(vec![t]);

check_sub(
&db,
Expand Down Expand Up @@ -1263,15 +1261,15 @@ Seq Scan on t
expect![[r#"
Index Join: Rhs on b
-> Index Join: Rhs on q
-> Index Join: Rhs on p
-> Index Scan using Index id 0 on u
-> Index Cond: (u.identity = U64(5))
-> Inner Unique: true
-> Index Cond: (u.entity_id = p.entity_id)
-> Inner Unique: false
-> Index Cond: (p.chunk = q.chunk)
-> Index Join: Rhs on p
-> Index Scan using Index id 0 on u
Index Cond: (u.identity = U64(5))
Inner Unique: true
Join Cond: (u.entity_id = p.entity_id)
Inner Unique: false
Join Cond: (p.chunk = q.chunk)
Inner Unique: true
Index Cond: (q.entity_id = b.entity_id)
Join Cond: (q.entity_id = b.entity_id)
Output: b.entity_id, b.misc"#]],
);

Expand Down Expand Up @@ -1472,21 +1470,21 @@ Index Join: Rhs on b
expect![[r#"
Hash Join
-> Hash Join
-> Hash Join
-> Hash Join
-> Hash Join
-> Seq Scan on m
-> Seq Scan on n
-> Inner Unique: false
-> Hash Cond: (m.manager = n.manager)
-> Seq Scan on u
-> Inner Unique: false
-> Hash Cond: (n.employee = u.employee)
-> Seq Scan on v
-> Inner Unique: false
-> Hash Cond: (u.project = v.project)
-> Seq Scan on m
-> Seq Scan on n
Inner Unique: false
Join Cond: (m.manager = n.manager)
-> Seq Scan on u
Inner Unique: false
Join Cond: (n.employee = u.employee)
-> Seq Scan on v
Inner Unique: false
Join Cond: (u.project = v.project)
-> Seq Scan on p
Inner Unique: false
Hash Cond: (p.id = v.project)
Join Cond: (p.id = v.project)
Filter: (m.employee = U64(5) AND v.employee = U64(5))
Output: p.id, p.name"#]],
);
Expand Down Expand Up @@ -1668,7 +1666,7 @@ Hash Join
expect![
r#"
Index Scan using Index id 2 on t
Index Cond: (t.z = U8(5), t.x = U8(3), t.y = U8(4))
Index Cond: (t.z = U8(5), t.x = U8(3), t.y = U8(4))
Output: t.w, t.x, t.y, t.z"#
],
);
Expand Down Expand Up @@ -1819,7 +1817,7 @@ Index Scan using Index id 2 on t
Query: SELECT m.* FROM m CROSS JOIN p WHERE m.employee = 1
Nested Loop
-> Index Scan using Index id 0 on m
-> Index Cond: (m.employee = U64(1))
Index Cond: (m.employee = U64(1))
-> Seq Scan on p:2
Output: m.employee, m.manager
-------
Expand Down Expand Up @@ -1927,7 +1925,7 @@ Label: p, TableId:3
"SELECT m.* FROM m WHERE employee = 1",
expect![[r#"
Index Scan using Index id 0 on m
Index Cond: (m.employee = U64(1))
Index Cond: (m.employee = U64(1))
Output: m.employee, m.manager"#]],
);
}
Expand Down Expand Up @@ -1959,7 +1957,7 @@ Index Scan using Index id 0 on m
-> Seq Scan on m
-> Seq Scan on p
Inner Unique: false
Hash Cond: (m.employee = p.id)
Join Cond: (m.employee = p.id)
Filter: (m.employee = U64(1))
Output: p.id, p.name"#]],
);
Expand All @@ -1976,7 +1974,7 @@ Index Scan using Index id 0 on m
Index Join: Rhs on p
-> Seq Scan on m
Inner Unique: true
Index Cond: (m.employee = p.id)
Join Cond: (m.employee = p.id)
Output: p.id, p.name"#]],
);
}
Expand Down
62 changes: 24 additions & 38 deletions crates/physical-plan/src/printer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -198,17 +198,11 @@ impl<'a> PrintIndex<'a> {
}
}

pub enum JoinKind {
IxJoin,
HashJoin,
NlJoin,
}

/// A formated line of output
pub enum Line<'a> {
TableScan {
table: &'a str,
label: Label,
label: usize,
ident: u16,
},
Filter {
Expand All @@ -227,7 +221,6 @@ pub enum Line<'a> {
},
IxJoin {
semi: &'a Semi,

rhs: String,
ident: u16,
},
Expand All @@ -239,7 +232,6 @@ pub enum Line<'a> {
ident: u16,
},
JoinExpr {
kind: JoinKind,
unique: bool,
lhs: Field<'a>,
rhs: Field<'a>,
Expand Down Expand Up @@ -365,7 +357,7 @@ fn eval_plan<'a>(lines: &mut Lines<'a>, plan: &'a PhysicalPlan, ident: u16) {

lines.add(Line::TableScan {
table: schema.name,
label: *label,
label: label.0,
ident,
});
}
Expand All @@ -385,7 +377,7 @@ fn eval_plan<'a>(lines: &mut Lines<'a>, plan: &'a PhysicalPlan, ident: u16) {
lines.add(Line::FilterIxScan {
idx,
label: *label,
ident: ident + 2,
ident: ident + 4,
});
}
PhysicalPlan::IxJoin(idx, semi) => {
Expand All @@ -398,15 +390,14 @@ fn eval_plan<'a>(lines: &mut Lines<'a>, plan: &'a PhysicalPlan, ident: u16) {
rhs: rhs.name.to_string(),
});

eval_plan(lines, &idx.lhs, ident + 4);
eval_plan(lines, &idx.lhs, ident + 2);

lines.output = output_join(lines, semi, idx.lhs_field.label, idx.rhs_label);

let lhs = lines.labels.field(&idx.lhs_field).unwrap();
let rhs = lines.labels.label(&idx.rhs_label, idx.rhs_field).unwrap();

lines.add(Line::JoinExpr {
kind: JoinKind::IxJoin,
unique: idx.unique,
lhs,
rhs,
Expand All @@ -416,16 +407,15 @@ fn eval_plan<'a>(lines: &mut Lines<'a>, plan: &'a PhysicalPlan, ident: u16) {
PhysicalPlan::HashJoin(idx, semi) => {
lines.add(Line::HashJoin { semi, ident });

eval_plan(lines, &idx.lhs, ident + 4);
eval_plan(lines, &idx.rhs, ident + 4);
eval_plan(lines, &idx.lhs, ident + 2);
eval_plan(lines, &idx.rhs, ident + 2);

lines.output = output_join(lines, semi, idx.lhs_field.label, idx.rhs_field.label);

let lhs = lines.labels.field(&idx.lhs_field).unwrap();
let rhs = lines.labels.field(&idx.rhs_field).unwrap();

lines.add(Line::JoinExpr {
kind: JoinKind::HashJoin,
unique: idx.unique,
lhs,
rhs,
Expand All @@ -435,8 +425,8 @@ fn eval_plan<'a>(lines: &mut Lines<'a>, plan: &'a PhysicalPlan, ident: u16) {
PhysicalPlan::NLJoin(lhs, rhs) => {
lines.add(Line::NlJoin { ident });

eval_plan(lines, lhs, ident + 4);
eval_plan(lines, rhs, ident + 4);
eval_plan(lines, lhs, ident + 2);
eval_plan(lines, rhs, ident + 2);
}
PhysicalPlan::Filter(plan, filter) => {
eval_plan(lines, plan, ident);
Expand Down Expand Up @@ -611,37 +601,39 @@ impl<'a> fmt::Display for Explain<'a> {

for line in &self.lines {
let ident = line.ident();
let (ident, arrow) = if ident > 2 { (ident - 2, "-> ") } else { (ident, "") };
write!(f, "{:ident$}{arrow}", "")?;
let arrow = if ident > 0 { "-> " } else { "" };

match line {
Line::TableScan { table, label, ident: _ } => {
if self.options.show_schema {
write!(f, "Seq Scan on {}:{}", table, label.0)?;
write!(f, "{:ident$}{arrow}Seq Scan on {table}:{label}", "")?;
} else {
write!(f, "Seq Scan on {}", table)?;
write!(f, "{:ident$}{arrow}Seq Scan on {table}", "")?;
}
}
Line::IxScan {
table_name,
index,
ident: _,
} => {
write!(f, "Index Scan using {index} on {table_name}")?;
write!(f, "{:ident$}{arrow}Index Scan using {index} on {table_name}", "")?;
}
Line::Filter { expr, ident: _ } => {
write!(f, "{:ident$}Filter: ", "")?;
write!(
f,
"Filter: ({})",
"({})",
PrintExpr {
expr,
labels: &self.labels,
},
}
)?;
}
Line::FilterIxScan { idx, label, ident: _ } => {
write!(f, "{:ident$}Index Cond: ", "")?;
write!(
f,
"Index Cond: ({})",
"({})",
PrintSarg {
expr: &idx.arg,
prefix: &idx.prefix,
Expand All @@ -652,33 +644,27 @@ impl<'a> fmt::Display for Explain<'a> {
}

Line::IxJoin { semi, rhs, ident: _ } => {
write!(f, "Index Join: {semi:?} on {rhs}")?;
write!(f, "{:ident$}{arrow}Index Join: {semi:?} on {rhs}", "")?;
}
Line::HashJoin { semi, ident: _ } => match semi {
Semi::All => {
write!(f, "Hash Join")?;
write!(f, "{:ident$}{arrow}Hash Join", "")?;
}
semi => {
write!(f, "Hash Join: {semi:?}")?;
write!(f, "{:ident$}{arrow}Hash Join: {semi:?}", "")?;
}
},
Line::NlJoin { ident: _ } => {
write!(f, "Nested Loop")?;
write!(f, "{:ident$}{arrow}Nested Loop", "")?;
}
Line::JoinExpr {
kind,
unique,
lhs,
rhs,
ident: _,
} => {
let kind = match kind {
JoinKind::IxJoin => "Index Cond",
JoinKind::HashJoin => "Hash Cond",
JoinKind::NlJoin => "Loop Cond",
};
writeln!(f, "Inner Unique: {unique}")?;
write!(f, "{:ident$}{arrow}{kind}: ({} = {})", "", lhs, rhs)?;
writeln!(f, "{:ident$}Inner Unique: {unique}", "")?;
write!(f, "{:ident$}Join Cond: ({} = {})", "", lhs, rhs)?;
}
}
writeln!(f)?;
Expand Down

0 comments on commit 1aeeae9

Please sign in to comment.