summaryrefslogtreecommitdiffstats
path: root/plugin/type_uuid/plugin.cc
diff options
context:
space:
mode:
Diffstat (limited to 'plugin/type_uuid/plugin.cc')
-rw-r--r--plugin/type_uuid/plugin.cc202
1 files changed, 202 insertions, 0 deletions
diff --git a/plugin/type_uuid/plugin.cc b/plugin/type_uuid/plugin.cc
new file mode 100644
index 00000000..499019e9
--- /dev/null
+++ b/plugin/type_uuid/plugin.cc
@@ -0,0 +1,202 @@
+/* Copyright (c) 2019,2021, MariaDB Corporation
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License.
+
+ 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 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-1335 USA */
+
+#define MYSQL_SERVER
+#include "mariadb.h"
+#include "sql_class.h"
+#include "sql_type_uuid.h"
+#include "item_uuidfunc.h"
+#include <mysql/plugin_data_type.h>
+#include <mysql/plugin_function.h>
+
+/*
+ The whole purpose of this Type_handler_uuid_dispatcher is to choose
+ whether the field should use Type_handler_uuid_new or Type_handler_uuid_old
+ based on the version of MariaDB that created the table.
+ When created every field will use either Type_handler_uuid_new or _old.
+ Literals and functions always use _new.
+*/
+class Type_handler_uuid_dispatcher: public Type_handler_uuid_new
+{
+public:
+ Field *make_table_field_from_def(TABLE_SHARE *share, MEM_ROOT *root,
+ const LEX_CSTRING *name, const Record_addr &addr,
+ const Bit_addr &bit,
+ const Column_definition_attributes *attr,
+ uint32 flags) const override
+ {
+ bool new_uuid= share->mysql_version == 0 ||
+ (share->mysql_version >= 100908 && share->mysql_version < 100999) ||
+ (share->mysql_version >= 101006 && share->mysql_version < 101099) ||
+ (share->mysql_version >= 101105 && share->mysql_version < 101199) ||
+ (share->mysql_version >= 110003 && share->mysql_version < 110099) ||
+ (share->mysql_version >= 110102 && share->mysql_version < 110199) ||
+ share->mysql_version >= 110201;
+ static Type_handler *th[]= {
+ Type_handler_uuid_old::singleton(), Type_handler_uuid_new::singleton()
+ };
+ return th[new_uuid]->
+ make_table_field_from_def(share, root, name, addr, bit, attr, flags);
+ }
+};
+
+static Type_handler_uuid_dispatcher type_handler_uuid_dispatcher;
+
+static struct st_mariadb_data_type plugin_descriptor_type_uuid=
+{
+ MariaDB_DATA_TYPE_INTERFACE_VERSION,
+ &type_handler_uuid_dispatcher
+};
+
+
+const Type_handler *Type_collection_uuid::find_in_array(const Type_handler *a,
+ const Type_handler *b,
+ bool for_cmp) const
+{
+ if (a == b) return a;
+
+ /*
+ in the search below we'll find if we can convert `b` to `a`.
+ So, if one of the arguments is uuid and the other is not,
+ we should put uuid type in `a` and not-uuid in `b`. And if one type is
+ new uuid and the other is old uuid, new uuid should be in `a`
+ */
+ if (a != Type_handler_uuid_new::singleton() && b->type_collection() == this)
+ std::swap(a, b);
+
+ DBUG_ASSERT(a != &type_handler_uuid_dispatcher);
+ DBUG_ASSERT(b != &type_handler_uuid_dispatcher);
+
+ /*
+ Search in the array for an element, equal to `b`.
+ If found - return `a`, if not found - return NULL.
+ Array is terminated by `a`.
+ */
+ static const Type_handler *arr[]={ &type_handler_varchar,
+ &type_handler_string, &type_handler_tiny_blob, &type_handler_blob,
+ &type_handler_medium_blob, &type_handler_hex_hybrid,
+ // in aggregate_for_comparison() all types above cannot happen,
+ // so we'll start the search from here:
+ &type_handler_null, &type_handler_long_blob,
+ Type_handler_uuid_old::singleton(), Type_handler_uuid_new::singleton() };
+
+ for (int i= for_cmp ? 6 : 0; arr[i] != a; i++)
+ if (arr[i] == b)
+ return a;
+ return NULL;
+}
+
+/*************************************************************************/
+
+class Create_func_uuid : public Create_func_arg0
+{
+public:
+ Item *create_builder(THD *thd) override
+ {
+ DBUG_ENTER("Create_func_uuid::create");
+ thd->lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_SYSTEM_FUNCTION);
+ thd->lex->safe_to_cache_query= 0;
+ DBUG_RETURN(new (thd->mem_root) Item_func_uuid(thd));
+ }
+ static Create_func_uuid s_singleton;
+
+protected:
+ Create_func_uuid() {}
+ virtual ~Create_func_uuid() {}
+};
+
+
+class Create_func_sys_guid : public Create_func_arg0
+{
+public:
+ Item *create_builder(THD *thd) override
+ {
+ DBUG_ENTER("Create_func_sys_guid::create");
+ thd->lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_SYSTEM_FUNCTION);
+ thd->lex->safe_to_cache_query= 0;
+ DBUG_RETURN(new (thd->mem_root) Item_func_sys_guid(thd));
+ }
+ static Create_func_sys_guid s_singleton;
+
+protected:
+ Create_func_sys_guid() {}
+ virtual ~Create_func_sys_guid() {}
+};
+
+Create_func_uuid Create_func_uuid::s_singleton;
+Create_func_sys_guid Create_func_sys_guid::s_singleton;
+
+static Plugin_function
+ plugin_descriptor_function_uuid(&Create_func_uuid::s_singleton),
+ plugin_descriptor_function_sys_guid(&Create_func_sys_guid::s_singleton);
+
+static constexpr Name type_name={STRING_WITH_LEN("uuid")};
+
+int uuid_init(void*)
+{
+ Type_handler_uuid_new::singleton()->set_name(type_name);
+ Type_handler_uuid_old::singleton()->set_name(type_name);
+ return 0;
+}
+
+/*************************************************************************/
+
+maria_declare_plugin(type_uuid)
+{
+ MariaDB_DATA_TYPE_PLUGIN, // the plugin type (see include/mysql/plugin.h)
+ &plugin_descriptor_type_uuid, // pointer to type-specific plugin descriptor
+ type_name.ptr(), // plugin name
+ "MariaDB Corporation", // plugin author
+ "Data type UUID", // the plugin description
+ PLUGIN_LICENSE_GPL, // the plugin license (see include/mysql/plugin.h)
+ uuid_init, // Pointer to plugin initialization function
+ 0, // Pointer to plugin deinitialization function
+ 0x0100, // Numeric version 0xAABB means AA.BB version
+ NULL, // Status variables
+ NULL, // System variables
+ "1.0", // String version representation
+ MariaDB_PLUGIN_MATURITY_STABLE// Maturity(see include/mysql/plugin.h)*/
+},
+{
+ MariaDB_FUNCTION_PLUGIN, // the plugin type (see include/mysql/plugin.h)
+ &plugin_descriptor_function_uuid,// pointer to type-specific plugin descriptor
+ "uuid", // plugin name
+ "MariaDB Corporation", // plugin author
+ "Function UUID()", // the plugin description
+ PLUGIN_LICENSE_GPL, // the plugin license (see include/mysql/plugin.h)
+ 0, // Pointer to plugin initialization function
+ 0, // Pointer to plugin deinitialization function
+ 0x0100, // Numeric version 0xAABB means AA.BB version
+ NULL, // Status variables
+ NULL, // System variables
+ "1.0", // String version representation
+ MariaDB_PLUGIN_MATURITY_STABLE// Maturity(see include/mysql/plugin.h)*/
+},
+{
+ MariaDB_FUNCTION_PLUGIN, // the plugin type (see include/mysql/plugin.h)
+ &plugin_descriptor_function_sys_guid,// pointer to type-specific plugin descriptor
+ "sys_guid", // plugin name
+ "MariaDB Corporation", // plugin author
+ "Function SYS_GUID()", // the plugin description
+ PLUGIN_LICENSE_GPL, // the plugin license (see include/mysql/plugin.h)
+ 0, // Pointer to plugin initialization function
+ 0, // Pointer to plugin deinitialization function
+ 0x0100, // Numeric version 0xAABB means AA.BB version
+ NULL, // Status variables
+ NULL, // System variables
+ "1.0", // String version representation
+ MariaDB_PLUGIN_MATURITY_STABLE// Maturity(see include/mysql/plugin.h)*/
+}
+maria_declare_plugin_end;