@@ -11015,47 +11015,85 @@ fn parse_is_boolean() {
1101511015 verified_stmt("SELECT f FROM foo WHERE field IS UNKNOWN");
1101611016 verified_stmt("SELECT f FROM foo WHERE field IS NOT UNKNOWN");
1101711017
11018- let sql = "SELECT f from foo where field is 0";
11019- let res = parse_sql_statements(sql);
11020- assert_eq!(
11021- ParserError::ParserError(
11022- "Expected: [NOT] NULL | TRUE | FALSE | DISTINCT | [form] NORMALIZED FROM after IS, found: 0"
11023- .to_string()
11024- ),
11025- res.unwrap_err()
11026- );
11018+ for sql in [
11019+ "SELECT f from foo where field is 0",
11020+ "SELECT s, s IS XYZ NORMALIZED FROM foo",
11021+ "SELECT s, s IS NFKC FROM foo",
11022+ "SELECT s, s IS TRIM(' NFKC ') FROM foo",
11023+ ] {
11024+ assert!(
11025+ parse_sql_statements(sql).is_err(),
11026+ "expected a parse failure for `{sql}`"
11027+ );
11028+ }
11029+ }
1102711030
11028- let sql = "SELECT s, s IS XYZ NORMALIZED FROM foo";
11029- let res = parse_sql_statements(sql);
11030- assert_eq!(
11031- ParserError::ParserError(
11032- "Expected: [NOT] NULL | TRUE | FALSE | DISTINCT | [form] NORMALIZED FROM after IS, found: XYZ"
11033- .to_string()
11034- ),
11035- res.unwrap_err()
11036- );
11031+ #[test]
11032+ fn parse_is_json_predicate() {
11033+ use self::Expr::*;
1103711034
11038- let sql = "SELECT s, s IS NFKC FROM foo";
11039- let res = parse_sql_statements(sql) ;
11035+ // Assert the full AST once for a case that exercises every field.
11036+ let sql = "a IS NOT JSON OBJECT WITHOUT UNIQUE KEYS" ;
1104011037 assert_eq!(
11041- ParserError::ParserError(
11042- "Expected: [NOT] NULL | TRUE | FALSE | DISTINCT | [form] NORMALIZED FROM after IS, found: FROM"
11043- .to_string()
11044- ),
11045- res.unwrap_err()
11038+ IsJson {
11039+ expr: Box::new(Identifier(Ident::new("a"))),
11040+ kind: Some(JsonPredicateType::Object),
11041+ unique_keys: Some(JsonKeyUniqueness::WithoutUniqueKeys),
11042+ negated: true,
11043+ },
11044+ verified_expr(sql)
1104611045 );
1104711046
11048- let sql = "SELECT s, s IS TRIM(' NFKC ') FROM foo";
11049- let res = parse_sql_statements(sql);
11050- assert_eq!(
11051- ParserError::ParserError(
11052- "Expected: [NOT] NULL | TRUE | FALSE | DISTINCT | [form] NORMALIZED FROM after IS, found: TRIM"
11053- .to_string()
11054- ),
11055- res.unwrap_err()
11047+ // The remaining forms only need to round-trip.
11048+ verified_expr("a IS JSON");
11049+ verified_expr("a IS NOT JSON");
11050+ verified_expr("a IS JSON VALUE");
11051+ verified_expr("a IS JSON SCALAR");
11052+ verified_expr("a IS JSON ARRAY");
11053+ verified_expr("a IS JSON OBJECT");
11054+ verified_expr("a IS JSON WITH UNIQUE KEYS");
11055+ verified_expr("a IS JSON WITHOUT UNIQUE KEYS");
11056+
11057+ all_dialects().expr_parses_to("a IS JSON WITH UNIQUE", "a IS JSON WITH UNIQUE KEYS");
11058+ all_dialects().expr_parses_to("a IS JSON WITHOUT UNIQUE", "a IS JSON WITHOUT UNIQUE KEYS");
11059+
11060+ assert_matches!(
11061+ verified_expr("NOT a IS JSON"),
11062+ Expr::UnaryOp {
11063+ op: UnaryOperator::Not,
11064+ expr
11065+ } if matches!(&*expr, Expr::IsJson { .. })
1105611066 );
1105711067}
1105811068
11069+ #[test]
11070+ fn parse_is_json_predicate_invalid() {
11071+ let dialects = all_dialects();
11072+
11073+ let invalid = [
11074+ "SELECT * FROM t WHERE a IS JSON WITH FROM",
11075+ "SELECT * FROM t WHERE a IS JSON WITH KEYS",
11076+ "SELECT * FROM t WHERE a IS JSON WITHOUT FROM",
11077+ "SELECT * FROM t WHERE a IS JSON WITHOUT KEYS",
11078+ "SELECT * FROM t WHERE a IS NOT JSON WITH FROM",
11079+ "SELECT * FROM t WHERE a IS JSON VALUE ARRAY",
11080+ "SELECT * FROM t WHERE a IS JSON OBJECT VALUE",
11081+ "SELECT * FROM t WHERE a IS JSON WITH UNIQUE EXTRA",
11082+ "SELECT * FROM t WHERE a IS JSON WITH UNIQUE KEYS EXTRA",
11083+ "SELECT * FROM t WHERE a IS JSON WITHOUT UNIQUE EXTRA",
11084+ "SELECT * FROM t WHERE a IS JSON WITHOUT UNIQUE KEYS EXTRA",
11085+ "SELECT * FROM t WHERE a IS JSON WITH UNIQUE KEYS WITH UNIQUE KEYS",
11086+ "SELECT * FROM t WHERE a IS JSON WITHOUT UNIQUE KEYS WITHOUT UNIQUE KEYS",
11087+ ];
11088+
11089+ for sql in invalid {
11090+ assert!(
11091+ dialects.parse_sql_statements(sql).is_err(),
11092+ "expected a parse failure for `{sql}`"
11093+ );
11094+ }
11095+ }
11096+
1105911097#[test]
1106011098fn parse_discard() {
1106111099 let sql = "DISCARD ALL";
0 commit comments