1/* Copyright (c) 2016, MariaDB corporation. All rights
2 reserved.
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; version 2 of the License.
7
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12
13 You should have received a copy of the GNU General Public License
14 along with this program; if not, write to the Free Software
15 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
16
17#define MYSQL_SERVER 1
18#include <my_global.h>
19#include <mysql_version.h>
20#include <mysqld.h>
21#include <mysql/plugin.h>
22#include "sql_plugin.h" // st_plugin_int
23#include "sql_class.h"
24#include "item.h"
25#include "vers_utils.h"
26
27/* System Versioning: TRT_TRX_ID(), TRT_COMMIT_ID(), TRT_BEGIN_TS(), TRT_COMMIT_TS(), TRT_ISO_LEVEL() */
28template <TR_table::field_id_t TRT_FIELD>
29class Create_func_trt : public Create_native_func
30{
31public:
32 virtual Item *create_native(THD *thd, LEX_CSTRING *name, List<Item> *item_list);
33
34 static Create_func_trt<TRT_FIELD> s_singleton;
35
36protected:
37 Create_func_trt<TRT_FIELD>() {}
38 virtual ~Create_func_trt<TRT_FIELD>() {}
39};
40
41template<TR_table::field_id_t TRT_FIELD>
42Create_func_trt<TRT_FIELD> Create_func_trt<TRT_FIELD>::s_singleton;
43
44template <TR_table::field_id_t TRT_FIELD>
45Item*
46Create_func_trt<TRT_FIELD>::create_native(THD *thd, LEX_CSTRING *name,
47 List<Item> *item_list)
48{
49 Item *func= NULL;
50 int arg_count= 0;
51
52 if (item_list != NULL)
53 arg_count= item_list->elements;
54
55 switch (arg_count) {
56 case 1:
57 {
58 Item *param_1= item_list->pop();
59 switch (TRT_FIELD)
60 {
61 case TR_table::FLD_BEGIN_TS:
62 case TR_table::FLD_COMMIT_TS:
63 func= new (thd->mem_root) Item_func_trt_ts(thd, param_1, TRT_FIELD);
64 break;
65 case TR_table::FLD_TRX_ID:
66 case TR_table::FLD_COMMIT_ID:
67 case TR_table::FLD_ISO_LEVEL:
68 func= new (thd->mem_root) Item_func_trt_id(thd, param_1, TRT_FIELD);
69 break;
70 default:
71 DBUG_ASSERT(0);
72 }
73 break;
74 }
75 case 2:
76 {
77 Item *param_1= item_list->pop();
78 Item *param_2= item_list->pop();
79 switch (TRT_FIELD)
80 {
81 case TR_table::FLD_TRX_ID:
82 case TR_table::FLD_COMMIT_ID:
83 func= new (thd->mem_root) Item_func_trt_id(thd, param_1, param_2, TRT_FIELD);
84 break;
85 default:
86 goto error;
87 }
88 break;
89 }
90 error:
91 default:
92 {
93 my_error(ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT, MYF(0), name->str);
94 break;
95 }
96 }
97
98 return func;
99};
100
101template <class Item_func_trt_trx_seesX>
102class Create_func_trt_trx_sees : public Create_native_func
103{
104public:
105 virtual Item *create_native(THD *thd, LEX_CSTRING *name, List<Item> *item_list)
106 {
107 Item *func= NULL;
108 int arg_count= 0;
109
110 if (item_list != NULL)
111 arg_count= item_list->elements;
112
113 switch (arg_count) {
114 case 2:
115 {
116 Item *param_1= item_list->pop();
117 Item *param_2= item_list->pop();
118 func= new (thd->mem_root) Item_func_trt_trx_seesX(thd, param_1, param_2);
119 break;
120 }
121 default:
122 my_error(ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT, MYF(0), name->str);
123 break;
124 }
125
126 return func;
127 }
128
129 static Create_func_trt_trx_sees<Item_func_trt_trx_seesX> s_singleton;
130
131protected:
132 Create_func_trt_trx_sees<Item_func_trt_trx_seesX>() {}
133 virtual ~Create_func_trt_trx_sees<Item_func_trt_trx_seesX>() {}
134};
135
136template<class X>
137Create_func_trt_trx_sees<X> Create_func_trt_trx_sees<X>::s_singleton;
138
139#define BUILDER(F) & F::s_singleton
140
141static Native_func_registry func_array[] =
142{
143 { { C_STRING_WITH_LEN("TRT_BEGIN_TS") }, BUILDER(Create_func_trt<TR_table::FLD_BEGIN_TS>)},
144 { { C_STRING_WITH_LEN("TRT_COMMIT_ID") }, BUILDER(Create_func_trt<TR_table::FLD_COMMIT_ID>)},
145 { { C_STRING_WITH_LEN("TRT_COMMIT_TS") }, BUILDER(Create_func_trt<TR_table::FLD_COMMIT_TS>)},
146 { { C_STRING_WITH_LEN("TRT_ISO_LEVEL") }, BUILDER(Create_func_trt<TR_table::FLD_ISO_LEVEL>)},
147 { { C_STRING_WITH_LEN("TRT_TRX_ID") }, BUILDER(Create_func_trt<TR_table::FLD_TRX_ID>)},
148 { { C_STRING_WITH_LEN("TRT_TRX_SEES") }, BUILDER(Create_func_trt_trx_sees<Item_func_trt_trx_sees>)},
149 { { C_STRING_WITH_LEN("TRT_TRX_SEES_EQ") }, BUILDER(Create_func_trt_trx_sees<Item_func_trt_trx_sees_eq>)},
150 { {0, 0}, NULL}
151};
152
153
154/*
155 Disable __attribute__() on non-gcc compilers.
156*/
157#if !defined(__attribute__) && !defined(__GNUC__)
158#define __attribute__(A)
159#endif
160
161static int versioning_plugin_init(void *p __attribute__ ((unused)))
162{
163 DBUG_ENTER("versioning_plugin_init");
164 // No need in locking since we so far single-threaded
165 int res= item_create_append(func_array);
166 if (res)
167 {
168 my_message(ER_PLUGIN_IS_NOT_LOADED, "Can't append function array" , MYF(0));
169 DBUG_RETURN(res);
170 }
171
172 DBUG_RETURN(0);
173}
174
175static int versioning_plugin_deinit(void *p __attribute__ ((unused)))
176{
177 DBUG_ENTER("versioning_plugin_deinit");
178 DBUG_RETURN(0);
179}
180
181struct st_mysql_daemon versioning_plugin=
182{ MYSQL_REPLICATION_INTERFACE_VERSION };
183
184/*
185 Plugin library descriptor
186*/
187
188maria_declare_plugin(versioning)
189{
190 MYSQL_REPLICATION_PLUGIN, // initialized after MYSQL_STORAGE_ENGINE_PLUGIN
191 &versioning_plugin,
192 "test_versioning",
193 "MariaDB Corp",
194 "System Vesioning testing features",
195 PLUGIN_LICENSE_GPL,
196 versioning_plugin_init, /* Plugin Init */
197 versioning_plugin_deinit, /* Plugin Deinit */
198 0x0100 /* 1.0 */,
199 NULL, /* status variables */
200 NULL, /* system variables */
201 "1.0", /* string version */
202 MariaDB_PLUGIN_MATURITY_EXPERIMENTAL
203}
204maria_declare_plugin_end;
205