diff --git a/e2e_test/batch/types/jsonb.slt.part b/e2e_test/batch/types/jsonb.slt.part index 8e8ec7aa0e60f..3420958aabdb5 100644 --- a/e2e_test/batch/types/jsonb.slt.part +++ b/e2e_test/batch/types/jsonb.slt.part @@ -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": "12345"}'::jsonb) AS v; +---- + (12345) + +query T +select JSONB_POPULATE_RECORD(NULL::struct, '{"id": "0.123"}'::jsonb) AS v; +---- + (0.123) + +query T +select JSONB_POPULATE_RECORDSET(NULL::struct, '[{"id": "0.123"},{"id": "123"}]'::jsonb) AS v; +---- + (0.123) + (123) + +query T +select JSONB_POPULATE_RECORD(NULL::struct, '{"id": "1e10"}'::jsonb) AS v; +---- + (10000000000) diff --git a/e2e_test/batch/types/map.slt.part b/e2e_test/batch/types/map.slt.part index fe98fa3633000..03525a6ae4d32 100644 --- a/e2e_test/batch/types/map.slt.part +++ b/e2e_test/batch/types/map.slt.part @@ -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( diff --git a/src/common/src/types/jsonb.rs b/src/common/src/types/jsonb.rs index 7e58b039fe356..9957a71851f5d 100644 --- a/src/common/src/types/jsonb.rs +++ b/src/common/src/types/jsonb.rs @@ -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, @@ -408,37 +409,19 @@ impl<'a> JsonbRef<'a> { /// Convert the jsonb value to a datum. pub fn to_datum(self, ty: &DataType) -> Result { - 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.