MySQL 9.0.0
Source Code Documentation
vector_conversion.h
Go to the documentation of this file.
1/* Copyright (c) 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 VECTOR_CONV_INCLUDED
25#define VECTOR_CONV_INCLUDED
26
27#include <errno.h>
28#include <math.h>
29#include <stddef.h>
30#include <stdint.h>
31#include <stdio.h>
32#include <stdlib.h>
33#include <sys/types.h>
34#include <cstring>
35#include "sql_string.h"
36
37static inline bool from_string_to_vector(const char *input, uint32_t input_len,
38 char *const output,
39 uint32_t *max_output_dims) {
40 if (input == nullptr || input[0] != '[' || input_len == 0 ||
41 input[input_len - 1] != ']') {
42 *max_output_dims = 0;
43 return true;
44 }
45
46 // Check for memory region overlap
47 size_t output_len = sizeof(float) * (*max_output_dims);
48 String temp_output(output, output_len, nullptr);
49 if (output + output_len >= input && input + input_len >= output) {
50 temp_output = String(output_len);
51 }
52
53 const char *const input_end = input + input_len - 1;
54 input = input + 1;
55 uint32_t dim = 0;
56 char *end = nullptr;
57 bool with_success = false;
58 errno = 0;
59 for (float fnum = strtof(input, &end); input != end;
60 fnum = strtof(input, &end)) {
61 input = end;
62 if (errno == ERANGE || dim >= *max_output_dims || std::isnan(fnum) ||
63 std::isinf(fnum)) {
64 errno = 0;
65 break;
66 }
67 memcpy(temp_output.ptr() + dim * sizeof(float), &fnum, sizeof(float));
68
69 if (*input == ',') {
70 input = input + 1;
71 dim++;
72 } else if (*input == ']' && input == input_end) {
73 with_success = true;
74 dim++;
75 break;
76 } else {
77 break;
78 }
79 }
80
81 if (temp_output.ptr() != output) {
82 memcpy(output, temp_output.ptr(), dim * sizeof(float));
83 }
84
85 *max_output_dims = dim;
86 return !with_success;
87}
88
89static inline bool from_vector_to_string(const char *const input,
90 uint32_t input_dims,
91 char *const output,
92 uint32_t *max_output_len) {
93 const uint32_t end_cushion = 12;
94 if (input == nullptr || *max_output_len < end_cushion) {
95 return true;
96 }
97
98 // Check for memory region overlap
99 size_t input_len = input_dims * sizeof(float);
100 String temp_output(output, *max_output_len, nullptr);
101 if (output + *max_output_len >= input && input + input_len >= output) {
102 temp_output = String(*max_output_len);
103 }
104
105 char *write_ptr = temp_output.ptr();
106 uint32_t total_length = 1;
107 write_ptr[0] = '[';
108 write_ptr += 1;
109 for (uint32_t i = 0; i < input_dims; i++) {
110 int remaining_bytes = *max_output_len - total_length;
111 int nchars = 0;
112 if (*max_output_len <= total_length + end_cushion) {
113 nchars = snprintf(write_ptr, remaining_bytes, "...");
114 i = input_dims;
115 } else {
116 char delimiter = (i == input_dims - 1) ? ']' : ',';
117 float input_value = 0;
118 memcpy(&input_value, input + i * sizeof(float), sizeof(float));
119 nchars = snprintf(write_ptr, remaining_bytes, "%.5e%c", input_value,
120 delimiter);
121 if (nchars < 0 || nchars >= remaining_bytes) {
122 return true; /* LCOV_EXCL_LINE */
123 }
124 }
125 write_ptr += nchars;
126 total_length += nchars;
127 }
128
129 if (temp_output.ptr() != output) {
130 memcpy(output, temp_output.ptr(), total_length);
131 }
132
133 *max_output_len = total_length;
134 return false;
135}
136
137static inline uint32_t get_dimensions(const uint32_t length,
138 const uint32_t precision) {
139 if (length == 0 || (length % precision > 0)) {
140 return UINT32_MAX;
141 }
142 return length / precision;
143}
144
145#endif /* VECTOR_CONV_INCLUDED */
Using this class is fraught with peril, and you need to be very careful when doing so.
Definition: sql_string.h:167
const char * ptr() const
Definition: sql_string.h:249
#define UINT32_MAX
Definition: lexyy.cc:86
const char * delimiter
Definition: mysqlslap.cc:160
borrowable::binary::String< true > String
Definition: classic_protocol_binary.h:323
bool length(const dd::Spatial_reference_system *srs, const Geometry *g1, double *length, bool *null) noexcept
Computes the length of linestrings and multilinestrings.
Definition: length.cc:76
Cursor end()
A past-the-end Cursor.
Definition: rules_table_service.cc:192
Our own string classes, used pervasively throughout the executor.
static bool from_vector_to_string(const char *const input, uint32_t input_dims, char *const output, uint32_t *max_output_len)
Definition: vector_conversion.h:89
static uint32_t get_dimensions(const uint32_t length, const uint32_t precision)
Definition: vector_conversion.h:137
static bool from_string_to_vector(const char *input, uint32_t input_len, char *const output, uint32_t *max_output_dims)
Definition: vector_conversion.h:37