Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: minor changes to lowering #4364

Merged
merged 1 commit into from
Mar 28, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 31 additions & 12 deletions prqlc/prqlc/src/semantic/lowering.rs
Original file line number Diff line number Diff line change
Expand Up @@ -457,7 +457,7 @@ impl Lowerer {
let lineage = expr.lineage.clone();
let prev_pipeline = self.pipeline.drain(..).collect_vec();

self.lower_pipeline(expr, None)?;
self.lower_relational_expr(expr, None)?;

let mut transforms = self.pipeline.drain(..).collect_vec();
let columns = self.push_select(lineage, &mut transforms).with_span(span)?;
Expand All @@ -471,31 +471,50 @@ impl Lowerer {
Ok(relation)
}

// Result is stored in self.pipeline
fn lower_pipeline(&mut self, ast: pl::Expr, closure_param: Option<usize>) -> Result<()> {
let transform_call = match ast.kind {
pl::ExprKind::TransformCall(transform) => transform,
pl::ExprKind::Func(closure) => {
let param = closure.params.first();
/// HACK: Result is stored in self.pipeline
fn lower_relational_expr(&mut self, ast: pl::Expr, closure_param: Option<usize>) -> Result<()> {
// find the actual transform that we want to compile to relational pipeline
// this is non trivial, because sometimes the transforms will be wrapped into
// functions that are still waiting for arguments
// for example: this would happen when lowering loop's pipeline
match ast.kind {
// base case
pl::ExprKind::TransformCall(transform) => {
self.lower_transform_call(transform, closure_param, ast.span)?;
}

// actually operate on func's body
pl::ExprKind::Func(func) => {
let param = func.params.first();
let param = param.and_then(|p| p.name.parse::<usize>().ok());
return self.lower_pipeline(*closure.body, param);
self.lower_relational_expr(*func.body, param)?;
}

// this relational expr is not a transform
_ => {
if let Some(target) = ast.target_id {
if Some(target) == closure_param {
// ast is a closure param, so we can skip pushing From
// ast is a closure param, so don't need to push From
return Ok(());
}
}

let table_ref = self.lower_table_ref(ast)?;
self.pipeline.push(Transform::From(table_ref));
return Ok(());
}
};
Ok(())
}

/// HACK: Result is stored in self.pipeline
fn lower_transform_call(
&mut self,
transform_call: pl::TransformCall,
closure_param: Option<usize>,
span: Option<Span>,
) -> Result<()> {
// lower input table
self.lower_pipeline(*transform_call.input, closure_param)?;
self.lower_relational_expr(*transform_call.input, closure_param)?;

// ... and continues with transforms created in this function

Expand Down Expand Up @@ -543,7 +562,7 @@ impl Lowerer {
let window = self.window.take().unwrap_or_default();
let range = self.lower_range(range)?;

validate_take_range(&range, ast.span)?;
validate_take_range(&range, span)?;

self.pipeline.push(Transform::Take(rq::Take {
range,
Expand Down
Loading