(
ecx: &ExprContext,
expr: HirScalarExpr,
positions: &[SubscriptPosition<Aug>],
)
| 4568 | } |
| 4569 | |
| 4570 | fn plan_subscript_jsonb( |
| 4571 | ecx: &ExprContext, |
| 4572 | expr: HirScalarExpr, |
| 4573 | positions: &[SubscriptPosition<Aug>], |
| 4574 | ) -> Result<CoercibleScalarExpr, PlanError> { |
| 4575 | use CastContext::Implicit; |
| 4576 | use SqlScalarType::{Int64, String}; |
| 4577 | |
| 4578 | // JSONB doesn't support the slicing syntax, so simply error if you |
| 4579 | // encounter any explicit slices. |
| 4580 | let subscripts = extract_scalar_subscript_from_positions(positions, "jsonb")?; |
| 4581 | |
| 4582 | let mut exprs = Vec::with_capacity(subscripts.len()); |
| 4583 | for s in subscripts { |
| 4584 | let subscript = plan_expr(ecx, s)?; |
| 4585 | let subscript = if let Ok(subscript) = subscript.clone().cast_to(ecx, Implicit, &String) { |
| 4586 | subscript |
| 4587 | } else if let Ok(subscript) = subscript.cast_to(ecx, Implicit, &Int64) { |
| 4588 | // Integers are converted to a string here and then re-parsed as an |
| 4589 | // integer by `JsonbGetPath`. Weird, but this is how PostgreSQL says to |
| 4590 | // do it. |
| 4591 | typeconv::to_string(ecx, subscript)? |
| 4592 | } else { |
| 4593 | sql_bail!("jsonb subscript type must be coercible to integer or text"); |
| 4594 | }; |
| 4595 | exprs.push(subscript); |
| 4596 | } |
| 4597 | |
| 4598 | // Subscripting works like `expr #> ARRAY[subscript]` rather than |
| 4599 | // `expr->subscript` as you might expect. |
| 4600 | let expr = expr.call_binary( |
| 4601 | HirScalarExpr::call_variadic( |
| 4602 | ArrayCreate { |
| 4603 | elem_type: SqlScalarType::String, |
| 4604 | }, |
| 4605 | exprs, |
| 4606 | ), |
| 4607 | expr_func::JsonbGetPath, |
| 4608 | ); |
| 4609 | Ok(expr.into()) |
| 4610 | } |
| 4611 | |
| 4612 | fn plan_exists(ecx: &ExprContext, query: &Query<Aug>) -> Result<CoercibleScalarExpr, PlanError> { |
| 4613 | if !ecx.allow_subqueries { |
no test coverage detected