diff options
Diffstat (limited to 'plugin/type_uuid/plugin.cc')
-rw-r--r-- | plugin/type_uuid/plugin.cc | 202 |
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; |