MySQL 8.4.0
Source Code Documentation
json_schema.h
Go to the documentation of this file.
1/* Copyright (c) 2018, 2024, Oracle and/or its affiliates.
2
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License, version 2.0,
5 as published by the Free Software Foundation.
6
7 This program is designed to work with certain software (including
8 but not limited to OpenSSL) that is licensed under separate terms,
9 as designated in a particular file or component or in included license
10 documentation. The authors of MySQL hereby grant you an additional
11 permission to link the program and your derivative works with the
12 separately licensed software that they have either included with
13 the program or referenced in the documentation.
14
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License, version 2.0, for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
23
24#ifndef SQL_JSON_SCHEMA_H_INCLUDED
25#define SQL_JSON_SCHEMA_H_INCLUDED
26
27/**
28 @file json_schema.h
29
30 Functions for validating a string against a JSON Schema
31
32 A JSON Schema is a way to describe the structure of a JSON document. The JSON
33 Schema is a JSON document in itself, and allows you to define required
34 names/attributes, data types etc. As an example, here is a minimal example of
35 a JSON Schema describing that the JSON document MUST be an object:
36
37 {
38 "type": "object"
39 }
40
41 If the JSON document to be validated is anything else than an object (array,
42 scalar), the validation will fail.
43
44 This file contains one class for validation JSON documents against a cached
45 JSON Schema, and free functions for validation any string input against a
46 (unparsed) JSON Schema. We use the rapidjson library to do the actual
47 validation with the following notable behaviors:
48
49 1) Remote references are not supported. If the user provides a JSON Schema
50 with a remote reference, an error will be raised.
51 2) JSON Schema supports regex patterns, and we use std::regex as the regex
52 engine. If an invalid regex pattern is provided in the JSON Schema, the
53 regex pattern will be silently ignored.
54 3) rapidjson currently supports JSON Schema draft-v4, while there are newer
55 versions available (as of writing, draft-v7 is the latest version).
56 */
57
58#include "my_rapidjson_size_t.h" // IWYU pragma: keep
59
60#include <rapidjson/schema.h>
61#include <cstddef>
62#include <string>
63
64#include "my_alloc.h"
65
66struct MEM_ROOT;
67
68/**
69 Json_schema_validation_report contains a more detailed report about a failed
70 JSON Schema validation. It's mainly used by the function
71 JSON_SCHEMA_VALIDATION_REPORT to print out a more detailed report to the user.
72*/
74 public:
75 /// @returns a human readable reason why the validation failed
76 std::string human_readable_reason() const;
77
78 /**
79 @returns a JSON pointer in URI format, pointing to where in the JSON
80 Schema the validation failed
81 */
82 const std::string &schema_location() const { return m_schema_location; }
83
84 /**
85 @returns a string describing the name of the JSON Schema keyword that
86 failed validation
87 */
88 const std::string &schema_failed_keyword() const {
90 }
91
92 /**
93 @returns a JSON pointer in URI format, pointing to where in the JSON
94 document the validation failed
95 */
96 const std::string &document_location() const { return m_document_location; }
97
98 /**
99 Populates the object with validation information.
100
101 @param schema_location a JSON pointer in URI format, pointing to where in
102 the JSON Schema the validation failed
103 @param schema_failed_keyword a string describing the name of the JSON Schema
104 keyword that failed validation
105 @param document_location a JSON pointer in URI format, pointing to where in
106 the JSON document the validation failed
107 */
109 const char *schema_failed_keyword,
110 std::string &&document_location) {
114 }
115
116 private:
117 std::string m_schema_location;
120};
121
122/**
123 Json_schema_validator is an object that contains a JSON Schema that can
124 be re-used multiple times. This is useful in the cases where we have a JSON
125 Schema that doesn't change (which should be quite often).
126*/
128 public:
129 /**
130 Construct the cached JSON Schema with the provided JSON document
131
132 @param schema_document A JSON document that contains the JSON Schema
133 definition
134 */
135 Json_schema_validator(const rapidjson::Document &schema_document);
136
137 /**
138 Validate a JSON input against the cached JSON Schema
139
140 @param document_str A pointer to the JSON input
141 @param document_length The length of the JSON input
142 @param function_name The function name of the caller (to be used in error
143 reporting)
144 @param[out] is_valid The result of the validation
145 @param[out] report A structure containing a detailed report from the
146 validation. Is only populated if is_valid is set to
147 "false" Can be nullptr if a detailed report isn't needed.
148
149 @retval true on error (my_error has been called)
150 @retval false on success (validation result can be found in the output
151 parameter is_valid)
152 */
153 bool is_valid_json_schema(const char *document_str, size_t document_length,
154 const char *function_name, bool *is_valid,
155 Json_schema_validation_report *report) const;
156
157 private:
158 /**
159 This object acts as a handler/callback for the JSON schema validator and is
160 called whenever a schema reference is encountered in the JSON document. Since
161 MySQL doesn't support schema references, this class is only used to detect
162 whether or not we actually found one in the JSON document.
163 */
165 : public rapidjson::IRemoteSchemaDocumentProvider {
166 public:
167 using rapidjson::IRemoteSchemaDocumentProvider::GetRemoteDocument;
168
169 const rapidjson::SchemaDocument *GetRemoteDocument(
170 const char *, rapidjson::SizeType) override {
171 m_used = true;
172 return nullptr;
173 }
174
175 bool used() const { return m_used; }
176
177 private:
178 bool m_used{false};
179 };
180
182 rapidjson::SchemaDocument m_cached_schema;
183};
184
185/**
186 This function will validate a JSON document against a JSON Schema using the
187 validation provided by rapidjson.
188
189 @param document_str A pointer to the JSON document to be validated.
190 @param document_length The length of the JSON document to be validated.
191 @param json_schema_str A pointer to the JSON Schema.
192 @param json_schema_length The length of the JSON Schema.
193 @param function_name The name of the SQL function calling this function. Used
194 in error reporting.
195 @param[out] is_valid A variable containing the result of the validation. If
196 true, the JSON document is valid according to the given
197 JSON Schema.
198 @param[out] report A structure containing a detailed report from the
199 validation. Is only populated if is_valid is set to
200 "false". Can be nullptr if a detailed report isn't needed.
201
202 @retval true if anything went wrong (like parsing the JSON inputs). my_error
203 has been called with an appropriate error message.
204 @retval false if the validation succeeded. The result of the validation can be
205 found in the output variable "is_valid".
206*/
207bool is_valid_json_schema(const char *document_str, size_t document_length,
208 const char *json_schema_str,
209 size_t json_schema_length, const char *function_name,
210 bool *is_valid,
212
213/**
214 Create a Json_schema_validator, allocated on a given MEM_ROOT
215
216 @param mem_root The MEM_ROOT to allocate the validator on
217 @param json_schema_str A pointer to the JSON Schema
218 @param json_schema_length The length of the JSON Schema input
219 @param function_name The function name of the caller (to be used in error
220 reporting)
221
222 @retval nullptr on error (my_error has been called)
223*/
225create_json_schema_validator(MEM_ROOT *mem_root, const char *json_schema_str,
226 size_t json_schema_length,
227 const char *function_name);
228
229#endif
Json_schema_validation_report contains a more detailed report about a failed JSON Schema validation.
Definition: json_schema.h:73
const std::string & schema_location() const
Definition: json_schema.h:82
const std::string & document_location() const
Definition: json_schema.h:96
std::string m_schema_location
Definition: json_schema.h:117
std::string human_readable_reason() const
Definition: json_schema.cc:212
const std::string & schema_failed_keyword() const
Definition: json_schema.h:88
std::string m_document_location
Definition: json_schema.h:119
void set_error_report(std::string &&schema_location, const char *schema_failed_keyword, std::string &&document_location)
Populates the object with validation information.
Definition: json_schema.h:108
std::string m_schema_failed_keyword
Definition: json_schema.h:118
This object acts as a handler/callback for the JSON schema validator and is called whenever a schema ...
Definition: json_schema.h:165
bool used() const
Definition: json_schema.h:175
const rapidjson::SchemaDocument * GetRemoteDocument(const char *, rapidjson::SizeType) override
Definition: json_schema.h:169
Json_schema_validator is an object that contains a JSON Schema that can be re-used multiple times.
Definition: json_schema.h:127
bool is_valid_json_schema(const char *document_str, size_t document_length, const char *function_name, bool *is_valid, Json_schema_validation_report *report) const
Validate a JSON input against the cached JSON Schema.
Definition: json_schema.cc:132
Json_schema_validator(const rapidjson::Document &schema_document)
Construct the cached JSON Schema with the provided JSON document.
Definition: json_schema.cc:113
rapidjson::SchemaDocument m_cached_schema
Definition: json_schema.h:182
My_remote_schema_document_provider m_remote_document_provider
Definition: json_schema.h:181
static MEM_ROOT mem_root
Definition: client_plugin.cc:114
bool is_valid_json_schema(const char *document_str, size_t document_length, const char *json_schema_str, size_t json_schema_length, const char *function_name, bool *is_valid, Json_schema_validation_report *report)
This function will validate a JSON document against a JSON Schema using the validation provided by ra...
Definition: json_schema.cc:97
unique_ptr_destroy_only< const Json_schema_validator > create_json_schema_validator(MEM_ROOT *mem_root, const char *json_schema_str, size_t json_schema_length, const char *function_name)
Create a Json_schema_validator, allocated on a given MEM_ROOT.
Definition: json_schema.cc:119
This file follows Google coding style, except for the name MEM_ROOT (which is kept for historical rea...
std::unique_ptr< T, Destroy_only< T > > unique_ptr_destroy_only
std::unique_ptr, but only destroying.
Definition: my_alloc.h:477
Define rapidjson::SizeType to be std::size_t.
bool is_valid(const dd::Spatial_reference_system *srs, const Geometry *g, const char *func_name, bool *is_valid) noexcept
Decides if a geometry is valid.
Definition: is_valid.cc:95
typedef::std::size_t SizeType
Definition: my_rapidjson_size_t.h:39
The MEM_ROOT is a simple arena, where allocations are carved out of larger blocks.
Definition: my_alloc.h:83