Skip to content

Commit

Permalink
fix: support string to number type in JSONB_POPULATE_RECORD (#19937) (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
zwang28 authored Jan 2, 2025
1 parent 3a91f87 commit 9c6a6ca
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 33 deletions.
21 changes: 21 additions & 0 deletions e2e_test/batch/types/jsonb.slt.part
Original file line number Diff line number Diff line change
Expand Up @@ -281,3 +281,24 @@ FROM (VALUES
{"a": "b"} t f t f
[1,2] t f f t
abc f f f f

query T
select JSONB_POPULATE_RECORD(NULL::struct<id BIGINT>, '{"id": "12345"}'::jsonb) AS v;
----
(12345)

query T
select JSONB_POPULATE_RECORD(NULL::struct<id REAL>, '{"id": "0.123"}'::jsonb) AS v;
----
(0.123)

query T
select JSONB_POPULATE_RECORDSET(NULL::struct<id REAL>, '[{"id": "0.123"},{"id": "123"}]'::jsonb) AS v;
----
(0.123)
(123)

query T
select JSONB_POPULATE_RECORD(NULL::struct<id DOUBLE>, '{"id": "1e10"}'::jsonb) AS v;
----
(10000000000)
10 changes: 2 additions & 8 deletions e2e_test/batch/types/map.slt.part
Original file line number Diff line number Diff line change
Expand Up @@ -150,19 +150,13 @@ select jsonb_populate_map(
{a:a,b:3,c:4}


query error
query ?
select jsonb_populate_map(
MAP {'a': 1, 'b': 2},
'{"b": "3", "c": 4}'::jsonb
);
----
db error: ERROR: Failed to run the query

Caused by these errors (recent errors listed first):
1: Expr error
2: error while evaluating expression `jsonb_populate_map('{a:1,b:2}', '{"b": "3", "c": 4}')`
3: Parse error: cannot cast jsonb string to type number

{a:1,b:3,c:4}

query error
select jsonb_populate_map(
Expand Down
33 changes: 8 additions & 25 deletions src/common/src/types/jsonb.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ use bytes::{Buf, BufMut, BytesMut};
use jsonbb::{Value, ValueRef};
use postgres_types::{accepts, to_sql_checked, FromSql, IsNull, ToSql, Type};
use risingwave_common_estimate_size::EstimateSize;
use thiserror_ext::AsReport;

use super::{
Datum, IntoOrdered, ListValue, MapType, MapValue, ScalarImpl, StructRef, ToOwnedDatum, F64,
Expand Down Expand Up @@ -408,37 +409,19 @@ impl<'a> JsonbRef<'a> {

/// Convert the jsonb value to a datum.
pub fn to_datum(self, ty: &DataType) -> Result<Datum, String> {
if !matches!(
ty,
DataType::Jsonb
| DataType::Boolean
| DataType::Int16
| DataType::Int32
| DataType::Int64
| DataType::Float32
| DataType::Float64
| DataType::Varchar
| DataType::List(_)
| DataType::Struct(_)
) {
return Err(format!("cannot cast jsonb to {ty}"));
}
if self.0.as_null().is_some() {
return Ok(None);
}
Ok(Some(match ty {
let datum = match ty {
DataType::Jsonb => ScalarImpl::Jsonb(self.into()),
DataType::Boolean => ScalarImpl::Bool(self.as_bool()?),
DataType::Int16 => ScalarImpl::Int16(self.as_number()?.try_into()?),
DataType::Int32 => ScalarImpl::Int32(self.as_number()?.try_into()?),
DataType::Int64 => ScalarImpl::Int64(self.as_number()?.try_into()?),
DataType::Float32 => ScalarImpl::Float32(self.as_number()?.try_into()?),
DataType::Float64 => ScalarImpl::Float64(self.as_number()?),
DataType::Varchar => ScalarImpl::Utf8(self.force_string().into()),
DataType::List(t) => ScalarImpl::List(self.to_list(t)?),
DataType::Struct(s) => ScalarImpl::Struct(self.to_struct(s)?),
_ => unreachable!(),
}))
_ => {
let s = self.force_string();
ScalarImpl::from_text(&s, ty).map_err(|e| format!("{}", e.as_report()))?
}
};
Ok(Some(datum))
}

/// Convert the jsonb value to a list value.
Expand Down

0 comments on commit 9c6a6ca

Please sign in to comment.