diff --git a/src/datatypes/src/json.rs b/src/datatypes/src/json.rs index e156e387330..a5b4940e048 100644 --- a/src/datatypes/src/json.rs +++ b/src/datatypes/src/json.rs @@ -31,7 +31,6 @@ use snafu::ResultExt; use crate::data_type::ConcreteDataType; use crate::error::{self, InvalidJson2SettingsSnafu, Result, UnsupportedJsonTypeSnafu}; use crate::json::value::{JsonValue, JsonVariant, encode_serde_json_as_jsonb}; -use crate::schema::ColumnDefaultConstraint; use crate::types::json_type::{JsonNativeType, JsonObjectType}; use crate::value::{ListValue, StructValue, Value}; @@ -91,9 +90,6 @@ pub struct JsonTypeHint { pub path: Vec, #[serde(rename = "type")] pub data_type: ConcreteDataType, - pub nullable: bool, - #[serde(skip_serializing_if = "Option::is_none")] - pub default_constraint: Option, pub inverted_index: bool, } @@ -217,20 +213,6 @@ fn validate_type_hints(type_hints: &[JsonTypeHint]) -> Result<()> { .fail(); } }; - let non_finite_default = match &hint.default_constraint { - Some(ColumnDefaultConstraint::Value(Value::Float32(value))) => !value.0.is_finite(), - Some(ColumnDefaultConstraint::Value(Value::Float64(value))) => !value.0.is_finite(), - _ => false, - }; - if non_finite_default { - return InvalidJson2SettingsSnafu { - reason: format!( - "JSON2 type hint default for '{}' must be finite", - hint.path.join(".") - ), - } - .fail(); - } validate_type_hint(&mut object, &hint.path, data_type)?; } Ok(()) @@ -319,12 +301,12 @@ fn encode_json_object_with_context<'a>( object.insert(key, value.into_variant()); } - apply_missing_type_hints(&mut object, context)?; + fill_missing_type_hints(&mut object, context)?; Ok(JsonValue::new(JsonVariant::Object(object))) } -fn apply_missing_type_hints( +fn fill_missing_type_hints( object: &mut BTreeMap, context: &mut JsonContext, ) -> Result<()> { @@ -351,8 +333,7 @@ fn insert_missing_type_hint( if is_leaf { if !object.contains_key(key) { - let value = encode_missing_type_hint_value(hint, field_context)?; - object.insert(key.clone(), value.into_variant()); + object.insert(key.clone(), JsonValue::null().into_variant()); } return Ok(()); } @@ -380,46 +361,13 @@ fn insert_missing_type_hint( } } -fn encode_missing_type_hint_value( - hint: &JsonTypeHint, - context: &mut JsonContext, -) -> Result { - if let Some(default_constraint) = &hint.default_constraint { - let value = default_constraint.create_default(&hint.data_type, hint.nullable)?; - let json = decode_primitive_value(value)?; - return encode_json_value_with_hint(json, hint, context); - } - - if hint.nullable { - Ok(JsonValue::null()) - } else { - error::InvalidJsonSnafu { - value: format!( - "missing non-null JSON2 type hint path {}", - hint.path.join(".") - ), - } - .fail() - } -} - fn encode_json_value_with_hint( json: Json, hint: &JsonTypeHint, context: &mut JsonContext, ) -> Result { if json.is_null() { - return if hint.nullable { - Ok(JsonValue::null()) - } else { - error::InvalidJsonSnafu { - value: format!( - "JSON2 type hint path {} is not nullable", - context.path.join(".") - ), - } - .fail() - }; + return Ok(JsonValue::null()); } let invalid_type = || { @@ -650,7 +598,7 @@ mod tests { } #[test] - fn test_json_settings_forward_compatibility() + fn test_json_settings_deserializes_legacy_type_hint_constraints() -> std::result::Result<(), Box> { let json_str = r#"{ "type_hints": [ @@ -687,15 +635,11 @@ mod tests { JsonTypeHint { path: vec!["user".to_string(), "age".to_string()], data_type: ConcreteDataType::int64_datatype(), - nullable: false, - default_constraint: Some(ColumnDefaultConstraint::Value(Value::Int64(18))), inverted_index: true, }, JsonTypeHint { path: vec!["user".to_string(), "name".to_string()], data_type: ConcreteDataType::string_datatype(), - nullable: true, - default_constraint: None, inverted_index: false, }, ], @@ -711,15 +655,11 @@ mod tests { JsonTypeHint { path: vec!["user".to_string(), "age".to_string()], data_type: ConcreteDataType::int64_datatype(), - nullable: false, - default_constraint: Some(ColumnDefaultConstraint::Value(Value::Int64(18))), inverted_index: true, }, JsonTypeHint { path: vec!["user".to_string(), "name".to_string()], data_type: ConcreteDataType::string_datatype(), - nullable: true, - default_constraint: None, inverted_index: false, }, ]; @@ -758,8 +698,6 @@ mod tests { let hint = |path, data_type| JsonTypeHint { path, data_type, - nullable: true, - default_constraint: None, inverted_index: false, }; assert!( @@ -955,8 +893,6 @@ mod tests { let type_hints = vec![JsonTypeHint { path: vec!["age".to_string()], data_type: ConcreteDataType::int64_datatype(), - nullable: false, - default_constraint: None, inverted_index: false, }]; let settings = JsonSettings::try_new(type_hints, None)?; @@ -989,8 +925,6 @@ mod tests { let type_hints = vec![JsonTypeHint { path: vec!["count".to_string()], data_type: ConcreteDataType::uint64_datatype(), - nullable: false, - default_constraint: None, inverted_index: false, }]; let settings = JsonSettings::try_new(type_hints, None)?; @@ -1021,12 +955,10 @@ mod tests { } #[test] - fn test_encode_json_fills_missing_type_hint_with_default() -> Result<()> { + fn test_encode_json_fills_missing_type_hint_with_null() -> Result<()> { let type_hints = vec![JsonTypeHint { path: vec!["user".to_string(), "age".to_string()], data_type: ConcreteDataType::int64_datatype(), - nullable: false, - default_constraint: Some(ColumnDefaultConstraint::Value(Value::Int64(7))), inverted_index: false, }]; let settings = JsonSettings::try_new(type_hints, None)?; @@ -1043,7 +975,7 @@ mod tests { let Value::Struct(user) = struct_field_value(&root, "user") else { panic!("Expected user Struct value"); }; - assert_eq!(struct_field_value(user, "age"), &Value::Int64(7)); + assert_eq!(struct_field_value(user, "age"), &Value::Null); Ok(()) } @@ -1052,8 +984,6 @@ mod tests { let type_hints = vec![JsonTypeHint { path: vec!["user".to_string(), "name".to_string()], data_type: ConcreteDataType::string_datatype(), - nullable: true, - default_constraint: None, inverted_index: false, }]; let settings = JsonSettings::try_new(type_hints, None)?; @@ -1075,21 +1005,15 @@ mod tests { } #[test] - fn test_encode_json_rejects_missing_non_null_type_hint() -> Result<()> { + fn test_encode_json_allows_missing_type_hint() -> Result<()> { let type_hints = vec![JsonTypeHint { path: vec!["user".to_string(), "age".to_string()], data_type: ConcreteDataType::int64_datatype(), - nullable: false, - default_constraint: None, inverted_index: false, }]; let settings = JsonSettings::try_new(type_hints, None)?; - let err = settings.encode(json!({})).unwrap_err(); - assert!( - err.to_string() - .contains("missing non-null JSON2 type hint path user.age") - ); + settings.encode(json!({}))?; Ok(()) } @@ -1099,17 +1023,11 @@ mod tests { JsonTypeHint { path: vec!["user".to_string(), "age".to_string()], data_type: ConcreteDataType::int64_datatype(), - nullable: false, - default_constraint: Some(ColumnDefaultConstraint::Value(Value::Int64(7))), inverted_index: false, }, JsonTypeHint { path: vec!["user".to_string(), "name".to_string()], data_type: ConcreteDataType::string_datatype(), - nullable: false, - default_constraint: Some(ColumnDefaultConstraint::Value(Value::String( - "unknown".into(), - ))), inverted_index: false, }, ]; @@ -1123,11 +1041,8 @@ mod tests { let Value::Struct(user) = struct_field_value(&root, "user") else { panic!("Expected user Struct value"); }; - assert_eq!(struct_field_value(user, "age"), &Value::Int64(7)); - assert_eq!( - struct_field_value(user, "name"), - &Value::String("unknown".into()) - ); + assert_eq!(struct_field_value(user, "age"), &Value::Null); + assert_eq!(struct_field_value(user, "name"), &Value::Null); Ok(()) } diff --git a/src/datatypes/src/vectors/json/array.rs b/src/datatypes/src/vectors/json/array.rs index e8b75dee259..08a2fd86555 100644 --- a/src/datatypes/src/vectors/json/array.rs +++ b/src/datatypes/src/vectors/json/array.rs @@ -701,8 +701,6 @@ mod test { vec![JsonTypeHint { path: vec!["kind".to_string()], data_type: ConcreteDataType::string_datatype(), - nullable: true, - default_constraint: None, inverted_index: false, }], Some(0), diff --git a/src/datatypes/src/vectors/json/builder.rs b/src/datatypes/src/vectors/json/builder.rs index 3a9c1587966..2b9c44a326a 100644 --- a/src/datatypes/src/vectors/json/builder.rs +++ b/src/datatypes/src/vectors/json/builder.rs @@ -1060,22 +1060,16 @@ mod tests { JsonTypeHint { path: vec!["kind".to_string()], data_type: ConcreteDataType::string_datatype(), - nullable: true, - default_constraint: None, inverted_index: false, }, JsonTypeHint { path: vec!["commit".to_string(), "operation".to_string()], data_type: ConcreteDataType::string_datatype(), - nullable: true, - default_constraint: None, inverted_index: false, }, JsonTypeHint { path: vec!["time_us".to_string()], data_type: ConcreteDataType::int64_datatype(), - nullable: true, - default_constraint: None, inverted_index: false, }, ], @@ -1171,8 +1165,6 @@ mod tests { vec![JsonTypeHint { path: vec!["hint".to_string()], data_type: ConcreteDataType::string_datatype(), - nullable: true, - default_constraint: None, inverted_index: false, }], Some(2), @@ -1338,8 +1330,6 @@ mod tests { vec![JsonTypeHint { path: vec!["nested".to_string(), "hinted".to_string()], data_type: ConcreteDataType::string_datatype(), - nullable: true, - default_constraint: None, inverted_index: false, }], Some(8), diff --git a/src/mito2/src/compaction/json2.rs b/src/mito2/src/compaction/json2.rs index 8eec0e11520..f381f80722e 100644 --- a/src/mito2/src/compaction/json2.rs +++ b/src/mito2/src/compaction/json2.rs @@ -280,8 +280,6 @@ fn select_dynamic_hints( .map(|(path, stat)| JsonTypeHint { path: path.iter().map(|x| (*x).to_owned()).collect(), data_type: ConcreteDataType::from_arrow_type(&stat.data_type.as_arrow_type()), - nullable: true, - default_constraint: None, inverted_index: false, }) .collect() @@ -372,8 +370,6 @@ mod tests { vec![JsonTypeHint { path: vec!["hint".to_string()], data_type: ConcreteDataType::string_datatype(), - nullable: true, - default_constraint: None, inverted_index: false, }], Some(2), @@ -430,8 +426,6 @@ mod tests { vec![JsonTypeHint { path: vec!["kind".to_string()], data_type: ConcreteDataType::string_datatype(), - nullable: true, - default_constraint: None, inverted_index: false, }], Some(0), @@ -486,8 +480,6 @@ mod tests { vec![JsonTypeHint { path: vec!["kind".to_string()], data_type: ConcreteDataType::string_datatype(), - nullable: true, - default_constraint: None, inverted_index: false, }], Some(0), @@ -508,15 +500,11 @@ mod tests { JsonTypeHint { path: vec!["kind".to_string()], data_type: ConcreteDataType::string_datatype(), - nullable: true, - default_constraint: None, inverted_index: false, }, JsonTypeHint { path: vec!["source_only".to_string()], data_type: ConcreteDataType::int64_datatype(), - nullable: true, - default_constraint: None, inverted_index: false, }, ], @@ -583,8 +571,6 @@ mod tests { vec![JsonTypeHint { path: vec!["kind".to_string()], data_type: ConcreteDataType::string_datatype(), - nullable: true, - default_constraint: None, inverted_index: false, }], Some(0), @@ -594,15 +580,11 @@ mod tests { JsonTypeHint { path: vec!["kind".to_string()], data_type: ConcreteDataType::string_datatype(), - nullable: true, - default_constraint: None, inverted_index: false, }, JsonTypeHint { path: vec!["promoted".to_string()], data_type: ConcreteDataType::int64_datatype(), - nullable: true, - default_constraint: None, inverted_index: false, }, ], diff --git a/src/mito2/src/memtable/bulk.rs b/src/mito2/src/memtable/bulk.rs index 155791f8ab6..ea2a1225f13 100644 --- a/src/mito2/src/memtable/bulk.rs +++ b/src/mito2/src/memtable/bulk.rs @@ -2032,8 +2032,6 @@ mod tests { vec![JsonTypeHint { path: vec!["id".to_string()], data_type: ConcreteDataType::int64_datatype(), - nullable: true, - default_constraint: None, inverted_index: false, }], Some(0), diff --git a/src/pipeline/src/etl/transform.rs b/src/pipeline/src/etl/transform.rs index c9a1510735c..0869a4be0fc 100644 --- a/src/pipeline/src/etl/transform.rs +++ b/src/pipeline/src/etl/transform.rs @@ -22,8 +22,7 @@ use api::v1::ColumnDataType; use api::v1::value::ValueData; use chrono::Utc; use datatypes::json::{JsonSettings, JsonTypeHint}; -use datatypes::schema::{ColumnDefaultConstraint, FulltextOptions, SkippingIndexOptions}; -use datatypes::value::Value; +use datatypes::schema::{FulltextOptions, SkippingIndexOptions}; use snafu::{OptionExt, ResultExt, ensure}; use sql::parsers::utils::{ validate_column_fulltext_create_option, validate_column_skipping_index_create_option, @@ -56,7 +55,6 @@ const TRANSFORM_ON_FAILURE: &str = "on_failure"; const JSON2_TYPE: &str = "json2"; const JSON2_TYPE_HINT: &str = "type.json2[]"; const JSON2_TYPE_HINT_PATH: &str = "path"; -const JSON2_TYPE_HINT_NULLABLE: &str = "nullable"; pub use transformer::greptime::GreptimeTransformer; @@ -480,8 +478,6 @@ fn parse_json2_type_hint(value: &yaml_rust::Yaml) -> Result { })?; let mut path = None; let mut type_name = None; - let mut nullable = true; - let mut default = None; let mut index = None; for (key, value) in config { @@ -491,10 +487,6 @@ fn parse_json2_type_hint(value: &yaml_rust::Yaml) -> Result { match key { JSON2_TYPE_HINT_PATH => path = Some(yaml_string(value, JSON2_TYPE_HINT_PATH)?), TRANSFORM_TYPE => type_name = Some(yaml_string(value, TRANSFORM_TYPE)?), - JSON2_TYPE_HINT_NULLABLE => { - nullable = yaml_bool(value, JSON2_TYPE_HINT_NULLABLE)?; - } - TRANSFORM_DEFAULT => default = Some(value), TRANSFORM_INDEX => index = Some(value), _ => { return InvalidJson2TypeHintSnafu { @@ -528,13 +520,6 @@ fn parse_json2_type_hint(value: &yaml_rust::Yaml) -> Result { } ); let data_type = ColumnDataTypeWrapper::new(type_, None).into(); - let default_constraint = default - .map(|value| parse_json2_type_hint_default(value, &type_)) - .transpose()?; - if let Some(default_constraint) = &default_constraint { - default_constraint.validate(&data_type, nullable)?; - } - let inverted_index = if let Some(value) = index { let (index, options) = parse_transform_index(value)?; ensure!( @@ -552,40 +537,10 @@ fn parse_json2_type_hint(value: &yaml_rust::Yaml) -> Result { Ok(JsonTypeHint { path, data_type, - nullable, - default_constraint, inverted_index, }) } -fn parse_json2_type_hint_default( - value: &yaml_rust::Yaml, - type_: &ColumnDataType, -) -> Result { - if value.is_null() { - return Ok(ColumnDefaultConstraint::Value(Value::Null)); - } - - let value = match value { - yaml_rust::Yaml::Real(value) | yaml_rust::Yaml::String(value) => value.clone(), - yaml_rust::Yaml::Integer(value) => value.to_string(), - yaml_rust::Yaml::Boolean(value) => value.to_string(), - _ => { - return FieldMustBeTypeSnafu { - field: TRANSFORM_DEFAULT, - ty: "scalar", - } - .fail(); - } - }; - let value = api::v1::Value { - value_data: Some(parse_str_value(type_, &value)?), - }; - Ok(ColumnDefaultConstraint::Value( - api::helper::pb_value_to_value_ref(&value, None).into(), - )) -} - impl TryFrom<&yaml_rust::yaml::Hash> for Transform { type Error = Error; @@ -708,8 +663,6 @@ type: json2: - path: "user.id" type: int64 - nullable: false - default: 7 index: type: inverted - path: 'attrs."http.status_code"' @@ -726,19 +679,13 @@ type: hints[0].data_type, datatypes::prelude::ConcreteDataType::int64_datatype() ); - assert!(!hints[0].nullable); - assert_eq!( - hints[0].default_constraint, - Some(ColumnDefaultConstraint::Value(Value::Int64(7))) - ); assert!(hints[0].inverted_index); assert_eq!(hints[1].path, ["attrs", "http.status_code"]); - assert!(hints[1].nullable); } #[test] - fn test_transform_rejects_non_finite_json2_default() { - for default in ["NaN", "1e9999"] { + fn test_transform_rejects_json2_nullable_and_default() { + for option in ["nullable: false", "default: 7"] { let err = parse_transform(&format!( r#" field: payload @@ -746,22 +693,12 @@ type: json2: - path: score type: float64 - default: {default} + {option} "#, )) .unwrap_err(); - assert!( - matches!( - &err, - Error::Datatypes { - source: datatypes::error::Error::InvalidJson2Settings { .. }, - .. - } - ), - "{err:?}" - ); - assert!(err.to_string().contains("must be finite"), "{err}"); + assert!(err.to_string().contains("unsupported field"), "{err}"); } } diff --git a/src/pipeline/src/etl/transform/transformer/greptime.rs b/src/pipeline/src/etl/transform/transformer/greptime.rs index c85510e3e40..bbe3949a540 100644 --- a/src/pipeline/src/etl/transform/transformer/greptime.rs +++ b/src/pipeline/src/etl/transform/transformer/greptime.rs @@ -1101,8 +1101,6 @@ mod tests { vec![JsonTypeHint { path: vec!["age".to_string()], data_type: ConcreteDataType::int64_datatype(), - nullable: false, - default_constraint: None, inverted_index: false, }], None, @@ -1118,8 +1116,6 @@ mod tests { vec![JsonTypeHint { path: vec!["age".to_string()], data_type: ConcreteDataType::string_datatype(), - nullable: false, - default_constraint: None, inverted_index: false, }], None, diff --git a/src/pipeline/src/etl/transform/transformer/greptime/coerce.rs b/src/pipeline/src/etl/transform/transformer/greptime/coerce.rs index 9f01af708b2..a63b5ca076e 100644 --- a/src/pipeline/src/etl/transform/transformer/greptime/coerce.rs +++ b/src/pipeline/src/etl/transform/transformer/greptime/coerce.rs @@ -773,8 +773,6 @@ mod tests { vec![JsonTypeHint { path: vec!["age".to_string()], data_type: ConcreteDataType::int64_datatype(), - nullable: false, - default_constraint: None, inverted_index: false, }], None, diff --git a/src/pipeline/tests/json_parse.rs b/src/pipeline/tests/json_parse.rs index b0c32950518..11c42f0fe4c 100644 --- a/src/pipeline/tests/json_parse.rs +++ b/src/pipeline/tests/json_parse.rs @@ -134,7 +134,6 @@ transform: json2: - path: "commitAuthor" type: string - nullable: false "#; let output = common::parse_and_exec(INPUT_VALUE_OBJ, pipeline_yaml); diff --git a/src/sql/src/parsers/alter_parser.rs b/src/sql/src/parsers/alter_parser.rs index d5a89f54076..ca38ec0d65e 100644 --- a/src/sql/src/parsers/alter_parser.rs +++ b/src/sql/src/parsers/alter_parser.rs @@ -1565,8 +1565,8 @@ ALTER TABLE metrics REPARTITION MODIFY COLUMN attrs JSON2 ( max_auto_expanded_paths = 2000, trace_id STRING, - user.id STRING NOT NULL, - user.name STRING DEFAULT 'anonymous', + user.id STRING, + user.name STRING, request_id STRING INVERTED INDEX )"#; let mut statements = @@ -1590,8 +1590,6 @@ MODIFY COLUMN attrs JSON2 ( assert_eq!(Some(2000), options.max_auto_expanded_paths); assert_eq!(4, options.type_hints.len()); assert_eq!(vec!["user", "id"], options.type_hints[1].path); - assert!(!options.type_hints[1].nullable); - assert!(options.type_hints[2].default.is_some()); assert!(options.type_hints[3].inverted_index); let formatted = alter_table.to_string(); diff --git a/src/sql/src/parsers/create_parser/json.rs b/src/sql/src/parsers/create_parser/json.rs index fadc37c6d2f..2bf3c9407a6 100644 --- a/src/sql/src/parsers/create_parser/json.rs +++ b/src/sql/src/parsers/create_parser/json.rs @@ -15,7 +15,7 @@ use datatypes::extension::json::JSON2_REMAINDER_FIELD_NAME; use datatypes::json::JSON2_MAX_STRUCTURED_DEPTH; use snafu::{ResultExt, ensure}; -use sqlparser::ast::{DataType, ExactNumberInfo, Expr, ObjectName, UnaryOperator}; +use sqlparser::ast::{DataType, ExactNumberInfo, ObjectName}; use sqlparser::dialect::keywords::Keyword; use sqlparser::parser::Parser; use sqlparser::tokenizer::Token; @@ -157,49 +157,22 @@ fn parse_json2_type_hint(parser: &mut Parser<'_>) -> Result { let data_type = parser.parse_data_type().context(SyntaxSnafu)?; let data_type = normalize_json2_type_hint_type(data_type)?; - let mut nullable = true; - let mut nullable_set = false; - let mut default = None; let mut inverted_index = false; loop { - if parser.parse_keywords(&[Keyword::NOT, Keyword::NULL]) { - ensure!( - !nullable_set, - InvalidSqlSnafu { - msg: format!( - "NULL/NOT NULL option already specified for JSON2 type hint '{}'", - path.join(".") - ) - } - ); - nullable = false; - nullable_set = true; - } else if parser.parse_keyword(Keyword::NULL) { - ensure!( - !nullable_set, - InvalidSqlSnafu { - msg: format!( - "NULL/NOT NULL option already specified for JSON2 type hint '{}'", - path.join(".") - ) - } - ); - nullable = true; - nullable_set = true; + if parser.parse_keywords(&[Keyword::NOT, Keyword::NULL]) + || parser.parse_keyword(Keyword::NULL) + { + return InvalidSqlSnafu { + msg: "JSON2 type hint NULL/NOT NULL is not supported; hinted fields are always nullable" + .to_string(), + } + .fail(); } else if parser.parse_keyword(Keyword::DEFAULT) { - ensure!( - default.is_none(), - InvalidSqlSnafu { - msg: format!( - "duplicated DEFAULT option for JSON2 type hint '{}'", - path.join(".") - ) - } - ); - let expr = parser.parse_expr().context(SyntaxSnafu)?; - ensure_json2_default_expr_is_literal(&expr)?; - default = Some(expr); + return InvalidSqlSnafu { + msg: "JSON2 type hint DEFAULT is not supported".to_string(), + } + .fail(); } else if let Token::Word(word) = parser.peek_token().token && word.value.eq_ignore_ascii_case(INVERTED) { @@ -242,8 +215,6 @@ fn parse_json2_type_hint(parser: &mut Parser<'_>) -> Result { Ok(JsonTypeHint { path, data_type, - nullable, - default, inverted_index, }) } @@ -298,24 +269,6 @@ fn normalize_json2_type_hint_type(data_type: DataType) -> Result { Ok(normalized) } -fn ensure_json2_default_expr_is_literal(expr: &Expr) -> Result<()> { - let is_literal = match expr { - Expr::Value(_) => true, - Expr::UnaryOp { op, expr } => { - matches!(op, UnaryOperator::Plus | UnaryOperator::Minus) - && matches!(expr.as_ref(), Expr::Value(_)) - } - _ => false, - }; - ensure!( - is_literal, - InvalidSqlSnafu { - msg: "JSON2 type hint DEFAULT only supports literal values", - } - ); - Ok(()) -} - fn ensure_no_path_conflict(hints: &[JsonTypeHint], path: &[String]) -> Result<()> { for hint in hints { ensure!( @@ -375,10 +328,10 @@ mod tests { r#" CREATE TABLE traces ( log_json_data JSON2 ( - "service.name" STRING NOT NULL DEFAULT 'null' INVERTED INDEX, - http.method STRING NOT NULL, - status_code INT64 NOT NULL, - comment STRING NULL, + "service.name" STRING INVERTED INDEX, + http.method STRING, + status_code INT64, + comment STRING, ), ts TIMESTAMP TIME INDEX, )"#, @@ -393,29 +346,17 @@ CREATE TABLE traces ( assert_eq!(hints[0].path, vec!["service.name"]); assert_eq!(hints[0].data_type, DataType::String(None)); - assert!(!hints[0].nullable); - assert_eq!( - hints[0] - .default - .as_ref() - .map(|expr| expr.to_string()) - .as_deref(), - Some("'null'") - ); assert!(hints[0].inverted_index); assert_eq!(hints[1].path, vec!["http", "method"]); assert_eq!(hints[1].data_type, DataType::String(None)); - assert!(!hints[1].nullable); assert!(!hints[1].inverted_index); assert_eq!(hints[2].path, vec!["status_code"]); assert_eq!(hints[2].data_type, DataType::BigInt(None)); - assert!(!hints[2].nullable); assert_eq!(hints[3].path, vec!["comment"]); assert_eq!(hints[3].data_type, DataType::String(None)); - assert!(hints[3].nullable); } #[test] @@ -484,7 +425,7 @@ CREATE TABLE traces ( } #[test] - fn test_parse_json2_type_hint_default_nullable() { + fn test_parse_json2_type_hint_defaults_to_nullable() { let column = parse_json2_column( r#" CREATE TABLE traces ( @@ -495,7 +436,7 @@ CREATE TABLE traces ( let hints = column.extensions.json2_options.unwrap().type_hints; assert_eq!(hints.len(), 1); - assert!(hints[0].nullable); + assert_eq!(hints[0].data_type, DataType::String(None)); } #[test] @@ -560,57 +501,19 @@ CREATE TABLE traces ( } #[test] - fn test_parse_json2_type_hint_default_accepts_signed_literals() { - let column = parse_json2_column( - r#" -CREATE TABLE traces ( - log_json_data JSON2 ( - negative_int INT64 DEFAULT -5, - positive_float FLOAT64 DEFAULT +1.5 - ), - ts TIMESTAMP TIME INDEX, -)"#, - ); - - let hints = column.extensions.json2_options.unwrap().type_hints; - assert_eq!(hints.len(), 2); - assert_eq!( - hints[0] - .default - .as_ref() - .map(|expr| expr.to_string()) - .as_deref(), - Some("-5") - ); - assert_eq!( - hints[1] - .default - .as_ref() - .map(|expr| expr.to_string()) - .as_deref(), - Some("+1.5") - ); - } - - #[test] - fn test_parse_json2_type_hint_default_rejects_function() { - let result = ParserContext::create_with_dialect( - r#" -CREATE TABLE traces ( - log_json_data JSON2 (status_code INT64 DEFAULT abs(-1)), - ts TIMESTAMP TIME INDEX, -)"#, - &GreptimeDbDialect {}, - ParseOptions::default(), - ); - - assert!(result.is_err()); - assert!( - result - .unwrap_err() - .to_string() - .contains("DEFAULT only supports literal values") - ); + fn test_parse_json2_type_hint_rejects_default() { + for default in ["-5", "abs(-1)"] { + let sql = format!( + "CREATE TABLE traces (log_json_data JSON2 (status_code INT64 DEFAULT {default}), ts TIMESTAMP TIME INDEX)" + ); + let err = ParserContext::create_with_dialect( + &sql, + &GreptimeDbDialect {}, + ParseOptions::default(), + ) + .unwrap_err(); + assert!(err.to_string().contains("DEFAULT is not supported")); + } } #[test] @@ -646,7 +549,7 @@ CREATE TABLE traces ( } #[test] - fn test_parse_json2_type_hint_rejects_duplicated_nullability() { + fn test_parse_json2_type_hint_rejects_nullability() { for sql in [ r#" CREATE TABLE traces ( @@ -680,7 +583,7 @@ CREATE TABLE traces ( result .unwrap_err() .to_string() - .contains("NULL/NOT NULL option already specified") + .contains("NULL/NOT NULL is not supported") ); } } diff --git a/src/sql/src/statements.rs b/src/sql/src/statements.rs index cf0b2486750..808e30f842c 100644 --- a/src/sql/src/statements.rs +++ b/src/sql/src/statements.rs @@ -678,8 +678,6 @@ mod tests { vec![datatypes::json::JsonTypeHint { path: vec!["kind".to_string()], data_type: ConcreteDataType::string_datatype(), - nullable: true, - default_constraint: None, inverted_index: false, }], None, diff --git a/src/sql/src/statements/create.rs b/src/sql/src/statements/create.rs index a4736d0a7aa..46b5b07c9f7 100644 --- a/src/sql/src/statements/create.rs +++ b/src/sql/src/statements/create.rs @@ -16,30 +16,27 @@ use std::collections::HashMap; use std::fmt::{Display, Formatter}; use common_catalog::consts::FILE_ENGINE; -use common_sql::default_constraint::parse_column_default_constraint; use datatypes::json::{JSON2_DEFAULT_MAX_AUTO_EXPANDED_PATHS, JsonSettings}; use datatypes::prelude::ConcreteDataType; use datatypes::schema::{ - ColumnDefaultConstraint, FulltextOptions, SkippingIndexOptions, VectorDistanceMetric, - VectorIndexEngineType, VectorIndexOptions, + FulltextOptions, SkippingIndexOptions, VectorDistanceMetric, VectorIndexEngineType, + VectorIndexOptions, }; use itertools::Itertools; use serde::Serialize; use snafu::ResultExt; -use sqlparser::ast::{ColumnOption, ColumnOptionDef, DataType, Expr}; +use sqlparser::ast::{ColumnOptionDef, DataType, Expr}; use sqlparser_derive::{Visit, VisitMut}; use crate::ast::{ColumnDef, Ident, ObjectName, Value as SqlValue}; -use crate::dialect::GreptimeDbDialect; use crate::error::{ InvalidFlowQuerySnafu, InvalidSqlSnafu, Result, SetFulltextOptionSnafu, SetSkippingIndexOptionSnafu, }; -use crate::parser::ParserContext; use crate::statements::query::Query as GtQuery; use crate::statements::statement::Statement; use crate::statements::tql::Tql; -use crate::statements::{OptionMap, sql_data_type_to_concrete_data_type, value_to_sql_value}; +use crate::statements::{OptionMap, sql_data_type_to_concrete_data_type}; const LINE_SEP: &str = ",\n"; const COMMA_SEP: &str = ", "; @@ -164,8 +161,6 @@ impl Display for Json2Options { pub struct JsonTypeHint { pub path: Vec, pub data_type: DataType, - pub nullable: bool, - pub default: Option, pub inverted_index: bool, } @@ -363,8 +358,6 @@ impl ColumnExtensions { Ok(datatypes::json::JsonTypeHint { path: hint.path.clone(), data_type: json_type_hint_concrete_data_type(&hint.data_type)?, - nullable: hint.nullable, - default_constraint: build_json_type_hint_default_constraint(hint)?, inverted_index: hint.inverted_index, }) }) @@ -384,15 +377,9 @@ impl ColumnExtensions { .into_iter() .map(|hint| { let data_type = json_type_hint_sql_data_type(&hint.data_type)?; - let default = hint - .default_constraint - .map(|constraint| column_default_constraint_to_expr(&constraint)) - .transpose()?; Ok(JsonTypeHint { path: hint.path, data_type, - nullable: hint.nullable, - default, inverted_index: hint.inverted_index, }) }) @@ -406,38 +393,6 @@ impl ColumnExtensions { } } -fn build_json_type_hint_default_constraint( - hint: &JsonTypeHint, -) -> Result> { - let Some(default) = &hint.default else { - return Ok(None); - }; - - let data_type = json_type_hint_concrete_data_type(&hint.data_type)?; - let opts = [ColumnOptionDef { - name: None, - option: ColumnOption::Default(default.clone()), - }]; - - // Use the JSON path as the column name context for default value parsing errors. - let json_path = hint.path.join("."); - let default_constraint = parse_column_default_constraint(&json_path, &data_type, &opts, None) - .context(crate::error::SqlCommonSnafu)?; - - if let Some(constraint) = &default_constraint { - constraint - .validate(&data_type, hint.nullable) - .map_err(|e| { - InvalidSqlSnafu { - msg: format!("invalid DEFAULT for JSON2 type hint '{}': {e}", json_path), - } - .build() - })?; - } - - Ok(default_constraint) -} - fn json_type_hint_concrete_data_type(data_type: &DataType) -> Result { let data_type = sql_data_type_to_concrete_data_type(data_type)?; normalize_json_type_hint_concrete_data_type(&data_type) @@ -483,36 +438,18 @@ fn json_type_hint_sql_data_type(data_type: &ConcreteDataType) -> Result Result { - match constraint { - ColumnDefaultConstraint::Value(value) => Ok(Expr::Value(value_to_sql_value(value)?.into())), - ColumnDefaultConstraint::Function(function) => { - ParserContext::parse_function(function, &GreptimeDbDialect {}) - } - } -} - fn format_json_type_hint(hint: &JsonTypeHint) -> String { let path = hint .path .iter() .map(|segment| format_json_path_segment(segment)) .join("."); - let nullability = if hint.nullable { " NULL" } else { " NOT NULL" }; - let default = hint - .default - .as_ref() - .map(|expr| format!(" DEFAULT {expr}")) - .unwrap_or_default(); let inverted_index = if hint.inverted_index { " INVERTED INDEX" } else { "" }; - format!( - "{} {}{}{}{}", - path, hint.data_type, nullability, default, inverted_index - ) + format!("{} {}{}", path, hint.data_type, inverted_index) } fn format_json_path_segment(segment: &str) -> String { @@ -817,8 +754,6 @@ mod tests { use datatypes::json::{JsonSettings, JsonTypeHint as DatatypeJsonTypeHint}; use datatypes::prelude::ConcreteDataType; - use datatypes::schema::ColumnDefaultConstraint; - use datatypes::value::Value; use super::*; use crate::dialect::GreptimeDbDialect; @@ -995,7 +930,7 @@ ENGINE=mito let sql = r#"CREATE TABLE traces ( log_json_data JSON2 ( "service.name" STRING, - "a.b"."c" INT64 NOT NULL, + "a.b"."c" INT64, a."b.c" STRING ), ts TIMESTAMP TIME INDEX @@ -1011,9 +946,9 @@ ENGINE=mito r#" CREATE TABLE traces ( log_json_data JSON2( - "service.name" STRING NULL, - "a.b"."c" BIGINT NOT NULL, - "a"."b.c" STRING NULL + "service.name" STRING, + "a.b"."c" BIGINT, + "a"."b.c" STRING ), ts TIMESTAMP NOT NULL, TIME INDEX (ts) @@ -1039,7 +974,7 @@ ENGINE=mito fn test_parse_json2_max_auto_expanded_paths_option() -> Result<()> { let sql = r#"CREATE TABLE traces ( log_json_data JSON2 ( - status_code INT64 NOT NULL, + status_code INT64, max_auto_expanded_paths = 1 ), ts TIMESTAMP TIME INDEX @@ -1065,7 +1000,7 @@ ENGINE=mito let sql = r#"CREATE TABLE traces ( log_json_data JSON2 ( "1abc" STRING, - a."2b" INT64 NOT NULL + a."2b" INT64 ), ts TIMESTAMP TIME INDEX )"#; @@ -1080,8 +1015,8 @@ ENGINE=mito r#" CREATE TABLE traces ( log_json_data JSON2( - "1abc" STRING NULL, - "a"."2b" BIGINT NOT NULL + "1abc" STRING, + "a"."2b" BIGINT ), ts TIMESTAMP NOT NULL, TIME INDEX (ts) @@ -1104,7 +1039,7 @@ ENGINE=mito } #[test] - fn test_json2_type_hint_default_builds_default_constraint() { + fn test_json2_type_hint_rejects_default() { let sql = r#"CREATE TABLE traces ( log_json_data JSON2 ( status_code INT64 DEFAULT -5, @@ -1114,67 +1049,24 @@ ENGINE=mito ), ts TIMESTAMP TIME INDEX )"#; - let result = + let err = ParserContext::create_with_dialect(sql, &GreptimeDbDialect {}, ParseOptions::default()) - .unwrap(); - - let Statement::CreateTable(create_table) = &result[0] else { - unreachable!() - }; - let settings = create_table.columns[0] - .extensions - .build_json_settings() - .unwrap() - .unwrap(); - let hints = settings.type_hints(); - - assert_eq!(hints[0].data_type, ConcreteDataType::int64_datatype()); - assert_eq!( - hints[0].default_constraint, - Some(ColumnDefaultConstraint::Value(Value::Int64(-5))) - ); - assert_eq!(hints[1].data_type, ConcreteDataType::float64_datatype()); - assert_eq!( - hints[1].default_constraint, - Some(ColumnDefaultConstraint::Value(Value::Float64(1.5.into()))) - ); - assert_eq!(hints[2].data_type, ConcreteDataType::boolean_datatype()); - assert_eq!( - hints[2].default_constraint, - Some(ColumnDefaultConstraint::Value(Value::Boolean(false))) - ); - assert_eq!(hints[3].data_type, ConcreteDataType::string_datatype()); - assert_eq!( - hints[3].default_constraint, - Some(ColumnDefaultConstraint::Value(Value::String( - "unknown".into() - ))) - ); + .unwrap_err(); + assert!(err.to_string().contains("DEFAULT is not supported")); } #[test] - fn test_json2_type_hint_not_null_default_null_is_rejected() { + fn test_json2_type_hint_rejects_not_null() { let sql = r#"CREATE TABLE traces ( log_json_data JSON2 ( status_code INT64 NOT NULL DEFAULT NULL ), ts TIMESTAMP TIME INDEX )"#; - let result = + let err = ParserContext::create_with_dialect(sql, &GreptimeDbDialect {}, ParseOptions::default()) - .unwrap(); - - let Statement::CreateTable(create_table) = &result[0] else { - unreachable!() - }; - let err = create_table.columns[0] - .extensions - .build_json_settings() - .unwrap_err(); - assert!( - err.to_string() - .contains("Default value should not be null for non null column") - ); + .unwrap_err(); + assert!(err.to_string().contains("NULL/NOT NULL is not supported")); } #[test] @@ -1185,36 +1077,26 @@ ENGINE=mito DatatypeJsonTypeHint { path: vec!["i".to_string()], data_type: ConcreteDataType::int32_datatype(), - nullable: true, - default_constraint: None, inverted_index: false, }, DatatypeJsonTypeHint { path: vec!["f".to_string()], data_type: ConcreteDataType::float32_datatype(), - nullable: true, - default_constraint: None, inverted_index: false, }, DatatypeJsonTypeHint { path: vec!["u".to_string()], data_type: ConcreteDataType::uint32_datatype(), - nullable: true, - default_constraint: None, inverted_index: false, }, DatatypeJsonTypeHint { path: vec!["s".to_string()], data_type: ConcreteDataType::string_datatype(), - nullable: true, - default_constraint: None, inverted_index: false, }, DatatypeJsonTypeHint { path: vec!["b".to_string()], data_type: ConcreteDataType::boolean_datatype(), - nullable: true, - default_constraint: None, inverted_index: false, }, ], @@ -1241,8 +1123,6 @@ ENGINE=mito vec![DatatypeJsonTypeHint { path: vec!["u".to_string()], data_type: ConcreteDataType::date_datatype(), - nullable: true, - default_constraint: None, inverted_index: false, }], None, diff --git a/tests/cases/standalone/common/types/json/json2.result b/tests/cases/standalone/common/types/json/json2.result index 493b1d85c16..ab529a20971 100644 --- a/tests/cases/standalone/common/types/json/json2.result +++ b/tests/cases/standalone/common/types/json/json2.result @@ -423,7 +423,7 @@ show create table json2_finite_paths; | | "ts" TIMESTAMP(3) NOT NULL, | | | "j" JSON2( | | | max_auto_expanded_paths = 1, | -| | "hint" STRING NULL | +| | "hint" STRING | | | ) NULL, | | | TIME INDEX ("ts") | | | ) | diff --git a/tests/cases/standalone/common/types/json/json2_alter.result b/tests/cases/standalone/common/types/json/json2_alter.result index 5662907d1d7..c23f9e2533f 100644 --- a/tests/cases/standalone/common/types/json/json2_alter.result +++ b/tests/cases/standalone/common/types/json/json2_alter.result @@ -27,8 +27,8 @@ Error: 1001(Unsupported), Not supported: ALTER TABLE MODIFY COLUMN to JSON2 type ALTER TABLE application_logs MODIFY COLUMN attrs JSON2 ( trace_id STRING, - user.id STRING NOT NULL, - user.name STRING DEFAULT 'anonymous', + user.id STRING, + user.name STRING, request_id STRING INVERTED INDEX ); @@ -38,8 +38,8 @@ ALTER TABLE application_logs MODIFY COLUMN attrs JSON2 ( max_auto_expanded_paths = 2000, trace_id STRING, - user.id STRING NOT NULL, - user.name STRING DEFAULT 'anonymous', + user.id STRING, + user.name STRING, request_id STRING INVERTED INDEX ); diff --git a/tests/cases/standalone/common/types/json/json2_alter.sql b/tests/cases/standalone/common/types/json/json2_alter.sql index 2c17138b86d..c89556c3485 100644 --- a/tests/cases/standalone/common/types/json/json2_alter.sql +++ b/tests/cases/standalone/common/types/json/json2_alter.sql @@ -19,8 +19,8 @@ ALTER TABLE application_logs ALTER TABLE application_logs MODIFY COLUMN attrs JSON2 ( trace_id STRING, - user.id STRING NOT NULL, - user.name STRING DEFAULT 'anonymous', + user.id STRING, + user.name STRING, request_id STRING INVERTED INDEX ); @@ -28,8 +28,8 @@ ALTER TABLE application_logs MODIFY COLUMN attrs JSON2 ( max_auto_expanded_paths = 2000, trace_id STRING, - user.id STRING NOT NULL, - user.name STRING DEFAULT 'anonymous', + user.id STRING, + user.name STRING, request_id STRING INVERTED INDEX ); diff --git a/tests/cases/standalone/common/types/json/json2_type_hints.result b/tests/cases/standalone/common/types/json/json2_type_hints.result index 4e997cb1451..7739d1d1f8a 100644 --- a/tests/cases/standalone/common/types/json/json2_type_hints.result +++ b/tests/cases/standalone/common/types/json/json2_type_hints.result @@ -1,10 +1,10 @@ CREATE TABLE json2_type_hints ( ts TIMESTAMP TIME INDEX, j JSON2 ( - user.age BIGINT NOT NULL DEFAULT 18, - user.name STRING DEFAULT 'unknown', - user.active BOOLEAN NULL, - score DOUBLE NULL DEFAULT 1.5 + user.age BIGINT, + user.name STRING, + user.active BOOLEAN, + score DOUBLE ) ) WITH ( 'append_mode' = 'true' @@ -14,26 +14,26 @@ Affected Rows: 0 SHOW CREATE TABLE json2_type_hints; -+------------------+--------------------------------------------------+ -| Table | Create Table | -+------------------+--------------------------------------------------+ -| json2_type_hints | CREATE TABLE IF NOT EXISTS "json2_type_hints" ( | -| | "ts" TIMESTAMP(3) NOT NULL, | -| | "j" JSON2( | -| | max_auto_expanded_paths = 100, | -| | "user"."age" BIGINT NOT NULL DEFAULT 18, | -| | "user"."name" STRING NULL DEFAULT 'unknown', | -| | "user"."active" BOOLEAN NULL, | -| | "score" DOUBLE NULL DEFAULT 1.5 | -| | ) NULL, | -| | TIME INDEX ("ts") | -| | ) | -| | | -| | ENGINE=mito | -| | WITH( | -| | append_mode = 'true' | -| | ) | -+------------------+--------------------------------------------------+ ++------------------+-------------------------------------------------+ +| Table | Create Table | ++------------------+-------------------------------------------------+ +| json2_type_hints | CREATE TABLE IF NOT EXISTS "json2_type_hints" ( | +| | "ts" TIMESTAMP(3) NOT NULL, | +| | "j" JSON2( | +| | max_auto_expanded_paths = 100, | +| | "user"."age" BIGINT, | +| | "user"."name" STRING, | +| | "user"."active" BOOLEAN, | +| | "score" DOUBLE | +| | ) NULL, | +| | TIME INDEX ("ts") | +| | ) | +| | | +| | ENGINE=mito | +| | WITH( | +| | append_mode = 'true' | +| | ) | ++------------------+-------------------------------------------------+ INSERT INTO json2_type_hints VALUES @@ -55,8 +55,8 @@ ORDER BY ts; | json_get(json2_type_hints.j,Utf8("$.user.age")) | json_get(json2_type_hints.j,Utf8("$.user.name")) | json_get(json2_type_hints.j,Utf8("$.user.active")) | json_get(json2_type_hints.j,Utf8("$.score")) | +-------------------------------------------------+--------------------------------------------------+----------------------------------------------------+----------------------------------------------+ | 42 | Alice | true | 3.25 | -| 18 | Bob | | 1.5 | -| 18 | unknown | | 1.5 | +| | Bob | | | +| | | | | +-------------------------------------------------+--------------------------------------------------+----------------------------------------------------+----------------------------------------------+ INSERT INTO json2_type_hints @@ -64,22 +64,6 @@ VALUES (4, '{"user":{"age":"bad"}}'); Error: 1004(InvalidArguments), Invalid JSON: JSON value at user.age does not match JSON2 type hint Int64 -CREATE TABLE json2_type_hints_required ( - ts TIMESTAMP TIME INDEX, - j JSON2 ( - user.age BIGINT NOT NULL - ) -) WITH ( - 'append_mode' = 'true' -); - -Affected Rows: 0 - -INSERT INTO json2_type_hints_required -VALUES (1, '{}'); - -Error: 1004(InvalidArguments), Invalid JSON: missing non-null JSON2 type hint path user.age - CREATE TABLE json2_type_hints_timestamp ( ts TIMESTAMP TIME INDEX, j JSON2 ( @@ -89,30 +73,6 @@ CREATE TABLE json2_type_hints_timestamp ( Error: 2000(InvalidSyntax), Invalid SQL, error: unsupported JSON2 type hint data type: TIMESTAMP -CREATE TABLE json2_default_null_ok ( - ts TIMESTAMP TIME INDEX, - j JSON2 ( - a BIGINT NULL DEFAULT NULL - ) -) WITH ( - 'append_mode' = 'true' -); - -Affected Rows: 0 - -DROP TABLE json2_default_null_ok; - -Affected Rows: 0 - -CREATE TABLE json2_default_null_check ( - ts TIMESTAMP TIME INDEX, - j JSON2 ( - a BIGINT NOT NULL DEFAULT NULL - ) -); - -Error: 2000(InvalidSyntax), Invalid SQL, error: invalid DEFAULT for JSON2 type hint 'a': Default value should not be null for non null column - -- A type hint at the maximum supported depth is accepted. CREATE TABLE json2_type_hint_depth_50 ( ts TIMESTAMP TIME INDEX, @@ -141,10 +101,6 @@ DROP TABLE json2_type_hints; Affected Rows: 0 -DROP TABLE json2_type_hints_required; - -Affected Rows: 0 - DROP TABLE json2_type_hint_depth_50; Affected Rows: 0 diff --git a/tests/cases/standalone/common/types/json/json2_type_hints.sql b/tests/cases/standalone/common/types/json/json2_type_hints.sql index 741684f79c5..aa88ae60bf0 100644 --- a/tests/cases/standalone/common/types/json/json2_type_hints.sql +++ b/tests/cases/standalone/common/types/json/json2_type_hints.sql @@ -1,10 +1,10 @@ CREATE TABLE json2_type_hints ( ts TIMESTAMP TIME INDEX, j JSON2 ( - user.age BIGINT NOT NULL DEFAULT 18, - user.name STRING DEFAULT 'unknown', - user.active BOOLEAN NULL, - score DOUBLE NULL DEFAULT 1.5 + user.age BIGINT, + user.name STRING, + user.active BOOLEAN, + score DOUBLE ) ) WITH ( 'append_mode' = 'true' @@ -29,18 +29,6 @@ ORDER BY ts; INSERT INTO json2_type_hints VALUES (4, '{"user":{"age":"bad"}}'); -CREATE TABLE json2_type_hints_required ( - ts TIMESTAMP TIME INDEX, - j JSON2 ( - user.age BIGINT NOT NULL - ) -) WITH ( - 'append_mode' = 'true' -); - -INSERT INTO json2_type_hints_required -VALUES (1, '{}'); - CREATE TABLE json2_type_hints_timestamp ( ts TIMESTAMP TIME INDEX, j JSON2 ( @@ -48,24 +36,6 @@ CREATE TABLE json2_type_hints_timestamp ( ) ); -CREATE TABLE json2_default_null_ok ( - ts TIMESTAMP TIME INDEX, - j JSON2 ( - a BIGINT NULL DEFAULT NULL - ) -) WITH ( - 'append_mode' = 'true' -); - -DROP TABLE json2_default_null_ok; - -CREATE TABLE json2_default_null_check ( - ts TIMESTAMP TIME INDEX, - j JSON2 ( - a BIGINT NOT NULL DEFAULT NULL - ) -); - -- A type hint at the maximum supported depth is accepted. CREATE TABLE json2_type_hint_depth_50 ( ts TIMESTAMP TIME INDEX, @@ -88,6 +58,4 @@ CREATE TABLE json2_type_hint_depth_51 ( DROP TABLE json2_type_hints; -DROP TABLE json2_type_hints_required; - DROP TABLE json2_type_hint_depth_50;