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

Function extract_atomic

prqlc/prqlc/src/sql/pq/anchor.rs:20–63  ·  view source on GitHub ↗

Extract last part of pipeline that is able to "fit" into a single SELECT statement. Remaining preceding pipeline is declared as a table and stored in AnchorContext.

(
    pipeline: Vec<SqlTransform>,
    ctx: &mut AnchorContext,
)

Source from the content-addressed store, hash-verified

18/// Extract last part of pipeline that is able to "fit" into a single SELECT statement.
19/// Remaining preceding pipeline is declared as a table and stored in AnchorContext.
20pub(super) fn extract_atomic(
21 pipeline: Vec<SqlTransform>,
22 ctx: &mut AnchorContext,
23) -> Vec<SqlTransform> {
24 let output = ctx.determine_select_columns(&pipeline);
25 let output = ctx.positional_mapping.apply_active_mapping(output);
26
27 let (preceding, atomic) = split_off_back(pipeline, output.clone(), ctx);
28
29 let atomic = if let Some(preceding) = preceding {
30 log::debug!(
31 "pipeline split after {}",
32 preceding.last().unwrap().as_str()
33 );
34 anchor_split(ctx, preceding, atomic)
35 } else {
36 atomic
37 };
38
39 // sometimes, additional columns will be added into select, because they are needed for
40 // other clauses. To filter them out, we use an additional limiting SELECT.
41 let output: Vec<_> = CidRedirector::redirect_cids(output, &atomic, ctx);
42 let select_cols = atomic
43 .iter()
44 .find_map(|x| x.as_super().and_then(|y| y.as_select()))
45 .unwrap();
46 if select_cols.iter().any(|c| !output.contains(c)) {
47 log::debug!(
48 "appending a projection SELECT, because previous one contained un-selected columns"
49 );
50
51 // duplicate Select for purposes of anchor_split
52 let duplicated_select = SqlTransform::Super(Transform::Select(select_cols.clone()));
53 let mut atomic = atomic;
54 atomic.push(duplicated_select);
55
56 // construct the new SELECT
57 let limited_view = vec![SqlTransform::Super(Transform::Select(output))];
58
59 return anchor_split(ctx, atomic, limited_view);
60 }
61
62 atomic
63}
64
65/// Splits pipeline into two parts, such that the second part contains
66/// maximum number of transforms while "fitting" into a SELECT query.

Callers 1

compile_pipelineFunction · 0.85

Calls 6

split_off_backFunction · 0.85
anchor_splitFunction · 0.85
apply_active_mappingMethod · 0.80
iterMethod · 0.80
pushMethod · 0.80

Tested by

no test coverage detected