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

Function plan_cast

src/sql/src/plan/typeconv.rs:1530–1567  ·  view source on GitHub ↗

Plans a cast between [`SqlScalarType`]s, specifying which types of casts are permitted using [`CastContext`]. # Errors If a cast between the `ScalarExpr`'s base type and the specified type is: - Not possible, e.g. `Bytes` to `Interval` - Not permitted, e.g. implicitly casting from `Float64` to `Float32`. - Not implemented yet

(
    ecx: &ExprContext,
    ccx: CastContext,
    expr: HirScalarExpr,
    to: &SqlScalarType,
)

Source from the content-addressed store, hash-verified

1528/// - Not permitted, e.g. implicitly casting from `Float64` to `Float32`.
1529/// - Not implemented yet
1530pub fn plan_cast(
1531 ecx: &ExprContext,
1532 ccx: CastContext,
1533 expr: HirScalarExpr,
1534 to: &SqlScalarType,
1535) -> Result<HirScalarExpr, PlanError> {
1536 let from = ecx.scalar_type(&expr);
1537
1538 // Close over `ccx`, `from`, and `to` to simplify error messages in the
1539 // face of intermediate expressions.
1540 let cast_inner = |from, to, expr| {
1541 get_cast(ecx, ccx, from, to)
1542 .map(|cast| cast(expr))
1543 .map_err(|e| e.into_plan_error(ecx.name.into()))
1544 };
1545
1546 // Get cast which might include parameter rewrites + generating intermediate
1547 // expressions.
1548 //
1549 // String-like types get special handling to match PostgreSQL.
1550 // See: https://github.com/postgres/postgres/blob/6b04abdfc/
1551 // src/backend/parser/parse_coerce.c#L3205-L3223
1552 let from_category = TypeCategory::from_type(&from);
1553 let to_category = TypeCategory::from_type(to);
1554 if from_category == TypeCategory::String && to_category != TypeCategory::String {
1555 // Converting from stringlike to something non-stringlike. Handle as if
1556 // `from` were a `SqlScalarType::String.
1557 cast_inner(&SqlScalarType::String, to, expr)
1558 } else if from_category != TypeCategory::String && to_category == TypeCategory::String {
1559 // Converting from non-stringlike to something stringlike. Convert to a
1560 // `SqlScalarType::String` and then to the desired type.
1561 let expr = cast_inner(&from, &SqlScalarType::String, expr)?;
1562 cast_inner(&SqlScalarType::String, to, expr)
1563 } else {
1564 // Standard cast.
1565 cast_inner(&from, to, expr)
1566 }
1567}
1568
1569/// Reports whether it is possible to perform a cast from the specified types.
1570pub fn can_cast(

Callers 6

to_stringFunction · 0.70
to_jsonbFunction · 0.70
plan_coerceFunction · 0.70
plan_hypothetical_castFunction · 0.70
cast_toMethod · 0.70

Calls 4

get_castFunction · 0.85
into_plan_errorMethod · 0.80
scalar_typeMethod · 0.45
mapMethod · 0.45

Tested by

no test coverage detected