MCPcopy Create free account
hub / github.com/PRQL/prql / fold_by_simulating_eval

Method fold_by_simulating_eval

prqlc/prqlc/src/semantic/resolver/transforms.rs:640–701  ·  view source on GitHub ↗

Simulate evaluation of the inner pipeline of group or window Creates a dummy node that acts as value that pipeline can be resolved upon.

(&mut self, pipeline: Expr, val: &Expr)

Source from the content-addressed store, hash-verified

638 /// Simulate evaluation of the inner pipeline of group or window
639 // Creates a dummy node that acts as value that pipeline can be resolved upon.
640 fn fold_by_simulating_eval(&mut self, pipeline: Expr, val: &Expr) -> Result<Expr> {
641 log::debug!("fold by simulating evaluation");
642 let span = pipeline.span;
643
644 let param_name = "_tbl";
645 let param_id = self.id.gen();
646
647 // resolver will not resolve a function call if any arguments are missing
648 // but would instead return a closure to be resolved later.
649 // because the pipeline of group is a function that takes a table chunk
650 // and applies the transforms to it, it would not get resolved.
651 // thats why we trick the resolver with a dummy node that acts as table
652 // chunk and instruct resolver to apply the transform on that.
653
654 let mut dummy = Expr::new(ExprKind::Ident(Ident::from_name(param_name)));
655 dummy.lineage.clone_from(&val.lineage);
656 dummy.ty.clone_from(&val.ty);
657
658 let pipeline = Expr::new(ExprKind::FuncCall(FuncCall::new_simple(
659 pipeline,
660 vec![dummy],
661 )));
662
663 let env = Module::singleton(param_name, Decl::from(DeclKind::Column(param_id)));
664 self.root_mod.module.stack_push(NS_PARAM, env);
665
666 let mut pipeline = self.fold_expr(pipeline)?;
667
668 // attach the span to the TransformCall, as this is what will
669 // be preserved after resolving is complete
670 pipeline.span = pipeline.span.or(span);
671
672 self.root_mod.module.stack_pop(NS_PARAM).unwrap();
673
674 // now, we need wrap the result into a closure and replace
675 // the dummy node with closure's parameter.
676
677 // validate that the return type is a relation
678 // this can be removed after we have proper type checking for all std functions
679 let expected = Some(Ty::relation(vec![TyTupleField::Wildcard(None)]));
680 self.validate_expr_type(&mut pipeline, expected.as_ref(), &|| {
681 Some("pipeline".to_string())
682 })?;
683
684 // construct the function back
685 let func = Box::new(Func {
686 name_hint: None,
687 body: Box::new(pipeline),
688 return_ty: None,
689
690 args: vec![],
691 params: vec![FuncParam {
692 name: param_id.to_string(),
693 ty: None,
694 default_value: None,
695 }],
696 named_params: vec![],
697

Callers 1

resolve_special_funcMethod · 0.80

Calls 8

IdentClass · 0.85
expr_of_funcFunction · 0.85
genMethod · 0.80
stack_pushMethod · 0.80
stack_popMethod · 0.80
validate_expr_typeMethod · 0.80
FuncCallClass · 0.50
fold_exprMethod · 0.45

Tested by

no test coverage detected