(
ecx: &ExprContext,
expr: &Expr<Aug>,
positions: &[SubscriptPosition<Aug>],
)
| 4324 | } |
| 4325 | |
| 4326 | fn plan_subscript( |
| 4327 | ecx: &ExprContext, |
| 4328 | expr: &Expr<Aug>, |
| 4329 | positions: &[SubscriptPosition<Aug>], |
| 4330 | ) -> Result<CoercibleScalarExpr, PlanError> { |
| 4331 | assert!( |
| 4332 | !positions.is_empty(), |
| 4333 | "subscript expression must contain at least one position" |
| 4334 | ); |
| 4335 | |
| 4336 | let ecx = &ecx.with_name("subscripting"); |
| 4337 | let expr = plan_expr(ecx, expr)?.type_as_any(ecx)?; |
| 4338 | let ty = ecx.scalar_type(&expr); |
| 4339 | match &ty { |
| 4340 | SqlScalarType::Array(..) | SqlScalarType::Int2Vector => plan_subscript_array( |
| 4341 | ecx, |
| 4342 | expr, |
| 4343 | positions, |
| 4344 | // Int2Vector uses 0-based indexing, while arrays use 1-based indexing, so we need to |
| 4345 | // adjust all Int2Vector subscript operations by 1 (both w/r/t input and the values we |
| 4346 | // track in its backing data). |
| 4347 | if ty == SqlScalarType::Int2Vector { |
| 4348 | 1 |
| 4349 | } else { |
| 4350 | 0 |
| 4351 | }, |
| 4352 | ), |
| 4353 | SqlScalarType::Jsonb => plan_subscript_jsonb(ecx, expr, positions), |
| 4354 | SqlScalarType::List { element_type, .. } => { |
| 4355 | // `elem_type_name` is used only in error msgs, so we set `postgres_compat` to false. |
| 4356 | let elem_type_name = ecx.humanize_sql_scalar_type(element_type, false); |
| 4357 | let n_layers = ty.unwrap_list_n_layers(); |
| 4358 | plan_subscript_list(ecx, expr, positions, n_layers, &elem_type_name) |
| 4359 | } |
| 4360 | ty => sql_bail!( |
| 4361 | "cannot subscript type {}", |
| 4362 | ecx.humanize_sql_scalar_type(ty, false) |
| 4363 | ), |
| 4364 | } |
| 4365 | } |
| 4366 | |
| 4367 | // All subscript positions are of the form [<expr>(:<expr>?)?]; extract all |
| 4368 | // expressions from those that look like indexes (i.e. `[<expr>]`) or error if |
no test coverage detected