@@ -876,6 +876,17 @@ pub enum Expr {
876876 IsDistinctFrom ( Box < Expr > , Box < Expr > ) ,
877877 /// `IS NOT DISTINCT FROM` operator
878878 IsNotDistinctFrom ( Box < Expr > , Box < Expr > ) ,
879+ /// `<expr> IS [NOT] JSON [VALUE|SCALAR|ARRAY|OBJECT] [WITH|WITHOUT UNIQUE [KEYS]]`
880+ IsJson {
881+ /// Expression being tested.
882+ expr : Box < Expr > ,
883+ /// Optional JSON shape constraint.
884+ kind : Option < JsonPredicateType > ,
885+ /// Optional duplicate-key handling constraint for JSON objects.
886+ unique_keys : Option < JsonKeyUniqueness > ,
887+ /// `true` when `NOT` is present.
888+ negated : bool ,
889+ } ,
879890 /// `<expr> IS [ NOT ] [ form ] NORMALIZED`
880891 IsNormalized {
881892 /// Expression being tested.
@@ -1685,6 +1696,25 @@ impl fmt::Display for Expr {
16851696 Expr :: IsNotNull ( ast) => write ! ( f, "{ast} IS NOT NULL" ) ,
16861697 Expr :: IsUnknown ( ast) => write ! ( f, "{ast} IS UNKNOWN" ) ,
16871698 Expr :: IsNotUnknown ( ast) => write ! ( f, "{ast} IS NOT UNKNOWN" ) ,
1699+ Expr :: IsJson {
1700+ expr,
1701+ kind,
1702+ unique_keys,
1703+ negated,
1704+ } => {
1705+ write ! ( f, "{expr} IS " ) ?;
1706+ if * negated {
1707+ write ! ( f, "NOT " ) ?;
1708+ }
1709+ write ! ( f, "JSON" ) ?;
1710+ if let Some ( kind) = kind {
1711+ write ! ( f, " {kind}" ) ?;
1712+ }
1713+ if let Some ( unique_keys) = unique_keys {
1714+ write ! ( f, " {unique_keys}" ) ?;
1715+ }
1716+ Ok ( ( ) )
1717+ }
16881718 Expr :: InList {
16891719 expr,
16901720 list,
@@ -8107,6 +8137,52 @@ pub enum AnalyzeFormat {
81078137 TREE ,
81088138}
81098139
8140+ /// Optional type constraint for `IS JSON`.
8141+ #[ derive( Debug , Clone , Copy , PartialEq , PartialOrd , Eq , Ord , Hash ) ]
8142+ #[ cfg_attr( feature = "serde" , derive( Serialize , Deserialize ) ) ]
8143+ #[ cfg_attr( feature = "visitor" , derive( Visit , VisitMut ) ) ]
8144+ pub enum JsonPredicateType {
8145+ /// `VALUE` form.
8146+ Value ,
8147+ /// `SCALAR` form.
8148+ Scalar ,
8149+ /// `ARRAY` form.
8150+ Array ,
8151+ /// `OBJECT` form.
8152+ Object ,
8153+ }
8154+
8155+ impl fmt:: Display for JsonPredicateType {
8156+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
8157+ match self {
8158+ JsonPredicateType :: Value => write ! ( f, "VALUE" ) ,
8159+ JsonPredicateType :: Scalar => write ! ( f, "SCALAR" ) ,
8160+ JsonPredicateType :: Array => write ! ( f, "ARRAY" ) ,
8161+ JsonPredicateType :: Object => write ! ( f, "OBJECT" ) ,
8162+ }
8163+ }
8164+ }
8165+
8166+ /// Optional duplicate-key handling for `IS JSON`.
8167+ #[ derive( Debug , Clone , Copy , PartialEq , PartialOrd , Eq , Ord , Hash ) ]
8168+ #[ cfg_attr( feature = "serde" , derive( Serialize , Deserialize ) ) ]
8169+ #[ cfg_attr( feature = "visitor" , derive( Visit , VisitMut ) ) ]
8170+ pub enum JsonKeyUniqueness {
8171+ /// `WITH UNIQUE KEYS` form.
8172+ WithUniqueKeys ,
8173+ /// `WITHOUT UNIQUE KEYS` form.
8174+ WithoutUniqueKeys ,
8175+ }
8176+
8177+ impl fmt:: Display for JsonKeyUniqueness {
8178+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
8179+ match self {
8180+ JsonKeyUniqueness :: WithUniqueKeys => write ! ( f, "WITH UNIQUE KEYS" ) ,
8181+ JsonKeyUniqueness :: WithoutUniqueKeys => write ! ( f, "WITHOUT UNIQUE KEYS" ) ,
8182+ }
8183+ }
8184+ }
8185+
81108186impl fmt:: Display for AnalyzeFormat {
81118187 fn fmt ( & self , f : & mut core:: fmt:: Formatter < ' _ > ) -> core:: fmt:: Result {
81128188 f. write_str ( match self {
0 commit comments