nodedb_sql/optimizer/
point_get.rs1use crate::types::*;
4
5pub 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
30fn 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 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}