Skip to content

Commit 023f91a

Browse files
author
Catalin Besleaga
committed
Bug#36288405 Add workers for JSON_SCHEMA_VALID to the JSON client library
Moved json_schema.{h,cc} to sql-common and replaced the calls to my_error with callback functions in order to be able to export it to the JSON client library, hid the calls to rapidjson behind a struct(PIMPL). Change-Id: I62eb63ca68a3725f66a7c0619a4b8d11048af620
1 parent 4ad86d2 commit 023f91a

File tree

9 files changed

+292
-147
lines changed

9 files changed

+292
-147
lines changed

client/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,7 @@ ADD_CONVENIENCE_LIBRARY(json_client_library
135135
${CMAKE_SOURCE_DIR}/sql-common/json_binary.cc
136136
${CMAKE_SOURCE_DIR}/sql-common/json_dom.cc
137137
${CMAKE_SOURCE_DIR}/sql-common/json_path.cc
138+
${CMAKE_SOURCE_DIR}/sql-common/json_schema.cc
138139
${CMAKE_SOURCE_DIR}/sql-common/json_syntax_check.cc
139140
${CMAKE_SOURCE_DIR}/sql-common/sql_string.cc
140141

client/json_client_library_main.cc

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
#include "sql-common/json_dom.h"
4444
#include "sql-common/json_error_handler.h"
4545
#include "sql-common/json_path.h"
46+
#include "sql-common/json_schema.h"
4647
#include "sql-common/my_decimal.h"
4748
#include "sql_string.h"
4849
#include "template_utils.h"
@@ -65,6 +66,16 @@ class CoutSerializationErrorHandler : public JsonSerializationErrorHandler {
6566
}
6667
};
6768

69+
class CoutJsonSchemaDefaultErrorHandler final : public JsonSchemaErrorHandler {
70+
public:
71+
void InvalidJsonText(size_t, const char *, size_t) const override {
72+
std::cout << "Invalid JSON text";
73+
}
74+
void InvalidJsonType() const override { std::cout << "Invalid JSON type"; }
75+
void HandleStdExceptions() const override { std::cout << "Std exception"; }
76+
void NotSupported() const override { std::cout << "Not supported "; }
77+
};
78+
6879
} // namespace
6980

7081
int main() {
@@ -316,6 +327,47 @@ int main() {
316327
std::cout << "9.6. 2023-12-11 09:23:00.360900 is" << (res ? " NOT " : " ")
317328
<< "a valid TIME \n";
318329
}
330+
{
331+
const std::string json_schema{
332+
"{"
333+
"\"type\": \"object\","
334+
" \"properties\": {"
335+
" \"a_string\": {"
336+
" \"type\": \"string\","
337+
" \"pattern\": \"^[5-9]$\""
338+
" }"
339+
" }"
340+
"}"};
341+
const std::string valid_doc{"{ \"a_string\": \"8\" }"};
342+
const std::string invalid_doc{"{ \"a_string\": \"a8\" }"};
343+
344+
bool is_valid{false};
345+
Json_schema_validation_report report;
346+
const CoutJsonSchemaDefaultErrorHandler error_handler;
347+
348+
if (is_valid_json_schema(valid_doc.c_str(), valid_doc.length(),
349+
json_schema.c_str(), json_schema.length(),
350+
error_handler, CoutDefaultDepthHandler,
351+
&is_valid, &report)) {
352+
std::cout << "ERROR";
353+
assert(false);
354+
}
355+
if (!is_valid) {
356+
std::cout << "ERROR";
357+
assert(false);
358+
}
359+
360+
if (is_valid_json_schema(invalid_doc.c_str(), invalid_doc.length(),
361+
json_schema.c_str(), json_schema.length(),
362+
error_handler, CoutDefaultDepthHandler,
363+
&is_valid, &report)) {
364+
std::cout << "ERROR";
365+
assert(false);
366+
}
367+
if (!is_valid) {
368+
std::cout << "10.1 " << report.human_readable_reason() << "\n";
369+
}
370+
}
319371
}
320372

