8000 WL#15440 MySQL REST Service (MRS) - Umbrella WL · mysql/mysql-server@09a3a38 · GitHub
[go: up one dir, main page]

Skip to content

Commit 09a3a38

Browse files
Andrzej Religadahlerlend
authored andcommitted
WL#15440 MySQL REST Service (MRS) - Umbrella WL
Bug#37697128 Cannot append a sqlstring with escapes left Fixed the FilterObject to properly handle '!' and '?' that it can contain. Change-Id: Ib186a5d7a6009b9d5b857d27c19820cdadcce53d
1 parent 1c05000 commit 09a3a38

File tree

3 files changed

+42
-32
lines changed

3 files changed

+42
-32
lines changed

router/src/mysql_rest_service/include/mrs/database/filter_object_generator.h

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -66,21 +66,21 @@ class FilterObjectGenerator {
6666
private:
6767
void parse(const Document &doc);
6868

69-
std::optional<std::string> parse_simple_operator_object(
69+
std::optional<mysqlrouter::sqlstring> parse_simple_operator_object(
7070
const std::string_view &column_name, Value *value);
71-
std::optional<std::string> parse_complex_operator_object(
71+
std::optional<mysqlrouter::sqlstring> parse_complex_operator_object(
7272
const std::string_view &column_name, Value *value,
7373
const std::string_view &complex_key);
74-
std::optional<std::string> parse_complex_value(
74+
std::optional<mysqlrouter::sqlstring> parse_complex_value(
7575
const std::string_view &column_name, Value *value);
76-
std::optional<std::string> parse_complex_values(
76+
std::optional<mysqlrouter::sqlstring> parse_complex_values(
7777
const std::string_view &column_name, Value *value,
7878
const std::string_view &complex_key);
79-
std::optional<std::string> parse_column_object(
79+
std::optional<mysqlrouter::sqlstring> parse_column_object(
8080
const std::string_view &column_name, Value *value);
81-
std::optional<std::string> parse_direct_value(
81+
std::optional<mysqlrouter::sqlstring> parse_direct_value(
8282
const std::string_view &column_name, Value *value);
83-
std::optional<std::string> parse_match(Value *value);
83+
std::optional<mysqlrouter::sqlstring> parse_match(Value *value);
8484
void parse_orderby_asof_wmember(Object object);
8585
void parse_order(Object object);
8686
void parse_asof(Value *value);

router/src/mysql_rest_service/src/mrs/database/filter_object_generator.cc

Lines changed: 27 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -352,8 +352,9 @@ void FilterObjectGenerator::parse_orderby_asof_wmember(Object object) {
352352
* 2) complexOperatorObject
353353
* 3) columnObject
354354
*/
355-
std::optional<std::string> FilterObjectGenerator::parse_complex_value(
356-
const std::string_view &column_name, Value *value) {
355+
std::optional<mysqlrouter::sqlstring>
356+
FilterObjectGenerator::parse_complex_value(const std::string_view &column_name,
357+
Value *value) {
357358
log_debug("parse_complex_value %s", column_name.data());
358359
if (!value->IsObject()) return {};
359360
if (value->MemberCount() != 1) return {};
@@ -378,7 +379,8 @@ std::optional<std::string> FilterObjectGenerator::parse_complex_value(
378379
* 1) complexKey : [complexValues]
379380
* 2) complexKey : simpleOperatorObject
380381
*/
381-
std::optional<std::string> FilterObjectGenerator::parse_complex_operator_object(
382+
std::optional<mysqlrouter::sqlstring>
383+
FilterObjectGenerator::parse_complex_operator_object(
382384
const std::string_view &column_name, Value *value,
383385
const std::string_view &complex_key) {
384386
log_debug("parse_complex_operator_object, column=%s, operator=%s",
@@ -398,7 +400,8 @@ std::optional<std::string> FilterObjectGenerator::parse_complex_operator_object(
398400
return {};
399401
}
400402

401-
std::optional<std::string> FilterObjectGenerator::parse_simple_operator_object(
403+
std::optional<mysqlrouter::sqlstring>
404+
FilterObjectGenerator::parse_simple_operator_object(
402405
const std::string_view &column_name, Value *object) {
403406
log_debug("parse_simple_operator_object %s", column_name.data());
404407
if (column_name.empty()) return {};
@@ -503,10 +506,11 @@ std::optional<std::string> FilterObjectGenerator::parse_simple_operator_object(
503506
return {};
504507
}
505508

506-
return result.str();
509+
return result;
507510
}
508511

509-
std::optional<std::string> FilterObjectGenerator::parse_match(Value *value) {
512+
std::optional<mysqlrouter::sqlstring> FilterObjectGenerator::parse_match(
513+
Value *value) {
510514
log_debug("parse_complex_match");
511515
if (!value->IsObject())
512516
throw RestError("Match operator, requires JSON object as value.");
@@ -557,7 +561,7 @@ std::optional<std::string> FilterObjectGenerator::parse_match(Value *value) {
557561
mysqlrouter::sqlstring v{"MATCH (!) AGAINST(? ?) "};
558562
v << fields << against_expr->value.GetString() << selected_modifier;
559563

560-
return v.str();
564+
return v;
561565
}
562566

563567
/*
@@ -567,7 +571,7 @@ std::optional<std::string> FilterObjectGenerator::parse_match(Value *value) {
567571
* columnName : date
568572
* columnName : <other types>
569573
*/
570-
std::optional<std::string> FilterObjectGenerator::parse_direct_value(
574+
std::optional<mysqlrouter::sqlstring> FilterObjectGenerator::parse_direct_value(
571575
const std::string_view &column_name, Value *value) {
572576
log_debug("parse_direct_value %s", column_name.data());
573577

@@ -597,14 +601,15 @@ std::optional<std::string> FilterObjectGenerator::parse_direct_value(
597601
throw;
598602
}
599603

600-
return result.str();
604+
return result;
601605
}
602606

603607
/*
604608
* complexValues
605609
* complexValue , complexValues
606610< 1E0A code class="diff-text syntax-highlighted-line">
*/
607-
std::optional<std::string> FilterObjectGenerator::parse_complex_values(
611+
std::optional<mysqlrouter::sqlstring>
612+
FilterObjectGenerator::parse_complex_values(
608613
const std::string_view &column_name, Value *value,
609614
const std::string_view &complex_key) {
610615
log_debug("parse_complex_values %s", column_name.data());
@@ -620,7 +625,7 @@ std::optional<std::string> FilterObjectGenerator::parse_complex_values(
620625
throw RestError("parse_complex_values: array can't be empty");
621626
}
622627

623-
std::string result_str;
628+
mysqlrouter::sqlstring output;
624629
bool first = true;
625630
for (auto &el : helper::json::array_iterator(arr)) {
626631
auto result = parse_complex_value(column_name, &el);
@@ -629,15 +634,19 @@ std::optional<std::string> FilterObjectGenerator::parse_complex_values(
629634
}
630635

631636
if (!first) {
632-
result_str += " " + sql_operator + " ";
637+
output.append_preformatted(" ");
638+
output.append_preformatted(sql_operator.c_str());
639+
output.append_preformatted(" ");
633640
} else {
634641
first = false;
635642
}
636643

637-
result_str += "(" + *result + ")";
644+
output.append_preformatted("(");
645+
output.append_preformatted(*result);
646+
output.append_preformatted(")");
638647
}
639648

640-
return result_str;
649+
return output;
641650
}
642651

643652
namespace {
@@ -669,8 +678,9 @@ bool is_valid_column_name(const std::string_view &str) {
669678
* 3) columnName : complexOperatorObject
670679
* 4) columnName : [complexValues]
671680
*/
672-
std::optional<std::string> FilterObjectGenerator::parse_column_object(
673-
const std::string_view &column_name, Value *value) {
681+
std::optional<mysqlrouter::sqlstring>
682+
FilterObjectGenerator::parse_column_object(const std::string_view &column_name,
683+
Value *value) {
674684
log_debug("parse_column_object %s", column_name.data());
675685
if (!is_valid_column_name(column_name)) return {};
676686

@@ -725,7 +735,7 @@ bool FilterObjectGenerator::parse_wmember(const std::string_view &name,
725735

726736
if (result) {
727737
where_.append_preformatted("(")
728-
.append_preformatted((*result).c_str())
738+
.append_preformatted(*result)
729739
.append_preformatted(")");
730740
return true;
731741
}

router/src/mysql_rest_service/tests/test_mrs_database_filter_object_generator.cc

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -117,8 +117,8 @@ TEST_F(FilterObjectsTest, match_field_by_int_value) {
117117
}
118118

119119
TEST_F(FilterObjectsTest, match_field_by_string_value) {
120-
sut_.parse(R"({"f1": "abc123"})");
121-
ASSERT_EQ("(`f1`='abc123')", sut_.get_result().str());
120+
sut_.parse(R"({"f1": "abc123!"})");
121+
ASSERT_EQ("(`f1`='abc123!')", sut_.get_result().str());
122122
}
123123

124124
TEST_F(FilterObjectsTest, match_field_by_binary_value) {
@@ -134,8 +134,8 @@ TEST_F(FilterObjectsTest, match_field_by_binary_value) {
134134
}
135135

136136
TEST_F(FilterObjectsTest, match_fields) {
137-
sut_.parse(R"({"f1":"abc123", "f2":10})");
138-
ASSERT_EQ("(`f1`='abc123') AND (`f2`=10)", sut_.get_result().str());
137+
sut_.parse(R"({"f1":"abc123!", "f2":10})");
138+
ASSERT_EQ("(`f1`='abc123!') AND (`f2`=10)", sut_.get_result().str());
139139
}
140140

141141
TEST_F(FilterObjectsTest, match_field_simple_operator_equal) {
@@ -210,8 +210,8 @@ TEST_F(FilterObjectsTest, match_expression_without_modifiers) {
210210
EXPECT_EQ("(MATCH (`c1`) AGAINST('q1' ) )", sut_.get_result().str());
211211

212212
sut_.parse(
213-
R"({"$match":{"$params":["c1", "c2"], "$against":{"$expr":"q1"}}})");
214-
EXPECT_EQ("(MATCH (`c1`,`c2`) AGAINST('q1' ) )", sut_.get_result().str());
213+
R"({"$match":{"$params":["c1", "c2"], "$against":{"$expr":"q1!"}}})");
214+
EXPECT_EQ("(MATCH (`c1`,`c2`) AGAINST('q1!' ) )", sut_.get_result().str());
215215
}
216216

217217
TEST_F(FilterObjectsTest, match_expression_invalid_modifier) {
@@ -250,8 +250,8 @@ TEST_F(FilterObjectsTest, match_expression_with_modifier) {
250250

251251
TEST_F(FilterObjectsTest, complex_and_two_columns) {
252252
sut_.parse(
253-
R"({"$and": [{"SALARY":{"$gt": 1000}}, {"ENAME":{"$like":"S%"}}]})");
254-
ASSERT_EQ("((`SALARY` > 1000) AND (`ENAME` like 'S%'))",
253+
R"({"$and": [{"SALARY":{"$gt": 1000}}, {"ENAME":{"$like":"!S?%"}}]})");
254+
ASSERT_EQ("((`SALARY` > 1000) AND (`ENAME` like '!S?%'))",
255255
sut_.get_result().str());
256256
}
257257

0 commit comments

Comments
 (0)
0