Change tests to use postgres-json-schema instead of hjsonschema.
Embeds https://github.com/gavinwahl/postgres-json-schema.
This commit is contained in:
committed by
Steve Chávez
parent
e34669b137
commit
65fc672417
@@ -232,6 +232,7 @@ jobs:
|
|||||||
psql "postgres:///postgrest_test" -f test/fixtures/roles.sql
|
psql "postgres:///postgrest_test" -f test/fixtures/roles.sql
|
||||||
psql "postgres:///postgrest_test" -f test/fixtures/schema.sql
|
psql "postgres:///postgrest_test" -f test/fixtures/schema.sql
|
||||||
psql "postgres:///postgrest_test" -f test/fixtures/jwt.sql
|
psql "postgres:///postgrest_test" -f test/fixtures/jwt.sql
|
||||||
|
psql "postgres:///postgrest_test" -f test/fixtures/jsonschema.sql
|
||||||
psql "postgres:///postgrest_test" -f test/fixtures/privileges.sql
|
psql "postgres:///postgrest_test" -f test/fixtures/privileges.sql
|
||||||
test/memory-tests.sh
|
test/memory-tests.sh
|
||||||
- save_cache:
|
- save_cache:
|
||||||
|
|||||||
+1
-1
@@ -158,7 +158,6 @@ Test-Suite spec
|
|||||||
, hasql-pool >= 0.5 && < 0.6
|
, hasql-pool >= 0.5 && < 0.6
|
||||||
, hasql-transaction >= 0.7 && < 0.8
|
, hasql-transaction >= 0.7 && < 0.8
|
||||||
, heredoc
|
, heredoc
|
||||||
, hjsonschema == 1.5.0.1
|
|
||||||
, hspec
|
, hspec
|
||||||
, hspec-wai >= 0.7.0
|
, hspec-wai >= 0.7.0
|
||||||
, hspec-wai-json
|
, hspec-wai-json
|
||||||
@@ -170,6 +169,7 @@ Test-Suite spec
|
|||||||
, process
|
, process
|
||||||
, protolude == 0.2.2
|
, protolude == 0.2.2
|
||||||
, regex-tdfa
|
, regex-tdfa
|
||||||
|
, text
|
||||||
, time
|
, time
|
||||||
, transformers-base
|
, transformers-base
|
||||||
, wai
|
, wai
|
||||||
|
|||||||
@@ -2,8 +2,6 @@ resolver: lts-9.6
|
|||||||
extra-deps:
|
extra-deps:
|
||||||
- configurator-ng-0.0.0.1
|
- configurator-ng-0.0.0.1
|
||||||
- critbit-0.2.0.0
|
- critbit-0.2.0.0
|
||||||
- hjsonpointer-1.1.1
|
|
||||||
- hjsonschema-1.5.0.1
|
|
||||||
- Ranged-sets-0.3.0
|
- Ranged-sets-0.3.0
|
||||||
- protolude-0.2.2
|
- protolude-0.2.2
|
||||||
- hasql-1.3
|
- hasql-1.3
|
||||||
@@ -18,6 +16,3 @@ ghc-options:
|
|||||||
postgrest: -O2 -Werror -Wall -fwarn-identities -fno-warn-redundant-constraints
|
postgrest: -O2 -Werror -Wall -fwarn-identities -fno-warn-redundant-constraints
|
||||||
nix:
|
nix:
|
||||||
shell-file: shell.nix
|
shell-file: shell.nix
|
||||||
# only added because of hjsonschema conflict with http-types
|
|
||||||
# once hjsonschema upper bounding on http-types is solved it can be removed
|
|
||||||
allow-newer: true
|
|
||||||
|
|||||||
@@ -3,14 +3,11 @@ module Feature.ProxySpec where
|
|||||||
import Network.Wai (Application)
|
import Network.Wai (Application)
|
||||||
import Test.Hspec hiding (pendingWith)
|
import Test.Hspec hiding (pendingWith)
|
||||||
|
|
||||||
import Test.Hspec.Wai
|
|
||||||
|
|
||||||
import Protolude
|
import Protolude
|
||||||
import SpecHelper
|
import SpecHelper
|
||||||
|
|
||||||
spec :: SpecWith Application
|
spec :: SpecWith Application
|
||||||
spec =
|
spec =
|
||||||
describe "GET / with proxy" $
|
describe "GET / with proxy" $
|
||||||
it "returns a valid openapi spec with proxy" $ do
|
it "returns a valid openapi spec with proxy" $
|
||||||
pendingWith "Test timing out frequently on CI, please run locally"
|
|
||||||
validateOpenApiResponse [("Accept", "application/openapi+json")]
|
validateOpenApiResponse [("Accept", "application/openapi+json")]
|
||||||
|
|||||||
@@ -21,8 +21,7 @@ spec :: SpecWith Application
|
|||||||
spec = do
|
spec = do
|
||||||
|
|
||||||
describe "OpenAPI" $ do
|
describe "OpenAPI" $ do
|
||||||
it "root path returns a valid openapi spec" $ do
|
it "root path returns a valid openapi spec" $
|
||||||
pendingWith "Test timing out frequently on CI, please run locally"
|
|
||||||
validateOpenApiResponse [("Accept", "application/openapi+json")]
|
validateOpenApiResponse [("Accept", "application/openapi+json")]
|
||||||
|
|
||||||
it "should respond to openapi request on none root path with 415" $
|
it "should respond to openapi request on none root path with 415" $
|
||||||
|
|||||||
+15
-14
@@ -5,14 +5,12 @@ import qualified Data.ByteString.Char8 as BS
|
|||||||
import qualified Data.ByteString.Lazy as BL
|
import qualified Data.ByteString.Lazy as BL
|
||||||
import qualified Data.Map.Strict as M
|
import qualified Data.Map.Strict as M
|
||||||
import qualified Data.Set as S
|
import qualified Data.Set as S
|
||||||
import qualified JSONSchema.Draft4 as D4
|
|
||||||
import qualified System.IO.Error as E
|
import qualified System.IO.Error as E
|
||||||
|
|
||||||
import Control.Monad (void)
|
import Control.Monad (void)
|
||||||
import Data.Aeson (Value (..), decode)
|
import Data.Aeson (Value (..), decode, encode)
|
||||||
import Data.CaseInsensitive (CI (..))
|
import Data.CaseInsensitive (CI (..))
|
||||||
import Data.List (lookup)
|
import Data.List (lookup)
|
||||||
import Data.Maybe (fromJust)
|
|
||||||
import Network.Wai.Test (SResponse (simpleBody, simpleHeaders, simpleStatus))
|
import Network.Wai.Test (SResponse (simpleBody, simpleHeaders, simpleStatus))
|
||||||
import System.Environment (getEnv)
|
import System.Environment (getEnv)
|
||||||
import System.Process (readProcess)
|
import System.Process (readProcess)
|
||||||
@@ -45,17 +43,19 @@ validateOpenApiResponse headers = do
|
|||||||
let respHeaders = simpleHeaders r in
|
let respHeaders = simpleHeaders r in
|
||||||
respHeaders `shouldSatisfy`
|
respHeaders `shouldSatisfy`
|
||||||
\hs -> ("Content-Type", "application/openapi+json; charset=utf-8") `elem` hs
|
\hs -> ("Content-Type", "application/openapi+json; charset=utf-8") `elem` hs
|
||||||
liftIO $
|
let Just body = decode (simpleBody r)
|
||||||
let respBody = simpleBody r
|
Just schema <- liftIO $ decode <$> BL.readFile "test/fixtures/openapi.json"
|
||||||
schema :: D4.Schema
|
let args :: M.Map Text Value
|
||||||
schema = D4.emptySchema { D4._schemaRef = Just "openapi.json" }
|
args = M.fromList
|
||||||
schemaContext :: D4.SchemaWithURI D4.Schema
|
[ ( "schema", schema )
|
||||||
schemaContext = D4.SchemaWithURI
|
, ( "data", body ) ]
|
||||||
{ D4._swSchema = schema
|
hdrs = acceptHdrs "application/json"
|
||||||
, D4._swURI = Just "test/fixtures/openapi.json"
|
request methodPost "/rpc/validate_json_schema" hdrs (encode args)
|
||||||
}
|
`shouldRespondWith` "true"
|
||||||
in
|
{ matchStatus = 200
|
||||||
D4.fetchFilesystemAndValidate schemaContext ((fromJust . decode) respBody) `shouldReturn` Right ()
|
, matchHeaders = []
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
getEnvVarWithDefault :: Text -> Text -> IO Text
|
getEnvVarWithDefault :: Text -> Text -> IO Text
|
||||||
getEnvVarWithDefault var def = toS <$>
|
getEnvVarWithDefault var def = toS <$>
|
||||||
@@ -130,6 +130,7 @@ setupDb dbConn = do
|
|||||||
loadFixture dbConn "roles"
|
loadFixture dbConn "roles"
|
||||||
loadFixture dbConn "schema"
|
loadFixture dbConn "schema"
|
||||||
loadFixture dbConn "jwt"
|
loadFixture dbConn "jwt"
|
||||||
|
loadFixture dbConn "jsonschema"
|
||||||
loadFixture dbConn "privileges"
|
loadFixture dbConn "privileges"
|
||||||
resetDb dbConn
|
resetDb dbConn
|
||||||
|
|
||||||
|
|||||||
Vendored
+280
@@ -0,0 +1,280 @@
|
|||||||
|
-- from gavinwahl/postgres-json-schema commit 5a257e19a1569a77b82e9182b0b7d9fc8b6f6382
|
||||||
|
|
||||||
|
/*
|
||||||
|
Copyright (c) 2016, Gavin Wahl
|
||||||
|
|
||||||
|
Permission to use, copy, modify, and distribute this software and its
|
||||||
|
documentation for any purpose, without fee, and without a written agreement is
|
||||||
|
hereby granted, provided that the above copyright notice and this paragraph and
|
||||||
|
the following two paragraphs appear in all copies.
|
||||||
|
|
||||||
|
IN NO EVENT SHALL GAVIN WAHL BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT,
|
||||||
|
SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING
|
||||||
|
OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF GAVIN WAHL HAS
|
||||||
|
BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
GAVIN WAHL SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||||
|
TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND GAVIN WAHL
|
||||||
|
HAS NO OBLIGATIONS TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR
|
||||||
|
MODIFICATIONS.
|
||||||
|
*/
|
||||||
|
|
||||||
|
CREATE OR REPLACE FUNCTION _validate_json_schema_type(type text, data jsonb) RETURNS boolean AS $f$
|
||||||
|
BEGIN
|
||||||
|
IF type = 'integer' THEN
|
||||||
|
IF jsonb_typeof(data) != 'number' THEN
|
||||||
|
RETURN false;
|
||||||
|
END IF;
|
||||||
|
IF trunc(data::text::numeric) != data::text::numeric THEN
|
||||||
|
RETURN false;
|
||||||
|
END IF;
|
||||||
|
ELSE
|
||||||
|
IF type != jsonb_typeof(data) THEN
|
||||||
|
RETURN false;
|
||||||
|
END IF;
|
||||||
|
END IF;
|
||||||
|
RETURN true;
|
||||||
|
END;
|
||||||
|
$f$ LANGUAGE 'plpgsql' IMMUTABLE;
|
||||||
|
|
||||||
|
CREATE OR REPLACE FUNCTION test.validate_json_schema(schema jsonb, data jsonb, root_schema jsonb DEFAULT NULL) RETURNS boolean AS $f$
|
||||||
|
DECLARE
|
||||||
|
prop text;
|
||||||
|
item jsonb;
|
||||||
|
path text[];
|
||||||
|
types text[];
|
||||||
|
pattern text;
|
||||||
|
props text[];
|
||||||
|
BEGIN
|
||||||
|
IF root_schema IS NULL THEN
|
||||||
|
root_schema = schema;
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
IF schema ? 'type' THEN
|
||||||
|
IF jsonb_typeof(schema->'type') = 'array' THEN
|
||||||
|
types = ARRAY(SELECT jsonb_array_elements_text(schema->'type'));
|
||||||
|
ELSE
|
||||||
|
types = ARRAY[schema->>'type'];
|
||||||
|
END IF;
|
||||||
|
IF (SELECT NOT bool_or(public._validate_json_schema_type(type, data)) FROM unnest(types) type) THEN
|
||||||
|
RETURN false;
|
||||||
|
END IF;
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
IF schema ? 'properties' THEN
|
||||||
|
FOR prop IN SELECT jsonb_object_keys(schema->'properties') LOOP
|
||||||
|
IF data ? prop AND NOT validate_json_schema(schema->'properties'->prop, data->prop, root_schema) THEN
|
||||||
|
RETURN false;
|
||||||
|
END IF;
|
||||||
|
END LOOP;
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
IF schema ? 'required' AND jsonb_typeof(data) = 'object' THEN
|
||||||
|
IF NOT ARRAY(SELECT jsonb_object_keys(data)) @>
|
||||||
|
ARRAY(SELECT jsonb_array_elements_text(schema->'required')) THEN
|
||||||
|
RETURN false;
|
||||||
|
END IF;
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
IF schema ? 'items' AND jsonb_typeof(data) = 'array' THEN
|
||||||
|
IF jsonb_typeof(schema->'items') = 'object' THEN
|
||||||
|
FOR item IN SELECT jsonb_array_elements(data) LOOP
|
||||||
|
IF NOT validate_json_schema(schema->'items', item, root_schema) THEN
|
||||||
|
RETURN false;
|
||||||
|
END IF;
|
||||||
|
END LOOP;
|
||||||
|
ELSE
|
||||||
|
IF NOT (
|
||||||
|
SELECT bool_and(i > jsonb_array_length(schema->'items') OR validate_json_schema(schema->'items'->(i::int - 1), elem, root_schema))
|
||||||
|
FROM jsonb_array_elements(data) WITH ORDINALITY AS t(elem, i)
|
||||||
|
) THEN
|
||||||
|
RETURN false;
|
||||||
|
END IF;
|
||||||
|
END IF;
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
IF jsonb_typeof(schema->'additionalItems') = 'boolean' and NOT (schema->'additionalItems')::text::boolean AND jsonb_typeof(schema->'items') = 'array' THEN
|
||||||
|
IF jsonb_array_length(data) > jsonb_array_length(schema->'items') THEN
|
||||||
|
RETURN false;
|
||||||
|
END IF;
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
IF jsonb_typeof(schema->'additionalItems') = 'object' THEN
|
||||||
|
IF NOT (
|
||||||
|
SELECT bool_and(validate_json_schema(schema->'additionalItems', elem, root_schema))
|
||||||
|
FROM jsonb_array_elements(data) WITH ORDINALITY AS t(elem, i)
|
||||||
|
WHERE i > jsonb_array_length(schema->'items')
|
||||||
|
) THEN
|
||||||
|
RETURN false;
|
||||||
|
END IF;
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
IF schema ? 'minimum' AND jsonb_typeof(data) = 'number' THEN
|
||||||
|
IF data::text::numeric < (schema->>'minimum')::numeric THEN
|
||||||
|
RETURN false;
|
||||||
|
END IF;
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
IF schema ? 'maximum' AND jsonb_typeof(data) = 'number' THEN
|
||||||
|
IF data::text::numeric > (schema->>'maximum')::numeric THEN
|
||||||
|
RETURN false;
|
||||||
|
END IF;
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
IF COALESCE((schema->'exclusiveMinimum')::text::bool, FALSE) THEN
|
||||||
|
IF data::text::numeric = (schema->>'minimum')::numeric THEN
|
||||||
|
RETURN false;
|
||||||
|
END IF;
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
IF COALESCE((schema->'exclusiveMaximum')::text::bool, FALSE) THEN
|
||||||
|
IF data::text::numeric = (schema->>'maximum')::numeric THEN
|
||||||
|
RETURN false;
|
||||||
|
END IF;
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
IF schema ? 'anyOf' THEN
|
||||||
|
IF NOT (SELECT bool_or(validate_json_schema(sub_schema, data, root_schema)) FROM jsonb_array_elements(schema->'anyOf') sub_schema) THEN
|
||||||
|
RETURN false;
|
||||||
|
END IF;
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
IF schema ? 'allOf' THEN
|
||||||
|
IF NOT (SELECT bool_and(validate_json_schema(sub_schema, data, root_schema)) FROM jsonb_array_elements(schema->'allOf') sub_schema) THEN
|
||||||
|
RETURN false;
|
||||||
|
END IF;
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
IF schema ? 'oneOf' THEN
|
||||||
|
IF 1 != (SELECT COUNT(*) FROM jsonb_array_elements(schema->'oneOf') sub_schema WHERE validate_json_schema(sub_schema, data, root_schema)) THEN
|
||||||
|
RETURN false;
|
||||||
|
END IF;
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
IF COALESCE((schema->'uniqueItems')::text::boolean, false) THEN
|
||||||
|
IF (SELECT COUNT(*) FROM jsonb_array_elements(data)) != (SELECT count(DISTINCT val) FROM jsonb_array_elements(data) val) THEN
|
||||||
|
RETURN false;
|
||||||
|
END IF;
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
IF schema ? 'additionalProperties' AND jsonb_typeof(data) = 'object' THEN
|
||||||
|
props := ARRAY(
|
||||||
|
SELECT key
|
||||||
|
FROM jsonb_object_keys(data) key
|
||||||
|
WHERE key NOT IN (SELECT jsonb_object_keys(schema->'properties'))
|
||||||
|
AND NOT EXISTS (SELECT * FROM jsonb_object_keys(schema->'patternProperties') pat WHERE key ~ pat)
|
||||||
|
);
|
||||||
|
IF jsonb_typeof(schema->'additionalProperties') = 'boolean' THEN
|
||||||
|
IF NOT (schema->'additionalProperties')::text::boolean AND jsonb_typeof(data) = 'object' AND NOT props <@ ARRAY(SELECT jsonb_object_keys(schema->'properties')) THEN
|
||||||
|
RETURN false;
|
||||||
|
END IF;
|
||||||
|
ELSEIF NOT (
|
||||||
|
SELECT bool_and(validate_json_schema(schema->'additionalProperties', data->key, root_schema))
|
||||||
|
FROM unnest(props) key
|
||||||
|
) THEN
|
||||||
|
RETURN false;
|
||||||
|
END IF;
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
IF schema ? '$ref' THEN
|
||||||
|
path := ARRAY(
|
||||||
|
SELECT regexp_replace(regexp_replace(path_part, '~1', '/'), '~0', '~')
|
||||||
|
FROM UNNEST(regexp_split_to_array(schema->>'$ref', '/')) path_part
|
||||||
|
);
|
||||||
|
-- ASSERT path[1] = '#', 'only refs anchored at the root are supported';
|
||||||
|
IF NOT validate_json_schema(root_schema #> path[2:array_length(path, 1)], data, root_schema) THEN
|
||||||
|
RETURN false;
|
||||||
|
END IF;
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
IF schema ? 'enum' THEN
|
||||||
|
IF NOT EXISTS (SELECT * FROM jsonb_array_elements(schema->'enum') val WHERE val = data) THEN
|
||||||
|
RETURN false;
|
||||||
|
END IF;
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
IF schema ? 'minLength' AND jsonb_typeof(data) = 'string' THEN
|
||||||
|
IF char_length(data #>> '{}') < (schema->>'minLength')::numeric THEN
|
||||||
|
RETURN false;
|
||||||
|
END IF;
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
IF schema ? 'maxLength' AND jsonb_typeof(data) = 'string' THEN
|
||||||
|
IF char_length(data #>> '{}') > (schema->>'maxLength')::numeric THEN
|
||||||
|
RETURN false;
|
||||||
|
END IF;
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
IF schema ? 'not' THEN
|
||||||
|
IF validate_json_schema(schema->'not', data, root_schema) THEN
|
||||||
|
RETURN false;
|
||||||
|
END IF;
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
IF schema ? 'maxProperties' AND jsonb_typeof(data) = 'object' THEN
|
||||||
|
IF (SELECT count(*) FROM jsonb_object_keys(data)) > (schema->>'maxProperties')::numeric THEN
|
||||||
|
RETURN false;
|
||||||
|
END IF;
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
IF schema ? 'minProperties' AND jsonb_typeof(data) = 'object' THEN
|
||||||
|
IF (SELECT count(*) FROM jsonb_object_keys(data)) < (schema->>'minProperties')::numeric THEN
|
||||||
|
RETURN false;
|
||||||
|
END IF;
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
IF schema ? 'maxItems' AND jsonb_typeof(data) = 'array' THEN
|
||||||
|
IF (SELECT count(*) FROM jsonb_array_elements(data)) > (schema->>'maxItems')::numeric THEN
|
||||||
|
RETURN false;
|
||||||
|
END IF;
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
IF schema ? 'minItems' AND jsonb_typeof(data) = 'array' THEN
|
||||||
|
IF (SELECT count(*) FROM jsonb_array_elements(data)) < (schema->>'minItems')::numeric THEN
|
||||||
|
RETURN false;
|
||||||
|
END IF;
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
IF schema ? 'dependencies' THEN
|
||||||
|
FOR prop IN SELECT jsonb_object_keys(schema->'dependencies') LOOP
|
||||||
|
IF data ? prop THEN
|
||||||
|
IF jsonb_typeof(schema->'dependencies'->prop) = 'array' THEN
|
||||||
|
IF NOT (SELECT bool_and(data ? dep) FROM jsonb_array_elements_text(schema->'dependencies'->prop) dep) THEN
|
||||||
|
RETURN false;
|
||||||
|
END IF;
|
||||||
|
ELSE
|
||||||
|
IF NOT validate_json_schema(schema->'dependencies'->prop, data, root_schema) THEN
|
||||||
|
RETURN false;
|
||||||
|
END IF;
|
||||||
|
END IF;
|
||||||
|
END IF;
|
||||||
|
END LOOP;
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
IF schema ? 'pattern' AND jsonb_typeof(data) = 'string' THEN
|
||||||
|
IF (data #>> '{}') !~ (schema->>'pattern') THEN
|
||||||
|
RETURN false;
|
||||||
|
END IF;
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
IF schema ? 'patternProperties' AND jsonb_typeof(data) = 'object' THEN
|
||||||
|
FOR prop IN SELECT jsonb_object_keys(data) LOOP
|
||||||
|
FOR pattern IN SELECT jsonb_object_keys(schema->'patternProperties') LOOP
|
||||||
|
RAISE NOTICE 'prop %s, pattern %, schema %', prop, pattern, schema->'patternProperties'->pattern;
|
||||||
|
IF prop ~ pattern AND NOT validate_json_schema(schema->'patternProperties'->pattern, data->prop, root_schema) THEN
|
||||||
|
RETURN false;
|
||||||
|
END IF;
|
||||||
|
END LOOP;
|
||||||
|
END LOOP;
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
IF schema ? 'multipleOf' AND jsonb_typeof(data) = 'number' THEN
|
||||||
|
IF data::text::numeric % (schema->>'multipleOf')::numeric != 0 THEN
|
||||||
|
RETURN false;
|
||||||
|
END IF;
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
RETURN true;
|
||||||
|
END;
|
||||||
|
$f$ LANGUAGE 'plpgsql' IMMUTABLE;
|
||||||
Reference in New Issue
Block a user