Skip to content

Commit 074c1f8

Browse files
fix: support string to number type in JSONB_POPULATE_RECORD (#19937) (#19996)
Co-authored-by: zwang28 <[email protected]>
1 parent b364088 commit 074c1f8

File tree

3 files changed

+31
-33
lines changed

3 files changed

+31
-33
lines changed

e2e_test/batch/types/jsonb.slt.part

+21
Original file line numberDiff line numberDiff line change
@@ -281,3 +281,24 @@ FROM (VALUES
281281
{"a": "b"} t f t f
282282
[1,2] t f f t
283283
abc f f f f
284+
285+
query T
286+
select JSONB_POPULATE_RECORD(NULL::struct<id BIGINT>, '{"id": "12345"}'::jsonb) AS v;
287+
----
288+
(12345)
289+
290+
query T
291+
select JSONB_POPULATE_RECORD(NULL::struct<id REAL>, '{"id": "0.123"}'::jsonb) AS v;
292+
----
293+
(0.123)
294+
295+
query T
296+
select JSONB_POPULATE_RECORDSET(NULL::struct<id REAL>, '[{"id": "0.123"},{"id": "123"}]'::jsonb) AS v;
297+
----
298+
(0.123)
299+
(123)
300+
301+
query T
302+
select JSONB_POPULATE_RECORD(NULL::struct<id DOUBLE>, '{"id": "1e10"}'::jsonb) AS v;
303+
----
304+
(10000000000)

e2e_test/batch/types/map.slt.part

+2-8
Original file line numberDiff line numberDiff line change
@@ -150,19 +150,13 @@ select jsonb_populate_map(
150150
{a:a,b:3,c:4}
151151

152152

153-
query error
153+
query ?
154154
select jsonb_populate_map(
155155
MAP {'a': 1, 'b': 2},
156156
'{"b": "3", "c": 4}'::jsonb
157157
);
158158
----
159-
db error: ERROR: Failed to run the query
160-
161-
Caused by these errors (recent errors listed first):
162-
1: Expr error
163-
2: error while evaluating expression `jsonb_populate_map('{a:1,b:2}', '{"b": "3", "c": 4}')`
164-
3: Parse error: cannot cast jsonb string to type number
165-
159+
{a:1,b:3,c:4}
166160

167161
query error
168162
select jsonb_populate_map(

src/common/src/types/jsonb.rs

+8-25
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ use bytes::{Buf, BufMut, BytesMut};
1919
use jsonbb::{Value, ValueRef};
2020
use postgres_types::{accepts, to_sql_checked, FromSql, IsNull, ToSql, Type};
2121
use risingwave_common_estimate_size::EstimateSize;
22+
use thiserror_ext::AsReport;
2223

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

409410
/// Convert the jsonb value to a datum.
410411
pub fn to_datum(self, ty: &DataType) -> Result<Datum, String> {
411-
if !matches!(
412-
ty,
413-
DataType::Jsonb
414-
| DataType::Boolean
415-
| DataType::Int16
416-
| DataType::Int32
417-
| DataType::Int64
418-
| DataType::Float32
419-
| DataType::Float64
420-
| DataType::Varchar
421-
| DataType::List(_)
422-
| DataType::Struct(_)
423-
) {
424-
return Err(format!("cannot cast jsonb to {ty}"));
425-
}
426412
if self.0.as_null().is_some() {
427413
return Ok(None);
428414
}
429-
Ok(Some(match ty {
415+
let datum = match ty {
430416
DataType::Jsonb => ScalarImpl::Jsonb(self.into()),
431-
DataType::Boolean => ScalarImpl::Bool(self.as_bool()?),
432-
DataType::Int16 => ScalarImpl::Int16(self.as_number()?.try_into()?),
433-
DataType::Int32 => ScalarImpl::Int32(self.as_number()?.try_into()?),
434-
DataType::Int64 => ScalarImpl::Int64(self.as_number()?.try_into()?),
435-
DataType::Float32 => ScalarImpl::Float32(self.as_number()?.try_into()?),
436-
DataType::Float64 => ScalarImpl::Float64(self.as_number()?),
437-
DataType::Varchar => ScalarImpl::Utf8(self.force_string().into()),
438417
DataType::List(t) => ScalarImpl::List(self.to_list(t)?),
439418
DataType::Struct(s) => ScalarImpl::Struct(self.to_struct(s)?),
440-
_ => unreachable!(),
441-
}))
419+
_ => {
420+
let s = self.force_string();
421+
ScalarImpl::from_text(&s, ty).map_err(|e| format!("{}", e.as_report()))?
422+
}
423+
};
424+
Ok(Some(datum))
442425
}
443426

444427
/// Convert the jsonb value to a list value.

0 commit comments

Comments
 (0)