Skip to main content

nodedb_sql/planner/
catalog_plan_shapes.rs

1// SPDX-License-Identifier: Apache-2.0
2
3//! Catalog folding for reusable projection, ordering, aggregate, and window shapes.
4
5use nodedb_types::DatabaseId;
6
7use crate::catalog::SqlCatalog;
8use crate::types::{AggregateExpr, Projection, SortKey, SqlExpr, WindowSpec};
9
10use super::catalog_expr_fold::{fold_expr, validate_expr};
11
12pub(super) fn validate_projection(
13    projection: &[Projection],
14    catalog: &dyn SqlCatalog,
15    database_id: DatabaseId,
16    tenant_id: u64,
17) -> crate::Result<()> {
18    for item in projection {
19        if let Projection::Computed { expr, .. } = item {
20            validate_expr(expr, catalog, database_id, tenant_id)?;
21        }
22    }
23    Ok(())
24}
25
26pub(super) fn validate_sort_keys(
27    sort_keys: &[SortKey],
28    catalog: &dyn SqlCatalog,
29    database_id: DatabaseId,
30    tenant_id: u64,
31) -> crate::Result<()> {
32    for key in sort_keys {
33        validate_expr(&key.expr, catalog, database_id, tenant_id)?;
34    }
35    Ok(())
36}
37
38pub(super) fn validate_aggregates(
39    aggregates: &[AggregateExpr],
40    catalog: &dyn SqlCatalog,
41    database_id: DatabaseId,
42    tenant_id: u64,
43) -> crate::Result<()> {
44    for aggregate in aggregates {
45        for arg in &aggregate.args {
46            validate_expr(arg, catalog, database_id, tenant_id)?;
47        }
48    }
49    Ok(())
50}
51
52pub(super) fn validate_windows(
53    windows: &[WindowSpec],
54    catalog: &dyn SqlCatalog,
55    database_id: DatabaseId,
56    tenant_id: u64,
57) -> crate::Result<()> {
58    for window in windows {
59        for expr in window.args.iter().chain(&window.partition_by) {
60            validate_expr(expr, catalog, database_id, tenant_id)?;
61        }
62        validate_sort_keys(&window.order_by, catalog, database_id, tenant_id)?;
63    }
64    Ok(())
65}
66
67pub(super) fn fold_projection(
68    projection: &mut [Projection],
69    catalog: &dyn SqlCatalog,
70    database_id: DatabaseId,
71    tenant_id: u64,
72) {
73    for item in projection {
74        if let Projection::Computed { expr, .. } = item {
75            let owned = std::mem::replace(expr, SqlExpr::Wildcard);
76            *expr = fold_expr(owned, catalog, database_id, tenant_id);
77        }
78    }
79}
80
81pub(super) fn fold_sort_keys(
82    sort_keys: &mut [SortKey],
83    catalog: &dyn SqlCatalog,
84    database_id: DatabaseId,
85    tenant_id: u64,
86) {
87    for key in sort_keys {
88        let owned = std::mem::replace(&mut key.expr, SqlExpr::Wildcard);
89        key.expr = fold_expr(owned, catalog, database_id, tenant_id);
90    }
91}
92
93pub(super) fn fold_aggregates(
94    aggregates: &mut [AggregateExpr],
95    catalog: &dyn SqlCatalog,
96    database_id: DatabaseId,
97    tenant_id: u64,
98) {
99    for aggregate in aggregates {
100        for arg in &mut aggregate.args {
101            let owned = std::mem::replace(arg, SqlExpr::Wildcard);
102            *arg = fold_expr(owned, catalog, database_id, tenant_id);
103        }
104    }
105}
106
107pub(super) fn fold_windows(
108    windows: &mut [WindowSpec],
109    catalog: &dyn SqlCatalog,
110    database_id: DatabaseId,
111    tenant_id: u64,
112) {
113    for window in windows {
114        for expr in window.args.iter_mut().chain(&mut window.partition_by) {
115            let owned = std::mem::replace(expr, SqlExpr::Wildcard);
116            *expr = fold_expr(owned, catalog, database_id, tenant_id);
117        }
118        fold_sort_keys(&mut window.order_by, catalog, database_id, tenant_id);
119    }
120}