supabase / pg_jsonschema

PostgreSQL extension providing JSON Schema validation
Apache License 2.0
1.03k stars 30 forks source link

Additional Properties doesn't restrict fields #44

Closed Sicria closed 11 months ago

Sicria commented 11 months ago

Bug report

Describe the bug

Check the tests it shows an example of using additionalProperties but upon trying it out, it doesn't actually restrict the properties correctly.

To Reproduce

Running the following query should return false but it returns true.

select
  extensions.jsonb_matches_schema(
    schema := '{
                "type": "object",
                "properties": {
                    "foo": {
                        "type": "string"
                    },
                    "bar": {
                        "type": "number"
                    },
                    "baz": {
                        "type": "boolean"
                    },
                    "additionalProperties": false
                }
            }',
    instance := '{"foo2": 1, "bar2": [], "baz2": "1"}'
  );

Expected behavior

I would expect it to return false as the object contains properties that aren't defined in the schema.

It also appears that there's no support for required fields? (eg. "required": ["foo"])

Invalid schema: ValidationError { instance: Array [String("foo")], kind: Type { kind: Multiple(PrimitiveTypesBitMap { inner: 34 }) }, instance_path: JSONPointer([Property("properties"), Property("required")]), schema_path: JSONPointer([Keyword("type")]) }
olirice commented 11 months ago

Additional properties need to be specified 1 level higher, rather than inside the properties key.

So your example would become:

select
    jsonb_matches_schema(
    schema := '{
                "type": "object",
                "additionalProperties": false,
                "properties": {
                    "foo": {
                        "type": "string"
                    },
                    "bar": {
                        "type": "number"
                    },
                    "baz": {
                        "type": "boolean"
                    }
                }
            }',
    instance := '{"foo2": 1, "bar2": [], "baz2": "1"}'
  );

Closing this out, but lmk if you have any trouble getting it working

Sicria commented 11 months ago

Appreciate the help, not sure how I didn't stumble on that whilst debugging.

Would it be worth updating this test to match the correct placement? https://github.com/supabase/pg_jsonschema/blob/master/src/lib.rs#L184C32-L184C32

Also, any chance of adding support for required? Happy to make a new feature request if you'd prefer.

olirice commented 11 months ago

is “required” not the same solution?

if not (I’m not in front of a computer), yes, please open a new issue with reproduction case

thanks!