mariadb/plugin/func_test/plugin.cc
Oleg Smirnov 405613ebb5 MDEV-34490 get_copy() and build_clone() may return an instance of an ancestor class instead of a copy/clone
The `Item` class methods `get_copy()`, `build_clone()`, and `clone_item()`
face an issue where they may be defined in a descendant class
(e.g., `Item_func`) but not in a further descendant (e.g., `Item_func_child`).
This can lead to scenarios where `build_clone()`, when operating on an
instance of `Item_func_child` with a pointer to the base class (`Item`),
returns an instance of `Item_func` instead of `Item_func_child`.

Since this limitation cannot be resolved at compile time, this commit
introduces runtime type checks for the copy/clone operations.
A debug assertion will now trigger in case of a type mismatch.

`get_copy()`, `build_clone()`, and `clone_item()` are no more virtual,
but virtual `do_get_copy()`, `do_build_clone()`, and `do_clone_item()`
are added to the protected section of the class `Item`.

Additionally, const qualifiers have been added to certain methods
to enhance code reliability.

Reviewer: Oleksandr Byelkin <sanja@mariadb.com>
2024-07-15 18:25:57 +07:00

87 lines
3 KiB
C++

/*
Copyright (c) 2019, 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-1301 USA */
#define MYSQL_SERVER
#include <my_global.h>
#include <sql_class.h>
#include <mysql/plugin_function.h>
class Item_func_sysconst_test :public Item_func_sysconst
{
public:
Item_func_sysconst_test(THD *thd): Item_func_sysconst(thd) {}
String *val_str(String *str) override
{
null_value= str->copy(STRING_WITH_LEN("sysconst_test"), system_charset_info);
return null_value ? NULL : str;
}
bool fix_length_and_dec() override
{
max_length= MAX_FIELD_NAME * system_charset_info->mbmaxlen;
maybe_null= true;
return false;
}
const char *func_name() const override { return "sysconst_test"; }
const char *fully_qualified_func_name() const override { return "sysconst_test()"; }
Item *do_get_copy(THD *thd) const override
{ return get_item_copy<Item_func_sysconst_test>(thd, this); }
};
class Create_func_sysconst_test : public Create_func_arg0
{
public:
Item *create_builder(THD *thd) override;
static Create_func_sysconst_test s_singleton;
protected:
Create_func_sysconst_test() {}
};
Create_func_sysconst_test Create_func_sysconst_test::s_singleton;
Item* Create_func_sysconst_test::create_builder(THD *thd)
{
return new (thd->mem_root) Item_func_sysconst_test(thd);
}
#define BUILDER(F) & F::s_singleton
static Plugin_function
plugin_descriptor_function_sysconst_test(BUILDER(Create_func_sysconst_test));
/*************************************************************************/
maria_declare_plugin(type_test)
{
MariaDB_FUNCTION_PLUGIN, // the plugin type (see include/mysql/plugin.h)
&plugin_descriptor_function_sysconst_test, // pointer to type-specific plugin descriptor
"sysconst_test", // plugin name
"MariaDB Corporation", // plugin author
"Function SYSCONST_TEST()", // 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_EXPERIMENTAL // Maturity(see include/mysql/plugin.h)*/
}
maria_declare_plugin_end;