hamelin_legacy 0.4.4

Legacy AST translation code for Hamelin (to be deprecated)
Documentation
use crate::ast::assignment_clause::HamelinAssignmentClause;
use crate::ast::pipeline::HamelinPipeline;
use crate::ast::sort_expression::HamelinSortExpression;
use crate::env::Environment;
use crate::translation::projection_builder::ProjectionBuilder;
use crate::translation::PendingQueryResult;
use hamelin_lib::antlr::hamelinparser::{
    AggCommandContext, AggCommandContextAttrs, GroupClauseContextAttrs,
};
use hamelin_lib::err::{TranslationError, TranslationErrors};
use hamelin_lib::func::def::{FunctionTranslationContext, SpecialPosition};
use hamelin_lib::sql::expression::literal::ColumnReference;
use hamelin_lib::sql::query::projection::Projection;

pub fn translate(
    ctx: &AggCommandContext<'static>,
    pipeline: &HamelinPipeline,
    pending_query_result: &mut PendingQueryResult,
) {
    let mut fctx = FunctionTranslationContext::default().with_special_allowed(SpecialPosition::Agg);
    let sort_expression = ctx.sortExpression_all();

    if !sort_expression.is_empty() {
        let sort_ctx = pipeline.context.expression_translation_context(
            &pending_query_result.translation.env,
            FunctionTranslationContext::default(),
        );

        if let Some(res) = pending_query_result
            .errors
            .consume_errors(HamelinSortExpression::new(sort_expression, sort_ctx).translate())
        {
            fctx.add_order_by(res.0);
        }
    }

    let mut agg_projections = ProjectionBuilder::default();
    for clause in ctx.assignmentClause_all() {
        let expr_ctx = pipeline
            .context
            .expression_translation_context(&pending_query_result.translation.env, fctx.clone());

        let result = HamelinAssignmentClause::new(clause.clone(), expr_ctx).to_sql();

        if let Some(res) = pending_query_result.errors.consume_errors(result) {
            agg_projections.bind(res.0, res.1.sql, res.1.typ);
        }
    }

    let mut group_projections = ProjectionBuilder::default();
    for clause in ctx.groupClause_all() {
        let expr_ctx = pipeline
            .context
            .expression_translation_context(&pending_query_result.translation.env, fctx.clone());
        let result = TranslationErrors::expect(clause.as_ref(), clause.assignmentClause())
            .and_then(|clause| HamelinAssignmentClause::new(clause.clone(), expr_ctx).to_sql());

        if let Some((identifier, translation)) = pending_query_result.errors.consume_errors(result)
        {
            group_projections.bind(identifier, translation.sql, translation.typ);
        }
    }

    let all_projection_result = group_projections
        .clone()
        .build_projections()
        .map_err(|e| TranslationError::wrap_box(ctx, e.into()).single())
        .and_then(|projections| {
            agg_projections
                .clone()
                .build_projections()
                .map_err(|e| TranslationError::wrap_box(ctx, e.into()).single())
                .map(|agg_projections| (projections, agg_projections))
        })
        .map(|(projections, agg_projections)| {
            projections
                .into_iter()
                .chain(agg_projections.into_iter())
                .collect::<Vec<_>>()
        });

    let group_expressions_result = group_projections
        .clone()
        .build_projections()
        .map_err(|e| TranslationError::wrap_box(ctx, e.into()).single())
        .map(|projections| {
            projections
                .into_iter()
                .map(|p| match p {
                    Projection::Binding(b) => b.expression,
                    Projection::ColumnProjection(cp) => ColumnReference::new(cp.identifier).into(),
                })
                .collect::<Vec<_>>()
        });

    pending_query_result.translation.env = Environment::new(
        agg_projections
            .build_hamelin_type()
            .prepend_overwrite(&group_projections.build_hamelin_type()),
    );

    match TranslationErrors::from_2(all_projection_result, group_expressions_result) {
        Ok((all_projection, group_expressions)) => {
            pending_query_result.translation.query = pending_query_result
                .translation
                .query
                .clone()
                .push_down()
                .add_group_expression(group_expressions)
                .select(all_projection);
        }
        Err(e) => {
            pending_query_result.errors.extend(e);
        }
    }
}