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

Function intersect

prqlc/prqlc/src/sql/pq/preprocess.rs:399–492  ·  view source on GitHub ↗

Creates [SqlTransform::Intersect] from [Transform::Join]

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

Source from the content-addressed store, hash-verified

397
398/// Creates [SqlTransform::Intersect] from [Transform::Join]
399pub(in crate::sql) fn intersect(
400 pipeline: Vec<SqlTransform>,
401 ctx: &mut Context,
402) -> Result<Vec<SqlTransform>> {
403 use SqlTransform::*;
404
405 let output = ctx.anchor.determine_select_columns(&pipeline);
406 let output: HashSet<CId, RandomState> = HashSet::from_iter(output);
407
408 let mut res = Vec::with_capacity(pipeline.len());
409 let mut pipeline = pipeline.into_iter().peekable();
410 while let Some(t) = pipeline.next() {
411 res.push(t);
412
413 if res.is_empty() {
414 continue;
415 }
416 let Join {
417 side: JoinSide::Inner,
418 filter: join_cond,
419 with,
420 } = &res[res.len() - 1]
421 else {
422 continue;
423 };
424 let with = ctx.anchor.relation_instances.get_mut(with).unwrap();
425
426 let bottom = with.table_ref.columns.iter().map(|(_, c)| *c).collect_vec();
427 let top = ctx.anchor.determine_select_columns(&res[0..res.len() - 1]);
428
429 // join_cond must be a join over all columns
430 // (this could be loosened to check only the relation key)
431 let (left, right) = collect_equals(join_cond)?;
432 if !(all_in(&top, left) && all_in(&bottom, right)) {
433 continue;
434 }
435
436 // select must not contain things from bottom
437 if bottom.iter().any(|c| output.contains(c)) {
438 continue;
439 }
440 // select must contain at least one thing from top
441 if top.iter().all(|c| !output.contains(c)) {
442 continue;
443 }
444
445 // determine DISTINCT
446 let mut distinct = false;
447 // INTERSECT ALL can become except INTERSECT DISTINCT
448 // - if top is DISTINCT or
449 // - if output is DISTINCT
450 if res.len() > 1 {
451 if let Distinct = &res[res.len() - 2] {
452 distinct = true;
453 }
454 }
455 if let Some(SqlTransform::Distinct) = pipeline.peek() {
456 distinct = true;

Callers 1

preprocessFunction · 0.85

Calls 15

collect_equalsFunction · 0.85
all_inFunction · 0.85
lenMethod · 0.80
into_iterMethod · 0.80
nextMethod · 0.80
pushMethod · 0.80
is_emptyMethod · 0.80
get_mutMethod · 0.80
mapMethod · 0.80
iterMethod · 0.80
intersect_allMethod · 0.80

Tested by

no test coverage detected