MySQL 26.10.0
Source Code Documentation
bulk_data_service.h
Go to the documentation of this file.
1/* Copyright (c) 2022, 2026, 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/**
25 @file
26 Services for bulk data conversion and load to SE.
27*/
28
29#pragma once
30
31#include <assert.h>
33#include <stddef.h>
34#include <atomic>
35#include <cstdint>
36#include <cstring>
37#include <functional>
38#include <iomanip>
39#include <iostream>
40#include <limits>
41#include <memory>
42#include <mutex>
43#include <optional>
44#include <sstream>
45#include <string>
46#include <vector>
47#include "field_types.h"
49
50class THD;
51struct TABLE;
52struct CHARSET_INFO;
53using Blob_context = void *;
54
55/** The blob reference size. Refer to lob::ref_t::SIZE or FIELD_REF_SIZE. */
56constexpr size_t BLOB_REF_SIZE = 20;
57
59 std::string filename;
60 size_t row_number;
61 std::string column_name;
62 std::string column_type;
63 std::string column_input_data;
64 std::string m_error_mesg{};
65 std::string m_table_name{};
66 size_t m_bytes;
68
69 std::ostream &print(std::ostream &out) const;
70};
71
73 std::ostream &out) const {
74 out << "[Bulk_load_error_location_details: filename=" << filename
75 << ", column_name=" << column_name << "]";
76 return out;
77}
78
79/** Overloading the global output operator to print objects of type
80Bulk_load_error_location_details.
81@param[in] out output stream
82@param[in] obj object to be printed
83@return given output stream. */
84inline std::ostream &operator<<(std::ostream &out,
86 return obj.print(out);
87}
88
90 /** Column data. */
91 const char *m_data_ptr{};
92
93 /** Column data length. */
94 size_t m_data_len{};
95
96 /** Prefix length. */
97 size_t m_prefix_len{};
98
99 /** Check if it is DB_ROW_ID column based on the value it contains.
100 @return true if it is DB_ROW_ID column, false otherwise */
101 bool is_row_id() const { return m_row_id != UINT64_MAX; }
102
103 /** The generated DB_ROW_ID value */
104 uint64_t m_row_id{UINT64_MAX};
105
106 /** Mark the column to be null, by setting length to a special value. This is
107 only used for columns whose state is maintained across chunks
108 (aka fragmented columns). */
109 void set_null() {
110 assert(m_data_ptr == nullptr);
112 }
113
114 /** Check if the column is null, by checking special value for length.
115 @return true if the column is null, false otherwise. */
116 bool is_null() const {
118 m_data_ptr == nullptr);
120 }
121
122 /** Check if the column data is stored externally. If the data is stored
123 externally, then the column data contains the prefix and the blob reference
124 of the externally stored data.
125 @return true if data is stored externally, false otherwise. */
126 bool is_ext() const {
128 return m_is_ext;
129 }
130
131 /** Check if the column data is stored externally. It is called relaxed,
132 because the column length might not be equal to BLOB_REF_SIZE. Only to
133 be used while the blob is being processed by the CSV parser.
134 @return true if data is stored externally, false otherwise. */
135 bool is_ext_relaxed() const {
136 assert(!m_is_ext || m_data_len >= BLOB_REF_SIZE);
137 return m_is_ext;
138 }
139
140 /** Mark that the column data has been stored externally. */
141 void set_ext() {
143 m_is_ext = true;
144 }
145
146 /** Initialize the members */
147 void init() {
148 m_data_ptr = nullptr;
149 m_data_len = 0;
150 m_is_ext = false;
151 m_row_id = UINT64_MAX;
152 }
153
154 /** Print this object into the given output stream.
155 @param[in] out output stream into which this object will be printed.
156 @return given output stream */
157 std::ostream &print(std::ostream &out) const;
158
159 std::string to_string() const;
160
161 private:
162 /** If true, the column data is stored externally. */
163 bool m_is_ext{false};
164};
165
166inline std::string Column_text::to_string() const {
168 sout << "[Column_text: len=" << m_data_len;
169 sout << ", val=";
170
171 if (m_data_ptr == nullptr) {
172 sout << "nullptr";
173 } else {
174 for (size_t i = 0; i < m_data_len; ++i) {
175 const char c = m_data_ptr[i];
176 if (isalnum(c)) {
177 sout << c;
178 } else {
179 sout << ".";
180 }
181 }
182 sout << "[hex=";
183 for (size_t i = 0; i < m_data_len; ++i) {
184 sout << std::setfill('0') << std::setw(2) << std::hex
185 << (int)*(&m_data_ptr[i]);
186 }
187 }
188 sout << "]";
189 return sout.str();
190}
191
192inline std::ostream &Column_text::print(std::ostream &out) const {
193 out << "[Column_text: this=" << static_cast<const void *>(this)
194 << ", m_data_ptr=" << static_cast<const void *>(m_data_ptr)
195 << ", m_data_len=" << m_data_len << ", m_is_ext=" << m_is_ext << "]";
196 return out;
197}
198
199/** Overloading the global output operator to print objects of type
200Column_text.
201@param[in] out output stream
202@param[in] obj object to be printed
203@return given output stream. */
204inline std::ostream &operator<<(std::ostream &out, const Column_text &obj) {
205 return obj.print(out);
206}
207
208struct Row_meta;
209
211 /** Column Data Type */
212 int16_t m_type{};
213
214 /** Column data length. */
215 uint16_t m_data_len{};
216
217 bool m_is_prefix{false};
218
219 /** If column is NULL. */
220 bool m_is_null{false};
221
222 /** If true, the column data is stored externally in InnoDB. It also means
223 that the data contains blob reference of length BTR_EXTERN_FIELD_REF_SIZE
224 bytes at the end. */
225 bool m_is_ext{false};
226
227 /** Get the column data.
228 @return nullptr if column is null, otherwise pointer to the data. */
229 char *get_data() const { return m_is_null ? nullptr : m_data_ptr; }
230
231 /** Set the column data to the given pointer location.
232 @param[in] ptr pointer pointing to column data. */
233 void set_data(char *ptr) { m_data_ptr = ptr; }
234
235 /** Mark this column as externally stored. */
236 void set_ext() { m_is_ext = true; }
237
238 /** Check if the column is externally stored.
239 @return true if externally stored, false otherwise. */
240 bool is_ext() const { return m_is_ext; }
241
242 /** Save the beginning of the row pointer in this object. This should be
243 called only when the column is null.
244 @param[in] row_begin pointer to beginning of row.*/
245 void row(char *row_begin) {
246 assert(m_is_null);
247 m_data_len = 0;
248 m_data_ptr = row_begin;
249 }
250
251 /** Get the pointer to the beginning of row. This is valid only if the
252 column is null. This should be called on the first column of the row. There
253 is no need to call this on other columns.
254 @param[in] row_meta meta data information about the row
255 @param[in] col_index Index of the first column which is 0.
256 @return pointer to row beginning. */
257 char *get_row_begin(const Row_meta &row_meta,
258 size_t col_index [[maybe_unused]]) const;
259
260 /** Column data in integer format. Used only for specific datatype. */
261 uint64_t m_int_data;
262
263 void init() {
264 m_type = 0;
265 m_data_len = 0;
266 m_is_prefix = false;
267 m_is_null = false;
268 m_is_ext = false;
269 m_data_ptr = nullptr;
270 m_int_data = 0;
271 }
272
273 std::string to_string() const;
274
275 private:
276 /** Column data or row begin. There is a need to fetch the beginning of
277 the row from the vector of Column_mysql. But in the case of secondary
278 indexes, all the keys could be null and it becomes impossible to obtain
279 the pointer to beginning of the row. To solve this problem, I am re-using
280 this pointer to hold the row begin when the column is null. So it becomes
281 important to make use of m_is_null to check if the column is null. It is NOT
282 correct to check this pointer against nullptr to confirm if column is null.*/
283 char *m_data_ptr{nullptr};
284};
285
286inline std::string Column_mysql::to_string() const {
288 sout << "[Column_mysql: type=" << m_type << ", len=" << m_data_len
289 << ", m_int_data=" << m_int_data;
290 sout << ", val=";
291
292 switch (m_type) {
293 case MYSQL_TYPE_LONG: {
294 sout << m_int_data;
295 } break;
296 default: {
297 for (size_t i = 0; i < m_data_len; ++i) {
298 const char c = m_data_ptr[i];
299 if (isalnum(c)) {
300 sout << c;
301 } else {
302 sout << ".";
303 }
304 }
305
306 } break;
307 }
308 if (m_type != MYSQL_TYPE_LONG) {
309 sout << "[hex=";
310 for (size_t i = 0; i < m_data_len; ++i) {
311 sout << std::setfill('0') << std::setw(2) << std::hex
312 << (int)*(&m_data_ptr[i]);
313 }
314 sout << "]";
315 }
316 return sout.str();
317}
318
319/** Implements the row and column memory management for parse and load
320operations. We try to pre-allocate the memory contiguously as much as we can
321to maximize the performance.
322
323@tparam Column_type Column_text when used in the CSV context, Column_sql when
324used in the InnoDB context.
325*/
326template <typename Column_type>
328 public:
329 /** Create a new row bunch.
330 @param[in] n_cols number of columns */
331 explicit Row_bunch(size_t n_cols) : m_num_columns(n_cols) {}
332
333 /** @return return number of rows in the bunch. */
334 size_t get_num_rows() const { return m_num_rows; }
335
336 /** @return return number of columns in each row. */
337 size_t get_num_cols() const { return m_num_columns; }
338
339 /** Process all columns, invoking callback for each.
340 @param[in] row_index index of the row
341 @param[in] cbk callback function
342 @return true if successful */
343 template <typename F>
344 bool process_columns(size_t row_index, F &&cbk) {
345 assert(row_index < m_num_rows);
346
347 auto row_offset = row_index * m_num_columns;
348 return process_columns_by_offset(row_offset, std::move(cbk));
349 }
350
351 template <typename F>
352 bool process_columns_by_offset(size_t row_offset, F &&cbk) {
353 assert(row_offset + m_num_columns <= m_columns.size());
354
355 for (size_t index = 0; index < m_num_columns; ++index) {
356 bool last_col = (index == m_num_columns - 1);
357 if (!cbk(m_columns[row_offset + index], last_col)) {
358 return false;
359 }
360 }
361 return true;
362 }
363
364 void reset() {
365 for (auto &col : m_columns) {
366 col.init();
367 }
368 }
369
370 /** Get current row offset to access columns.
371 @param[in] row_index row index
372 @return row offset in column vector. */
373 size_t get_row_offset(size_t row_index) const {
374 assert(row_index < m_num_rows);
375 return row_index * m_num_columns;
376 }
377
378 /** Get next row offset from current row offset.
379 @param[in,out] offset row offset
380 @return true if there is a next row. */
381 size_t get_next_row_offset(size_t &offset) const {
382 offset += m_num_columns;
383 return (offset < m_columns.size());
384 }
385
386 /** Get column using row offset and column index.
387 @param[in] row_offset row offset in column vector
388 @param[in] col_index index of the column within row
389 @return column data */
390 Column_type &get_column(size_t row_offset, size_t col_index) {
391 assert(col_index < m_num_columns);
392 assert(row_offset + col_index < m_columns.size());
393 return m_columns[row_offset + col_index];
394 }
395
396 /** Get column using row index and column index.
397 @param[in] row_index index of the row in the bunch
398 @param[in] col_index index of the column within row
399 @return column data */
400 Column_type &get_col(size_t row_index, size_t col_index) {
401 return get_column(get_row_offset(row_index), col_index);
402 }
403
404 /** Get column using the column offset.
405 @param[in] col_offset column offset
406 @return column data */
407 Column_type &get_col(size_t col_offset) { return m_columns[col_offset]; }
408
409 /** Get constant column for reading using row offset and column index.
410 @param[in] row_offset row offset in column vector
411 @param[in] col_index index of the column within row
412 @return column data */
413 const Column_type &read_column(size_t row_offset, size_t col_index) const {
414 assert(col_index < m_num_columns);
415 assert(row_offset + col_index < m_columns.size());
416 return m_columns[row_offset + col_index];
417 }
418
419 /** Set the number of rows. Adjust number of rows base on maximum column
420 storage limit.
421 @param[in,out] n_rows number of rows
422 @return true if successful, false if too many rows or columns. */
423 bool set_num_rows(size_t n_rows) {
424 /* Avoid any overflow during multiplication. */
425 if (n_rows > std::numeric_limits<uint32_t>::max() ||
427 return false;
428 }
429 auto total_cols = (uint64_t)n_rows * m_num_columns;
430
431 if (total_cols > S_MAX_TOTAL_COLS) {
432 return false;
433 }
434
435 m_num_rows = n_rows;
436
437 /* Extend columns if needed. */
438 if (m_columns.size() < total_cols) {
439 m_columns.resize(total_cols);
440 }
441 return true;
442 }
443
444 /** Limit allocation up to 600M columns. This number is rounded up from an
445 * estimate of the number of columns with the max chunk size (1024M). In the
446 * worst case we can have 2 bytes per column so a chunk can contain around
447 * 512M columns, and because of rows that spill over chunk boundaries we
448 * assume we can append a full additional row (which should have at most
449 * 4096 columns). Rounded up to 600M. */
450 const static size_t S_MAX_TOTAL_COLS = 600 * 1024 * 1024;
451
452 /** Get the total number of columns available in this row bunch.
453 @return total number of columns. */
454 size_t get_total_cols() const { return m_num_rows * m_num_columns; }
455
456 private:
457 /** All the columns. */
458 std::vector<Column_type> m_columns;
459
460 /** Number of rows. */
461 size_t m_num_rows{};
462
463 /** Number of columns in each row. */
465};
466
469
470/** Column metadata information. */
472 /** Data comparison method. */
473 enum class Compare {
474 /* Integer comparison */
476 /* Unsigned Integer comparison */
478 /* Binary comparison (memcmp) */
479 BINARY,
480 /* Need to callback to use appropriate comparison function in server. */
481 MYSQL
482 };
483
484 std::string get_compare_string() const {
485 switch (m_compare) {
487 return "INTEGER_SIGNED";
489 return "INTEGER_UNSIGNED";
490 case Compare::BINARY:
491 return "BINARY";
492 case Compare::MYSQL:
493 return "MYSQL";
494 }
495 assert(0);
496 return "INVALID";
497 }
498
499 /** @return true if integer type. */
500 bool is_integer() const {
503 }
504
505 /** Based on the column data type check if it can be stored externally.
506 @return true if the column data can be stored externally
507 @return false if the column data cannot be stored externally */
508 bool can_be_stored_externally() const;
509
510 /** true if this column is part of secondary index. */
511 bool m_is_part_of_sk{false};
512
513 /** Field type. (@ref enum_field_types) */
515
516 /** If column could be NULL. */
517 bool m_is_nullable{false};
518
519 /** true if column belongs to primary index (key or non-key) */
520 bool m_is_pk{false};
521
522 /** true if column is a key for primary or secondary index. */
523 bool m_is_key{false};
524
525 /** If the key is descending. */
526 bool m_is_desc_key{false};
527
528 /** If the prefix of this column is part of key */
529 bool m_is_prefix_key{false};
530
531 /** Prefix length */
532 size_t m_prefix_len{0};
533
534 /** If it is fixed length type. */
535 bool m_is_fixed_len{false};
536
537 /** If it is integer type. */
539
540 /** If it is unsigned integer type. */
541 bool m_is_unsigned{false};
542
543 /** Check the row header to find out if it is fixed length. For
544 character data type the row header indicates fixed length. */
546
547 /** If character column length can be kept in one byte. */
549
550 /** The length of column data if fixed. */
551 uint16_t m_fixed_len;
552
553 /** Maximum length of data in bytes. */
554 uint16_t m_max_len;
555
556 /** Index of column in row. */
557 uint16_t m_index;
558
559 /** Position of column in table. Refer to Field::field_index() */
561
562 /** Byte index in NULL bitmap. */
563 uint16_t m_null_byte;
564
565 /** BIT number in NULL bitmap. */
566 uint16_t m_null_bit;
567
568 /** Character set for char & varchar columns. */
569 const void *m_charset;
570
571 /** Field name */
572 std::string m_field_name;
573
574 /** Get a string representation of Column_meta object. Useful only for
575 debugging purposes.
576 @see Column_meta
577 @return string representation of this object. */
578 std::string to_string() const;
579
580 /** Print this object into the given output stream.
581 @param[in] out output stream into which object will be printed
582 @return given output stream. */
583 std::ostream &print(std::ostream &out) const;
584
585 /** Get the data type of the column as a string.
586 @return data type of the column as a string. */
587 std::string get_type_string() const;
588
589 /** The number of bytes used to store length information. This depends on
590 the data type.
591 @return number of bytes used to store length of column data. */
592 size_t get_length_size() const;
593};
594
595inline size_t Column_meta::get_length_size() const {
596 size_t length_size = m_is_single_byte_len ? 1 : 2;
597 switch (m_type) {
599 length_size = 1;
600 break;
601 case MYSQL_TYPE_BLOB:
602 length_size = 0;
603 break;
605 length_size = 3;
606 break;
608 [[fallthrough]];
609 case MYSQL_TYPE_JSON:
610 [[fallthrough]];
613 length_size = 4;
614 break;
615 default:
616 break;
617 }
618 return length_size;
619}
620
621inline std::string Column_meta::get_type_string() const {
622 switch (m_type) {
624 return "decimal";
625 case MYSQL_TYPE_TINY:
626 return "tiny";
627 case MYSQL_TYPE_SHORT:
628 return "short";
629 case MYSQL_TYPE_LONG:
630 return "long";
631 case MYSQL_TYPE_FLOAT:
632 return "float";
634 return "double";
635 case MYSQL_TYPE_NULL:
636 return "null";
638 return "timestamp";
640 return "longlong";
641 case MYSQL_TYPE_INT24:
642 return "int";
643 case MYSQL_TYPE_DATE:
644 return "date";
645 case MYSQL_TYPE_TIME:
646 return "time";
648 return "datetime";
649 case MYSQL_TYPE_YEAR:
650 return "year";
652 return "date";
654 return "varchar";
655 case MYSQL_TYPE_BIT:
656 return "bit";
658 return "timestamp";
660 return "datetime";
661 case MYSQL_TYPE_TIME2:
662 return "time";
664 return "typed_array";
666 return "vector";
668 return "invalid";
669 case MYSQL_TYPE_BOOL:
670 return "bool";
671 case MYSQL_TYPE_JSON:
672 return "json";
674 return "decimal";
675 case MYSQL_TYPE_ENUM:
676 return "enum";
677 case MYSQL_TYPE_SET:
678 return "set";
680 return "tiny_blob";
682 return "medium_blob";
684 return "long_blob";
685 case MYSQL_TYPE_BLOB:
686 return "blob";
688 return "var_string";
690 return "string";
692 return "geometry";
693 }
694 return "invalid";
695}
696
698 switch (m_type) {
699 case MYSQL_TYPE_JSON:
704 case MYSQL_TYPE_BLOB:
707 return true;
708 }
709 default:
710 break;
711 }
712 return false;
713}
714
715inline std::string Column_meta::to_string() const {
717 out << "[Column_meta: m_type=" << get_type_string()
718 << ", m_field_name=" << m_field_name << ", m_index=" << m_index
719 << ", m_field_index=" << m_field_index
720 << ", m_is_single_byte_len=" << m_is_single_byte_len
721 << ", m_is_fixed_len=" << m_is_fixed_len
722 << ", m_fixed_len=" << m_fixed_len << ", m_null_byte=" << m_null_byte
723 << ", m_null_bit=" << m_null_bit << ", m_compare=" << get_compare_string()
724 << ", m_is_desc_key=" << m_is_desc_key << ", m_is_key=" << m_is_key
725 << ", m_max_len=" << m_max_len << ", m_is_prefix_key=" << m_is_prefix_key
726 << ", m_prefix_len=" << m_prefix_len << "]";
727 return out.str();
728}
729
730inline std::ostream &Column_meta::print(std::ostream &out) const {
731 out << to_string();
732 return out;
733}
734
735/** Overloading the global output operator to print objects of type
736Column_meta.
737@param[in] out output stream
738@param[in] obj object to be printed
739@return given output stream. */
740inline std::ostream &operator<<(std::ostream &out, const Column_meta &obj) {
741 return obj.print(out);
742}
743
744/** Table metadata. */
746 /** Number of keys/indexes the table has. */
747 size_t m_n_keys;
748
749 /** Key number of the primary key. */
751
752 /** True if generated DB_ROW_ID is the pk. */
753 bool dbrowid_is_pk{false};
754
757
758 /** Table being bulk loaded. */
759 std::string m_table_name;
760};
761
762/** Row metadata */
763struct Row_meta {
764 /** Key type for fast comparison. */
765 enum class Key_type {
766 /* All Keys are signed integer an ascending. */
768 /* All keys are integer. */
769 INT,
770 /* Keys are of any supported type. */
771 ANY
772 };
773 /** All columns in a row are arranged with key columns first. */
774 std::vector<Column_meta> m_columns;
775
776 /** All columns in a row arranged as per col_index. */
777 std::vector<const Column_meta *> m_columns_text_order;
778
779 /** Get a string representation of this Row_meta object.
780 @see Row_meta
781 @return string representation of this object. */
782 std::string to_string() const;
783
784 /** Get the metadata of the given column.
785 @param[in] col_index position of the column in the index.
786 @return metadata of the requested column. */
787 const Column_meta &get_column_meta_index_order(size_t col_index) const {
788 assert(col_index < m_columns.size());
789 return m_columns[col_index];
790 }
791
792 /** Get the meta data of the column.
793 @param[in] col_index the index of the column as it appears in CSV file.
794 @return a reference to the column meta data.*/
795 const Column_meta &get_column_meta(size_t col_index) const {
796 assert(col_index < m_columns_text_order.size());
797 assert(col_index == m_columns_text_order[col_index]->m_index);
798 return *m_columns_text_order[col_index];
799 }
800
801 /** Total bitmap header length for the row. */
802 size_t m_bitmap_length = 0;
803
804 /** Total header length. */
805 size_t m_header_length = 0;
806
807 /** Length of the first key column. Helps to get the row pointer from first
808 key data pointer. */
809 size_t m_first_key_len = 0;
810
811 /** Key length in bytes for non-integer keys. This is required to estimate
812 the space required to save keys. */
813 size_t m_key_length = 0;
814
815 /** Number of columns used in primary key. */
816 uint32_t m_keys = 0;
817
818 /** Number of columns not used in primary Key. */
819 uint32_t m_non_keys = 0;
820
821 /** Key type for comparison. */
823
824 /** Total number of columns. A key could be on a column prefix.
825 m_columns <= m_keys + m_non_keys */
826 uint32_t m_num_columns = 0;
827
828 /** Approximate row length. */
830
831 /** Number of columns that can be stored externally. */
832 size_t m_n_blob_cols{0};
833
834 /** Name of the key */
835 std::string m_name;
836
837 /** true if primary key, false if secondary key. */
838 bool is_pk{false};
839
840 /** true if DB_ROW_ID is the pk, false otherwise. */
841 bool dbrowid_is_pk{false};
842
843 /** Key number of the index being built. */
844 size_t m_keynr;
845};
846
847inline std::ostream &operator<<(std::ostream &os,
849 switch (key_type) {
851 os << "ANY";
852 break;
854 os << "INT_SIGNED_ASC";
855 break;
857 os << "INT";
858 break;
859 }
860 return os;
861}
862
863inline std::string Row_meta::to_string() const {
865 out << "[Row_meta: m_name=" << m_name << ", m_num_columns=" << m_num_columns
866 << ", m_keys=" << m_keys << ", m_non_keys=" << m_non_keys
867 << ", m_key_length=" << m_key_length << ", m_key_type=" << m_key_type
868 << ", m_approx_row_len=" << m_approx_row_len
869 << ", m_bitmap_length=" << m_bitmap_length
870 << ", m_header_length=" << m_header_length
871 << ", m_first_key_len=" << m_first_key_len << ", m_keynr=" << m_keynr;
872 for (auto &col_meta : m_columns) {
873 out << col_meta.to_string() << ", ";
874 }
875 out << "]";
876 return out.str();
877}
878
879inline char *Column_mysql::get_row_begin(const Row_meta &row_meta,
880 size_t col_index
881 [[maybe_unused]]) const {
882 assert(m_is_null || col_index == 0);
883 return m_is_null ? m_data_ptr
884 : (m_data_ptr - row_meta.m_first_key_len -
885 row_meta.m_header_length);
886}
887
888namespace Bulk_load {
889
892 public:
893 void KeyTooBig() const override;
894 void ValueTooBig() const override;
895 void TooDeep() const override;
896 void InvalidJson() const override;
897 void InternalError(const char *message) const override;
898 bool CheckStack() const override;
899
900 const char *c_str() const { return m_error.c_str(); }
901
902 std::string get_error() const { return m_error; }
903
904 private:
905 mutable std::string m_error{};
906};
907
909 m_error = "Key is too big";
910}
911
913 m_error = "Value is too big";
914}
915
917 m_error = "JSON document has more nesting levels than supported";
918}
920 m_error = "Invalid JSON value is encountered";
921}
923 const char *message [[maybe_unused]]) const {
924 m_error = message;
925 m_error += " (Internal Error)";
926}
927
929 return false;
930}
931
932/** Callbacks for collecting time statistics */
934 /* Operation begin. */
935 std::function<void()> m_fn_begin;
936 /* Operation end. */
937 std::function<void()> m_fn_end;
938};
939
941 std::pair<std::optional<Rows_mysql>, std::optional<Rows_mysql>>;
942
944 std::string schema;
945 std::string table;
947};
948
949/** Contains the data needed for the ROW_ID generation for tables without
950explicit primary key */
952 /** Get an estimate of the number of rows to be handled by each thread.
953 This will give the number of row ids to be generated by each thread.
954 @return number of rows to be handled by each thread. */
955 size_t get_rows_per_thread() const {
956 size_t estimated_total_rows = m_total_size / m_avg_row_len.load();
957 size_t min_total_rows = 1000;
958
959 if (estimated_total_rows < min_total_rows) {
960 estimated_total_rows = min_total_rows;
961 }
962
963 return (estimated_total_rows + m_n_loaders) / m_n_loaders;
964 }
965
966 /** Get the next available range for generating DB_ROW_ID. The range includes
967 the begin value but excludes the end value.
968 @return the range for row ids for exclusive use by the calling thread. */
969 inline std::pair<uint64_t, uint64_t> get_next_rowid_range() const {
970 std::unique_lock<std::mutex> lock(m_rowid_mutex);
971
972 const uint64_t range_begin = m_next_rowid_range;
974
975 return std::make_pair(range_begin, m_next_rowid_range);
976 }
977
978 void set_begin_rowid_value(size_t row_id) { m_next_rowid_range = row_id; }
979 /* Total data size of CSV files (in bytes) */
981 /* Average row length, updated by the CSV parsing threads for each batch. */
982 std::atomic<size_t> m_avg_row_len;
983 /* Number of loaders aka concurrency in phase 1. */
985
986 private:
987 /** Protects the member m_next_rowid_range */
988 mutable std::mutex m_rowid_mutex;
989
990 /* Number of rows per subtree. */
991 mutable size_t m_next_rowid_range{0};
992};
993
994} // namespace Bulk_load
995
996/** Bulk Data conversion. */
997BEGIN_SERVICE_DEFINITION(bulk_data_convert)
998/** Convert row from text format for MySQL column format. Convert as many
999rows as possible consuming the data buffer starting form next_index. On
1000output next_index is the next row index that is not yet consumed. If it
1001matches the size of input text_rows, then all rows are consumed.
1002@param[in,out] thd session THD
1003@param[in] table MySQL TABLE
1004@param[in] text_rows rows with column in text
1005@param[in,out] next_index next_index in text_rows to be processed
1006@param[in,out] buffer data buffer for keeping sql row data
1007@param[in,out] buffer_length length of the data buffer
1008@param[in] charset input row data character set
1009@param[in] metadata row metadata
1010@param[out] sql_rows rows with column in MySQL column format
1011@return error code. */
1013 (THD * thd, const TABLE *table, const Rows_text &text_rows,
1014 size_t &next_index, char *buffer, size_t &buffer_length,
1015 const CHARSET_INFO *charset, const Row_meta &metadata,
1016 Rows_mysql &sql_rows,
1018
1019/** Convert row to MySQL column format from raw form
1020@param[in,out] buffer input raw data buffer
1021@param[in] buffer_length buffer length
1022@param[in] metadata row metadata
1023@param[in] start_index start row index in row bunch
1024@param[out] consumed_length length of buffer consumed
1025@param[in,out] sql_rows row bunch to fill data
1026@return error code. */
1028 (char *buffer, size_t buffer_length, const Row_meta &metadata,
1029 size_t start_index, size_t &consumed_length,
1030 Rows_mysql &sql_rows));
1031
1032/** Convert row to MySQL column format using the key
1033@param[in] metadata row metadata
1034@param[in] sql_keys Key bunch
1035@param[in] key_offset offset for the key
1036@param[in,out] sql_rows row bunch to fill data
1037@param[in] sql_index index of the row to be filled
1038@return error code. */
1040 (const Row_meta &metadata, const Rows_mysql &sql_keys,
1041 size_t key_offset, Rows_mysql &sql_rows, size_t sql_index));
1042
1043/** Check if session is interrupted.
1044@param[in,out] thd session THD
1045@return true if connection or statement is killed. */
1047
1048/** Compare two key columns
1049@param[in] key1 first key
1050@param[in] key2 second key
1051@param[in] col_meta column meta information
1052@return positive, 0, negative, if key_1 is greater, equal, less than key_2 */
1054 (const Column_mysql &key1, const Column_mysql &key2,
1055 const Column_meta &col_meta));
1056
1057/** Get row metadata information for all the indexes.
1058@param[in,out] thd session THD
1059@param[in] table MySQL TABLE
1060@param[in] have_key include Primary Key metadata
1061@param[out] metadata Metadata for each of the indexes.
1062@return true if successful. */
1064 (THD * thd, const TABLE *table, bool have_key,
1065 std::vector<Row_meta> &metadata));
1066
1067/** Get table metadata information for the table being bulk loaded.
1068@param[in,out] thd session THD
1069@param[in] table MySQL TABLE
1070@param[out] metadata Metadata of the table.
1071@return true if successful. */
1073 (THD * thd, const TABLE *table, Table_meta &metadata));
1074
1075END_SERVICE_DEFINITION(bulk_data_convert)
1076
1077/** Column metadata information. */
1078/* Bulk data load to SE. */
1080/** Begin Loading bulk data to SE.
1081@param[in,out] thd session THD
1082@param[in] table MySQL TABLE
1083@param[in] keynr key number, identifying the index being loaded.
1084@param[in] data_size total data size to load
1085@param[in] memory SE memory to be used
1086@param[in] num_threads Number of concurrent threads
1087@return SE bulk load context or nullptr in case of an error. */
1088DECLARE_METHOD(void *, begin,
1089 (THD * thd, const TABLE *table, size_t keynr, size_t data_size,
1090 size_t memory, size_t num_threads));
1091
1092/** Load a set of rows to SE table by one thread.
1093@param[in,out] thd session THD
1094@param[in,out] ctx SE load context returned by begin()
1095@param[in] table MySQL TABLE
1096@param[in] sql_rows row data to load
1097@param[in] thread current thread number
1098@param[in] wait_cbks wait stat callbacks
1099@return true if successful. */
1100DECLARE_METHOD(bool, load,
1101 (THD * thd, void *ctx, const TABLE *table,
1102 const Rows_mysql &sql_rows, size_t thread,
1103 Bulk_load::Stat_callbacks &wait_cbks));
1104
1105/** Create a blob context object to insert a blob.
1106@param[in,out] thd session THD
1107@param[in,out] load_ctx SE load context returned by begin()
1108@param[in] table MySQL TABLE
1109@param[out] blob_ctx a blob context object to insert a blob.
1110@param[out] blobref buffer to hold blob reference
1111@param[in] thread current thread number
1112@return true if successful. */
1114 (THD * thd, void *load_ctx, const TABLE *table,
1115 Blob_context &blob_ctx, unsigned char *blobref, size_t thread));
1116
1117/** Write data into a blob
1118@param[in,out] thd session THD
1119@param[in,out] load_ctx SE load context returned by begin()
1120@param[in] table MySQL TABLE
1121@param[in] blob_ctx a blob context object to insert a blob.
1122@param[out] blobref buffer to hold blob reference
1123@param[in] thread current thread number
1124@param[in] data blob data to be written
1125@param[in] data_len length of blob data to be written (in bytes);
1126@return true if successful. */
1128 (THD * thd, void *load_ctx, const TABLE *table,
1129 Blob_context blob_ctx, unsigned char *blobref, size_t thread,
1130 const unsigned char *data, size_t data_len));
1131
1132/** Close the blob
1133@param[in,out] thd session THD
1134@param[in,out] load_ctx SE load context returned by begin()
1135@param[in] table MySQL TABLE
1136@param[in] blob_ctx a blob context object to insert a blob.
1137@param[out] blobref buffer to hold blob reference
1138@param[in] thread current thread number
1139@return true if successful. */
1141 (THD * thd, void *load_ctx, const TABLE *table,
1142 Blob_context blob_ctx, unsigned char *blobref, size_t thread));
1143
1144/** End Loading bulk data to SE.
1145
1146Called at the end of bulk load execution, even if begin or load calls failed.
1147
1148@param[in,out] thd session THD
1149@param[in,out] ctx SE load context
1150@param[in] table MySQL TABLE
1151@param[in] error true, if exiting after error
1152@return true if successful. */
1153DECLARE_METHOD(bool, end,
1154 (THD * thd, void *ctx, const TABLE *table, bool error));
1155
1156/** Check if a table is supported by the bulk load implementation.
1157@param[in,out] thd session THD
1158@param[in] table MySQL TABLE
1159@return true if table is supported. */
1161
1162/** Get available buffer pool memory for bulk load operations.
1163@param[in,out] thd session THD
1164@param[in] table MySQL TABLE
1165@return buffer pool memory available for bulk load. */
1167
1168/** Copies data from existing table into the duplicated table during incremental
1169load. This is called after the bulk load component detects we reached the end of
1170the CSV input for the respective sub-loader and it signals that the loader
1171should now iterate through the remainded or the existing data in the original
1172table and migrate it.
1173@param[in,out] ctx SE load context
1174@param[in] table MySQL TABLE
1175@param[in] thread loader thread index
1176@param[in,out] wait_cbks wait stat callbacks
1177@return true if successful, false otherwise. */
1179 (void *ctx, const TABLE *table, size_t thread,
1180 Bulk_load::Stat_callbacks &wait_cbks));
1181
1182/** Sets the source table data (table name and key range boundaries) for all
1183loaders.
1184@param[in,out] ctx SE load context
1185@param[in] table MySQL TABLE
1186@param[in] source_table_data vector containing the source table data
1187@return true if successful, false otherwise. */
1190 (void *ctx, const TABLE *table,
1191 const std::vector<Bulk_load::Source_table_data> &source_table_data));
1192
Kerberos Client Authentication nullptr
Definition: auth_kerberos_client_plugin.cc:247
constexpr size_t BLOB_REF_SIZE
The blob reference size.
Definition: bulk_data_service.h:56
void * Blob_context
Definition: bulk_data_service.h:53
std::ostream & operator<<(std::ostream &out, const Bulk_load_error_location_details &obj)
Overloading the global output operator to print objects of type Bulk_load_error_location_details.
Definition: bulk_data_service.h:84
Definition: bulk_data_service.h:891
const char * c_str() const
Definition: bulk_data_service.h:900
void KeyTooBig() const override
Called when a JSON object contains a member with a name that is longer than supported by the JSON bin...
Definition: bulk_data_service.h:908
std::string get_error() const
Definition: bulk_data_service.h:902
std::string m_error
Definition: bulk_data_service.h:905
void InternalError(const char *message) const override
Called when an internal error occurs.
Definition: bulk_data_service.h:922
void ValueTooBig() const override
Called when a JSON document is too big to be stored in the JSON binary format.
Definition: bulk_data_service.h:912
void TooDeep() const override
Called when a JSON document has more nesting levels than supported.
Definition: bulk_data_service.h:916
void InvalidJson() const override
Called when an invalid JSON value is encountered.
Definition: bulk_data_service.h:919
bool CheckStack() const override
Check if the stack is about to be exhausted, and report the error.
Definition: bulk_data_service.h:928
Error handler for the functions that serialize a JSON value in the JSON binary storage format.
Definition: json_error_handler.h:49
Implements the row and column memory management for parse and load operations.
Definition: bulk_data_service.h:327
bool set_num_rows(size_t n_rows)
Set the number of rows.
Definition: bulk_data_service.h:423
std::vector< Column_type > m_columns
All the columns.
Definition: bulk_data_service.h:458
size_t get_next_row_offset(size_t &offset) const
Get next row offset from current row offset.
Definition: bulk_data_service.h:381
Column_type & get_col(size_t col_offset)
Get column using the column offset.
Definition: bulk_data_service.h:407
bool process_columns(size_t row_index, F &&cbk)
Process all columns, invoking callback for each.
Definition: bulk_data_service.h:344
bool process_columns_by_offset(size_t row_offset, F &&cbk)
Definition: bulk_data_service.h:352
size_t get_num_cols() const
Definition: bulk_data_service.h:337
void reset()
Definition: bulk_data_service.h:364
size_t m_num_rows
Number of rows.
Definition: bulk_data_service.h:461
size_t get_row_offset(size_t row_index) const
Get current row offset to access columns.
Definition: bulk_data_service.h:373
size_t get_num_rows() const
Definition: bulk_data_service.h:334
const Column_type & read_column(size_t row_offset, size_t col_index) const
Get constant column for reading using row offset and column index.
Definition: bulk_data_service.h:413
Column_type & get_col(size_t row_index, size_t col_index)
Get column using row index and column index.
Definition: bulk_data_service.h:400
size_t get_total_cols() const
Get the total number of columns available in this row bunch.
Definition: bulk_data_service.h:454
Row_bunch(size_t n_cols)
Create a new row bunch.
Definition: bulk_data_service.h:331
static const size_t S_MAX_TOTAL_COLS
Limit allocation up to 600M columns.
Definition: bulk_data_service.h:450
size_t m_num_columns
Number of columns in each row.
Definition: bulk_data_service.h:464
Column_type & get_column(size_t row_offset, size_t col_index)
Get column using row offset and column index.
Definition: bulk_data_service.h:390
For each client connection we create a separate thread with THD serving as a thread/connection descri...
Definition: sql_lexer_thd.h:36
This file contains the field type.
enum_field_types
Column types for MySQL Note: Keep include/mysql/components/services/bits/stored_program_bits....
Definition: field_types.h:56
@ MYSQL_TYPE_BOOL
Currently just a placeholder.
Definition: field_types.h:80
@ MYSQL_TYPE_TIME2
Internal to MySQL.
Definition: field_types.h:76
@ MYSQL_TYPE_VARCHAR
Definition: field_types.h:72
@ MYSQL_TYPE_LONGLONG
Definition: field_types.h:65
@ MYSQL_TYPE_LONG_BLOB
Definition: field_types.h:87
@ MYSQL_TYPE_VAR_STRING
Definition: field_types.h:89
@ MYSQL_TYPE_BLOB
Definition: field_types.h:88
@ MYSQL_TYPE_TINY
Definition: field_types.h:58
@ MYSQL_TYPE_TIME
Definition: field_types.h:68
@ MYSQL_TYPE_SET
Definition: field_types.h:84
@ MYSQL_TYPE_NEWDATE
Internal to MySQL.
Definition: field_types.h:71
@ MYSQL_TYPE_VECTOR
Definition: field_types.h:78
@ MYSQL_TYPE_JSON
Definition: field_types.h:81
@ MYSQL_TYPE_STRING
Definition: field_types.h:90
@ MYSQL_TYPE_NULL
Definition: field_types.h:63
@ MYSQL_TYPE_ENUM
Definition: field_types.h:83
@ MYSQL_TYPE_TINY_BLOB
Definition: field_types.h:85
@ MYSQL_TYPE_LONG
Definition: field_types.h:60
@ MYSQL_TYPE_BIT
Definition: field_types.h:73
@ MYSQL_TYPE_INVALID
Definition: field_types.h:79
@ MYSQL_TYPE_GEOMETRY
Definition: field_types.h:91
@ MYSQL_TYPE_NEWDECIMAL
Definition: field_types.h:82
@ MYSQL_TYPE_DECIMAL
Definition: field_types.h:57
@ MYSQL_TYPE_TYPED_ARRAY
Used for replication only.
Definition: field_types.h:77
@ MYSQL_TYPE_DOUBLE
Definition: field_types.h:62
@ MYSQL_TYPE_MEDIUM_BLOB
Definition: field_types.h:86
@ MYSQL_TYPE_DATETIME2
Internal to MySQL.
Definition: field_types.h:75
@ MYSQL_TYPE_SHORT
Definition: field_types.h:59
@ MYSQL_TYPE_DATE
Definition: field_types.h:67
@ MYSQL_TYPE_FLOAT
Definition: field_types.h:61
@ MYSQL_TYPE_TIMESTAMP
Definition: field_types.h:64
@ MYSQL_TYPE_INT24
Definition: field_types.h:66
@ MYSQL_TYPE_DATETIME
Definition: field_types.h:69
@ MYSQL_TYPE_TIMESTAMP2
Definition: field_types.h:74
@ MYSQL_TYPE_YEAR
Definition: field_types.h:70
static int compare_keys(PFS_table_share *pfs, const TABLE_SHARE *share)
Definition: pfs_instr_class.cc:2435
static uint16 key1[1001]
Definition: hp_test2.cc:50
#define F
Definition: jit_executor_value.cc:374
#define UINT16_MAX
Definition: lexyy.cc:83
void error(const char *format,...)
int mysql_format_from_raw(char *buffer, size_t buffer_length, const Row_meta &metadata, size_t start_index, size_t &consumed_length, Rows_mysql &sql_rows) noexcept
Definition: bulk_data_service.cc:1893
bool get_table_metadata(THD *thd, const TABLE *table, Table_meta &table_meta) noexcept
Definition: bulk_data_service.cc:2592
int mysql_format(THD *thd, const TABLE *table, const Rows_text &text_rows, size_t &next_index, char *buffer, size_t &buffer_length, const CHARSET_INFO *charset, const Row_meta &metadata, Rows_mysql &sql_rows, Bulk_load_error_location_details &error_details) noexcept
Definition: bulk_data_service.cc:1924
bool get_row_metadata_all(THD *thd, const TABLE *table, bool have_key, std::vector< Row_meta > &row_meta_all) noexcept
Definition: bulk_data_service.cc:2613
int mysql_format_using_key(const Row_meta &metadata, const Rows_mysql &sql_keys, size_t key_offset, Rows_mysql &sql_rows, size_t sql_index) noexcept
Definition: bulk_data_service.cc:1871
bool is_killed(THD *thd) noexcept
Definition: bulk_data_service.cc:1976
bool copy_existing_data(void *ctx, const TABLE *duplicate_table, size_t thread, Bulk_load::Stat_callbacks &wait_cbks) noexcept
Definition: bulk_data_service.cc:2795
bool open_blob(THD *thd, void *load_ctx, const TABLE *table, Blob_context &blob_ctx, unsigned char *blobref, size_t thread) noexcept
Definition: bulk_data_service.cc:2681
size_t get_se_memory_size(THD *thd, const TABLE *table) noexcept
Definition: bulk_data_service.cc:2789
bool set_source_table_data(void *ctx, const TABLE *duplicate_table, const std::vector< Bulk_load::Source_table_data > &source_table_data) noexcept
Definition: bulk_data_service.cc:2804
bool write_blob(THD *thd, void *load_ctx, const TABLE *table, Blob_context blob_ctx, unsigned char *blobref, size_t thread, const unsigned char *data, size_t data_len) noexcept
Definition: bulk_data_service.cc:2691
bool close_blob(THD *thd, void *load_ctx, const TABLE *table, Blob_context blob_ctx, unsigned char *blobref, size_t thread) noexcept
Definition: bulk_data_service.cc:2699
bool is_table_supported(THD *thd, const TABLE *table) noexcept
Definition: bulk_data_service.cc:2809
Definition: bulk_data_service.h:888
std::pair< std::optional< Rows_mysql >, std::optional< Rows_mysql > > Read_range
Definition: bulk_data_service.h:941
static PFS_engine_table_share_proxy table
Definition: pfs.cc:61
const std::string charset("charset")
bool load(THD *, const dd::String_type &fname, dd::String_type *buf)
Read an sdi file from disk and store in a buffer.
Definition: sdi_file.cc:308
std::string hex(const Container &c)
Definition: hex.h:61
bool index(const std::string &value, const String &search_for, uint32_t *idx)
Definition: contains.h:76
int key_type
Definition: method.h:38
Definition: aligned_atomic.h:44
ValueType max(X &&first)
Definition: gtid.h:103
const char * begin(const char *const c)
Definition: base64.h:44
mutable_buffer buffer(void *p, size_t n) noexcept
Definition: buffer.h:418
Cursor end()
A past-the-end Cursor.
Definition: rules_table_service.cc:192
Define std::hash<Gtid>.
Definition: gtid.h:355
std::basic_ostringstream< char, std::char_traits< char >, ut::allocator< char > > ostringstream
Specialization of basic_ostringstream which uses ut::allocator.
Definition: ut0new.h:2720
std::vector< T, ut::allocator< T > > vector
Specialization of vector which uses allocator.
Definition: ut0new.h:2724
static std::mutex lock
Definition: net_ns.cc:56
Column_type
Framework that helps consuming data in a specific format, typically provided by a service API,...
Definition: row_proxy.h:43
#define DECLARE_METHOD(retval, name, args)
Declares a method as a part of the Service definition.
Definition: service.h:103
#define END_SERVICE_DEFINITION(name)
A macro to end the last Service definition started with the BEGIN_SERVICE_DEFINITION macro.
Definition: service.h:91
#define BEGIN_SERVICE_DEFINITION(name)
Declares a new Service.
Definition: service.h:86
Contains the data needed for the ROW_ID generation for tables without explicit primary key.
Definition: bulk_data_service.h:951
std::pair< uint64_t, uint64_t > get_next_rowid_range() const
Get the next available range for generating DB_ROW_ID.
Definition: bulk_data_service.h:969
size_t get_rows_per_thread() const
Get an estimate of the number of rows to be handled by each thread.
Definition: bulk_data_service.h:955
std::atomic< size_t > m_avg_row_len
Definition: bulk_data_service.h:982
std::mutex m_rowid_mutex
Protects the member m_next_rowid_range.
Definition: bulk_data_service.h:988
void set_begin_rowid_value(size_t row_id)
Definition: bulk_data_service.h:978
size_t m_n_loaders
Definition: bulk_data_service.h:984
size_t m_total_size
Definition: bulk_data_service.h:980
size_t m_next_rowid_range
Definition: bulk_data_service.h:991
Definition: bulk_data_service.h:943
Read_range range
Definition: bulk_data_service.h:946
std::string table
Definition: bulk_data_service.h:945
std::string schema
Definition: bulk_data_service.h:944
Callbacks for collecting time statistics.
Definition: bulk_data_service.h:933
std::function< void()> m_fn_begin
Definition: bulk_data_service.h:935
std::function< void()> m_fn_end
Definition: bulk_data_service.h:937
Definition: bulk_data_service.h:58
std::string filename
Definition: bulk_data_service.h:59
std::string m_table_name
Definition: bulk_data_service.h:65
size_t m_bytes
Definition: bulk_data_service.h:66
size_t row_number
Definition: bulk_data_service.h:60
std::string column_input_data
Definition: bulk_data_service.h:63
std::string column_name
Definition: bulk_data_service.h:61
size_t m_column_length
Definition: bulk_data_service.h:67
std::string m_error_mesg
Definition: bulk_data_service.h:64
std::ostream & print(std::ostream &out) const
Definition: bulk_data_service.h:72
std::string column_type
Definition: bulk_data_service.h:62
Definition: m_ctype.h:421
Column metadata information.
Definition: bulk_data_service.h:471
bool m_is_prefix_key
If the prefix of this column is part of key.
Definition: bulk_data_service.h:529
enum_field_types m_type
Field type.
Definition: bulk_data_service.h:514
std::string m_field_name
Field name.
Definition: bulk_data_service.h:572
std::string get_type_string() const
Get the data type of the column as a string.
Definition: bulk_data_service.h:621
uint16_t m_index
Index of column in row.
Definition: bulk_data_service.h:557
bool m_is_single_byte_len
If character column length can be kept in one byte.
Definition: bulk_data_service.h:548
uint16_t m_null_byte
Byte index in NULL bitmap.
Definition: bulk_data_service.h:563
bool m_is_desc_key
If the key is descending.
Definition: bulk_data_service.h:526
Compare m_compare
If it is integer type.
Definition: bulk_data_service.h:538
bool m_is_pk
true if column belongs to primary index (key or non-key)
Definition: bulk_data_service.h:520
uint16_t m_fixed_len
The length of column data if fixed.
Definition: bulk_data_service.h:551
std::string to_string() const
Get a string representation of Column_meta object.
Definition: bulk_data_service.h:715
bool is_integer() const
Definition: bulk_data_service.h:500
Compare
Data comparison method.
Definition: bulk_data_service.h:473
uint16_t m_field_index
Position of column in table.
Definition: bulk_data_service.h:560
uint16_t m_max_len
Maximum length of data in bytes.
Definition: bulk_data_service.h:554
bool m_is_fixed_len
If it is fixed length type.
Definition: bulk_data_service.h:535
bool m_is_key
true if column is a key for primary or secondary index.
Definition: bulk_data_service.h:523
uint16_t m_null_bit
BIT number in NULL bitmap.
Definition: bulk_data_service.h:566
bool can_be_stored_externally() const
Based on the column data type check if it can be stored externally.
Definition: bulk_data_service.h:697
bool m_fixed_len_if_set_in_row
Check the row header to find out if it is fixed length.
Definition: bulk_data_service.h:545
std::ostream & print(std::ostream &out) const
Print this object into the given output stream.
Definition: bulk_data_service.h:730
bool m_is_nullable
If column could be NULL.
Definition: bulk_data_service.h:517
bool m_is_part_of_sk
true if this column is part of secondary index.
Definition: bulk_data_service.h:511
bool m_is_unsigned
If it is unsigned integer type.
Definition: bulk_data_service.h:541
size_t get_length_size() const
The number of bytes used to store length information.
Definition: bulk_data_service.h:595
std::string get_compare_string() const
Definition: bulk_data_service.h:484
size_t m_prefix_len
Prefix length.
Definition: bulk_data_service.h:532
const void * m_charset
Character set for char & varchar columns.
Definition: bulk_data_service.h:569
Definition: bulk_data_service.h:210
uint64_t m_int_data
Column data in integer format.
Definition: bulk_data_service.h:261
bool is_ext() const
Check if the column is externally stored.
Definition: bulk_data_service.h:240
std::string to_string() const
Definition: bulk_data_service.h:286
bool m_is_null
If column is NULL.
Definition: bulk_data_service.h:220
void set_ext()
Mark this column as externally stored.
Definition: bulk_data_service.h:236
bool m_is_prefix
Definition: bulk_data_service.h:217
char * get_row_begin(const Row_meta &row_meta, size_t col_index) const
Get the pointer to the beginning of row.
Definition: bulk_data_service.h:879
char * m_data_ptr
Column data or row begin.
Definition: bulk_data_service.h:283
char * get_data() const
Get the column data.
Definition: bulk_data_service.h:229
int16_t m_type
Column Data Type.
Definition: bulk_data_service.h:212
uint16_t m_data_len
Column data length.
Definition: bulk_data_service.h:215
void set_data(char *ptr)
Set the column data to the given pointer location.
Definition: bulk_data_service.h:233
void init()
Definition: bulk_data_service.h:263
bool m_is_ext
If true, the column data is stored externally in InnoDB.
Definition: bulk_data_service.h:225
void row(char *row_begin)
Save the beginning of the row pointer in this object.
Definition: bulk_data_service.h:245
Definition: bulk_data_service.h:89
bool is_null() const
Check if the column is null, by checking special value for length.
Definition: bulk_data_service.h:116
bool is_ext_relaxed() const
Check if the column data is stored externally.
Definition: bulk_data_service.h:135
bool m_is_ext
If true, the column data is stored externally.
Definition: bulk_data_service.h:163
void set_null()
Mark the column to be null, by setting length to a special value.
Definition: bulk_data_service.h:109
std::ostream & print(std::ostream &out) const
Print this object into the given output stream.
Definition: bulk_data_service.h:192
const char * m_data_ptr
Column data.
Definition: bulk_data_service.h:91
bool is_row_id() const
Check if it is DB_ROW_ID column based on the value it contains.
Definition: bulk_data_service.h:101
uint64_t m_row_id
The generated DB_ROW_ID value.
Definition: bulk_data_service.h:104
size_t m_prefix_len
Prefix length.
Definition: bulk_data_service.h:97
void init()
Initialize the members.
Definition: bulk_data_service.h:147
void set_ext()
Mark that the column data has been stored externally.
Definition: bulk_data_service.h:141
bool is_ext() const
Check if the column data is stored externally.
Definition: bulk_data_service.h:126
size_t m_data_len
Column data length.
Definition: bulk_data_service.h:94
std::string to_string() const
Definition: bulk_data_service.h:166
Definition: mysql.h:303
Row metadata.
Definition: bulk_data_service.h:763
const Column_meta & get_column_meta_index_order(size_t col_index) const
Get the metadata of the given column.
Definition: bulk_data_service.h:787
const Column_meta & get_column_meta(size_t col_index) const
Get the meta data of the column.
Definition: bulk_data_service.h:795
size_t m_n_blob_cols
Number of columns that can be stored externally.
Definition: bulk_data_service.h:832
size_t m_bitmap_length
Total bitmap header length for the row.
Definition: bulk_data_service.h:802
std::string to_string() const
Get a string representation of this Row_meta object.
Definition: bulk_data_service.h:863
bool dbrowid_is_pk
true if DB_ROW_ID is the pk, false otherwise.
Definition: bulk_data_service.h:841
size_t m_first_key_len
Length of the first key column.
Definition: bulk_data_service.h:809
size_t m_header_length
Total header length.
Definition: bulk_data_service.h:805
Key_type
Key type for fast comparison.
Definition: bulk_data_service.h:765
uint32_t m_non_keys
Number of columns not used in primary Key.
Definition: bulk_data_service.h:819
uint32_t m_num_columns
Total number of columns.
Definition: bulk_data_service.h:826
size_t m_keynr
Key number of the index being built.
Definition: bulk_data_service.h:844
uint32_t m_keys
Number of columns used in primary key.
Definition: bulk_data_service.h:816
size_t m_key_length
Key length in bytes for non-integer keys.
Definition: bulk_data_service.h:813
std::string m_name
Name of the key.
Definition: bulk_data_service.h:835
std::vector< Column_meta > m_columns
All columns in a row are arranged with key columns first.
Definition: bulk_data_service.h:774
std::vector< const Column_meta * > m_columns_text_order
All columns in a row arranged as per col_index.
Definition: bulk_data_service.h:777
Key_type m_key_type
Key type for comparison.
Definition: bulk_data_service.h:822
size_t m_approx_row_len
Approximate row length.
Definition: bulk_data_service.h:829
bool is_pk
true if primary key, false if secondary key.
Definition: bulk_data_service.h:838
Definition: table.h:1456
Table metadata.
Definition: bulk_data_service.h:745
size_t m_keynr_pk
Key number of the primary key.
Definition: bulk_data_service.h:750
size_t max_row_id_value
Definition: bulk_data_service.h:756
bool dbrowid_is_pk
True if generated DB_ROW_ID is the pk.
Definition: bulk_data_service.h:753
std::string m_table_name
Table being bulk loaded.
Definition: bulk_data_service.h:759
size_t min_row_id_value
Definition: bulk_data_service.h:755
size_t m_n_keys
Number of keys/indexes the table has.
Definition: bulk_data_service.h:747