MySQL 9.7.0
Source Code Documentation
packet_based_table_with_cursor.h
Go to the documentation of this file.
1/* Copyright (c) 2024, 2026, Oracle and/or its affiliates.
2
3This program is free software; you can redistribute it and/or modify
4it under the terms of the GNU General Public License, version 2.0,
5as published by the Free Software Foundation.
6
7This program is designed to work with certain software (including
8but not limited to OpenSSL) that is licensed under separate terms,
9as designated in a particular file or component or in included license
10documentation. The authors of MySQL hereby grant you an additional
11permission to link the program and your derivative works with the
12separately licensed software that they have either included with
13the program or referenced in the documentation.
14
15This program is distributed in the hope that it will be useful,
16but WITHOUT ANY WARRANTY; without even the implied warranty of
17MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18GNU General Public License, version 2.0, for more details.
19
20You should have received a copy of the GNU General Public License
21along with this program; if not, write to the Free Software
22Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
23
24#ifndef PACKET_BASED_TABLE_WITH_CURSOR_H
25#define PACKET_BASED_TABLE_WITH_CURSOR_H
26
27#include <atomic> // std::atomic
28#include <cassert> // assert
29#include <concepts> // std::same_as, std::derived_from
30#include <type_traits> // std::is_enum_v
31#include "mysql/abi_helpers/packet.h" // Packet_array
33#include "mysql/meta/is_const_ref.h" // Is_const_ref
34#include "row_proxy.h" // Row_proxy
35
36namespace detail {
37
38/// Helper to define Is_row_view_definition. This is the "false" case,
39/// matching any type that does not match the following case.
40template <class Type>
41struct Is_row_view_definition_helper : public std::false_type {};
42/// Helper to define Is_row_view_definition. This is the "true" case, matching
43/// any type that is a specialization of Row_view_definition.
44template <class T1, auto T2, auto T3>
46 : public std::true_type {};
47
48/// True if std::remove_cvref_t<Type> is a speciaization of Row_view_definition.
49template <class Type>
51 Is_row_view_definition_helper<std::remove_cvref_t<Type>>::value;
52
53/// True if Type is a const reference to a specialization of
54/// Row_view_definition.
55template <class Type>
58
59/// The return type for the non-static member function
60/// Type::get_row_view_definition.
61template <class Type>
62using Return_type_for_get_row_view_definition = std::remove_cvref_t<
63 decltype(std::declval<Type>().get_row_view_definition())>;
64
65/// Row_proxy_type_info object based on the types found in the given
66/// Row_view_definition.
67template <class Type>
69 Row_proxy_type_info<typename Type::value_type::Typecode_t,
70 Type::value_type::typecode_end,
71 std::tuple_size<Type>{}>;
72
73/// Row_proxy_type_info object based on the types found in the
74/// Row_view_definition returned from Type::get_row_view_definition().
75template <class Type>
78
79} // namespace detail
80
81/// Concept that identifies classes that correctly implement the requirements
82/// for classes used to implement @c Packet_based_table_with_cursor .
83///
84/// In order to satisfy the concept, classes must define the following member
85/// functions:
86///
87/// - get_table_data() -> mysql::abi_helpers::Packet_array<Typecode_tp>:
88/// Will be called from the constructor and must return the table data as an
89/// array of packets.
90///
91/// - free_table_data(mysql::abi_helpers::Packet_array<Typecode_tp>): Will
92/// be called from the destructor and must release any memory that was allocated
93/// in get_table.
94///
95/// - static get_row_view_definition() -> const Row_view_definition<...> &: must
96/// return a const reference to a specialization of Row_view_definition. The
97/// returned object determines how the table data will be converted to an SQL
98/// table. See @c Row_proxy. The referenced object must outlive the
99/// Packet_based_table_with_cursor object. Typically, the referenced object may
100/// reside in static storage, for example as a static local variable in
101/// get_row_view_definition.
102///
103/// - static get_table_name() -> const char *: must return the table name as a
104/// string.
105///
106/// - static get_table_definition() -> const char *: must return the table
107/// definition as a string.
108///
109/// tparam Impl_tp The implementation class to test.
110template <class Impl_tp>
112 requires(const Impl_tp const_impl) {
113 {
114 const_impl.get_row_view_definition()
116 { const_impl.get_table_name() } -> std::same_as<const char *>;
117 { const_impl.get_table_definition() } -> std::same_as<const char *>;
118 } &&
119 requires(
120 Impl_tp impl,
122 table) {
123 {
124 impl.get_table_data()
125 }
126 -> std::same_as<typename detail::Type_info_for_get_row_view_definition<
127 Impl_tp>::Table_t>;
128 { impl.free_table_data(table) };
129 };
130
131/// @brief Class to aid implementing a _table with cursor_ ( @c
132/// Is_table_with_cursor) where the table data is represented in a @c
133/// mysql::abi_helpers::Packet_array object.
134///
135/// @tparam Impl_tp Implementation capable of returning the name, definition,
136/// and data for the table.
137template <Is_packet_based_table_with_cursor_implementation Impl_tp>
139 public:
140 /// Type of the implementation.
141 using Impl_t = Impl_tp;
142 /// Type of Row_view_definitions returned by the get_row_view_definition()
143 /// member of Impl_t.
145
147 : m_impl{},
148 m_table(m_impl.get_table_data()),
149 m_row_proxy(m_impl.get_row_view_definition()) {
151 std::memory_order_relaxed);
152 }
153
155
156 /// Delete copy/move semantics
158 delete;
161 const Packet_based_table_with_cursor &) = delete;
163 delete;
164
165 /// Return the table name.
166 static const char *get_table_name() { return Impl_t::get_table_name(); }
167
168 /// Return the table definition.
169 static const char *get_table_definition() {
170 return Impl_t::get_table_definition();
171 }
172
173 /// Move the cursor to the given row number.
174 void set_cursor(int row) {
175 m_cursor = row;
176 m_cursor_dirty = true;
177 }
178
179 /// Return the current cursor (row number).
180 int get_cursor() { return m_cursor; }
181
182 /// Move the cursor to next row.
183 void advance() {
184 ++m_cursor;
185 m_cursor_dirty = true;
186 }
187
188 /// @return true if the cursor is positioned at the end of the table.
189 bool is_at_end() const { return m_cursor == m_table.ssize(); }
190
191 /// Copy the value of the given field index to the given PSI_field object.
192 /// @param index The column number
193 /// @param field The output PSI_field.
194 void copy_field(int index, PSI_field *field) const {
195 if (m_cursor_dirty) {
196 assert(m_cursor < m_table.ssize());
198 m_cursor_dirty = false;
199 }
201 }
202
203 /// Return the cached approximate row count.
206 std::memory_order_relaxed);
207 }
208
209 private:
211
212 /// Return a reference to an atomic integer that caches the row count for the
213 /// last created object.
214 ///
215 /// (This could have been implemented as a static member variable. But that
216 /// would be less convenient, since each specialization of this class template
217 /// would have to provide a definition of the member variable in exactly one
218 /// compilation unit. Using a function-local static variable, the variable
219 /// gets automatically instantiated in each specialization of the function.)
220 static std::atomic<int> &get_cached_approximate_row_count_ref() {
221 static std::atomic<int> counter{0};
222 return counter;
223 }
224
225 /// Table object.
227
228 /// Current cursor position.
229 int m_cursor{0};
230
231 /// Row proxy, containing a view over the current row.
232 ///
233 /// This is capable of translating column index to an entry in the
234 /// mysql::abi_helpers::Packet object for the current row, and of copying the
235 /// value in that column to a PSI_field object.
236 ///
237 /// Mutable, because it is updated lazily. The actual object state is
238 /// represented by m_table and m_cursor.
240
241 /// True if the cursor has moved away from the row that m_row_proxy refers to.
242 mutable bool m_cursor_dirty{true};
243};
244
245#endif // ifndef PACKET_BASED_TABLE_WITH_CURSOR_H
Class to aid implementing a table with cursor ( Is_table_with_cursor) where the table data is represe...
Definition: packet_based_table_with_cursor.h:138
void advance()
Move the cursor to next row.
Definition: packet_based_table_with_cursor.h:183
bool m_cursor_dirty
True if the cursor has moved away from the row that m_row_proxy refers to.
Definition: packet_based_table_with_cursor.h:242
Packet_based_table_with_cursor(const Packet_based_table_with_cursor &)=delete
Delete copy/move semantics.
static const char * get_table_name()
Return the table name.
Definition: packet_based_table_with_cursor.h:166
Impl_tp Impl_t
Type of the implementation.
Definition: packet_based_table_with_cursor.h:141
Packet_based_table_with_cursor & operator=(const Packet_based_table_with_cursor &)=delete
Packet_based_table_with_cursor(Packet_based_table_with_cursor &&)=delete
static int get_approximate_row_count()
Return the cached approximate row count.
Definition: packet_based_table_with_cursor.h:204
static const char * get_table_definition()
Return the table definition.
Definition: packet_based_table_with_cursor.h:169
bool is_at_end() const
Definition: packet_based_table_with_cursor.h:189
Impl_t m_impl
Definition: packet_based_table_with_cursor.h:210
~Packet_based_table_with_cursor()
Definition: packet_based_table_with_cursor.h:154
static std::atomic< int > & get_cached_approximate_row_count_ref()
Return a reference to an atomic integer that caches the row count for the last created object.
Definition: packet_based_table_with_cursor.h:220
Packet_based_table_with_cursor & operator=(Packet_based_table_with_cursor &&)=delete
void set_cursor(int row)
Move the cursor to the given row number.
Definition: packet_based_table_with_cursor.h:174
Type_info_t::Row_proxy_t m_row_proxy
Row proxy, containing a view over the current row.
Definition: packet_based_table_with_cursor.h:239
Packet_based_table_with_cursor()
Definition: packet_based_table_with_cursor.h:146
void copy_field(int index, PSI_field *field) const
Copy the value of the given field index to the given PSI_field object.
Definition: packet_based_table_with_cursor.h:194
int get_cursor()
Return the current cursor (row number).
Definition: packet_based_table_with_cursor.h:180
int m_cursor
Current cursor position.
Definition: packet_based_table_with_cursor.h:229
Type_info_t::Table_t m_table
Table object.
Definition: packet_based_table_with_cursor.h:226
Forward declaration.
Definition: row_proxy.h:142
void set_row(const typename Type_info_t::Row_t &row)
Make the proxy be a view over the given row.
Definition: row_proxy.h:168
void copy_field(int index, PSI_field *target) const
Copy the value of the given field of the current row to the target.
Definition: row_proxy.h:180
Ownership-agnostic array class, which is both trivial and standard-layout.
Definition: array_view.h:53
std::ptrdiff_t ssize() const
Definition: array_base.h:58
std::size_t size() const
Definition: array_base.h:55
Concept that identifies classes that correctly implement the requirements for classes used to impleme...
Definition: packet_based_table_with_cursor.h:111
True if Type is a const reference to a specialization of Row_view_definition.
Definition: packet_based_table_with_cursor.h:56
True if std::remove_cvref_t<Type> is a speciaization of Row_view_definition.
Definition: packet_based_table_with_cursor.h:50
True if Type is a const reference.
Definition: is_const_ref.h:39
Experimental API header.
uint counter
Definition: mysqlimport.cc:58
static PFS_engine_table_share_proxy table
Definition: pfs.cc:61
Definition: packet_based_table_with_cursor.h:36
std::remove_cvref_t< decltype(std::declval< Type >().get_row_view_definition())> Return_type_for_get_row_view_definition
The return type for the non-static member function Type::get_row_view_definition.
Definition: packet_based_table_with_cursor.h:63
bool index(const std::string &value, const String &search_for, uint32_t *idx)
Definition: contains.h:76
Definition: http_server_component.cc:34
ValueType value(const std::optional< ValueType > &v)
Definition: gtid.h:83
Experimental API header.
struct PSI_field PSI_field
This is an opaque structure to denote field in plugin/component code.
Definition: pfs_plugin_table_service.h:93
std::array< Field_view_definition< Typecode_tp, typecode_end_tp >, column_count_tp > Row_view_definition
Description of the mapping between columns and field typecodes, for all columns in a table.
Definition: row_proxy.h:84
Aggregates type definitions and constants for a given typecode enum, end element of that enum,...
Definition: row_proxy.h:96
Helper to define Is_row_view_definition.
Definition: packet_based_table_with_cursor.h:41