MCPcopy Create free account
hub / github.com/NodeDB-Lab/nodedb / preprocess

Function preprocess

nodedb-sql/src/parser/preprocess/pipeline.rs:42–136  ·  view source on GitHub ↗

Pre-process a SQL string, rewriting NodeDB-specific syntax. Returns `Ok(None)` if no rewriting was needed. Temporal clause parse errors bubble up as `SqlError::Parse` so they surface to the caller identically to sqlparser errors.

(sql: &str)

Source from the content-addressed store, hash-verified

40/// errors bubble up as `SqlError::Parse` so they surface to the caller
41/// identically to sqlparser errors.
42pub fn preprocess(sql: &str) -> Result<Option<PreprocessedSql>, SqlError> {
43 let trimmed = sql.trim();
44
45 // Extract temporal clauses first — they can appear in both SELECT and
46 // INSERT...SELECT, and stripping them before the UPSERT/object-literal
47 // rewrites keeps those rewriters pattern-free of NodeDB extensions.
48 let (temporal_sql, temporal) =
49 match extract_temporal(trimmed).map_err(|e| SqlError::Parse { detail: e.0 })? {
50 Some(ex) => (ex.sql, ex.temporal),
51 None => (trimmed.to_string(), TemporalScope::default()),
52 };
53 let any_temporal = temporal != TemporalScope::default();
54
55 // Rewrite `SEARCH <coll> USING VECTOR(...)` to canonical
56 // `SELECT * FROM <coll> ORDER BY vector_distance(...) LIMIT k` before any
57 // first-word dispatch — the rewritten form re-enters the rest of the
58 // pipeline as a plain SELECT.
59 let (temporal_sql, search_vector_rewritten) =
60 match try_rewrite_search_using_vector(&temporal_sql) {
61 Some(rewritten) => (rewritten, true),
62 None => (temporal_sql, false),
63 };
64
65 let first_word = first_sql_word(&temporal_sql)
66 .map(|w| w.to_uppercase())
67 .unwrap_or_default();
68 let is_upsert = first_word == "UPSERT";
69
70 if is_upsert {
71 let rewritten = format!("INSERT INTO {}", &temporal_sql["UPSERT INTO ".len()..]);
72 if let Some(result) = try_rewrite_object_literal(&rewritten) {
73 return Ok(Some(PreprocessedSql {
74 sql: result,
75 is_upsert: true,
76 temporal,
77 }));
78 }
79 return Ok(Some(PreprocessedSql {
80 sql: rewritten,
81 is_upsert: true,
82 temporal,
83 }));
84 }
85
86 if first_word == "INSERT"
87 && let Some(result) = try_rewrite_object_literal(&temporal_sql)
88 {
89 return Ok(Some(PreprocessedSql {
90 sql: result,
91 is_upsert: false,
92 temporal,
93 }));
94 }
95
96 let mut sql_buf = temporal_sql;
97 let mut any_rewrite = any_temporal || search_vector_rewritten;
98
99 if has_operator_outside_literals(&sql_buf, "<->")

Callers 7

plan_sqlFunction · 0.85
plan_sql_with_paramsFunction · 0.85
plan_annFunction · 0.85
plan_ann_errFunction · 0.85
plan_select_sqlFunction · 0.85
ppFunction · 0.85
parse_write_statementFunction · 0.85

Calls 10

first_sql_wordFunction · 0.85
rewrite_arrow_distanceFunction · 0.85
rewrite_cosine_distanceFunction · 0.85
to_stringMethod · 0.80

Tested by 1

plan_select_sqlFunction · 0.68