@@ -4,21 +4,21 @@ CREATE TYPE json_schema_validation_result AS (
44);
55
66
7- CREATE OR REPLACE FUNCTION json_schema_validation_result_as_bool (json_schema_validation_result) RETURNS bool AS $$
7+ CREATE OR REPLACE FUNCTION json_schema_validation_result_as_bool (@extschema@. json_schema_validation_result) RETURNS bool AS $$
88 SELECT ($1 ).error IS NULL ;
99$$ LANGUAGE SQL IMMUTABLE;
1010
11- CREATE OR REPLACE FUNCTION json_schema_validation_result_array_as_bool (json_schema_validation_result[]) RETURNS bool AS $$
12- SELECT $1 IS NULL OR true = ALL ($1 );
11+ CREATE OR REPLACE FUNCTION json_schema_validation_result_array_as_bool (@extschema@. json_schema_validation_result[]) RETURNS bool AS $$
12+ SELECT $1 IS NULL OR true = ALL ($1 ::bool[] );
1313$$ LANGUAGE SQL IMMUTABLE;
1414
1515CREATE CAST ( json_schema_validation_result AS bool )
1616 WITH FUNCTION @extschema@.json_schema_validation_result_as_bool(json_schema_validation_result)
17- AS IMPLICIT ;
17+ AS ASSIGNMENT ;
1818
1919CREATE CAST ( json_schema_validation_result[] AS bool )
2020 WITH FUNCTION @extschema@.json_schema_validation_result_array_as_bool(json_schema_validation_result[])
21- AS IMPLICIT ;
21+ AS ASSIGNMENT ;
2222
2323
2424
@@ -93,12 +93,24 @@ CREATE OR REPLACE FUNCTION validate_json_schema(schema jsonb, data jsonb, root_s
9393 SELECT @extschema@.get_json_schema_validations(schema, data, root_schema, ARRAY []::text [], string_as_number)::bool;
9494$f$ LANGUAGE SQL IMMUTABLE ;
9595
96- CREATE OR REPLACE FUNCTION json_schema_check_constraint (schema jsonb, data jsonb, string_as_number bool default true) RETURNS bool AS $$
97- DECLARE result json_schema_validation_result[];
96+ CREATE OR REPLACE FUNCTION json_schema_check_constraint (
97+ schema jsonb,
98+ data jsonb,
99+ string_as_number bool default false,
100+ table_name text default ' ' ,
101+ column_name text default ' '
102+ ) RETURNS bool AS $$
103+ DECLARE
104+ result json_schema_validation_result[];
98105 BEGIN
99106 result := @extschema@.get_json_schema_validations(schema, data, schema, ' {}' ::text [], string_as_number := string_as_number);
100107 IF (NOT result) THEN
101- RAISE check_violation USING MESSAGE = ' json_schema_validation_failed' , DETAIL = result;
108+ RAISE check_violation USING
109+ MESSAGE = ' json_schema_validation_failed' ,
110+ DETAIL = to_jsonb(result),
111+ -- HINT = v_value,
112+ TABLE = table_name,
113+ COLUMN = column_name;
102114 END IF;
103115 RETURN true;
104116 END;
@@ -109,7 +121,7 @@ $$ LANGUAGE plpgsql IMMUTABLE ;
109121CREATE OR REPLACE FUNCTION _validate_json_multiple_schemas (
110122 schemas_array jsonb, data jsonb, root_schema jsonb, schema_path text [], string_as_number bool,
111123 OUT validation_booleans bool[],
112- OUT all_errors json_schema_validation_result[]
124+ OUT all_errors @extschema@. json_schema_validation_result[]
113125) AS $f$
114126 WITH schema_validations AS (
115127 SELECT q FROM jsonb_array_elements(schemas_array) sub_schema,
@@ -122,7 +134,7 @@ $f$ LANGUAGE SQL IMMUTABLE ;
122134
123135
124136CREATE OR REPLACE FUNCTION get_json_schema_validations (schema jsonb, data jsonb, root_schema jsonb, schema_path text [], string_as_number bool)
125- RETURNS json_schema_validation_result[] AS $f$
137+ RETURNS @extschema@. json_schema_validation_result[] AS $f$
126138DECLARE
127139 prop text ;
128140 item jsonb;
@@ -133,7 +145,7 @@ DECLARE
133145 additionalItems jsonb;
134146 pattern text ;
135147 props text [];
136- result json_schema_validation_result[];
148+ result @extschema@. json_schema_validation_result[];
137149 q_result record;
138150BEGIN
139151 IF root_schema IS NULL THEN
@@ -160,7 +172,7 @@ BEGIN
160172 ELSE
161173 types = ARRAY[schema- >> ' type' ];
162174 END IF;
163- IF (SELECT NOT bool_or(@extschema@._validate_json_schema_type(type, data)) FROM unnest(types) type) THEN
175+ IF (SELECT NOT bool_or(@extschema@._validate_json_schema_type(type, data, string_as_number )) FROM unnest(types) type) THEN
164176 RETURN ARRAY [(schema_path, format(' %s is not a valid type: %s' , jsonb_typeof(data), types))];
165177 END IF;
166178 END IF;
@@ -179,7 +191,7 @@ BEGIN
179191 IF schema ? ' required' AND jsonb_typeof(data) = ' object' THEN
180192 IF NOT ARRAY(SELECT jsonb_object_keys(data)) @>
181193 ARRAY(SELECT jsonb_array_elements_text(schema- > ' required' )) THEN
182- RETURN ARRAY [(path , format(' %s is missing required properties: %s' , schema- >> ' type' , ARRAY(
194+ RETURN ARRAY [(schema_path , format(' %s is missing required properties: %s' , schema- >> ' type' , ARRAY(
183195 SELECT jsonb_array_elements_text(schema- > ' required' )
184196 EXCEPT
185197 SELECT jsonb_object_keys(data)
@@ -215,7 +227,7 @@ BEGIN
215227 IF prefixItems IS NOT NULL THEN
216228 SELECT array_agg(q) INTO result
217229 FROM jsonb_array_elements(prefixItems) WITH ORDINALITY AS t(sub_schema, i),
218- @extschema@.get_json_schema_validations(sub_schema, data- > (i::int - 1 ), root_schema, schema_path || i ::text , string_as_number) q1, unnest(q1) q
230+ @extschema@.get_json_schema_validations(sub_schema, data- > (i::int - 1 ), root_schema, schema_path || (i - 1 ) ::text , string_as_number) q1, unnest(q1) q
219231 WHERE i <= jsonb_array_length(data);
220232 IF NOT result THEN
221233 RETURN result;
@@ -225,14 +237,14 @@ BEGIN
225237
226238 IF jsonb_typeof(additionalItems) = ' boolean' and NOT (additionalItems)::text ::boolean THEN
227239 IF jsonb_array_length(data) > COALESCE(jsonb_array_length(prefixItems), 0 ) THEN
228- RETURN ARRAY [(path , format(' field only accepts %s items' , COALESCE(jsonb_array_length(prefixItems), 0 )))];
240+ RETURN ARRAY [(schema_path , format(' field only accepts %s items' , COALESCE(jsonb_array_length(prefixItems), 0 )))];
229241 END IF;
230242 END IF;
231243
232244 IF jsonb_typeof(additionalItems) = ' object' THEN
233245 SELECT array_agg(q) INTO result
234246 FROM jsonb_array_elements(data) WITH ORDINALITY AS t(elem, i),
235- @extschema@.get_json_schema_validations(additionalItems, elem, root_schema, schema_path || i ::text , string_as_number) AS q1, unnest(q1) q
247+ @extschema@.get_json_schema_validations(additionalItems, elem, root_schema, schema_path || (i - 1 ) ::text , string_as_number) AS q1, unnest(q1) q
236248 WHERE i > coalesce(jsonb_array_length(prefixItems), 0 ) AND NOT q LIMIT 1 ;
237249
238250 IF NOT result THEN
@@ -244,59 +256,59 @@ BEGIN
244256
245257 IF schema ? ' minimum' AND jsonb_typeof(data) = ' number' THEN
246258 IF data::text ::numeric < (schema- >> ' minimum' )::numeric THEN
247- RETURN ARRAY [(path , format(' value must be >= %s' , (schema- >> ' minimum' )))];
259+ RETURN ARRAY [(schema_path , format(' value must be >= %s' , (schema- >> ' minimum' )))];
248260 END IF;
249261 END IF;
250262
251263 IF schema ? ' maximum' AND jsonb_typeof(data) = ' number' THEN
252264 IF data::text ::numeric > (schema- >> ' maximum' )::numeric THEN
253- RETURN ARRAY [(path , format(' value must be <= %s' , (schema- >> ' maximum' )))];
265+ RETURN ARRAY [(schema_path , format(' value must be <= %s' , (schema- >> ' maximum' )))];
254266 END IF;
255267 END IF;
256268
257269 IF schema ? ' exclusiveMinimum' AND jsonb_typeof(data) = ' number' THEN
258270 IF jsonb_typeof(schema- > ' exclusiveMinimum' ) = ' number' THEN
259271 IF data::text ::numeric <= (schema- >> ' exclusiveMinimum' )::numeric THEN
260- RETURN ARRAY [(path , format(' value must be > %s' , (schema- >> ' exclusiveMinimum' )))];
272+ RETURN ARRAY [(schema_path , format(' value must be > %s' , (schema- >> ' exclusiveMinimum' )))];
261273 END IF;
262274 ELSEIF COALESCE((schema- > ' exclusiveMinimum' )::text ::bool, FALSE) THEN
263275 IF data::text ::numeric = (schema- >> ' minimum' )::numeric THEN
264- RETURN ARRAY [(path , format(' value must be > %s' , (schema- >> ' minimum' )))];
276+ RETURN ARRAY [(schema_path , format(' value must be > %s' , (schema- >> ' minimum' )))];
265277 END IF;
266278 END IF;
267279 END IF;
268280
269281 IF schema ? ' exclusiveMaximum' AND jsonb_typeof(data) = ' number' THEN
270282 IF jsonb_typeof(schema- > ' exclusiveMaximum' ) = ' number' THEN
271283 IF data::text ::numeric >= (schema- >> ' exclusiveMaximum' )::numeric THEN
272- RETURN ARRAY [(path , format(' value must be < %s' , (schema- >> ' exclusiveMinimum' )))];
284+ RETURN ARRAY [(schema_path , format(' value must be < %s' , (schema- >> ' exclusiveMinimum' )))];
273285 END IF;
274286 ELSEIF COALESCE((schema- > ' exclusiveMaximum' )::text ::bool, FALSE) THEN
275287 IF data::text ::numeric = (schema- >> ' maximum' )::numeric THEN
276- RETURN ARRAY [(path , format(' value must be < %s' , (schema- >> ' maximum' )))];
288+ RETURN ARRAY [(schema_path , format(' value must be < %s' , (schema- >> ' maximum' )))];
277289 END IF;
278290 END IF;
279291 END IF;
280292
281293 IF schema ? ' anyOf' THEN
282294 q_result := @extschema@._validate_json_multiple_schemas(schema- > ' anyOf' , data, root_schema, schema_path, string_as_number);
283295 IF NOT (SELECT true = any (q_result .validation_booleans )) THEN
284- RETURN q_result .all_errors || (schema_path, ' does not match any of the required schemas' )::json_schema_validation_result;
296+ RETURN q_result .all_errors || (schema_path, ' does not match any of the required schemas' )::@extschema@. json_schema_validation_result;
285297 END IF;
286298 END IF;
287299
288300 IF schema ? ' allOf' THEN
289301 q_result := @extschema@._validate_json_multiple_schemas(schema- > ' allOf' , data, root_schema, schema_path, string_as_number);
290302 IF NOT (SELECT true = all(q_result .validation_booleans )) THEN
291- RETURN q_result .all_errors || (schema_path, ' does not match all of the required schemas' )::json_schema_validation_result;
303+ RETURN q_result .all_errors || (schema_path, ' does not match all of the required schemas' )::@extschema@. json_schema_validation_result;
292304 END IF;
293305 END IF;
294306
295307 IF schema ? ' oneOf' THEN
296308 q_result := @extschema@._validate_json_multiple_schemas(schema- > ' oneOf' , data, root_schema, schema_path, string_as_number);
297309 SELECT count (a::bool) INTO idx FROM unnest(q_result .validation_booleans ) a WHERE a = true;
298310 IF (idx != 1 ) THEN
299- RETURN ARRAY [(schema_path, format(' should match exactly one of the schemas, but matches %s' , idx))::json_schema_validation_result];
311+ RETURN ARRAY [(schema_path, format(' should match exactly one of the schemas, but matches %s' , idx))::@extschema@. json_schema_validation_result];
300312 END IF;
301313 END IF;
302314
@@ -319,7 +331,7 @@ BEGIN
319331 END IF;
320332 ELSE
321333 SELECT array_agg(q) INTO result FROM unnest(props) key, @extschema@.get_json_schema_validations(schema- > ' additionalProperties' , data- > key, root_schema, schema_path || key, string_as_number) q1, unnest(q1) q;
322- IF NOT (true = all(result)) THEN
334+ IF NOT (true = all(result::bool[] )) THEN
323335 RETURN result;
324336 END IF;
325337 END IF;
@@ -338,7 +350,7 @@ BEGIN
338350 END IF;
339351
340352 result := @extschema@.get_json_schema_validations(root_schema # > path, data, root_schema, schema_path, string_as_number);
341- IF NOT (true = all(result)) THEN
353+ IF NOT (true = all(result::bool[] )) THEN
342354 RETURN result;
343355 END IF;
344356 END IF;
@@ -402,14 +414,14 @@ BEGIN
402414 IF schema ? ' maxItems' AND jsonb_typeof(data) = ' array' THEN
403415 SELECT count (* ) INTO idx FROM jsonb_array_elements(data);
404416 IF idx > (schema- >> ' maxItems' )::numeric THEN
405- RETURN ARRAY [(schema_path, format(' field items count %s exceeds maxItems of %s' , idx, schema- > ' maxItems' ))];
417+ RETURN ARRAY [(schema_path, format(' items count of %s exceeds maxItems of %s' , idx, schema- > ' maxItems' ))];
406418 END IF;
407419 END IF;
408420
409421 IF schema ? ' minItems' AND jsonb_typeof(data) = ' array' THEN
410422 SELECT count (* ) INTO idx FROM jsonb_array_elements(data);
411423 IF idx < (schema- >> ' minItems' )::numeric THEN
412- RETURN ARRAY [(schema_path, format(' field items count %s is less than minItems of %s' , idx, schema- > ' minItems' ))];
424+ RETURN ARRAY [(schema_path, format(' items count of %s is less than minItems of %s' , idx, schema- > ' minItems' ))];
413425 END IF;
414426 END IF;
415427
@@ -477,7 +489,7 @@ BEGIN
477489 END IF;
478490 END IF;
479491
480- RETURN ' {}' ::json_schema_validation_result[];
492+ RETURN ' {}' ::@extschema@. json_schema_validation_result[];
481493END;
482494$f$ LANGUAGE ' plpgsql' VOLATILE ;
483495
@@ -691,7 +703,7 @@ CREATE OR REPLACE FUNCTION json_schema_resolve_ids_to_paths (
691703 ELSEIF jsonb_typeof(schema) = ' array' THEN
692704 RETURN QUERY SELECT q.*
693705 FROM jsonb_array_elements(schema) WITH ORDINALITY t(elem, idx),
694- @extschema@.json_schema_resolve_ids_to_paths(elem, path || (idx - 1 )::text , base_uri, base_path) q;
706+ @extschema@.json_schema_resolve_ids_to_paths(elem, path || (idx - 1 )::text , base_uri, base_path) q;
695707
696708 END IF;
697709 resolved_path := path ;
0 commit comments