| 1 | // |
| 2 | // Copyright (c) 2019-2024 Ruben Perez Hidalgo (rubenperez038 at gmail dot com) |
| 3 | // |
| 4 | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
| 5 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
| 6 | // |
| 7 | |
| 8 | #include <boost/mysql/blob_view.hpp> |
| 9 | #include <boost/mysql/column_type.hpp> |
| 10 | #include <boost/mysql/date.hpp> |
| 11 | #include <boost/mysql/datetime.hpp> |
| 12 | #include <boost/mysql/metadata.hpp> |
| 13 | |
| 14 | #include <boost/mysql/impl/internal/protocol/deserialize_binary_field.hpp> |
| 15 | #include <boost/mysql/impl/internal/protocol/serialization.hpp> |
| 16 | |
| 17 | #include <boost/test/unit_test.hpp> |
| 18 | |
| 19 | #include <cstddef> |
| 20 | |
| 21 | #include "operators.hpp" |
| 22 | #include "serialization_test.hpp" |
| 23 | #include "test_common/create_basic.hpp" |
| 24 | #include "test_unit/create_meta.hpp" |
| 25 | |
| 26 | using namespace boost::mysql; |
| 27 | using namespace boost::mysql::test; |
| 28 | using detail::deserialize_errc; |
| 29 | |
| 30 | namespace { |
| 31 | |
| 32 | BOOST_AUTO_TEST_SUITE(test_deserialize_binary_field) |
| 33 | |
| 34 | BOOST_AUTO_TEST_SUITE(success) |
| 35 | |
| 36 | struct success_sample |
| 37 | { |
| 38 | std::string name; |
| 39 | deserialization_buffer from; |
| 40 | field_view expected; |
| 41 | metadata meta; |
| 42 | |
| 43 | template <class T> |
| 44 | success_sample(std::string name, std::vector<std::uint8_t> from, T&& expected_value, metadata meta) |
| 45 | : name(std::move(name)), |
| 46 | from(std::move(from)), |
| 47 | expected(std::forward<T>(expected_value)), |
| 48 | meta(std::move(meta)) |
| 49 | { |
| 50 | } |
| 51 | }; |
| 52 | |
| 53 | void add_string_samples(std::vector<success_sample>& output) |
| 54 | { |
| 55 | output.push_back( |
| 56 | x: success_sample("varchar" , {0x04, 0x74, 0x65, 0x73, 0x74}, "test" , create_meta(type: column_type::varchar)) |
| 57 | ); |
| 58 | output.push_back( |
| 59 | x: success_sample("char" , {0x04, 0x74, 0x65, 0x73, 0x74}, "test" , create_meta(type: column_type::char_)) |
| 60 | ); |
| 61 | output.push_back( |
| 62 | x: success_sample("text" , {0x04, 0x74, 0x65, 0x73, 0x74}, "test" , create_meta(type: column_type::text)) |
| 63 | ); |
| 64 | output.push_back( |
| 65 | x: success_sample("enum" , {0x04, 0x74, 0x65, 0x73, 0x74}, "test" , create_meta(type: column_type::enum_)) |
| 66 | ); |
| 67 | output.push_back( |
| 68 | x: success_sample("set" , {0x04, 0x74, 0x65, 0x73, 0x74}, "test" , create_meta(type: column_type::set)) |
| 69 | ); |
| 70 | output.push_back(x: success_sample("decimal" , {0x02, 0x31, 0x30}, "10" , create_meta(type: column_type::decimal))); |
| 71 | output.push_back(x: success_sample("json" , {0x02, 0x7b, 0x7d}, "{}" , create_meta(type: column_type::json))); |
| 72 | } |
| 73 | |
| 74 | void add_blob_samples(std::vector<success_sample>& output) |
| 75 | { |
| 76 | static constexpr std::uint8_t buff[] = {0x01, 0x00, 0x73, 0x74}; |
| 77 | |
| 78 | output.push_back(x: success_sample( |
| 79 | "varbinary" , |
| 80 | {0x04, 0x01, 0x00, 0x73, 0x74}, |
| 81 | blob_view(buff), |
| 82 | create_meta(type: column_type::varbinary) |
| 83 | )); |
| 84 | output.push_back(x: success_sample( |
| 85 | "binary" , |
| 86 | {0x04, 0x01, 0x00, 0x73, 0x74}, |
| 87 | blob_view(buff), |
| 88 | create_meta(type: column_type::binary) |
| 89 | )); |
| 90 | output.push_back(x: success_sample( |
| 91 | "blob" , |
| 92 | {0x04, 0x01, 0x00, 0x73, 0x74}, |
| 93 | blob_view(buff), |
| 94 | create_meta(type: column_type::blob) |
| 95 | )); |
| 96 | output.push_back(x: success_sample( |
| 97 | "geometry" , |
| 98 | {0x04, 0x01, 0x00, 0x73, 0x74}, |
| 99 | blob_view(buff), |
| 100 | create_meta(type: column_type::geometry) |
| 101 | )); |
| 102 | |
| 103 | // Anything we don't know what it is, we interpret as a blob |
| 104 | output.push_back(x: success_sample( |
| 105 | "unknown_protocol_type" , |
| 106 | {0x04, 0x01, 0x00, 0x73, 0x74}, |
| 107 | blob_view(buff), |
| 108 | create_meta(type: column_type::unknown) |
| 109 | )); |
| 110 | } |
| 111 | |
| 112 | // Note: these employ regular integer deserialization functions, which have |
| 113 | // already been tested |
| 114 | void add_int_samples(std::vector<success_sample>& output) |
| 115 | { |
| 116 | output.push_back(x: success_sample( |
| 117 | "tinyint_unsigned" , |
| 118 | {0x14}, |
| 119 | std::uint64_t(20), |
| 120 | meta_builder().type(v: column_type::tinyint).unsigned_flag(v: true).build() |
| 121 | )); |
| 122 | output.push_back( |
| 123 | x: success_sample("tinyint_signed" , {0xec}, std::int64_t(-20), create_meta(type: column_type::tinyint)) |
| 124 | ); |
| 125 | |
| 126 | output.push_back(x: success_sample( |
| 127 | "smallint_unsigned" , |
| 128 | {0x14, 0x00}, |
| 129 | std::uint64_t(20), |
| 130 | meta_builder().type(v: column_type::smallint).unsigned_flag(v: true).build() |
| 131 | )); |
| 132 | output.push_back( |
| 133 | x: success_sample("smallint_signed" , {0xec, 0xff}, std::int64_t(-20), create_meta(type: column_type::smallint)) |
| 134 | ); |
| 135 | |
| 136 | output.push_back(x: success_sample( |
| 137 | "mediumint_unsigned" , |
| 138 | {0x14, 0x00, 0x00, 0x00}, |
| 139 | std::uint64_t(20), |
| 140 | meta_builder().type(v: column_type::mediumint).unsigned_flag(v: true).build() |
| 141 | )); |
| 142 | output.push_back(x: success_sample( |
| 143 | "mediumint_signed" , |
| 144 | {0xec, 0xff, 0xff, 0xff}, |
| 145 | std::int64_t(-20), |
| 146 | create_meta(type: column_type::mediumint) |
| 147 | )); |
| 148 | |
| 149 | output.push_back(x: success_sample( |
| 150 | "int_unsigned" , |
| 151 | {0x14, 0x00, 0x00, 0x00}, |
| 152 | std::uint64_t(20), |
| 153 | meta_builder().type(v: column_type::int_).unsigned_flag(v: true).build() |
| 154 | )); |
| 155 | output.push_back(x: success_sample( |
| 156 | "int_signed" , |
| 157 | {0xec, 0xff, 0xff, 0xff}, |
| 158 | std::int64_t(-20), |
| 159 | create_meta(type: column_type::int_) |
| 160 | )); |
| 161 | |
| 162 | output.push_back(x: success_sample( |
| 163 | "bigint_unsigned" , |
| 164 | {0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, |
| 165 | std::uint64_t(20), |
| 166 | meta_builder().type(v: column_type::bigint).unsigned_flag(v: true).build() |
| 167 | )); |
| 168 | output.push_back(x: success_sample( |
| 169 | "bigint_signed" , |
| 170 | {0xec, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, |
| 171 | std::int64_t(-20), |
| 172 | create_meta(type: column_type::bigint) |
| 173 | )); |
| 174 | |
| 175 | output.push_back(x: success_sample( |
| 176 | "year" , |
| 177 | {0xe3, 0x07}, |
| 178 | std::uint64_t(2019), |
| 179 | meta_builder().type(v: column_type::year).unsigned_flag(v: true).build() |
| 180 | )); |
| 181 | } |
| 182 | |
| 183 | // bit |
| 184 | void add_bit_types(std::vector<success_sample>& output) |
| 185 | { |
| 186 | auto meta = meta_builder().type(v: column_type::bit).unsigned_flag(v: true).build(); |
| 187 | |
| 188 | output.push_back(x: success_sample("bit_8" , {0x01, 0x12}, std::uint64_t(0x12), meta)); |
| 189 | output.push_back(x: success_sample("bit_16" , {0x02, 0x12, 0x34}, std::uint64_t(0x1234), meta)); |
| 190 | output.push_back(x: success_sample("bit_24" , {0x03, 0x12, 0x34, 0x56}, std::uint64_t(0x123456), meta)); |
| 191 | output.push_back(x: success_sample("bit_32" , {0x04, 0x12, 0x34, 0x56, 0x78}, std::uint64_t(0x12345678), meta) |
| 192 | ); |
| 193 | output.push_back( |
| 194 | x: success_sample("bit_40" , {0x05, 0x12, 0x34, 0x56, 0x78, 0x9a}, std::uint64_t(0x123456789a), meta) |
| 195 | ); |
| 196 | output.push_back(x: success_sample( |
| 197 | "bit_48" , |
| 198 | {0x06, 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc}, |
| 199 | std::uint64_t(0x123456789abc), |
| 200 | meta |
| 201 | )); |
| 202 | output.push_back(x: success_sample( |
| 203 | "bit_56" , |
| 204 | {0x07, 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde}, |
| 205 | std::uint64_t(0x123456789abcde), |
| 206 | meta |
| 207 | )); |
| 208 | output.push_back(x: success_sample( |
| 209 | "bit_64" , |
| 210 | {0x08, 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0}, |
| 211 | std::uint64_t(0x123456789abcdef0), |
| 212 | meta |
| 213 | )); |
| 214 | } |
| 215 | |
| 216 | void add_float_samples(std::vector<success_sample>& output) |
| 217 | { |
| 218 | auto meta = create_meta(type: column_type::float_); |
| 219 | output.push_back(x: success_sample("fractional_negative" , {0x66, 0x66, 0x86, 0xc0}, -4.2f, meta)); |
| 220 | output.push_back(x: success_sample("fractional_positive" , {0x66, 0x66, 0x86, 0x40}, 4.2f, meta)); |
| 221 | output.push_back( |
| 222 | x: success_sample("positive_exp_positive_fractional" , {0x01, 0x2d, 0x88, 0x61}, 3.14e20f, meta) |
| 223 | ); |
| 224 | output.push_back(x: success_sample("zero" , {0x00, 0x00, 0x00, 0x00}, 0.0f, meta)); |
| 225 | } |
| 226 | |
| 227 | void add_double_samples(std::vector<success_sample>& output) |
| 228 | { |
| 229 | auto meta = create_meta(type: column_type::double_); |
| 230 | output.push_back( |
| 231 | x: success_sample("fractional_negative" , {0xcd, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x10, 0xc0}, -4.2, meta) |
| 232 | ); |
| 233 | output.push_back( |
| 234 | x: success_sample("fractional_positive" , {0xcd, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x10, 0x40}, 4.2, meta) |
| 235 | ); |
| 236 | output.push_back(x: success_sample( |
| 237 | "positive_exp_positive_fractional" , |
| 238 | {0xce, 0x46, 0x3c, 0x76, 0x9c, 0x68, 0x90, 0x69}, |
| 239 | 3.14e200, |
| 240 | meta |
| 241 | )); |
| 242 | output.push_back(x: success_sample("zero" , {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, 0.0, meta)); |
| 243 | } |
| 244 | |
| 245 | void add_date_samples(std::vector<success_sample>& output) |
| 246 | { |
| 247 | auto meta = create_meta(type: column_type::date); |
| 248 | output.push_back(x: success_sample("regular" , {0x04, 0xda, 0x07, 0x03, 0x1c}, date(2010u, 3u, 28u), meta)); |
| 249 | output.push_back(x: success_sample("min" , {0x04, 0x00, 0x00, 0x01, 0x01}, date(0u, 1u, 1u), meta)); |
| 250 | output.push_back(x: success_sample("max" , {0x04, 0x0f, 0x27, 0x0c, 0x1f}, date(9999u, 12u, 31u), meta)); |
| 251 | output.push_back(x: success_sample("empty" , {0x00}, date(), meta)); |
| 252 | output.push_back(x: success_sample("zero" , {0x04, 0x00, 0x00, 0x00, 0x00}, date(), meta)); |
| 253 | output.push_back(x: success_sample("zero_month" , {0x04, 0xda, 0x07, 0x00, 0x01}, date(2010u, 0u, 1u), meta)); |
| 254 | output.push_back(x: success_sample("zero_day" , {0x04, 0xda, 0x07, 0x01, 0x00}, date(2010u, 1u, 0u), meta)); |
| 255 | output.push_back( |
| 256 | x: success_sample("zero_month_day" , {0x04, 0xda, 0x07, 0x00, 0x00}, date(2010u, 0u, 0u), meta) |
| 257 | ); |
| 258 | output.push_back( |
| 259 | x: success_sample("invalid_date" , {0x04, 0xda, 0x07, 0x0b, 0x1f}, date(2010u, 11u, 31u), meta) |
| 260 | ); |
| 261 | } |
| 262 | |
| 263 | void add_datetime_samples(column_type type, std::vector<success_sample>& output) |
| 264 | { |
| 265 | auto meta = create_meta(type); |
| 266 | output.push_back( |
| 267 | x: success_sample("only_date" , {0x04, 0xda, 0x07, 0x01, 0x01}, datetime(2010u, 1u, 1u), meta) |
| 268 | ); |
| 269 | output.push_back(x: success_sample( |
| 270 | "date_h" , |
| 271 | {0x07, 0xda, 0x07, 0x01, 0x01, 0x14, 0x00, 0x00}, |
| 272 | datetime(2010u, 1u, 1u, 20u, 0u, 0u, 0u), |
| 273 | meta |
| 274 | )); |
| 275 | output.push_back(x: success_sample( |
| 276 | "date_m" , |
| 277 | {0x07, 0xda, 0x07, 0x01, 0x01, 0x00, 0x01, 0x00}, |
| 278 | datetime(2010u, 1u, 1u, 0u, 1u, 0u, 0u), |
| 279 | meta |
| 280 | )); |
| 281 | output.push_back(x: success_sample( |
| 282 | "date_hm" , |
| 283 | {0x07, 0xda, 0x07, 0x01, 0x01, 0x03, 0x02, 0x00}, |
| 284 | datetime(2010u, 1u, 1u, 3u, 2u, 0u, 0u), |
| 285 | meta |
| 286 | )); |
| 287 | output.push_back(x: success_sample( |
| 288 | "date_s" , |
| 289 | {0x07, 0xda, 0x07, 0x01, 0x01, 0x00, 0x00, 0x01}, |
| 290 | datetime(2010u, 1u, 1u, 0u, 0u, 1u, 0u), |
| 291 | meta |
| 292 | )); |
| 293 | output.push_back(x: success_sample( |
| 294 | "date_ms" , |
| 295 | {0x07, 0xda, 0x07, 0x01, 0x01, 0x00, 0x3b, 0x01}, |
| 296 | datetime(2010u, 1u, 1u, 0u, 59u, 1u, 0u), |
| 297 | meta |
| 298 | )); |
| 299 | output.push_back(x: success_sample( |
| 300 | "date_hs" , |
| 301 | {0x07, 0xda, 0x07, 0x01, 0x01, 0x05, 0x00, 0x01}, |
| 302 | datetime(2010u, 1u, 1u, 5u, 0u, 1u, 0u), |
| 303 | meta |
| 304 | )); |
| 305 | output.push_back(x: success_sample( |
| 306 | "date_hms" , |
| 307 | {0x07, 0xda, 0x07, 0x01, 0x01, 0x17, 0x01, 0x3b}, |
| 308 | datetime(2010u, 1u, 1u, 23u, 1u, 59u, 0u), |
| 309 | meta |
| 310 | )); |
| 311 | output.push_back(x: success_sample( |
| 312 | "date_u" , |
| 313 | {0x0b, 0xda, 0x07, 0x01, 0x01, 0x00, 0x00, 0x00, 0x78, 0xd4, 0x03, 0x00}, |
| 314 | datetime(2010u, 1u, 1u, 0u, 0u, 0u, 251000u), |
| 315 | meta |
| 316 | )); |
| 317 | output.push_back(x: success_sample( |
| 318 | "date_hu" , |
| 319 | {0x0b, 0xda, 0x07, 0x01, 0x01, 0x17, 0x00, 0x00, 0x56, 0xc3, 0x0e, 0x00}, |
| 320 | datetime(2010u, 1u, 1u, 23u, 0u, 0u, 967510u), |
| 321 | meta |
| 322 | )); |
| 323 | output.push_back(x: success_sample( |
| 324 | "date_mu" , |
| 325 | {0x0b, 0xda, 0x07, 0x01, 0x01, 0x00, 0x01, 0x00, 0x56, 0xc3, 0x0e, 0x00}, |
| 326 | datetime(2010u, 1u, 1u, 0u, 1u, 0u, 967510u), |
| 327 | meta |
| 328 | )); |
| 329 | output.push_back(x: success_sample( |
| 330 | "date_hmu" , |
| 331 | {0x0b, 0xda, 0x07, 0x01, 0x01, 0x17, 0x01, 0x00, 0x56, 0xc3, 0x0e, 0x00}, |
| 332 | datetime(2010u, 1u, 1u, 23u, 1u, 0u, 967510u), |
| 333 | meta |
| 334 | )); |
| 335 | output.push_back(x: success_sample( |
| 336 | "date_su" , |
| 337 | {0x0b, 0xda, 0x07, 0x01, 0x01, 0x00, 0x00, 0x3b, 0x56, 0xc3, 0x0e, 0x00}, |
| 338 | datetime(2010u, 1u, 1u, 0u, 0u, 59u, 967510u), |
| 339 | meta |
| 340 | )); |
| 341 | output.push_back(x: success_sample( |
| 342 | "date_msu" , |
| 343 | {0x0b, 0xda, 0x07, 0x01, 0x01, 0x00, 0x01, 0x3b, 0x56, 0xc3, 0x0e, 0x00}, |
| 344 | datetime(2010u, 1u, 1u, 0u, 1u, 59u, 967510u), |
| 345 | meta |
| 346 | )); |
| 347 | output.push_back(x: success_sample( |
| 348 | "date_hsu" , |
| 349 | {0x0b, 0xda, 0x07, 0x01, 0x01, 0x17, 0x00, 0x3b, 0x56, 0xc3, 0x0e, 0x00}, |
| 350 | datetime(2010u, 1u, 1u, 23u, 0u, 59u, 967510u), |
| 351 | meta |
| 352 | )); |
| 353 | output.push_back(x: success_sample( |
| 354 | "date_hmsu" , |
| 355 | {0x0b, 0xda, 0x07, 0x01, 0x01, 0x17, 0x01, 0x3b, 0x56, 0xc3, 0x0e, 0x00}, |
| 356 | datetime(2010u, 1u, 1u, 23u, 1u, 59u, 967510u), |
| 357 | meta |
| 358 | )); |
| 359 | |
| 360 | // Invalid datetimes (because their date is invalid) |
| 361 | output.push_back(x: success_sample("empty" , {0x00}, datetime(), meta)); |
| 362 | output.push_back(x: success_sample("only_date_zeros" , {0x04, 0x00, 0x00, 0x00, 0x00}, datetime(), meta)); |
| 363 | output.push_back(x: success_sample( |
| 364 | "only_date_invalid_date" , |
| 365 | {0x04, 0xda, 0x07, 0x0b, 0x1f}, |
| 366 | datetime(2010u, 11u, 31u), |
| 367 | meta |
| 368 | )); |
| 369 | output.push_back( |
| 370 | x: success_sample("only_date_zero_month" , {0x04, 0xda, 0x07, 0x00, 0x01}, datetime(2010u, 0u, 1u), meta) |
| 371 | ); |
| 372 | output.push_back( |
| 373 | x: success_sample("only_date_zero_day" , {0x04, 0xda, 0x07, 0x01, 0x00}, datetime(2010u, 1u, 0u), meta) |
| 374 | ); |
| 375 | output.push_back(x: success_sample( |
| 376 | "only_date_zero_month_day" , |
| 377 | {0x04, 0xda, 0x07, 0x00, 0x00}, |
| 378 | datetime(2010u, 0u, 0u), |
| 379 | meta |
| 380 | )); |
| 381 | |
| 382 | output.push_back( |
| 383 | x: success_sample("date_hms_zeros" , {0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, datetime(), meta) |
| 384 | ); |
| 385 | output.push_back(x: success_sample( |
| 386 | "date_hms_invalid_date" , |
| 387 | {0x07, 0xda, 0x07, 0x0b, 0x1f, 0x17, 0x01, 0x3b}, |
| 388 | datetime(2010u, 11u, 31u, 23u, 1u, 59u), |
| 389 | meta |
| 390 | )); |
| 391 | output.push_back(x: success_sample( |
| 392 | "date_hms_zero_month" , |
| 393 | {0x07, 0xda, 0x07, 0x00, 0x01, 0x17, 0x01, 0x3b}, |
| 394 | datetime(2010u, 0u, 1u, 23u, 1u, 59u), |
| 395 | meta |
| 396 | )); |
| 397 | output.push_back(x: success_sample( |
| 398 | "date_hms_zero_day" , |
| 399 | {0x07, 0xda, 0x07, 0x01, 0x00, 0x17, 0x01, 0x3b}, |
| 400 | datetime(2010u, 1u, 0u, 23u, 1u, 59u), |
| 401 | meta |
| 402 | )); |
| 403 | output.push_back(x: success_sample( |
| 404 | "date_hms_zero_month_day" , |
| 405 | {0x07, 0xda, 0x07, 0x00, 0x00, 0x17, 0x01, 0x3b}, |
| 406 | datetime(2010u, 0u, 0u, 23u, 1u, 59u), |
| 407 | meta |
| 408 | )); |
| 409 | |
| 410 | output.push_back(x: success_sample( |
| 411 | "date_hmsu_zeros" , |
| 412 | {0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, |
| 413 | datetime(), |
| 414 | meta |
| 415 | )); |
| 416 | output.push_back(x: success_sample( |
| 417 | "date_hmsu_invalid_date" , |
| 418 | {0x0b, 0xda, 0x07, 0x0b, 0x1f, 0x17, 0x01, 0x3b, 0x56, 0xc3, 0x0e, 0x00}, |
| 419 | datetime(2010u, 11u, 31u, 23u, 1u, 59u, 967510u), |
| 420 | meta |
| 421 | )); |
| 422 | output.push_back(x: success_sample( |
| 423 | "date_hmsu_zero_month" , |
| 424 | {0x0b, 0xda, 0x07, 0x00, 0x01, 0x17, 0x01, 0x3b, 0x56, 0xc3, 0x0e, 0x00}, |
| 425 | datetime(2010u, 0u, 1u, 23u, 1u, 59u, 967510u), |
| 426 | meta |
| 427 | )); |
| 428 | output.push_back(x: success_sample( |
| 429 | "date_hmsu_zero_day" , |
| 430 | {0x0b, 0xda, 0x07, 0x01, 0x00, 0x17, 0x01, 0x3b, 0x56, 0xc3, 0x0e, 0x00}, |
| 431 | datetime(2010u, 1u, 0u, 23u, 1u, 59u, 967510u), |
| 432 | meta |
| 433 | )); |
| 434 | output.push_back(x: success_sample( |
| 435 | "date_hmsu_zero_month_day" , |
| 436 | {0x0b, 0xda, 0x07, 0x00, 0x00, 0x17, 0x01, 0x3b, 0x56, 0xc3, 0x0e, 0x00}, |
| 437 | datetime(2010u, 0u, 0u, 23u, 1u, 59u, 967510u), |
| 438 | meta |
| 439 | )); |
| 440 | } |
| 441 | |
| 442 | void add_time_samples(std::vector<success_sample>& output) |
| 443 | { |
| 444 | auto meta = create_meta(type: column_type::time); |
| 445 | output.push_back(x: success_sample("zero" , {0x00}, maket(hours: 0, mins: 0, secs: 0), meta)); |
| 446 | output.push_back(x: success_sample( |
| 447 | "positive_d" , |
| 448 | {0x08, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, |
| 449 | maket(hours: 48, mins: 0, secs: 0, micros: 0), |
| 450 | meta |
| 451 | )); |
| 452 | output.push_back(x: success_sample( |
| 453 | "positive_h" , |
| 454 | {0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00}, |
| 455 | maket(hours: 21, mins: 0, secs: 0, micros: 0), |
| 456 | meta |
| 457 | )); |
| 458 | output.push_back(x: success_sample( |
| 459 | "positive_m" , |
| 460 | {0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x00}, |
| 461 | maket(hours: 0, mins: 40, secs: 0), |
| 462 | meta |
| 463 | )); |
| 464 | output.push_back(x: success_sample( |
| 465 | "positive_s" , |
| 466 | {0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15}, |
| 467 | maket(hours: 0, mins: 0, secs: 21), |
| 468 | meta |
| 469 | )); |
| 470 | output.push_back(x: success_sample( |
| 471 | "positive_u" , |
| 472 | {0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe8, 0xe5, 0x04, 0x00}, |
| 473 | maket(hours: 0, mins: 0, secs: 0, micros: 321000), |
| 474 | meta |
| 475 | )); |
| 476 | output.push_back(x: success_sample( |
| 477 | "positive_hmsu" , |
| 478 | {0x0c, 0x00, 0x22, 0x00, 0x00, 0x00, 0x16, 0x3b, 0x3a, 0x58, 0x3e, 0x0f, 0x00}, |
| 479 | maket(hours: 838, mins: 59, secs: 58, micros: 999000), |
| 480 | meta |
| 481 | )); |
| 482 | output.push_back(x: success_sample( |
| 483 | "negative_d" , |
| 484 | {0x08, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, |
| 485 | -maket(hours: 48, mins: 0, secs: 0, micros: 0), |
| 486 | meta |
| 487 | )); |
| 488 | output.push_back(x: success_sample( |
| 489 | "negative_h" , |
| 490 | {0x08, 0x01, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00}, |
| 491 | -maket(hours: 21, mins: 0, secs: 0, micros: 0), |
| 492 | meta |
| 493 | )); |
| 494 | output.push_back(x: success_sample( |
| 495 | "negative_m" , |
| 496 | {0x08, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x00}, |
| 497 | -maket(hours: 0, mins: 40, secs: 0), |
| 498 | meta |
| 499 | )); |
| 500 | output.push_back(x: success_sample( |
| 501 | "negative_s" , |
| 502 | {0x08, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15}, |
| 503 | -maket(hours: 0, mins: 0, secs: 21), |
| 504 | meta |
| 505 | )); |
| 506 | output.push_back(x: success_sample( |
| 507 | "negative_u" , |
| 508 | {0x0c, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe8, 0xe5, 0x04, 0x00}, |
| 509 | -maket(hours: 0, mins: 0, secs: 0, micros: 321000), |
| 510 | meta |
| 511 | )); |
| 512 | output.push_back(x: success_sample( |
| 513 | "negative_hmsu" , |
| 514 | {0x0c, 0x01, 0x22, 0x00, 0x00, 0x00, 0x16, 0x3b, 0x3a, 0x58, 0x3e, 0x0f, 0x00}, |
| 515 | -maket(hours: 838, mins: 59, secs: 58, micros: 999000), |
| 516 | meta |
| 517 | )); |
| 518 | output.push_back(x: success_sample( |
| 519 | "negative_sign_not_one" , |
| 520 | {0x0c, 0x03, 0x22, 0x00, 0x00, 0x00, 0x16, 0x3b, 0x3a, 0x58, 0x3e, 0x0f, 0x00}, |
| 521 | -maket(hours: 838, mins: 59, secs: 58, micros: 999000), |
| 522 | meta |
| 523 | )); |
| 524 | } |
| 525 | |
| 526 | std::vector<success_sample> make_all_samples() |
| 527 | { |
| 528 | std::vector<success_sample> res; |
| 529 | add_string_samples(output&: res); |
| 530 | add_blob_samples(output&: res); |
| 531 | add_int_samples(output&: res); |
| 532 | add_bit_types(output&: res); |
| 533 | add_float_samples(output&: res); |
| 534 | add_double_samples(output&: res); |
| 535 | add_date_samples(output&: res); |
| 536 | add_datetime_samples(type: column_type::datetime, output&: res); |
| 537 | add_datetime_samples(type: column_type::timestamp, output&: res); |
| 538 | add_time_samples(output&: res); |
| 539 | return res; |
| 540 | } |
| 541 | |
| 542 | BOOST_AUTO_TEST_CASE(success) |
| 543 | { |
| 544 | for (const auto& tc : make_all_samples()) |
| 545 | { |
| 546 | BOOST_TEST_CONTEXT("type=" << tc.meta.type() << ", name=" << tc.name) |
| 547 | { |
| 548 | const auto& buffer = tc.from; |
| 549 | detail::deserialization_context ctx(buffer); |
| 550 | |
| 551 | field_view actual_value; |
| 552 | auto err = deserialize_binary_field(ctx, meta: tc.meta, output&: actual_value); |
| 553 | |
| 554 | BOOST_TEST(err == deserialize_errc::ok); |
| 555 | BOOST_TEST(actual_value == tc.expected); |
| 556 | BOOST_TEST(ctx.first() == buffer.data() + buffer.size()); // all bytes consumed |
| 557 | } |
| 558 | } |
| 559 | } |
| 560 | |
| 561 | BOOST_AUTO_TEST_SUITE_END() |
| 562 | |
| 563 | BOOST_AUTO_TEST_SUITE(error) |
| 564 | |
| 565 | struct error_sample |
| 566 | { |
| 567 | std::string name; |
| 568 | deserialization_buffer from; |
| 569 | metadata meta; |
| 570 | deserialize_errc expected_err; |
| 571 | |
| 572 | error_sample( |
| 573 | std::string&& name, |
| 574 | deserialization_buffer&& from, |
| 575 | metadata meta, |
| 576 | deserialize_errc expected_err = deserialize_errc::protocol_value_error |
| 577 | ) |
| 578 | : name(std::move(name)), from(std::move(from)), meta(std::move(meta)), expected_err(expected_err) |
| 579 | { |
| 580 | } |
| 581 | }; |
| 582 | |
| 583 | void add_int_samples(column_type type, std::size_t num_bytes, std::vector<error_sample>& output) |
| 584 | { |
| 585 | output.emplace_back(args: error_sample( |
| 586 | "signed_not_enough_space" , |
| 587 | deserialization_buffer(num_bytes, 0x0a), |
| 588 | create_meta(type), |
| 589 | deserialize_errc::incomplete_message |
| 590 | )); |
| 591 | output.emplace_back(args: error_sample( |
| 592 | "unsigned_not_enough_space" , |
| 593 | deserialization_buffer(num_bytes, 0x0a), |
| 594 | meta_builder().type(v: type).unsigned_flag(v: true).build(), |
| 595 | deserialize_errc::incomplete_message |
| 596 | )); |
| 597 | } |
| 598 | |
| 599 | void add_bit_samples(std::vector<error_sample>& output) |
| 600 | { |
| 601 | auto meta = meta_builder().type(v: column_type::bit).unsigned_flag(v: true).build(); |
| 602 | |
| 603 | output.emplace_back(args: error_sample( |
| 604 | "bit_error_deserializing_string_view" , |
| 605 | {0x01}, |
| 606 | meta, |
| 607 | deserialize_errc::incomplete_message |
| 608 | )); |
| 609 | output.emplace_back(args: error_sample("bit_string_view_too_short" , {0x00}, meta)); |
| 610 | output.emplace_back(args: error_sample( |
| 611 | "bit_string_view_too_long" , |
| 612 | {0x09, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09}, |
| 613 | meta |
| 614 | )); |
| 615 | } |
| 616 | |
| 617 | void add_float_samples(std::vector<error_sample>& output) |
| 618 | { |
| 619 | auto meta = create_meta(type: column_type::float_); |
| 620 | |
| 621 | output.push_back( |
| 622 | x: error_sample("not_enough_space" , {0x01, 0x02, 0x03}, meta, deserialize_errc::incomplete_message) |
| 623 | ); |
| 624 | output.push_back(x: error_sample("inf" , {0x00, 0x00, 0x80, 0x7f}, meta)); |
| 625 | output.push_back(x: error_sample("minus_inf" , {0x00, 0x00, 0x80, 0xff}, meta)); |
| 626 | output.push_back(x: error_sample("nan" , {0xff, 0xff, 0xff, 0x7f}, meta)); |
| 627 | output.push_back(x: error_sample("minus_nan" , {0xff, 0xff, 0xff, 0xff}, meta)); |
| 628 | } |
| 629 | |
| 630 | void add_double_samples(std::vector<error_sample>& output) |
| 631 | { |
| 632 | auto meta = create_meta(type: column_type::double_); |
| 633 | |
| 634 | output.push_back(x: error_sample( |
| 635 | "not_enough_space" , |
| 636 | {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07}, |
| 637 | meta, |
| 638 | deserialize_errc::incomplete_message |
| 639 | )); |
| 640 | output.push_back(x: error_sample("inf" , {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x7f}, meta)); |
| 641 | output.push_back(x: error_sample("minus_inf" , {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xff}, meta)); |
| 642 | output.push_back(x: error_sample("nan" , {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f}, meta)); |
| 643 | output.push_back(x: error_sample("minus_nan" , {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, meta)); |
| 644 | } |
| 645 | |
| 646 | // Based on correct, regular date {0x04, 0xda, 0x07, 0x03, 0x1c} |
| 647 | void add_date_samples(std::vector<error_sample>& output) |
| 648 | { |
| 649 | auto meta = create_meta(type: column_type::date); |
| 650 | |
| 651 | output.push_back(x: error_sample("empty" , {}, meta, deserialize_errc::incomplete_message)); |
| 652 | output.push_back(x: error_sample("incomplete_year" , {0x04, 0xda}, meta, deserialize_errc::incomplete_message) |
| 653 | ); |
| 654 | output.push_back( |
| 655 | x: error_sample("no_month_day" , {0x04, 0xda, 0x07}, meta, deserialize_errc::incomplete_message) |
| 656 | ); |
| 657 | output.push_back( |
| 658 | x: error_sample("no_day" , {0x04, 0xda, 0x07, 0x03}, meta, deserialize_errc::incomplete_message) |
| 659 | ); |
| 660 | output.push_back(x: error_sample( |
| 661 | "invalid_year" , |
| 662 | {0x04, 0x10, 0x27, 0x03, 0x1c}, // year 10000 |
| 663 | meta |
| 664 | )); |
| 665 | output.push_back(x: error_sample("invalid_year_max" , {0x04, 0xff, 0xff, 0x03, 0x1c}, meta)); |
| 666 | output.push_back(x: error_sample("invalid_month" , {0x04, 0xda, 0x07, 13, 0x1c}, meta)); |
| 667 | output.push_back(x: error_sample("invalid_month_max" , {0x04, 0xda, 0x07, 0xff, 0x1c}, meta)); |
| 668 | output.push_back(x: error_sample("invalid_day" , {0x04, 0xda, 0x07, 0x03, 32}, meta)); |
| 669 | output.push_back(x: error_sample("invalid_day_max" , {0x04, 0xda, 0x07, 0x03, 0xff}, meta)); |
| 670 | output.push_back(x: error_sample("protocol_max" , {0xff, 0xff, 0xff, 0xff, 0xff}, meta)); |
| 671 | } |
| 672 | |
| 673 | // Based on correct datetime {0x0b, 0xda, 0x07, 0x01, 0x01, 0x17, 0x01, 0x3b, 0x56, 0xc3, 0x0e, |
| 674 | // 0x00} |
| 675 | void add_datetime_samples(column_type type, std::vector<error_sample>& output) |
| 676 | { |
| 677 | auto meta = create_meta(type); |
| 678 | |
| 679 | output.push_back(x: error_sample("empty" , {}, meta, deserialize_errc::incomplete_message)); |
| 680 | output.push_back( |
| 681 | x: error_sample("incomplete_date" , {0x04, 0xda, 0x07, 0x01}, meta, deserialize_errc::incomplete_message) |
| 682 | ); |
| 683 | output.push_back(x: error_sample( |
| 684 | "no_hours_mins_secs" , |
| 685 | {0x07, 0xda, 0x07, 0x01, 0x01}, |
| 686 | meta, |
| 687 | deserialize_errc::incomplete_message |
| 688 | )); |
| 689 | output.push_back(x: error_sample( |
| 690 | "no_mins_secs" , |
| 691 | {0x07, 0xda, 0x07, 0x01, 0x01, 0x17}, |
| 692 | meta, |
| 693 | deserialize_errc::incomplete_message |
| 694 | )); |
| 695 | output.push_back(x: error_sample( |
| 696 | "no_secs" , |
| 697 | {0x07, 0xda, 0x07, 0x01, 0x01, 0x17, 0x01}, |
| 698 | meta, |
| 699 | deserialize_errc::incomplete_message |
| 700 | )); |
| 701 | output.push_back(x: error_sample( |
| 702 | "incomplete_micros" , |
| 703 | {0x0b, 0xda, 0x07, 0x01, 0x01, 0x17, 0x01, 0x3b, 0x56, 0xc3, 0x0e}, |
| 704 | meta, |
| 705 | deserialize_errc::incomplete_message |
| 706 | )); |
| 707 | output.push_back(x: error_sample("invalid_year_d" , {0x04, 0x10, 0x27, 0x01, 0x01}, meta)); // year 10000 |
| 708 | output.push_back(x: error_sample("invalid_year_hms" , {0x07, 0x10, 0x27, 0x01, 0x01, 0x17, 0x01, 0x3b}, meta) |
| 709 | ); |
| 710 | output.push_back(x: error_sample( |
| 711 | "invalid_year_hmsu" , |
| 712 | {0x0b, 0x10, 0x27, 0x01, 0x01, 0x17, 0x01, 0x3b, 0x56, 0xc3, 0x0e, 0x00}, |
| 713 | meta |
| 714 | )); |
| 715 | output.push_back(x: error_sample( |
| 716 | "invalid_year_max_hmsu" , |
| 717 | {0x0b, 0xff, 0xff, 0x01, 0x01, 0x17, 0x01, 0x3b, 0x56, 0xc3, 0x0e, 0x00}, |
| 718 | meta |
| 719 | )); |
| 720 | output.push_back(x: error_sample("invalid_hour_hms" , {0x07, 0xda, 0x07, 0x01, 0x01, 24, 0x01, 0x3b}, meta)); |
| 721 | output.push_back(x: error_sample( |
| 722 | "invalid_hour_hmsu" , |
| 723 | {0x0b, 0xda, 0x07, 0x01, 0x01, 24, 0x01, 0x3b, 0x56, 0xc3, 0x0e, 0x00}, |
| 724 | meta |
| 725 | )); |
| 726 | output.push_back(x: error_sample( |
| 727 | "invalid_hour_max_hmsu" , |
| 728 | {0x0b, 0xda, 0x07, 0x01, 0x01, 0xff, 0x01, 0x3b, 0x56, 0xc3, 0x0e, 0x00}, |
| 729 | meta |
| 730 | )); |
| 731 | output.push_back(x: error_sample("invalid_min_hms" , {0x07, 0xda, 0x07, 0x01, 0x01, 0x17, 60, 0x3b}, meta)); |
| 732 | output.push_back(x: error_sample( |
| 733 | "invalid_min_hmsu" , |
| 734 | {0x0b, 0xda, 0x07, 0x01, 0x01, 0x17, 60, 0x3b, 0x56, 0xc3, 0x0e, 0x00}, |
| 735 | meta |
| 736 | )); |
| 737 | output.push_back(x: error_sample( |
| 738 | "invalid_min_max_hmsu" , |
| 739 | {0x0b, 0xda, 0x07, 0x01, 0x01, 0x17, 0xff, 0x3b, 0x56, 0xc3, 0x0e, 0x00}, |
| 740 | meta |
| 741 | )); |
| 742 | output.push_back(x: error_sample("invalid_sec_hms" , {0x07, 0xda, 0x07, 0x01, 0x01, 0x17, 0x01, 60}, meta)); |
| 743 | output.push_back(x: error_sample( |
| 744 | "invalid_sec_hmsu" , |
| 745 | {0x0b, 0xda, 0x07, 0x01, 0x01, 0x17, 0x01, 60, 0x56, 0xc3, 0x0e, 0x00}, |
| 746 | meta |
| 747 | )); |
| 748 | output.push_back(x: error_sample( |
| 749 | "invalid_sec_max_hmsu" , |
| 750 | {0x0b, 0xda, 0x07, 0x01, 0x01, 0x17, 0x01, 0xff, 0x56, 0xc3, 0x0e, 0x00}, |
| 751 | meta |
| 752 | )); |
| 753 | output.push_back(x: error_sample( |
| 754 | "invalid_micro_hmsu" , |
| 755 | {0x0b, 0xda, 0x07, 0x01, 0x01, 0x17, 0x01, 0x3b, 0x40, 0x42, 0xf4, 0x00}, |
| 756 | meta |
| 757 | )); // 1M |
| 758 | output.push_back(x: error_sample( |
| 759 | "invalid_micro_max_hmsu" , |
| 760 | {0x0b, 0xda, 0x07, 0x01, 0x01, 0x17, 0x01, 0x3b, 0xff, 0xff, 0xff, 0xff}, |
| 761 | meta |
| 762 | )); |
| 763 | output.push_back(x: error_sample( |
| 764 | "invalid_hour_invalid_date" , |
| 765 | {0x0b, 0x00, 0x00, 0x00, 0x00, 0xff, 0x01, 0x3b, 0x56, 0xc3, 0x0e, 0x00}, |
| 766 | meta |
| 767 | )); |
| 768 | output.push_back(x: error_sample( |
| 769 | "invalid_min_invalid_date" , |
| 770 | {0x0b, 0x00, 0x00, 0x00, 0x00, 0x17, 0xff, 0x3b, 0x56, 0xc3, 0x0e, 0x00}, |
| 771 | meta |
| 772 | )); |
| 773 | output.push_back(x: error_sample( |
| 774 | "invalid_sec_invalid_date" , |
| 775 | {0x0b, 0x00, 0x00, 0x00, 0x00, 0x17, 0x01, 0xff, 0x56, 0xc3, 0x0e, 0x00}, |
| 776 | meta |
| 777 | )); |
| 778 | output.push_back(x: error_sample( |
| 779 | "invalid_micro_invalid_date" , |
| 780 | {0x0b, 0x00, 0x00, 0x00, 0x00, 0x17, 0x01, 0x3b, 0xff, 0xff, 0xff, 0xff}, |
| 781 | meta |
| 782 | )); |
| 783 | output.push_back(x: error_sample( |
| 784 | "protocol_max" , |
| 785 | {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, |
| 786 | meta |
| 787 | )); |
| 788 | } |
| 789 | |
| 790 | void add_time_samples(std::vector<error_sample>& output) |
| 791 | { |
| 792 | auto meta = create_meta(type: column_type::time); |
| 793 | |
| 794 | output.push_back(x: error_sample("empty" , {}, meta, deserialize_errc::incomplete_message)); |
| 795 | output.push_back( |
| 796 | x: error_sample("no_sign_days_hours_mins_secs" , {0x08}, meta, deserialize_errc::incomplete_message) |
| 797 | ); |
| 798 | output.push_back( |
| 799 | x: error_sample("no_days_hours_mins_secs" , {0x08, 0x01}, meta, deserialize_errc::incomplete_message) |
| 800 | ); |
| 801 | output.push_back(x: error_sample( |
| 802 | "no_hours_mins_secs" , |
| 803 | {0x08, 0x01, 0x22, 0x00, 0x00, 0x00}, |
| 804 | meta, |
| 805 | deserialize_errc::incomplete_message |
| 806 | )); |
| 807 | output.push_back(x: error_sample( |
| 808 | "no_mins_secs" , |
| 809 | {0x08, 0x01, 0x22, 0x00, 0x00, 0x00, 0x16}, |
| 810 | meta, |
| 811 | deserialize_errc::incomplete_message |
| 812 | )); |
| 813 | output.push_back(x: error_sample( |
| 814 | "no_secs" , |
| 815 | {0x08, 0x01, 0x22, 0x00, 0x00, 0x00, 0x16, 0x3b}, |
| 816 | meta, |
| 817 | deserialize_errc::incomplete_message |
| 818 | )); |
| 819 | output.push_back(x: error_sample( |
| 820 | "no_micros" , |
| 821 | {0x0c, 0x01, 0x22, 0x00, 0x00, 0x00, 0x16, 0x3b, 0x3a}, |
| 822 | meta, |
| 823 | deserialize_errc::incomplete_message |
| 824 | )); |
| 825 | |
| 826 | std::pair<const char*, std::vector<std::uint8_t>> out_of_range_cases[]{ |
| 827 | {"invalid_days" , {0x08, 0x00, 35, 0x00, 0x00, 0x00, 0x16, 0x3b, 0x3a} }, |
| 828 | {"invalid_days_max" , {0x08, 0x00, 0xff, 0xff, 0xff, 0xff, 0x16, 0x3b, 0x3a} }, |
| 829 | {"invalid_hours" , {0x08, 0x01, 0x22, 0x00, 0x00, 0x00, 24, 0x3b, 0x3a} }, |
| 830 | {"invalid_hours_max" , {0x08, 0x01, 0x22, 0x00, 0x00, 0x00, 0xff, 0x3b, 0x3a} }, |
| 831 | {"invalid_mins" , {0x08, 0x01, 0x22, 0x00, 0x00, 0x00, 0x16, 60, 0x3a} }, |
| 832 | {"invalid_mins_max" , {0x08, 0x01, 0x22, 0x00, 0x00, 0x00, 0x16, 0xff, 0x3a} }, |
| 833 | {"invalid_secs" , {0x08, 0x01, 0x22, 0x00, 0x00, 0x00, 0x16, 0x3b, 60} }, |
| 834 | {"invalid_secs_max" , {0x08, 0x01, 0x22, 0x00, 0x00, 0x00, 0x16, 0x3b, 0xff} }, |
| 835 | {"invalid_micros" , {0x0c, 0x01, 0x22, 0x00, 0x00, 0x00, 0x16, 0x3b, 0x3a, 0x40, 0x42, 0xf4, 0x00}}, |
| 836 | {"invalid_micros_max" , |
| 837 | {0x0c, 0x01, 0x22, 0x00, 0x00, 0x00, 0x16, 0x3b, 0x3a, 0xff, 0xff, 0xff, 0xff} }, |
| 838 | }; |
| 839 | |
| 840 | for (auto& c : out_of_range_cases) |
| 841 | { |
| 842 | // Positive |
| 843 | c.second[1] = 0x00; |
| 844 | output.emplace_back(args: c.first + std::string("_positive" ), args: deserialization_buffer(c.second), args&: meta); |
| 845 | |
| 846 | // Negative |
| 847 | c.second[1] = 0x01; |
| 848 | output.emplace_back(args: c.first + std::string("_negative" ), args: deserialization_buffer(c.second), args&: meta); |
| 849 | } |
| 850 | } |
| 851 | |
| 852 | std::vector<error_sample> make_all_samples() |
| 853 | { |
| 854 | std::vector<error_sample> res; |
| 855 | add_int_samples(type: column_type::tinyint, num_bytes: 0, output&: res); |
| 856 | add_int_samples(type: column_type::smallint, num_bytes: 1, output&: res); |
| 857 | add_int_samples(type: column_type::mediumint, num_bytes: 3, output&: res); |
| 858 | add_int_samples(type: column_type::int_, num_bytes: 3, output&: res); |
| 859 | add_int_samples(type: column_type::bigint, num_bytes: 7, output&: res); |
| 860 | add_int_samples(type: column_type::year, num_bytes: 1, output&: res); |
| 861 | add_bit_samples(output&: res); |
| 862 | add_float_samples(output&: res); |
| 863 | add_double_samples(output&: res); |
| 864 | add_date_samples(output&: res); |
| 865 | add_datetime_samples(type: column_type::datetime, output&: res); |
| 866 | add_datetime_samples(type: column_type::timestamp, output&: res); |
| 867 | add_time_samples(output&: res); |
| 868 | return res; |
| 869 | } |
| 870 | |
| 871 | BOOST_AUTO_TEST_CASE(error) |
| 872 | { |
| 873 | for (const auto& tc : make_all_samples()) |
| 874 | { |
| 875 | BOOST_TEST_CONTEXT("type=" << tc.meta.type() << ", name=" << tc.name) |
| 876 | { |
| 877 | detail::deserialization_context ctx(tc.from); |
| 878 | |
| 879 | field_view actual_value; |
| 880 | auto err = deserialize_binary_field(ctx, meta: tc.meta, output&: actual_value); |
| 881 | |
| 882 | BOOST_TEST(err == tc.expected_err); |
| 883 | } |
| 884 | } |
| 885 | } |
| 886 | |
| 887 | BOOST_AUTO_TEST_SUITE_END() |
| 888 | |
| 889 | BOOST_AUTO_TEST_SUITE_END() |
| 890 | |
| 891 | } // namespace |
| 892 | |