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

Function rewrite_binary_op

nodedb-sql/src/parser/preprocess/vector_ops.rs:106–152  ·  view source on GitHub ↗

Generic binary-operator rewriter: replaces all occurrences of `op` (outside literals/comments/quoted idents) with `func_name(left, right)`.

(sql: &str, op: &str, func_name: &str)

Source from the content-addressed store, hash-verified

104/// Generic binary-operator rewriter: replaces all occurrences of `op`
105/// (outside literals/comments/quoted idents) with `func_name(left, right)`.
106fn rewrite_binary_op(sql: &str, op: &str, func_name: &str) -> Option<String> {
107 if !has_operator_outside_literals(sql, op) {
108 return None;
109 }
110
111 let positions = find_operator_positions(sql, op);
112 if positions.is_empty() {
113 return None;
114 }
115
116 let mut result = String::with_capacity(sql.len());
117 let mut consumed = 0usize;
118 let mut found = false;
119
120 for op_pos in positions {
121 if op_pos < consumed {
122 continue;
123 }
124
125 let before = &sql[consumed..op_pos];
126 let left = extract_left_operand(before)?;
127 // The left operand is the trailing identifier of `before`. Subtract
128 // its length from the *trimmed* end of `before` — using `before.len()`
129 // directly is off-by-one whenever there is whitespace between the
130 // column and the operator (e.g. `embedding <-> ARRAY[...]`), which
131 // would leave the column's first character behind in the result and
132 // corrupt the rewritten function name (`evector_distance(...)`).
133 let trimmed_end_len = before.trim_end().len();
134 let left_start = consumed + (trimmed_end_len - left.len());
135
136 let after_op = &sql[op_pos + op.len()..];
137 let (right, right_len) = extract_right_operand(after_op.trim_start())?;
138 let ws_skip = after_op.len() - after_op.trim_start().len();
139
140 result.push_str(&sql[consumed..left_start]);
141 result.push_str(&format!("{func_name}({left}, {right})"));
142 consumed = op_pos + op.len() + ws_skip + right_len;
143 found = true;
144 }
145
146 if !found {
147 return None;
148 }
149
150 result.push_str(&sql[consumed..]);
151 Some(result)
152}
153
154#[cfg(test)]
155mod tests {

Callers 3

rewrite_arrow_distanceFunction · 0.85
rewrite_cosine_distanceFunction · 0.85

Calls 6

find_operator_positionsFunction · 0.85
extract_left_operandFunction · 0.85
extract_right_operandFunction · 0.85
is_emptyMethod · 0.45
lenMethod · 0.45

Tested by

no test coverage detected