1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59
// Copyright Materialize, Inc. and contributors. All rights reserved.
//
// Use of this software is governed by the Business Source License
// included in the LICENSE file.
//
// As of the Change Date specified in that file, in accordance with
// the Business Source License, use of this software will be governed
// by the Apache License, Version 2.0.
//! Remove TopK operators with both an offset of zero and no limit.
use mz_expr::visit::Visit;
use mz_expr::MirRelationExpr;
use crate::TransformCtx;
/// Remove TopK operators with both an offset of zero and no limit.
#[derive(Debug)]
pub struct TopKElision;
impl crate::Transform for TopKElision {
#[mz_ore::instrument(
target = "optimizer",
level = "debug",
fields(path.segment = "topk_elision")
)]
fn transform(
&self,
relation: &mut MirRelationExpr,
_: &mut TransformCtx,
) -> Result<(), crate::TransformError> {
relation.visit_mut_post(&mut Self::action)?;
mz_repr::explain::trace_plan(&*relation);
Ok(())
}
}
impl TopKElision {
/// Remove TopK operators with both an offset of zero and no limit.
pub fn action(relation: &mut MirRelationExpr) {
if let MirRelationExpr::TopK {
input,
group_key: _,
order_key: _,
limit,
offset,
monotonic: _,
expected_group_size: _,
} = relation
{
// The limit is not set if it either `None` or literal `Null`.
if limit.as_ref().map_or(true, |l| l.is_literal_null()) && *offset == 0 {
*relation = input.take_dangerous();
} else if limit.as_ref().and_then(|l| l.as_literal_int64()) == Some(0) {
relation.take_safely();
}
}
}
}