From 66d8360d709c6ffb6a1b6694e854d7f15c67ba55 Mon Sep 17 00:00:00 2001 From: Xiangjin Date: Thu, 16 Feb 2023 18:14:21 +0800 Subject: [PATCH] basic e2e with casting from and into string --- e2e_test/batch/catalog/pg_cast.slt.part | 26 ++++++++------- e2e_test/batch/types/jsonb.slt.part | 37 +++++++++++++++++++++ e2e_test/batch/types/jsonb_ord.slt.part | 44 +++++++++++++++++++++++++ src/common/src/array/jsonb_array.rs | 9 +++++ src/expr/src/expr/data_types.rs | 12 +++++++ src/expr/src/sig/cast.rs | 1 + src/expr/src/vector_op/cast.rs | 2 ++ src/frontend/src/binder/expr/mod.rs | 1 + 8 files changed, 120 insertions(+), 12 deletions(-) create mode 100644 e2e_test/batch/types/jsonb.slt.part create mode 100644 e2e_test/batch/types/jsonb_ord.slt.part diff --git a/e2e_test/batch/catalog/pg_cast.slt.part b/e2e_test/batch/catalog/pg_cast.slt.part index 51e26062be4ca..35fe3749e556a 100644 --- a/e2e_test/batch/catalog/pg_cast.slt.part +++ b/e2e_test/batch/catalog/pg_cast.slt.part @@ -55,18 +55,20 @@ SELECT * FROM pg_catalog.pg_cast 51 1043 1114 EXPLICIT 52 1043 1184 EXPLICIT 53 1043 1186 EXPLICIT -54 1083 1043 ASSIGN -55 1083 1186 IMPLICIT -56 1114 1082 ASSIGN -57 1114 1043 ASSIGN -58 1114 1083 ASSIGN -59 1114 1184 IMPLICIT -60 1184 1082 ASSIGN -61 1184 1043 ASSIGN -62 1184 1083 ASSIGN -63 1184 1114 ASSIGN -64 1186 1043 ASSIGN -65 1186 1083 ASSIGN +54 1043 3802 EXPLICIT +55 1083 1043 ASSIGN +56 1083 1186 IMPLICIT +57 1114 1082 ASSIGN +58 1114 1043 ASSIGN +59 1114 1083 ASSIGN +60 1114 1184 IMPLICIT +61 1184 1082 ASSIGN +62 1184 1043 ASSIGN +63 1184 1083 ASSIGN +64 1184 1114 ASSIGN +65 1186 1043 ASSIGN +66 1186 1083 ASSIGN +67 3802 1043 ASSIGN query TT rowsort SELECT s.typname, t.typname diff --git a/e2e_test/batch/types/jsonb.slt.part b/e2e_test/batch/types/jsonb.slt.part new file mode 100644 index 0000000000000..c34ba5850b17b --- /dev/null +++ b/e2e_test/batch/types/jsonb.slt.part @@ -0,0 +1,37 @@ +statement ok +SET RW_IMPLICIT_FLUSH TO true; + +query T rowsort +values ('{"a":[2, true, "", {}]}'::jsonb), ('1'), ('true'), ('null'), (null), ('[1, true]'); +---- +1 +NULL +[1,true] +null +true +{"a":[2,true,"",{}]} + +statement ok +create table t (v1 jsonb); + +statement ok +insert into t values ('1'), ('true'), ('null'), (null); + +query T rowsort +select * from t; +---- +1 +NULL +null +true + +query T +select * from t order by v1::varchar; +---- +1 +null +true +NULL + +statement ok +drop table t; diff --git a/e2e_test/batch/types/jsonb_ord.slt.part b/e2e_test/batch/types/jsonb_ord.slt.part new file mode 100644 index 0000000000000..59dc5406ab718 --- /dev/null +++ b/e2e_test/batch/types/jsonb_ord.slt.part @@ -0,0 +1,44 @@ +# We do not intend to support using `jsonb` type for `group by` / `order by` / `primary key` +# Before #7981 is done, we need these tests to make sure our system do not panic. +# After #7981, we need them to make sure proper errors are returned to user. + +statement ok +SET RW_IMPLICIT_FLUSH TO true; + +statement ok +values ('{"a":[2, true, "", {}]}'::jsonb), ('1'), ('true'), ('null'), (null), ('[1, true]') order by 1; + +statement ok +create table t (v1 jsonb); + +statement ok +insert into t values ('1'), ('true'), ('null'), (null); + +statement ok +select * from t order by v1; + +# deserialize length +statement ok +create materialized view mv1 as select * from t group by v1; + +statement ok +select * from mv1; + +statement ok +drop materialized view mv1; + +# deserialize pk +statement ok +create table t2 (v1 jsonb primary key); + +statement ok +insert into t2 values ('1'), ('true'), ('null'), (null); + +statement ok +select * from t2; + +statement ok +drop table t2; + +statement ok +drop table t; diff --git a/src/common/src/array/jsonb_array.rs b/src/common/src/array/jsonb_array.rs index f635c2f4d5aa2..7690a38f9baac 100644 --- a/src/common/src/array/jsonb_array.rs +++ b/src/common/src/array/jsonb_array.rs @@ -116,6 +116,15 @@ impl crate::types::to_binary::ToBinary for JsonbRef<'_> { } } +impl std::str::FromStr for JsonbVal { + type Err = ::Err; + + fn from_str(s: &str) -> Result { + let v: Value = s.parse()?; + Ok(Self(v.into())) + } +} + impl JsonbVal { /// Avoid this function (or `impl From`) which is leak of abstraction. /// In most cases you would be using `JsonbRef`. diff --git a/src/expr/src/expr/data_types.rs b/src/expr/src/expr/data_types.rs index 20d0e52400b58..6fe46a9fc37b7 100644 --- a/src/expr/src/expr/data_types.rs +++ b/src/expr/src/expr/data_types.rs @@ -71,6 +71,18 @@ macro_rules! list { pub(crate) use list; +#[macro_export] +macro_rules! jsonb { + ($macro:ident) => { + $macro! { + risingwave_common::types::DataType::Jsonb, + risingwave_common::array::JsonbArray + } + }; +} + +pub(crate) use jsonb; + #[macro_export] macro_rules! int16 { ($macro:ident) => { diff --git a/src/expr/src/sig/cast.rs b/src/expr/src/sig/cast.rs index cd9f5fe2c194d..8a02c47176338 100644 --- a/src/expr/src/sig/cast.rs +++ b/src/expr/src/sig/cast.rs @@ -90,6 +90,7 @@ pub static CAST_MAP: LazyLock = LazyLock::new(|| { T::Timestamptz, T::Time, T::Interval, + T::Jsonb, ] { m.insert((t, T::Varchar), CastContext::Assign); m.insert((T::Varchar, t), CastContext::Explicit); diff --git a/src/expr/src/vector_op/cast.rs b/src/expr/src/vector_op/cast.rs index cbbd68cfb2c73..39fc4c3fa6fc9 100644 --- a/src/expr/src/vector_op/cast.rs +++ b/src/expr/src/vector_op/cast.rs @@ -456,6 +456,7 @@ macro_rules! for_all_cast_variants { { varchar, decimal, str_parse, false }, { varchar, boolean, str_to_bool, false }, { varchar, bytea, str_to_bytea, false }, + { varchar, jsonb, str_parse, false }, // `str_to_list` requires `target_elem_type` and is handled elsewhere { boolean, varchar, bool_to_varchar, false }, @@ -469,6 +470,7 @@ macro_rules! for_all_cast_variants { { interval, varchar, general_to_text, false }, { date, varchar, general_to_text, false }, { timestamp, varchar, general_to_text, false }, + { jsonb, varchar, |x, w| general_to_text(x, w), false }, { list, varchar, |x, w| general_to_text(x, w), false }, { boolean, int32, try_cast, false }, diff --git a/src/frontend/src/binder/expr/mod.rs b/src/frontend/src/binder/expr/mod.rs index d45c4985b63fd..de782f7e02110 100644 --- a/src/frontend/src/binder/expr/mod.rs +++ b/src/frontend/src/binder/expr/mod.rs @@ -510,6 +510,7 @@ pub fn bind_data_type(data_type: &AstDataType) -> Result { "float4" => DataType::Float32, "float8" => DataType::Float64, "timestamptz" => DataType::Timestamptz, + "jsonb" => DataType::Jsonb, _ => return Err(new_err().into()), } }