24#ifndef MYSQL_SETS_STRCONV_DECODE_H
25#define MYSQL_SETS_STRCONV_DECODE_H
61template <mysql::sets::Is_discrete_set_traits Set_traits_t>
65 using Element_t =
typename Set_traits_t::Element_t;
69 Element_t inclusive_end{};
73 .check_prev_token([&] {
74 if (!Set_traits_t::in_range(
start)) {
75 parser.set_parse_error(
"Interval start out of range");
77 inclusive_end =
start;
80 .literal(
format.m_boundary_separator)
82 .check_prev_token([&] {
83 if (Set_traits_t::ge(inclusive_end, Set_traits_t::max_exclusive()) ||
84 Set_traits_t::lt(Set_traits_t::next(inclusive_end),
85 Set_traits_t::min())) {
86 parser.set_parse_error(
"Interval end out of range");
90 out.
assign(
start, Set_traits_t::next(inclusive_end));
115template <mysql::sets::Is_boundary_container Boundary_container_t>
117 typename Boundary_container_t::Set_traits_t>
120 const std::pair<Boundary_container_t &,
121 typename Boundary_container_t::Iterator_t &> &out) {
122 using Set_traits_t =
typename Boundary_container_t::Set_traits_t;
123 Boundary_container_t &boundary_container = out.first;
124 auto &cursor = out.second;
129 boundary_container.inplace_union(cursor,
interval.start(),
148template <mysql::sets::Is_boundary_container Boundary_container_t>
150 typename Boundary_container_t::Set_traits_t>
153 Boundary_container_t &out) {
157 Boundary_container_t::has_fast_insertion,
158 "Use a boundary container type that supports less-than-linear-time "
159 "insertion operations, such as Map_boundary_container.");
161 auto position = out.begin();
162 std::pair<Boundary_container_t &,
decltype(position) &> interval_cursor(
168 if (
format.m_allow_redundant_separators ==
174 std::size_t min_count =
178 repeated, leading, trailing);
192template <mysql::sets::Is_boundary_container Boundary_container_t>
194 typename Boundary_container_t::Set_traits_t>
197 Boundary_container_t &out) {
198 using Set_traits_t =
typename Boundary_container_t::Set_traits_t;
199 using Element_t =
typename Set_traits_t::Element_t;
200 using Difference_t =
typename Set_traits_t::Difference_t;
204 uint64_t remaining{};
209 if (remaining >
parser.remaining_size()) {
210 parser.set_parse_error(
211 "The value stored in the size field exceeds the number of remaining "
217 if (
parser.read(
format | check_remaining, remaining) != Return_status::ok)
221 auto cursor = out.begin();
227 Element_t next_min = Set_traits_t::next(Set_traits_t::min());
230 Difference_t delta{};
235 parser.set_parse_error(
"Value exceeds maximum");
240 auto read_next = [&](Element_t &element) {
241 if (
parser.read(
format | check_delta, delta) != Return_status::ok)
244 next_min = Set_traits_t::next(element);
245 return Return_status::ok;
249 auto insert = [&](
const Element_t &
start,
const Element_t &exclusive_end) {
251 out.inplace_union(cursor,
start, exclusive_end)));
252 if (ret != Return_status::ok)
parser.set_oom();
258 if ((remaining & 1) == 1) {
259 Element_t exclusive_end{Set_traits_t::min()};
260 if (read_next(exclusive_end) != Return_status::ok)
return;
261 if (
insert(Set_traits_t::min(), exclusive_end) != Return_status::ok)
return;
266 while (remaining != 0) {
268 if (read_next(
start) != Return_status::ok)
return;
269 Element_t exclusive_end;
270 if (read_next(exclusive_end) != Return_status::ok)
return;
271 if (
insert(
start, exclusive_end) != Return_status::ok)
return;
286template <mysql::sets::Is_boundary_container Boundary_container_t>
288 typename Boundary_container_t::Set_traits_t>
291 Boundary_container_t &out) {
292 using Set_traits_t =
typename Boundary_container_t::Set_traits_t;
293 using Element_t =
typename Set_traits_t::Element_t;
297 uint64_t remaining_intervals{};
302 if (remaining_intervals * 8 * 2 >
parser.remaining_size()) {
303 parser.set_parse_error(
304 "The value stored in the size field exceeds the number of values "
305 "that fit in the remaining string");
310 if (
parser.read(
format | check_remaining, remaining_intervals) !=
315 auto cursor = out.begin();
317 Element_t last_value{};
322 auto read_next = [&](Element_t &
value) {
325 if (Set_traits_t::lt(
value, Set_traits_t::min()))
326 parser.set_parse_error(
"Value is less than minimum");
328 if (Set_traits_t::le(
value, last_value))
330 "Value is less than or equal to previous value");
332 if (Set_traits_t::gt(
value, Set_traits_t::max_exclusive()))
333 parser.set_parse_error(
"Value exceeds maximum");
340 return Return_status::ok;
344 auto insert = [&](Element_t
start, Element_t exclusive_end) {
346 out.inplace_union(cursor,
start, exclusive_end)));
347 if (ret != Return_status::ok)
parser.set_oom();
352 while (remaining_intervals) {
354 if (read_next(
start) != Return_status::ok)
return;
355 Element_t exclusive_end;
356 if (read_next(exclusive_end) != Return_status::ok)
return;
357 if (
insert(
start, exclusive_end) != Return_status::ok)
return;
358 --remaining_intervals;
366template <mysql::sets::Is_
interval_container Interval_container_t>
369 Interval_container_t &out) {
380template <mysql::sets::Is_discrete_set_traits Set_traits_t>
390template <mysql::sets::Is_boundary_container Boundary_container_t>
392 typename Boundary_container_t::Set_traits_t>
395 const std::pair<Boundary_container_t &,
396 typename Boundary_container_t::Iterator_t &> &out) {
402template <mysql::sets::Is_boundary_container Boundary_container_t>
404 typename Boundary_container_t::Set_traits_t>
412template <mysql::sets::Is_boundary_container Boundary_container_t>
414 typename Boundary_container_t::Set_traits_t>
416 Boundary_container_t &out) {
422template <mysql::sets::Is_boundary_container Boundary_container_t>
424 typename Boundary_container_t::Set_traits_t>
432template <mysql::sets::Is_
interval_container Interval_container_t>
434 Interval_container_t &out) {
#define DEDUCED_NOEXCEPT_FUNCTION(X)
Helper macro to define a function that returns the result of a single expression, and has a condition...
Definition: call_and_catch.h:151
Holds the start boundary and endpoint boundary of an interval.
Definition: interval.h:140
void assign(const Element_t &start_arg, const Element_t &exclusive_end_arg)
Set both boundaries to the given values, without validating the range.
Definition: interval.h:86
Class holding a checker function, used to check the validity of a parsed value.
Definition: checker.h:57
Object used to parse strings.
Definition: parser.h:69
static Repeat at_least(Int_t min_arg)
Return a Repeat object representing min_arg or more repetitions (bounded only by std::numeric_limits)
Definition: repeat.h:145
True if Test is a "bounded" Set traits class.
Definition: set_traits.h:105
True if Test satisfies both Is_discrete_set_traits and Is_metric_set_traits.
Definition: set_traits.h:151
True if Test is a "discrete" Set traits class, i.e., it bounded, and it is possible to compute succes...
Definition: set_traits.h:119
static void start(mysql_harness::PluginFuncEnv *env)
Definition: http_auth_backend_plugin.cc:180
static const char separator
Definition: item_func.cc:4532
static int interval
Definition: mysqladmin.cc:72
void error(const char *format,...)
Type sub(Shards< COUNT > &shards, size_t id, size_t n)
Decrement the counter for a shard by n.
Definition: ut0counter.h:280
void insert(dd::cache::SPI_lru_cache_owner_ptr &c, dd::Object_id id)
Definition: dictionary_client.cc:3077
ValueType value(const std::optional< ValueType > &v)
Definition: gtid.h:83
void interval_from_text(const Is_format auto &format, mysql::strconv::Parser &parser, mysql::sets::detail::Relaxed_interval< Set_traits_t > &out)
Read an interval into the output Relaxed_interval, checking that the boundaries are in range,...
Definition: decode.h:62
void decode_interval_set(const Is_format auto &format, mysql::strconv::Parser &parser, Interval_container_t &out)
Parse into an interval container, advance the position, and return the status.
Definition: decode.h:367
void boundary_set_from_binary_fixint(const Is_format auto &format, mysql::strconv::Parser &parser, Boundary_container_t &out)
Parse from binary format (with fixed-length integers) into a boundary container.
Definition: decode.h:289
void boundary_set_from_binary(const Is_format auto &format, mysql::strconv::Parser &parser, Boundary_container_t &out)
Parse from binary format (with variable-length integers) into a boundary container.
Definition: decode.h:195
void boundary_set_from_text(const Is_format auto &format, mysql::strconv::Parser &parser, Boundary_container_t &out)
Parse from text format into a boundary container.
Definition: decode.h:151
Definition: gtid_binary_format.h:41
void decode_impl(const Gtid_binary_format &format, Parser &parser, mysql::gtids::Is_tag auto &tag)
Definition: gtid_binary_format_conv.h:63
Return_status
Simple, strongly-typed enumeration to indicate internal status: ok, error.
Definition: return_status.h:40
static mysql_service_status_t add(reference_caching_channel channel, const char *implementation_name) noexcept
Definition: component.cc:127
Tag to identify the formatting algorithm for boundary sets of integrals, and provide the separator st...
Definition: boundary_set_text_format.h:51