MCPcopy Create free account
hub / github.com/MaterializeInc/materialize / plan_select_inner

Function plan_select_inner

src/sql/src/plan/statement/dml.rs:214–291  ·  view source on GitHub ↗
(
    scx: &StatementContext,
    select: SelectStatement<Aug>,
    params: &Params,
    copy_to: Option<CopyFormat>,
)

Source from the content-addressed store, hash-verified

212}
213
214fn plan_select_inner(
215 scx: &StatementContext,
216 select: SelectStatement<Aug>,
217 params: &Params,
218 copy_to: Option<CopyFormat>,
219) -> Result<(SelectPlan, RelationDesc), PlanError> {
220 let when = query::plan_as_of(scx, select.as_of.clone())?;
221 let lifetime = QueryLifetime::OneShot;
222 let query::PlannedRootQuery {
223 mut expr,
224 desc,
225 finishing,
226 scope: _,
227 } = query::plan_root_query(scx, select.query.clone(), lifetime)?;
228 expr.bind_parameters_and_simplify_offset(scx, lifetime, params)?;
229
230 // We need to concretize the `limit` and `offset` of the RowSetFinishing, so that we go from
231 // `RowSetFinishing<HirScalarExpr, HirScalarExpr>` to `RowSetFinishing`.
232 // This involves binding parameters and evaluating each expression to a number.
233 // (This should be possible even for `limit` here, because we are at the top level of a SELECT,
234 // so this `limit` has to be a constant.)
235 let limit = match finishing.limit {
236 None => None,
237 Some(mut limit) => {
238 limit.bind_parameters_and_simplify_offset(scx, lifetime, params)?;
239 // TODO: Call `try_into_literal_int64` instead of `as_literal`.
240 let Some(limit) = limit.as_literal() else {
241 sql_bail!(
242 "Top-level LIMIT must be a constant expression, got {}",
243 limit
244 )
245 };
246 match limit {
247 Datum::Null => None,
248 Datum::Int64(v) if v >= 0 => NonNeg::<i64>::try_from(v).ok(),
249 _ => {
250 soft_panic_or_log!("Valid literal limit must be asserted in `plan_select`");
251 sql_bail!("LIMIT must be a non-negative INT or NULL")
252 }
253 }
254 }
255 };
256 let offset = {
257 let mut offset = finishing.offset.clone();
258 offset.bind_parameters_and_simplify_offset(scx, lifetime, params)?;
259 let offset = offset_into_value(offset.take())?;
260 offset.try_into().map_err(|_| {
261 // We already checked in bind_parameters_and_simplify_offset / offset_into_value.
262 soft_panic_or_log!("unexpectedly negative OFFSET");
263 negative_offset_error(offset)
264 })?
265 };
266
267 // Unmaterializable functions are evaluated based on various information (e.g., the catalog)
268 // during sequencing, without taking AS OF into account. This would be hard to fix, so for now
269 // we just disallow AS OF when there is an unmaterializable function in a query (except mz_now).
270 if scx.is_feature_flag_enabled(&DISALLOW_UNMATERIALIZABLE_FUNCTIONS_AS_OF)
271 && select.as_of.is_some()

Callers 3

plan_selectFunction · 0.85
plan_explaineeFunction · 0.85
plan_copyFunction · 0.85

Calls 13

plan_as_ofFunction · 0.85
plan_root_queryFunction · 0.85
offset_into_valueFunction · 0.85
negative_offset_errorFunction · 0.85
is_someMethod · 0.80
cloneMethod · 0.45
as_literalMethod · 0.45
okMethod · 0.45
takeMethod · 0.45

Tested by

no test coverage detected