321373
return 0;

sql-common/json_error_handler.cc

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
#include "sql/sql_class.h"
3232
#include "sql/sql_const.h"
3333
#include "sql/sql_error.h"
34+
#include "sql/sql_exception_handler.h"
3435

3536
void JsonParseDefaultErrorHandler::operator()(const char *parse_err,
3637
size_t err_offset) const {
@@ -87,4 +88,22 @@ void JsonCoercionDeprecatedDefaultHandler::operator()(
8788
MYSQL_TIME_STATUS &status) const {
8889
check_deprecated_datetime_format(current_thd, &my_charset_utf8mb4_bin,
8990
status);
91+
}
92+
void JsonSchemaDefaultErrorHandler::InvalidJsonText(size_t arg_no,
93+
const char *wrong_string,
94+
size_t offset) const {
95+
my_error(ER_INVALID_JSON_TEXT_IN_PARAM, MYF(0), arg_no,
96+
m_calling_function_name, wrong_string, offset, "");
97+
}
98+
99+
void JsonSchemaDefaultErrorHandler::NotSupported() const {
100+
my_error(ER_NOT_SUPPORTED_YET, MYF(0), "references in JSON Schema");
101+
}
102+
103+
void JsonSchemaDefaultErrorHandler::HandleStdExceptions() const {
104+
handle_std_exception(m_calling_function_name);
105+
}
106+
107+
void JsonSchemaDefaultErrorHandler::InvalidJsonType() const {
108+
my_error(ER_INVALID_JSON_TYPE, MYF(0), 1, m_calling_function_name, "object");
90109
}

sql-common/json_error_handler.h

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,25 @@ class JsonSerializationErrorHandler {
7272
virtual bool CheckStack() const = 0;
7373
};
7474

75+
/**
76+
Error handler to be used when parsing JSON schemas and validating JSON
77+
objects using a JSON schema.
78+
*/
79+
class JsonSchemaErrorHandler {
80+
public:
81+
virtual ~JsonSchemaErrorHandler() = default;
82+
/// Called when an invalid JSON value is encountered.
83+
virtual void InvalidJsonText(size_t arg_no, const char *wrong_string,
84+
size_t offset) const = 0;
85+
/// Called if the provided JSON is not a JSON object.
86+
virtual void InvalidJsonType() const = 0;
87+
/// Called if a std exception is thrown
88+
virtual void HandleStdExceptions() const = 0;
89+
/// Called if a schema reference is encountered in the JSON document as
90+
/// MySQL does not support such constructs.
91+
virtual void NotSupported() const = 0;
92+
};
93+
7594
#ifdef MYSQL_SERVER
7695

7796
class JsonParseDefaultErrorHandler {
@@ -107,6 +126,25 @@ class JsonSerializationDefaultErrorHandler final
107126
const THD *m_thd;
108127
};
109128

129+
/**
130+
The default error handler to be used when parsing JSON schemas and
131+
validating JSON objects using a JSON schema inside the MySQL server.
132+
*/
133+
class JsonSchemaDefaultErrorHandler final : public JsonSchemaErrorHandler {
134+
public:
135+
explicit JsonSchemaDefaultErrorHandler(const char *function_name)
136+
: m_calling_function_name(function_name) {}
137+
void InvalidJsonText(size_t arg_no, const char *wrong_string,
138+
size_t offset) const override;
139+
void InvalidJsonType() const override;
140+
virtual void HandleStdExceptions() const override;
141+
virtual void NotSupported() const override;
142+
143+
private:
144+
/// Used for error reporting and holds the name of the function.
145+
const char *m_calling_function_name;
146+
};
147+
110148
/// Callback function called when a coercion error occurs. It reports the
111149
/// error as ERROR
112150
class JsonCoercionErrorHandler {

0 commit comments

Comments
 (0)