fix: support empty objects in JSON2

Signed-off-by: fys <fengys1996@gmail.com>
This commit is contained in:
fys
2026-08-26 15:17:36 +08:00
parent c42f595225
commit af49e4e5e1
7 changed files with 801 additions and 7 deletions
+18
View File
@@ -140,6 +140,13 @@ impl JsonSettings {
/// Encode a serde_json::Value into a Value::Json using current settings.
pub fn encode(&self, json: Json) -> Result<Value> {
if self.type_hints.is_empty()
&& self.max_auto_expanded_paths.is_none()
&& let Json::Object(object) = &json
&& object.is_empty()
{
return Ok(Value::Json(Box::new(JsonValue::null())));
}
let mut context = JsonContext {
path: Vec::new(),
settings: self,
@@ -777,6 +784,17 @@ mod tests {
}
}
#[test]
fn test_encode_root_empty_object_without_type_hints_as_json_null() -> Result<()> {
let settings = JsonSettings::default();
assert_eq!(
Value::Json(Box::new(JsonValue::null())),
settings.encode(json!({}))?
);
Ok(())
}
#[test]
fn test_encode_json_object() {
let json = json!({
+14
View File
@@ -180,6 +180,10 @@ impl JsonArray<'_> {
data_type, expect
);
if data_type == &DataType::Null {
return Ok(new_null_array(expect, self.inner.len()));
}
let struct_array = self.inner.as_struct_opt().context(AlignJsonArraySnafu {
reason: "expect struct array",
})?;
@@ -709,6 +713,16 @@ mod test {
assert_eq!(2, widened.null_count());
}
let target_type = DataType::Struct(Fields::from(vec![Field::new(
"value",
DataType::Int64,
true,
)]));
let widened = JsonArray::from(&nulls).widen_to(&target_type)?;
assert_eq!(&target_type, widened.data_type());
assert_eq!(2, widened.len());
assert_eq!(2, widened.null_count());
Ok(())
}
+20 -1
View File
@@ -24,7 +24,7 @@ use crate::prelude::{ValueRef, Vector, VectorRef};
use crate::types::StructType;
use crate::types::json_type::{JsonNativeType, is_include};
use crate::value::{ListValue, StructValue, StructValueRef, Value};
use crate::vectors::{MutableVector, StructVectorBuilder};
use crate::vectors::{MutableVector, NullVector, StructVectorBuilder};
#[derive(Clone)]
pub(crate) struct JsonVectorBuilder {
@@ -45,6 +45,12 @@ impl JsonVectorBuilder {
}
fn try_build(&mut self) -> Result<VectorRef> {
if matches!(self.merged_type, JsonNativeType::Null) {
let len = self.values.len();
self.values.clear();
return Ok(Arc::new(NullVector::new(len)));
}
let DataType::Struct(fields) = self.merged_type.as_arrow_type() else {
return UnexpectedSnafu {
reason: "merged JSON2 type must map to Arrow Struct in JsonVectorBuilder",
@@ -357,6 +363,19 @@ mod tests {
.unwrap_err();
assert!(err.to_string().contains("expected json value"));
let mut null_builder = JsonVectorBuilder::new(JsonNativeType::Null, 2);
null_builder.try_push_value_ref(&ValueRef::Json(Box::new(
crate::json::value::JsonValueRef::null(),
)))?;
null_builder.try_push_value_ref(&ValueRef::Json(Box::new(
crate::json::value::JsonValueRef::null(),
)))?;
let vector = null_builder.to_vector();
assert_eq!(2, vector.len());
assert_eq!(Value::Null, vector.get(0));
assert_eq!(Value::Null, vector.get(1));
Ok(())
}
@@ -28,10 +28,6 @@ insert into json2_disable_non_object_insert values (5, 'null');
Error: 1001(Unsupported), Non-object json is not supported currently
insert into json2_disable_non_object_insert values (6, '{}');
Error: 1004(InvalidArguments), Invalid InsertRequest, reason: empty json object is not supported, consider adding a dummy field
drop table json2_disable_non_object_insert;
Affected Rows: 0
@@ -16,8 +16,6 @@ insert into json2_disable_non_object_insert values (4, 'true');
insert into json2_disable_non_object_insert values (5, 'null');
insert into json2_disable_non_object_insert values (6, '{}');
drop table json2_disable_non_object_insert;
create table json2_whole_and_path_read (
@@ -0,0 +1,510 @@
CREATE TABLE json_empty_no_type_hints (
ts TIMESTAMP TIME INDEX,
app_name STRING,
log_level STRING,
log_message STRING,
attrs JSON2
) WITH (
'append_mode' = 'true'
);
Affected Rows: 0
INSERT INTO json_empty_no_type_hints
VALUES
(1, 'checkout', 'INFO', 'request completed', '{}');
Affected Rows: 1
SELECT *
FROM json_empty_no_type_hints
ORDER BY ts;
+-------------------------+----------+-----------+-------------------+-------+
| ts | app_name | log_level | log_message | attrs |
+-------------------------+----------+-----------+-------------------+-------+
| 1970-01-01T00:00:00.001 | checkout | INFO | request completed | |
+-------------------------+----------+-----------+-------------------+-------+
INSERT INTO json_empty_no_type_hints
VALUES
(2, 'checkout', 'INFO', 'request completed', '{"a": 1}');
Affected Rows: 1
SELECT
ts,
app_name,
log_level,
log_message,
json_get(attrs, 'a')::int64
FROM json_empty_no_type_hints
ORDER BY ts;
+-------------------------+----------+-----------+-------------------+------------------------------------------------------------------------------+
| ts | app_name | log_level | log_message | arrow_cast(json_get(json_empty_no_type_hints.attrs,Utf8("a")),Utf8("Int64")) |
+-------------------------+----------+-----------+-------------------+------------------------------------------------------------------------------+
| 1970-01-01T00:00:00.001 | checkout | INFO | request completed | |
| 1970-01-01T00:00:00.002 | checkout | INFO | request completed | 1 |
+-------------------------+----------+-----------+-------------------+------------------------------------------------------------------------------+
SELECT *
FROM json_empty_no_type_hints
ORDER BY ts;
+-------------------------+----------+-----------+-------------------+---------+
| ts | app_name | log_level | log_message | attrs |
+-------------------------+----------+-----------+-------------------+---------+
| 1970-01-01T00:00:00.001 | checkout | INFO | request completed | |
| 1970-01-01T00:00:00.002 | checkout | INFO | request completed | {"a":1} |
+-------------------------+----------+-----------+-------------------+---------+
ADMIN FLUSH_TABLE('json_empty_no_type_hints');
+-----------------------------------------------+
| ADMIN FLUSH_TABLE('json_empty_no_type_hints') |
+-----------------------------------------------+
| 0 |
+-----------------------------------------------+
SELECT
ts,
app_name,
log_level,
log_message,
json_get(attrs, 'a')::int64
FROM json_empty_no_type_hints
ORDER BY ts;
+-------------------------+----------+-----------+-------------------+------------------------------------------------------------------------------+
| ts | app_name | log_level | log_message | arrow_cast(json_get(json_empty_no_type_hints.attrs,Utf8("a")),Utf8("Int64")) |
+-------------------------+----------+-----------+-------------------+------------------------------------------------------------------------------+
| 1970-01-01T00:00:00.001 | checkout | INFO | request completed | |
| 1970-01-01T00:00:00.002 | checkout | INFO | request completed | 1 |
+-------------------------+----------+-----------+-------------------+------------------------------------------------------------------------------+
INSERT INTO json_empty_no_type_hints
VALUES
(3, 'checkout', 'INFO', 'request completed', '{"a": 2}');
Affected Rows: 1
SELECT
ts,
app_name,
log_level,
log_message,
json_get(attrs, 'a')::int64
FROM json_empty_no_type_hints
ORDER BY ts;
+-------------------------+----------+-----------+-------------------+------------------------------------------------------------------------------+
| ts | app_name | log_level | log_message | arrow_cast(json_get(json_empty_no_type_hints.attrs,Utf8("a")),Utf8("Int64")) |
+-------------------------+----------+-----------+-------------------+------------------------------------------------------------------------------+
| 1970-01-01T00:00:00.001 | checkout | INFO | request completed | |
| 1970-01-01T00:00:00.002 | checkout | INFO | request completed | 1 |
| 1970-01-01T00:00:00.003 | checkout | INFO | request completed | 2 |
+-------------------------+----------+-----------+-------------------+------------------------------------------------------------------------------+
ADMIN FLUSH_TABLE('json_empty_no_type_hints');
+-----------------------------------------------+
| ADMIN FLUSH_TABLE('json_empty_no_type_hints') |
+-----------------------------------------------+
| 0 |
+-----------------------------------------------+
ADMIN COMPACT_TABLE('json_empty_no_type_hints', 'swcs', '86400');
+------------------------------------------------------------------+
| ADMIN COMPACT_TABLE('json_empty_no_type_hints', 'swcs', '86400') |
+------------------------------------------------------------------+
| 0 |
+------------------------------------------------------------------+
SELECT
ts,
app_name,
log_level,
log_message,
json_get(attrs, 'a')::int64
FROM json_empty_no_type_hints
ORDER BY ts;
+-------------------------+----------+-----------+-------------------+------------------------------------------------------------------------------+
| ts | app_name | log_level | log_message | arrow_cast(json_get(json_empty_no_type_hints.attrs,Utf8("a")),Utf8("Int64")) |
+-------------------------+----------+-----------+-------------------+------------------------------------------------------------------------------+
| 1970-01-01T00:00:00.001 | checkout | INFO | request completed | |
| 1970-01-01T00:00:00.002 | checkout | INFO | request completed | 1 |
| 1970-01-01T00:00:00.003 | checkout | INFO | request completed | 2 |
+-------------------------+----------+-----------+-------------------+------------------------------------------------------------------------------+
CREATE TABLE json_empty_after_object (
ts TIMESTAMP TIME INDEX,
attrs JSON2
) WITH (
'append_mode' = 'true'
);
Affected Rows: 0
INSERT INTO json_empty_after_object
VALUES
(1, '{"a": 1}'),
(2, '{}');
Affected Rows: 2
SELECT ts, json_get(attrs, 'a')::int64
FROM json_empty_after_object
ORDER BY ts;
+-------------------------+-----------------------------------------------------------------------------+
| ts | arrow_cast(json_get(json_empty_after_object.attrs,Utf8("a")),Utf8("Int64")) |
+-------------------------+-----------------------------------------------------------------------------+
| 1970-01-01T00:00:00.001 | 1 |
| 1970-01-01T00:00:00.002 | |
+-------------------------+-----------------------------------------------------------------------------+
SELECT *
FROM json_empty_after_object
ORDER BY ts;
+-------------------------+---------+
| ts | attrs |
+-------------------------+---------+
| 1970-01-01T00:00:00.001 | {"a":1} |
| 1970-01-01T00:00:00.002 | |
+-------------------------+---------+
ADMIN FLUSH_TABLE('json_empty_after_object');
+----------------------------------------------+
| ADMIN FLUSH_TABLE('json_empty_after_object') |
+----------------------------------------------+
| 0 |
+----------------------------------------------+
SELECT ts, json_get(attrs, 'a')::int64
FROM json_empty_after_object
ORDER BY ts;
+-------------------------+-----------------------------------------------------------------------------+
| ts | arrow_cast(json_get(json_empty_after_object.attrs,Utf8("a")),Utf8("Int64")) |
+-------------------------+-----------------------------------------------------------------------------+
| 1970-01-01T00:00:00.001 | 1 |
| 1970-01-01T00:00:00.002 | |
+-------------------------+-----------------------------------------------------------------------------+
INSERT INTO json_empty_after_object
VALUES (3, '{}');
Affected Rows: 1
ADMIN FLUSH_TABLE('json_empty_after_object');
+----------------------------------------------+
| ADMIN FLUSH_TABLE('json_empty_after_object') |
+----------------------------------------------+
| 0 |
+----------------------------------------------+
ADMIN COMPACT_TABLE('json_empty_after_object', 'swcs', '86400');
+-----------------------------------------------------------------+
| ADMIN COMPACT_TABLE('json_empty_after_object', 'swcs', '86400') |
+-----------------------------------------------------------------+
| 0 |
+-----------------------------------------------------------------+
SELECT ts, json_get(attrs, 'a')::int64
FROM json_empty_after_object
ORDER BY ts;
+-------------------------+-----------------------------------------------------------------------------+
| ts | arrow_cast(json_get(json_empty_after_object.attrs,Utf8("a")),Utf8("Int64")) |
+-------------------------+-----------------------------------------------------------------------------+
| 1970-01-01T00:00:00.001 | 1 |
| 1970-01-01T00:00:00.002 | |
| 1970-01-01T00:00:00.003 | |
+-------------------------+-----------------------------------------------------------------------------+
SELECT *
FROM json_empty_after_object
ORDER BY ts;
+-------------------------+---------+
| ts | attrs |
+-------------------------+---------+
| 1970-01-01T00:00:00.001 | {"a":1} |
| 1970-01-01T00:00:00.002 | |
| 1970-01-01T00:00:00.003 | |
+-------------------------+---------+
CREATE TABLE json_empty_only_sst (
ts TIMESTAMP TIME INDEX,
attrs JSON2
) WITH (
'append_mode' = 'true'
);
Affected Rows: 0
INSERT INTO json_empty_only_sst
VALUES (1, '{}');
Affected Rows: 1
ADMIN FLUSH_TABLE('json_empty_only_sst');
+------------------------------------------+
| ADMIN FLUSH_TABLE('json_empty_only_sst') |
+------------------------------------------+
| 0 |
+------------------------------------------+
SELECT *
FROM json_empty_only_sst
ORDER BY ts;
+-------------------------+-------+
| ts | attrs |
+-------------------------+-------+
| 1970-01-01T00:00:00.001 | |
+-------------------------+-------+
ADMIN COMPACT_TABLE('json_empty_only_sst', 'swcs', '86400');
+-------------------------------------------------------------+
| ADMIN COMPACT_TABLE('json_empty_only_sst', 'swcs', '86400') |
+-------------------------------------------------------------+
| 0 |
+-------------------------------------------------------------+
SELECT *
FROM json_empty_only_sst
ORDER BY ts;
+-------------------------+-------+
| ts | attrs |
+-------------------------+-------+
| 1970-01-01T00:00:00.001 | |
+-------------------------+-------+
CREATE TABLE json_empty_conflict (
ts TIMESTAMP TIME INDEX,
attrs JSON2
) WITH (
'append_mode' = 'true'
);
Affected Rows: 0
INSERT INTO json_empty_conflict
VALUES
(1, '{}'),
(2, '{"a": 1}');
Affected Rows: 2
ADMIN FLUSH_TABLE('json_empty_conflict');
+------------------------------------------+
| ADMIN FLUSH_TABLE('json_empty_conflict') |
+------------------------------------------+
| 0 |
+------------------------------------------+
INSERT INTO json_empty_conflict
VALUES (3, '{"a": "x"}');
Affected Rows: 1
SELECT ts, json_get(attrs, 'a')
FROM json_empty_conflict
ORDER BY ts;
+-------------------------+-----------------------------------------------+
| ts | json_get(json_empty_conflict.attrs,Utf8("a")) |
+-------------------------+-----------------------------------------------+
| 1970-01-01T00:00:00.001 | |
| 1970-01-01T00:00:00.002 | 1 |
| 1970-01-01T00:00:00.003 | x |
+-------------------------+-----------------------------------------------+
SELECT *
FROM json_empty_conflict
ORDER BY ts;
+-------------------------+-----------+
| ts | attrs |
+-------------------------+-----------+
| 1970-01-01T00:00:00.001 | |
| 1970-01-01T00:00:00.002 | {"a":1} |
| 1970-01-01T00:00:00.003 | {"a":"x"} |
+-------------------------+-----------+
ADMIN FLUSH_TABLE('json_empty_conflict');
+------------------------------------------+
| ADMIN FLUSH_TABLE('json_empty_conflict') |
+------------------------------------------+
| 0 |
+------------------------------------------+
ADMIN COMPACT_TABLE('json_empty_conflict', 'swcs', '86400');
+-------------------------------------------------------------+
| ADMIN COMPACT_TABLE('json_empty_conflict', 'swcs', '86400') |
+-------------------------------------------------------------+
| 0 |
+-------------------------------------------------------------+
SELECT ts, json_get(attrs, 'a')
FROM json_empty_conflict
ORDER BY ts;
+-------------------------+-----------------------------------------------+
| ts | json_get(json_empty_conflict.attrs,Utf8("a")) |
+-------------------------+-----------------------------------------------+
| 1970-01-01T00:00:00.001 | |
| 1970-01-01T00:00:00.002 | 1 |
| 1970-01-01T00:00:00.003 | x |
+-------------------------+-----------------------------------------------+
SELECT *
FROM json_empty_conflict
ORDER BY ts;
+-------------------------+-----------+
| ts | attrs |
+-------------------------+-----------+
| 1970-01-01T00:00:00.001 | |
| 1970-01-01T00:00:00.002 | {"a":1} |
| 1970-01-01T00:00:00.003 | {"a":"x"} |
+-------------------------+-----------+
CREATE TABLE json_empty_type_hints_nullable (
ts TIMESTAMP TIME INDEX,
j JSON2 (
user.age BIGINT NULL
)
) WITH (
'append_mode' = 'true'
);
Affected Rows: 0
INSERT INTO json_empty_type_hints_nullable
VALUES (1, '{}');
Affected Rows: 1
ADMIN FLUSH_TABLE('json_empty_type_hints_nullable');
+-----------------------------------------------------+
| ADMIN FLUSH_TABLE('json_empty_type_hints_nullable') |
+-----------------------------------------------------+
| 0 |
+-----------------------------------------------------+
INSERT INTO json_empty_type_hints_nullable
VALUES (2, '{}');
Affected Rows: 1
SELECT j.user.age
FROM json_empty_type_hints_nullable
ORDER BY ts;
+-------------------------------------------------------------+
| json_get(json_empty_type_hints_nullable.j,Utf8("user.age")) |
+-------------------------------------------------------------+
| |
| |
+-------------------------------------------------------------+
CREATE TABLE json_empty_type_hints_default (
ts TIMESTAMP TIME INDEX,
j JSON2 (
user.age BIGINT NULL DEFAULT 18
)
) WITH (
'append_mode' = 'true'
);
Affected Rows: 0
INSERT INTO json_empty_type_hints_default
VALUES (1, '{}');
Affected Rows: 1
ADMIN FLUSH_TABLE('json_empty_type_hints_default');
+----------------------------------------------------+
| ADMIN FLUSH_TABLE('json_empty_type_hints_default') |
+----------------------------------------------------+
| 0 |
+----------------------------------------------------+
INSERT INTO json_empty_type_hints_default
VALUES (2, '{}');
Affected Rows: 1
SELECT j.user.age
FROM json_empty_type_hints_default
ORDER BY ts;
+------------------------------------------------------------+
| json_get(json_empty_type_hints_default.j,Utf8("user.age")) |
+------------------------------------------------------------+
| 18 |
| 18 |
+------------------------------------------------------------+
CREATE TABLE json_empty_type_hints_required (
ts TIMESTAMP TIME INDEX,
j JSON2 (
user.age BIGINT NOT NULL
)
) WITH (
'append_mode' = 'true'
);
Affected Rows: 0
INSERT INTO json_empty_type_hints_required
VALUES (1, '{}');
Error: 1004(InvalidArguments), Invalid JSON: missing non-null JSON2 type hint path user.age
DROP TABLE json_empty_no_type_hints;
Affected Rows: 0
DROP TABLE json_empty_after_object;
Affected Rows: 0
DROP TABLE json_empty_only_sst;
Affected Rows: 0
DROP TABLE json_empty_conflict;
Affected Rows: 0
DROP TABLE json_empty_type_hints_nullable;
Affected Rows: 0
DROP TABLE json_empty_type_hints_default;
Affected Rows: 0
DROP TABLE json_empty_type_hints_required;
Affected Rows: 0
@@ -0,0 +1,239 @@
CREATE TABLE json_empty_no_type_hints (
ts TIMESTAMP TIME INDEX,
app_name STRING,
log_level STRING,
log_message STRING,
attrs JSON2
) WITH (
'append_mode' = 'true'
);
INSERT INTO json_empty_no_type_hints
VALUES
(1, 'checkout', 'INFO', 'request completed', '{}');
SELECT *
FROM json_empty_no_type_hints
ORDER BY ts;
INSERT INTO json_empty_no_type_hints
VALUES
(2, 'checkout', 'INFO', 'request completed', '{"a": 1}');
SELECT
ts,
app_name,
log_level,
log_message,
json_get(attrs, 'a')::int64
FROM json_empty_no_type_hints
ORDER BY ts;
SELECT *
FROM json_empty_no_type_hints
ORDER BY ts;
ADMIN FLUSH_TABLE('json_empty_no_type_hints');
SELECT
ts,
app_name,
log_level,
log_message,
json_get(attrs, 'a')::int64
FROM json_empty_no_type_hints
ORDER BY ts;
INSERT INTO json_empty_no_type_hints
VALUES
(3, 'checkout', 'INFO', 'request completed', '{"a": 2}');
SELECT
ts,
app_name,
log_level,
log_message,
json_get(attrs, 'a')::int64
FROM json_empty_no_type_hints
ORDER BY ts;
ADMIN FLUSH_TABLE('json_empty_no_type_hints');
ADMIN COMPACT_TABLE('json_empty_no_type_hints', 'swcs', '86400');
SELECT
ts,
app_name,
log_level,
log_message,
json_get(attrs, 'a')::int64
FROM json_empty_no_type_hints
ORDER BY ts;
CREATE TABLE json_empty_after_object (
ts TIMESTAMP TIME INDEX,
attrs JSON2
) WITH (
'append_mode' = 'true'
);
INSERT INTO json_empty_after_object
VALUES
(1, '{"a": 1}'),
(2, '{}');
SELECT ts, json_get(attrs, 'a')::int64
FROM json_empty_after_object
ORDER BY ts;
SELECT *
FROM json_empty_after_object
ORDER BY ts;
ADMIN FLUSH_TABLE('json_empty_after_object');
SELECT ts, json_get(attrs, 'a')::int64
FROM json_empty_after_object
ORDER BY ts;
INSERT INTO json_empty_after_object
VALUES (3, '{}');
ADMIN FLUSH_TABLE('json_empty_after_object');
ADMIN COMPACT_TABLE('json_empty_after_object', 'swcs', '86400');
SELECT ts, json_get(attrs, 'a')::int64
FROM json_empty_after_object
ORDER BY ts;
SELECT *
FROM json_empty_after_object
ORDER BY ts;
CREATE TABLE json_empty_only_sst (
ts TIMESTAMP TIME INDEX,
attrs JSON2
) WITH (
'append_mode' = 'true'
);
INSERT INTO json_empty_only_sst
VALUES (1, '{}');
ADMIN FLUSH_TABLE('json_empty_only_sst');
SELECT *
FROM json_empty_only_sst
ORDER BY ts;
ADMIN COMPACT_TABLE('json_empty_only_sst', 'swcs', '86400');
SELECT *
FROM json_empty_only_sst
ORDER BY ts;
CREATE TABLE json_empty_conflict (
ts TIMESTAMP TIME INDEX,
attrs JSON2
) WITH (
'append_mode' = 'true'
);
INSERT INTO json_empty_conflict
VALUES
(1, '{}'),
(2, '{"a": 1}');
ADMIN FLUSH_TABLE('json_empty_conflict');
INSERT INTO json_empty_conflict
VALUES (3, '{"a": "x"}');
SELECT ts, json_get(attrs, 'a')
FROM json_empty_conflict
ORDER BY ts;
SELECT *
FROM json_empty_conflict
ORDER BY ts;
ADMIN FLUSH_TABLE('json_empty_conflict');
ADMIN COMPACT_TABLE('json_empty_conflict', 'swcs', '86400');
SELECT ts, json_get(attrs, 'a')
FROM json_empty_conflict
ORDER BY ts;
SELECT *
FROM json_empty_conflict
ORDER BY ts;
CREATE TABLE json_empty_type_hints_nullable (
ts TIMESTAMP TIME INDEX,
j JSON2 (
user.age BIGINT NULL
)
) WITH (
'append_mode' = 'true'
);
INSERT INTO json_empty_type_hints_nullable
VALUES (1, '{}');
ADMIN FLUSH_TABLE('json_empty_type_hints_nullable');
INSERT INTO json_empty_type_hints_nullable
VALUES (2, '{}');
SELECT j.user.age
FROM json_empty_type_hints_nullable
ORDER BY ts;
CREATE TABLE json_empty_type_hints_default (
ts TIMESTAMP TIME INDEX,
j JSON2 (
user.age BIGINT NULL DEFAULT 18
)
) WITH (
'append_mode' = 'true'
);
INSERT INTO json_empty_type_hints_default
VALUES (1, '{}');
ADMIN FLUSH_TABLE('json_empty_type_hints_default');
INSERT INTO json_empty_type_hints_default
VALUES (2, '{}');
SELECT j.user.age
FROM json_empty_type_hints_default
ORDER BY ts;
CREATE TABLE json_empty_type_hints_required (
ts TIMESTAMP TIME INDEX,
j JSON2 (
user.age BIGINT NOT NULL
)
) WITH (
'append_mode' = 'true'
);
INSERT INTO json_empty_type_hints_required
VALUES (1, '{}');
DROP TABLE json_empty_no_type_hints;
DROP TABLE json_empty_after_object;
DROP TABLE json_empty_only_sst;
DROP TABLE json_empty_conflict;
DROP TABLE json_empty_type_hints_nullable;
DROP TABLE json_empty_type_hints_default;
DROP TABLE json_empty_type_hints_required;