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

Method execute_sql

nodedb/src/control/gateway/core.rs:148–204  ·  view source on GitHub ↗

SQL-text entry point: checks the plan cache first. `plan_fn` is called at most once (on cache miss or after a descriptor cache-miss recovery that requires re-planning). ## Two-phase cache lookup (Gap 5 fix) A `PlanCacheKey` requires a `GatewayVersionSet`, which we cannot build from SQL text alone — it requires knowing which collections the plan touches. Previously this method used a speculative

(
        &self,
        ctx: &QueryContext,
        sql: &str,
        placeholder_types: &[&str],
        plan_fn: impl FnOnce() -> Result<PhysicalPlan, Error>,
    )

Source from the content-addressed store, hash-verified

146 /// descriptor versions), and — if current — use it to build the full key
147 /// for the plan lookup.
148 pub async fn execute_sql(
149 &self,
150 ctx: &QueryContext,
151 sql: &str,
152 placeholder_types: &[&str],
153 plan_fn: impl FnOnce() -> Result<PhysicalPlan, Error>,
154 ) -> Result<Vec<Vec<u8>>, Error> {
155 let sql_hash = hash_sql(sql);
156 let ph_hash = hash_placeholder_types(placeholder_types);
157 let sql_key = SqlKey {
158 sql_text_hash: sql_hash,
159 placeholder_types_hash: ph_hash,
160 };
161
162 // Phase 1: check the side cache for a previously stored version set.
163 if let Some(stored_vs) = self.plan_cache.lookup_version_set(&sql_key) {
164 // Verify the stored version set is still current by cross-checking
165 // each collection's current descriptor version.
166 let current_vs =
167 self.verify_version_set(&stored_vs, ctx.tenant_id.as_u64(), ctx.database_id);
168 if current_vs == stored_vs {
169 // Version set is still current — try the full plan cache.
170 let full_key = PlanCacheKey {
171 sql_text_hash: sql_hash,
172 placeholder_types_hash: ph_hash,
173 version_set: stored_vs.clone(),
174 };
175 if let Some(cached_plan) = self.plan_cache.get(&full_key) {
176 debug!(sql = %sql, "gateway: plan cache hit (two-phase)");
177 return self
178 .execute_with_version_set(ctx, (*cached_plan).clone(), stored_vs)
179 .await;
180 }
181 }
182 // Stored version set is stale or plan was evicted — fall through
183 // to re-plan. The stale side-cache entry will be overwritten below.
184 }
185
186 // Cache miss — invoke the planner.
187 let plan = plan_fn()?;
188
189 // Compute the actual version set from the plan (contains the real
190 // collection names and their current descriptor versions).
191 let actual_vs = self.collect_version_set(&plan, ctx.tenant_id.as_u64(), ctx.database_id);
192 let actual_key = PlanCacheKey {
193 sql_text_hash: sql_hash,
194 placeholder_types_hash: ph_hash,
195 version_set: actual_vs.clone(),
196 };
197
198 // Populate both caches so the next call hits.
199 self.plan_cache
200 .insert_version_set(sql_key, actual_vs.clone());
201 self.plan_cache.insert(actual_key, Arc::new(plan.clone()));
202
203 self.execute_with_version_set(ctx, plan, actual_vs).await
204 }
205

Callers

nothing calls this directly

Calls 11

hash_placeholder_typesFunction · 0.85
lookup_version_setMethod · 0.80
verify_version_setMethod · 0.80
collect_version_setMethod · 0.80
insert_version_setMethod · 0.80
hash_sqlFunction · 0.70
as_u64Method · 0.45
cloneMethod · 0.45
getMethod · 0.45
insertMethod · 0.45

Tested by

no test coverage detected