forked from mysql/mysql-server
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsdi_utils.h
145 lines (124 loc) · 4.91 KB
/
sdi_utils.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
/* Copyright (c) 2014, 2024, Oracle and/or its affiliates.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License, version 2.0,
as published by the Free Software Foundation.
This program is designed to work with certain software (including
but not limited to OpenSSL) that is licensed under separate terms,
as designated in a particular file or component or in included license
documentation. The authors of MySQL hereby grant you an additional
permission to link the program and your derivative works with the
separately licensed software that they have either included with
the program or referenced in the documentation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
#ifndef DD__SDI_UTILS_INCLUDED
#define DD__SDI_UTILS_INCLUDED
#include <assert.h>
#include "sql/current_thd.h" // inline_current_thd
#include "sql/dd/string_type.h" // dd::String_type
#include "sql/error_handler.h" // Internal_error_handler
#include "sql/mdl.h" // MDL_request
#include "sql/sql_class.h" // THD
#ifndef NDEBUG
#define ENTITY_FMT "(%s, %llu)"
#define ENTITY_VAL(obj) (obj).name().c_str(), (obj).id()
#endif /* !NDEBUG */
/**
@file
@ingroup sdi
Inline utility functions used in different
TUs. Declared inline in header to avoid any overhead as they are
only a syntactic convnience (macro replacement).
*/
namespace dd {
namespace sdi_utils {
/**
In debug mode, check that a true argument is paired with
thd->is_error() or thd->killed being set. In optimized mode it turns into
a noop.
@param[in] ret return value to check
@return same as argument passed in
*/
inline bool checked_return(bool ret) {
#ifndef NDEBUG
THD *cthd = current_thd;
assert(!ret || cthd->is_system_thread() || cthd->is_error() || cthd->killed);
#endif /*!NDEBUG*/
return ret;
}
/**
Convenience function for obtaining MDL. Sets up the MDL_request
struct and populates it, before calling Mdl_context::acquire_lock.
@param thd thread context
@param ns MDL key namespace
@param schema_name schema name
@param object_name object name
@param mt MDL type
@param md MDL duration
@return value from Mdl_context::acquire_lock
*/
inline bool mdl_lock(THD *thd, MDL_key::enum_mdl_namespace ns,
const String_type &schema_name,
const String_type &object_name,
enum_mdl_type mt = MDL_EXCLUSIVE,
enum_mdl_duration md = MDL_TRANSACTION) {
MDL_request mdl_request;
MDL_REQUEST_INIT(&mdl_request, ns, schema_name.c_str(), object_name.c_str(),
mt, md);
return checked_return(thd->mdl_context.acquire_lock(
&mdl_request, thd->variables.lock_wait_timeout));
}
template <typename T>
const T &ptr_as_cref(const T *p) {
assert(p != nullptr);
return *p;
}
/**
Class template which derives from Internal_error_handler and
overrides handle_condition with the CONDITION_HANDLER_CLOS template
parameter.
*/
template <typename CONDITION_HANDLER_CLOS>
class Closure_error_handler : public Internal_error_handler {
CONDITION_HANDLER_CLOS m_ch;
bool handle_condition(THD *, uint sql_errno, const char *sqlstate,
Sql_condition::enum_severity_level *level,
const char *msg) override {
return m_ch(sql_errno, sqlstate, level, msg);
}
public:
// CONDITION_HANDLER_CLOS is *class* template argument, so there is no type
// deduction, and ch must refer to an R-value. So it is safe to move.
explicit Closure_error_handler(CONDITION_HANDLER_CLOS &&ch)
: m_ch(std::move(ch)) {}
};
/**
Set up a custom error handler to use for errors from the execution
of a closure.
@param thd thread context
@param chc closure which implements the
Internal_error_handler::handle_condition override
@param ac closure action for which error conditions should be handled.
@retval true if an error occurs
@retval false otherwise
*/
template <typename CH_CLOS, typename ACTION_CLOS>
bool handle_errors(THD *thd, CH_CLOS &&chc, ACTION_CLOS &&ac) {
Closure_error_handler<CH_CLOS> eh{std::forward<CH_CLOS>(chc)};
thd->push_internal_handler(&eh);
bool r = ac();
thd->pop_internal_handler();
return r;
}
template <typename P_TYPE, typename CLOS_TYPE>
std::unique_ptr<P_TYPE, CLOS_TYPE> make_guard(P_TYPE *p, CLOS_TYPE &&clos) {
return std::unique_ptr<P_TYPE, CLOS_TYPE>(p, std::forward<CLOS_TYPE>(clos));
}
} // namespace sdi_utils
} // namespace dd
#endif // DD__SDI_UTILS_INCLUDED