Skip to content

Commit

Permalink
jsonb_typeof and jsonb_array_length
Browse files Browse the repository at this point in the history
  • Loading branch information
xiangjinwu committed Feb 21, 2023
1 parent 750a996 commit 8b0b489
Show file tree
Hide file tree
Showing 9 changed files with 93 additions and 10 deletions.
12 changes: 12 additions & 0 deletions dashboard/proto/gen/expr.ts

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

31 changes: 22 additions & 9 deletions e2e_test/batch/types/jsonb.slt.part
Original file line number Diff line number Diff line change
Expand Up @@ -88,23 +88,36 @@ select jsonb_array_element(jsonb_object_field('{"k2":[2,true,4]}', 'k2'), -2)::b
----
t

query TT
# Note the difference between access text directly vs access jsonb then cast to text.
query TTT
with t(v1) as (values (null::jsonb), ('null'), ('true'), ('1'), ('"a"'), ('[]'), ('{}')),
j(v1) as (select ('{"k":' || v1::varchar || '}')::jsonb from t)
select jsonb_object_field_text(v1, 'k'), jsonb_object_field(v1, 'k')::varchar from j order by 2;
select
jsonb_object_field_text(v1, 'k'),
jsonb_object_field(v1, 'k')::varchar,
jsonb_typeof(jsonb_object_field(v1, 'k'))
from j order by 2;
----
a "a"
1 1
[] []
NULL null
true true
{} {}
NULL NULL
a "a" string
1 1 number
[] [] array
NULL null null
true true boolean
{} {} object
NULL NULL NULL

query T
select jsonb_array_element_text('true'::jsonb, 2);
----
NULL

query I
select jsonb_array_length('[7, 2]');
----
2

statement error cannot get array length
select jsonb_array_length('null');

statement ok
drop table t;
2 changes: 2 additions & 0 deletions proto/expr.proto
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,8 @@ message ExprNode {
JSONB_ACCESS_INNER = 600;
// jsonb ->> int, jsonb ->> text, jsonb #>> text[] that returns text
JSONB_ACCESS_STR = 601;
JSONB_TYPEOF = 602;
JSONB_ARRAY_LENGTH = 603;

// Non-pure functions below (> 1000)
// ------------------------
Expand Down
4 changes: 3 additions & 1 deletion src/expr/src/expr/build_expr_from_prost.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,9 @@ pub fn build_from_prost(prost: &ExprNode) -> Result<BoxedExpression> {
// Fixed number of arguments and based on `Unary/Binary/Ternary/...Expression`
Cast | Upper | Lower | Md5 | Not | IsTrue | IsNotTrue | IsFalse | IsNotFalse | IsNull
| IsNotNull | Neg | Ascii | Abs | Ceil | Floor | Round | Exp | BitwiseNot | CharLength
| BoolOut | OctetLength | BitLength | ToTimestamp => build_unary_expr_prost(prost),
| BoolOut | OctetLength | BitLength | ToTimestamp | JsonbTypeof | JsonbArrayLength => {
build_unary_expr_prost(prost)
}
Equal | NotEqual | LessThan | LessThanOrEqual | GreaterThan | GreaterThanOrEqual | Add
| Subtract | Multiply | Divide | Modulus | Extract | RoundDigit | Pow | TumbleStart
| Position | BitwiseShiftLeft | BitwiseShiftRight | BitwiseAnd | BitwiseOr | BitwiseXor
Expand Down
13 changes: 13 additions & 0 deletions src/expr/src/expr/expr_unary.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ use crate::vector_op::cast::*;
use crate::vector_op::cmp::{is_false, is_not_false, is_not_true, is_true};
use crate::vector_op::conjunction;
use crate::vector_op::exp::exp_f64;
use crate::vector_op::jsonb_info::{jsonb_array_length, jsonb_typeof};
use crate::vector_op::length::{bit_length, length_default, octet_length};
use crate::vector_op::lower::lower;
use crate::vector_op::ltrim::ltrim;
Expand Down Expand Up @@ -307,6 +308,18 @@ pub fn new_unary_expr(
f64_sec_to_timestamptz,
))
}
(ProstType::JsonbTypeof, DataType::Varchar, DataType::Jsonb) => {
UnaryBytesExpression::<JsonbArray, _>::new(child_expr, return_type, jsonb_typeof)
.boxed()
}
(ProstType::JsonbArrayLength, DataType::Int32, DataType::Jsonb) => {
UnaryExpression::<JsonbArray, I32Array, _>::new(
child_expr,
return_type,
jsonb_array_length,
)
.boxed()
}
(expr, ret, child) => {
return Err(ExprError::UnsupportedFunction(format!(
"{:?}({:?}) -> {:?}",
Expand Down
2 changes: 2 additions & 0 deletions src/expr/src/sig/func.rs
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,8 @@ fn build_type_derive_map() -> FuncSigMap {
map.insert(E::JsonbAccessInner, vec![T::Jsonb, T::Varchar], T::Jsonb);
map.insert(E::JsonbAccessStr, vec![T::Jsonb, T::Int32], T::Varchar);
map.insert(E::JsonbAccessStr, vec![T::Jsonb, T::Varchar], T::Varchar);
map.insert(E::JsonbTypeof, vec![T::Jsonb], T::Varchar);
map.insert(E::JsonbArrayLength, vec![T::Jsonb], T::Int32);

map
}
Expand Down
36 changes: 36 additions & 0 deletions src/expr/src/vector_op/jsonb_info.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// Copyright 2023 RisingWave Labs
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

use std::fmt::Write;

use risingwave_common::array::JsonbRef;

use crate::{ExprError, Result};

#[inline(always)]
pub fn jsonb_typeof(v: JsonbRef<'_>, writer: &mut dyn Write) -> Result<()> {
writer
.write_str(v.type_name())
.map_err(|e| ExprError::Internal(e.into()))
}

#[inline(always)]
pub fn jsonb_array_length(v: JsonbRef<'_>) -> Result<i32> {
v.array_len()
.map(|n| n as i32)
.map_err(|e| ExprError::InvalidParam {
name: "",
reason: e,
})
}
1 change: 1 addition & 0 deletions src/expr/src/vector_op/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ pub mod date_trunc;
pub mod exp;
pub mod extract;
pub mod format_type;
pub mod jsonb_info;
pub mod length;
pub mod like;
pub mod lower;
Expand Down
2 changes: 2 additions & 0 deletions src/frontend/src/binder/expr/function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -380,6 +380,8 @@ impl Binder {
("jsonb_array_element", raw_call(ExprType::JsonbAccessInner)),
("jsonb_object_field_text", raw_call(ExprType::JsonbAccessStr)),
("jsonb_array_element_text", raw_call(ExprType::JsonbAccessStr)),
("jsonb_typeof", raw_call(ExprType::JsonbTypeof)),
("jsonb_array_length", raw_call(ExprType::JsonbArrayLength)),
// System information operations.
(
"pg_typeof",
Expand Down

0 comments on commit 8b0b489

Please sign in to comment.