linkrs-query 0.1.0

Query engine, parser, and executor for Linkrs
Documentation
use super::super::super::super::operators::spec::BlockingSpec;
use super::super::super::properties::{PhysicalProperties, SPILL_DEFAULT_THRESHOLD};
use super::super::super::types::{
    FragmentId, FragmentSpec, PhysicalOperatorId, PhysicalOperatorIdAllocator, PhysicalOperatorSpec,
};
use super::super::assembler::{ArenaFragmentAllocator, ArenaPlanAssembler};
use super::super::specs::{
    build_aggregate_spec, build_filter_spec, build_limit_spec, build_project_spec, build_sort_spec,
    build_topn_spec, build_window_spec,
};
use crate::executor::base::ExecutionContext;
use crate::executor::build_error::PlanBuildError;
use crate::planning::plan::core::nodes::base::plan_node_enum::PlanNodeEnum;

pub(super) fn push_global_op(
    operators: &mut Vec<PhysicalOperatorSpec>,
    fragments: &mut Vec<FragmentSpec>,
    op_alloc: &mut PhysicalOperatorIdAllocator,
    frag_alloc: &mut ArenaFragmentAllocator,
    child_fid: FragmentId,
    op: &PlanNodeEnum,
    exec_ctx: &ExecutionContext,
) -> Result<(FragmentId, PhysicalOperatorId), PlanBuildError> {
    match op {
        PlanNodeEnum::Filter(filter) => {
            let subquery_runners = super::super::assembler::build_subquery_runner_specs(
                filter.subqueries(),
                exec_ctx,
            )?;
            let spec = build_filter_spec(filter, subquery_runners)?;
            let (fid, op_id) = ArenaPlanAssembler::push_global_unary_op(
                operators,
                fragments,
                op_alloc,
                frag_alloc,
                child_fid,
                op.id(),
                spec,
            )?;
            operators[op_id.0].has_folded_expressions = filter.has_folded_expressions();
            Ok((fid, op_id))
        }
        PlanNodeEnum::Project(project) => {
            let subquery_runners = super::super::assembler::build_subquery_runner_specs(
                project.subqueries(),
                exec_ctx,
            )?;
            let spec = build_project_spec(project, subquery_runners)?;
            let (fid, op_id) = ArenaPlanAssembler::push_global_unary_op(
                operators,
                fragments,
                op_alloc,
                frag_alloc,
                child_fid,
                op.id(),
                spec,
            )?;
            operators[op_id.0].has_folded_expressions = project.has_folded_expressions();
            Ok((fid, op_id))
        }
        PlanNodeEnum::Limit(limit) => {
            let spec = build_limit_spec(limit)?;
            ArenaPlanAssembler::push_global_unary_op(
                operators,
                fragments,
                op_alloc,
                frag_alloc,
                child_fid,
                op.id(),
                spec,
            )
        }
        PlanNodeEnum::Sort(sort) => {
            let spec = build_sort_spec(sort)?;
            let (fid, op_id) = ArenaPlanAssembler::push_global_blocking_op(
                operators,
                fragments,
                op_alloc,
                frag_alloc,
                child_fid,
                op.id(),
                spec,
                PhysicalProperties::single_blocking_spillable(SPILL_DEFAULT_THRESHOLD),
            )?;
            operators[op_id.0].has_folded_expressions = sort.has_folded_expressions();
            Ok((fid, op_id))
        }
        PlanNodeEnum::Aggregate(agg) => {
            let spec = build_aggregate_spec(agg)?;
            let (fid, op_id) = ArenaPlanAssembler::push_global_blocking_op(
                operators,
                fragments,
                op_alloc,
                frag_alloc,
                child_fid,
                op.id(),
                spec,
                PhysicalProperties::single_blocking_with_budget(),
            )?;
            operators[op_id.0].has_folded_expressions = agg.has_folded_expressions();
            Ok((fid, op_id))
        }
        PlanNodeEnum::TopN(topn) => {
            let spec = build_topn_spec(topn)?;
            ArenaPlanAssembler::push_global_blocking_op(
                operators,
                fragments,
                op_alloc,
                frag_alloc,
                child_fid,
                op.id(),
                spec,
                PhysicalProperties::single_blocking_with_budget(),
            )
        }
        PlanNodeEnum::Dedup(_) => ArenaPlanAssembler::push_global_blocking_op(
            operators,
            fragments,
            op_alloc,
            frag_alloc,
            child_fid,
            op.id(),
            BlockingSpec::Distinct,
            PhysicalProperties::single_blocking_with_budget(),
        ),
        PlanNodeEnum::Window(window) => {
            let spec = build_window_spec(window)?;
            let (fid, op_id) = ArenaPlanAssembler::push_global_blocking_op(
                operators,
                fragments,
                op_alloc,
                frag_alloc,
                child_fid,
                op.id(),
                spec,
                PhysicalProperties::single_blocking_with_budget(),
            )?;
            operators[op_id.0].has_folded_expressions = window.has_folded_expressions();
            Ok((fid, op_id))
        }
        _ => Err(PlanBuildError::unsupported(
            op.name(),
            op.id(),
            "operator is not supported above a partition exchange",
        )),
    }
}