Skip to main content

nodedb_sql/optimizer/
point_get.rs

1//! Detect equality on primary key → convert Scan to PointGet.
2
3use crate::types::*;
4
5/// If a Scan has a single equality filter on the primary key, convert to PointGet.
6pub fn optimize(plan: SqlPlan) -> SqlPlan {
7    match plan {
8        SqlPlan::Scan {
9            ref collection,
10            ref alias,
11            ref engine,
12            ref filters,
13            ..
14        } if filters.len() == 1 => {
15            if let Some((key_col, key_val)) = extract_pk_equality(&filters[0]) {
16                return SqlPlan::PointGet {
17                    collection: collection.clone(),
18                    alias: alias.clone(),
19                    engine: *engine,
20                    key_column: key_col,
21                    key_value: key_val,
22                };
23            }
24            plan
25        }
26        _ => plan,
27    }
28}
29
30/// Extract a simple equality filter on a known PK column.
31fn extract_pk_equality(filter: &Filter) -> Option<(String, SqlValue)> {
32    match &filter.expr {
33        FilterExpr::Comparison {
34            field,
35            op: CompareOp::Eq,
36            value,
37        } => {
38            // Only optimize for known PK columns.
39            let f = field.to_lowercase();
40            if f == "id" || f == "document_id" || f == "key" {
41                Some((f, value.clone()))
42            } else {
43                None
44            }
45        }
46        FilterExpr::Expr(SqlExpr::BinaryOp {
47            left,
48            op: BinaryOp::Eq,
49            right,
50        }) => {
51            let col = match left.as_ref() {
52                SqlExpr::Column { name, .. } => name.to_lowercase(),
53                _ => return None,
54            };
55            if col != "id" && col != "document_id" && col != "key" {
56                return None;
57            }
58            let val = match right.as_ref() {
59                SqlExpr::Literal(v) => v.clone(),
60                _ => return None,
61            };
62            Some((col, val))
63        }
64        _ => None,
65    }
66}