risingwave_common/types/
from_sql.rs

1// Copyright 2025 RisingWave Labs
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15use postgres_types::{FromSql, Type};
16use risingwave_common::types::{
17    Date, Interval, JsonbVal, ScalarImpl, Time, Timestamp, Timestamptz,
18};
19
20impl<'a> FromSql<'a> for ScalarImpl {
21    fn from_sql(
22        ty: &Type,
23        raw: &'a [u8],
24    ) -> Result<Self, Box<dyn std::error::Error + Sync + Send>> {
25        Ok(match *ty {
26            Type::BOOL => ScalarImpl::from(bool::from_sql(ty, raw)?),
27            Type::INT2 => ScalarImpl::from(i16::from_sql(ty, raw)?),
28            Type::INT4 => ScalarImpl::from(i32::from_sql(ty, raw)?),
29            Type::INT8 => ScalarImpl::from(i64::from_sql(ty, raw)?),
30            Type::FLOAT4 => ScalarImpl::from(f32::from_sql(ty, raw)?),
31            Type::FLOAT8 => ScalarImpl::from(f64::from_sql(ty, raw)?),
32            Type::DATE => ScalarImpl::from(Date::from_sql(ty, raw)?),
33            Type::TIME => ScalarImpl::from(Time::from_sql(ty, raw)?),
34            Type::TIMESTAMP => ScalarImpl::from(Timestamp::from_sql(ty, raw)?),
35            Type::TIMESTAMPTZ => ScalarImpl::from(Timestamptz::from_sql(ty, raw)?),
36            Type::JSON | Type::JSONB => ScalarImpl::from(JsonbVal::from_sql(ty, raw)?),
37            Type::INTERVAL => ScalarImpl::from(Interval::from_sql(ty, raw)?),
38            Type::BYTEA => ScalarImpl::from(Vec::<u8>::from_sql(ty, raw)?.into_boxed_slice()),
39            Type::VARCHAR | Type::TEXT | Type::BPCHAR => {
40                ScalarImpl::from(String::from_sql(ty, raw)?)
41            }
42            ref ty
43                if (ty.name() == "citext"
44                    || ty.name() == "ltree"
45                    || ty.name() == "lquery"
46                    || ty.name() == "ltxtquery") =>
47            {
48                ScalarImpl::from(String::from_sql(ty, raw)?)
49            }
50            // Serial, Int256, Struct, List and Decimal are not supported here
51            // Note: The Decimal type is specially handled in the `ScalarAdapter`.
52            _ => {
53                bail_not_implemented!("the postgres decoding for {ty} is unsupported")
54            }
55        })
56    }
57
58    fn accepts(ty: &Type) -> bool {
59        matches!(
60            *ty,
61            Type::BOOL
62                | Type::INT2
63                | Type::INT4
64                | Type::INT8
65                | Type::FLOAT4
66                | Type::FLOAT8
67                | Type::DATE
68                | Type::TIME
69                | Type::TIMESTAMP
70                | Type::TIMESTAMPTZ
71                | Type::JSON
72                | Type::JSONB
73                | Type::INTERVAL
74                | Type::BYTEA
75                | Type::VARCHAR
76                | Type::TEXT
77                | Type::BPCHAR
78        ) || (ty.name() == "citext"
79            || ty.name() == "ltree"
80            || ty.name() == "lquery"
81            || ty.name() == "ltxtquery")
82    }
83}