From 2fd587846862094f3bcfc20035181732a4396d93 Mon Sep 17 00:00:00 2001 From: ec2-user Date: Fri, 28 Mar 2025 01:10:11 +0000 Subject: [PATCH 1/6] gitignore --- .gitignore | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.gitignore b/.gitignore index b453d8b56780..acf0078b6b3d 100644 --- a/.gitignore +++ b/.gitignore @@ -31,3 +31,7 @@ scalability_jobs_* .cproject .project .settings/ +.idea/* +cmake-build-debug/* +db/* +.vscode/* \ No newline at end of file From a6b33af8dd571676381d0fd07d1d86c83da4f127 Mon Sep 17 00:00:00 2001 From: ec2-user Date: Fri, 28 Mar 2025 01:30:02 +0000 Subject: [PATCH 2/6] my.cnf --- my.cnf | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 my.cnf diff --git a/my.cnf b/my.cnf new file mode 100644 index 000000000000..7b268b2207bd --- /dev/null +++ b/my.cnf @@ -0,0 +1,4 @@ +[mysqld] +socket=/home/ec2-user/mysql-server/mysql.sock +datadir=/home/ec2-user/mysql-server/db +log_error=/tmp/mysql-error.log From c21fe143f46e6cf255012a08db541c49523f638c Mon Sep 17 00:00:00 2001 From: ec2-user Date: Fri, 28 Mar 2025 01:30:19 +0000 Subject: [PATCH 3/6] ha_memem --- mysql-test/suite/x/r/ha_memem.result | 22 ++ mysql-test/suite/x/t/ha_memem.test | 20 ++ storage/memem/CMakeLists.txt | 11 + storage/memem/ha_memem.cc | 322 +++++++++++++++++++++++++++ storage/memem/ha_memem.h | 44 ++++ 5 files changed, 419 insertions(+) create mode 100644 mysql-test/suite/x/r/ha_memem.result create mode 100644 mysql-test/suite/x/t/ha_memem.test create mode 100644 storage/memem/CMakeLists.txt create mode 100644 storage/memem/ha_memem.cc create mode 100644 storage/memem/ha_memem.h diff --git a/mysql-test/suite/x/r/ha_memem.result b/mysql-test/suite/x/r/ha_memem.result new file mode 100644 index 000000000000..94f9c7165b76 --- /dev/null +++ b/mysql-test/suite/x/r/ha_memem.result @@ -0,0 +1,22 @@ +Simple test to verify MEMEM storage engine +create database testdb; +use testdb; +drop table if exists testtbl; +Warnings: +Note 1051 Unknown table 'testdb.testtbl' +drop table if exists testtbl2; +Warnings: +Note 1051 Unknown table 'testdb.testtbl2' +create table testtbl(a int, b int) engine = MEMEM; +insert into testtbl values (2, 1029); +insert into testtbl values (92, 8); +select * from testtbl where a>2; +a b +92 8 +create table testtbl2(a int) engine = MEMEM; +insert into testtbl2 values (322); +insert into testtbl2 values (8); +select * from testtbl2 where a > 20; +a +322 +drop database testdb; diff --git a/mysql-test/suite/x/t/ha_memem.test b/mysql-test/suite/x/t/ha_memem.test new file mode 100644 index 000000000000..5e43cee2a7f6 --- /dev/null +++ b/mysql-test/suite/x/t/ha_memem.test @@ -0,0 +1,20 @@ +--echo Simple test to verify MEMEM storage engine + +create database testdb; +use testdb; + + +drop table if exists testtbl; +drop table if exists testtbl2; + +create table testtbl(a int, b int) engine = MEMEM; +insert into testtbl values (2, 1029); +insert into testtbl values (92, 8); +select * from testtbl where a>2; + +create table testtbl2(a int) engine = MEMEM; +insert into testtbl2 values (322); +insert into testtbl2 values (8); +select * from testtbl2 where a > 20; + +drop database testdb; diff --git a/storage/memem/CMakeLists.txt b/storage/memem/CMakeLists.txt new file mode 100644 index 000000000000..5221e314eee4 --- /dev/null +++ b/storage/memem/CMakeLists.txt @@ -0,0 +1,11 @@ +SET(MEMEM_PLUGIN_STATIC "memem") +SET(MEMEM_PLUGIN_MANDATORY TRUE) + +SET(MEMEM_SOURCES + ha_memem.cc + ha_memem.h +) + +MYSQL_ADD_PLUGIN(memem ${MEMEM_SOURCES} + STORAGE_ENGINE MANDATORY + LINK_LIBRARIES extra::rapidjson) diff --git a/storage/memem/ha_memem.cc b/storage/memem/ha_memem.cc new file mode 100644 index 000000000000..ef24f6442ba1 --- /dev/null +++ b/storage/memem/ha_memem.cc @@ -0,0 +1,322 @@ +#include "mysql/plugin.h" +#include "sql/sql_class.h" +#include "storage/memem/ha_memem.h" + +//------------------------------------------------------ +// Flags +//------------------------------------------------------ + +/** + * @brief Get the storage engine name + * + * Returns the name used to identify this storage engine. + * This name is used in SHOW TABLE STATUS and SHOW CREATE TABLE. + * + * @return const char* Storage engine name + */ +const char* ha_memem::table_type() const { return "MEMEM"; } + +/** + * @brief Get table flags that specify handler capabilities + * + * Returns a bitmap of flags that tells MySQL about the capabilities + * of this storage engine. Current flags: + * - HA_NO_TRANSACTIONS: Engine doesn't support transactions + * - HA_BINLOG_ROW_CAPABLE: Can handle row-based binary logging + * + * @return ulonglong Bitmap of handler flags + */ +ulonglong ha_memem::table_flags() const { + return HA_NO_TRANSACTIONS | HA_BINLOG_ROW_CAPABLE; +} + +/** + * @brief Get index capabilities + * + * Returns flags that indicate what kind of indexes this storage engine + * supports. Returns 0 as this basic implementation doesn't support indexes. + */ +uLong ha_memem::index_flags(uint, uint, bool) const { return 0; } + +//------------------------------------------------------ +// Core +//------------------------------------------------------ + +// +// Called when: CREATE TABLE is executed +// Purpose: Initialize the table structure/files +// +int ha_memem::create(const char* name, + TABLE* form [[maybe_unused]], + HA_CREATE_INFO* create_info [[maybe_unused]], + dd::Table* table_def [[maybe_unused]]) { + mem_table = new MememTable(); + mem_table->name = name; + thr_lock_init(&mem_table->lock); // Initialize lock + thr_lock_data_init(&mem_table->lock, &lock, NULL); // Initialize lock data + return 0; +} + +// +// Called when: Table is opened for operations +// Purpose: Open existing table for read/write +// +int ha_memem::open(const char* name, + int mode [[maybe_unused]], + uint test_if_locked [[maybe_unused]], + const dd::Table* table_def [[maybe_unused]]) { + mem_table = new MememTable(); + mem_table->name = name; + thr_lock_init(&mem_table->lock); // Initialize lock + thr_lock_data_init(&mem_table->lock, &lock, NULL); // Initialize lock data + return 0; +} + +int ha_memem::close() { + if (mem_table) { + thr_lock_delete(&mem_table->lock); // Clean up lock + delete mem_table; + mem_table = nullptr; + } + return 0; +} + + +int ha_memem::write_row(uchar* buf) { + size_t row_length = table->s->stored_rec_length; + mem_table->rows.emplace_back(buf, buf + row_length); + return 0; +} + +/** + * @brief Initialize table scanning + * + * Called before starting a table scan. Initializes position + * for sequential reading of rows. + * + * @param scan True if this is a full table scan + * @return int 0 for success, non-zero for failure + */ +int ha_memem::rnd_init(bool scan [[maybe_unused]]) { + current_position = 0; + return 0; +} + +/** + * @brief Read the next row in a table scan + * + * Reads the next row in a sequential scan and places it in + * the provided buffer. + * + * @param buf Buffer to store the row + * @return int 0 for success, HA_ERR_END_OF_FILE for end of table + */ +int ha_memem::rnd_next(uchar* buf) { + if (current_position >= mem_table->rows.size()) { + return HA_ERR_END_OF_FILE; + } + + memcpy(buf, mem_table->rows[current_position].data(), + mem_table->rows[current_position].size()); + current_position++; + return 0; +} + +/** + * @brief Store position for later retrieval + * + * Stores current position for later retrieval by rnd_pos(). + * Used for ORDER BY and GROUP BY operations. + * + * @param record Currently unused + */ +void ha_memem::position(const uchar*) { + size_t* position = reinterpret_cast(ref); + *position = current_position - 1; +} + +/** + * @brief Read a row using position + * + * Reads a row from a given position. The position information + * comes from an earlier call to position(). + * + * @param buf Buffer to store the row + * @param pos Position information + * @return int 0 for success, HA_ERR_END_OF_FILE for invalid position + */ +int ha_memem::rnd_pos(uchar* buf, uchar* pos) { + size_t position = *reinterpret_cast(pos); + if (position >= mem_table->rows.size()) { + return HA_ERR_END_OF_FILE; + } + + memcpy(buf, mem_table->rows[position].data(), + mem_table->rows[position].size()); + return 0; +} + + +/** + * @brief Information about the table + * + * Called to get information about the table. Currently a no-op + * in this basic implementation. + * + * @param flag Type of information requested + * @return int 0 for success + */ +int ha_memem::info(uint) { return 0; } + +//------------------------------------------------------ +// Locks +//------------------------------------------------------ + +/** + * @brief External table lock handler + * + * This function is called by MySQL at the beginning and end of every statement that + * references this table. It manages external/file-level locks for the table. + * + * Called twice for each statement: + * 1. At start with lock_type = F_RDLCK (read) or F_WRLCK (write) + * 2. At end with lock_type = F_UNLCK + * + * For transactional tables, this should be a no-op as transactions + * handle the locking automatically. + * + * @param thd Thread handler (unused in basic implementation) + * @param lock_type Type of lock (F_RDLCK, F_WRLCK, F_UNLCK) + * @return 0 for success, non-zero for failure + */ +int ha_memem::external_lock(THD* thd [[maybe_unused]], int lock_type [[maybe_unused]]) { + DBUG_TRACE; + return 0; +} + +/** + * @brief Store lock request in lock structure + * + * This method is called by MySQL to build a list of table-level locks needed + * for a particular statement. It's called multiple times to build the complete + * lock list before actually trying to acquire the locks. + * + * Lock upgrade protocol: + * - If lock_type is TL_IGNORE, keep existing lock type + * - If current lock is TL_UNLOCK, set to requested lock_type + * - Otherwise, keep existing lock type (don't downgrade) + * + * Common lock types: + * - TL_READ: Normal read lock + * - TL_READ_WITH_SHARED_LOCKS: READ with LOCK IN SHARE MODE + * - TL_WRITE: Normal write lock + * - TL_WRITE_ALLOW_WRITE: INSERT operations + * + * @param thd Thread handler + * @param to Pointer to an array of lock requests + * @param lock_type Type of lock requested + * @return Position after the current lock in the lock array + */ +THR_LOCK_DATA** ha_memem::store_lock(THD* thd [[maybe_unused]], + THR_LOCK_DATA** to, + enum thr_lock_type lock_type) { + // Only change lock type if: + // 1. Lock type is not TL_IGNORE + // 2. Current lock type is TL_UNLOCK (no lock) + if (lock_type != TL_IGNORE && lock.type == TL_UNLOCK) { + lock.type = lock_type; + } + + // Add this lock to the table's lock list + *to++ = &lock; + + // Return position after our lock + return to; +} + +//-------------------------------------------------- +// Plugin-specific declarations and definitions +//-------------------------------------------------- + +/** + * @brief Create handler instance for the storage engine + * + * Called by MySQL to create a new handler instance when a table is opened. + * Uses placement new to create the handler in the provided memory root. + * + * @param hton Handlerton for this storage engine + * @param table TABLE_SHARE containing table definition + * @param partitioned Whether table is partitioned (unused in basic implementation) + * @param mem_root Memory root to allocate handler from + * @return handler* Pointer to newly created handler instance + */ +static handler* memem_create_handler(handlerton* hton, + TABLE_SHARE* table, + bool, + MEM_ROOT* mem_root) { + return new (mem_root) ha_memem(hton, table); +} + +ha_memem::ha_memem(handlerton* hton, TABLE_SHARE* table_arg) + : handler(hton, table_arg), mem_table(nullptr), current_position(0) {} + +ha_memem::~ha_memem() = default; + +/** Global handlerton instance for the MEMEM storage engine */ +handlerton *memem_hton; + +/** + * @brief Initialize the storage engine plugin + * + * Called when the storage engine is loaded. Initializes the handlerton + * with the necessary function pointers and capabilities. + */ +static int memem_init_func(void* p) { + memem_hton = (handlerton *)p; + memem_hton->state = SHOW_OPTION_YES; // Mark plugin as active + memem_hton->create = memem_create_handler; // Set handler creation function + memem_hton->flags = HTON_CAN_RECREATE; // Set capabilities + return 0; +} + +static int memem_deinit_func(void* p [[maybe_unused]]) { + return 0; +} + +/** + * @brief Storage engine descriptor + * + * Contains version information for the storage engine interface. + * Used by MySQL to verify compatibility. + */ +static struct st_mysql_storage_engine memem_storage_engine = { + MYSQL_HANDLERTON_INTERFACE_VERSION +}; + +/** + * @brief Plugin declaration structure + * + * Declares the storage engine plugin to MySQL, including: + * - Plugin type (storage engine) + * - Name and author information + * - License information + * - Initialize and cleanup functions + * - Version and status information + */ +mysql_declare_plugin(memem) { + MYSQL_STORAGE_ENGINE_PLUGIN, + &memem_storage_engine, // Plugin descriptor + "MEMEM", // Plugin name + PLUGIN_AUTHOR_ORACLE, // Author + "MEMEM storage engine", // Description + PLUGIN_LICENSE_GPL, // License + memem_init_func, // Initialization function + nullptr, // Check uninstall function + memem_deinit_func, // Cleanup function + 0x0001, // Version number (0.1) + nullptr, // Status variables + nullptr, // System variables + nullptr, // Config options + 0, // Flags +} +mysql_declare_plugin_end; \ No newline at end of file diff --git a/storage/memem/ha_memem.h b/storage/memem/ha_memem.h new file mode 100644 index 000000000000..6bd8087b3432 --- /dev/null +++ b/storage/memem/ha_memem.h @@ -0,0 +1,44 @@ +#include "sql/handler.h" +#include "thr_lock.h" +#include "sql/table.h" +#include +#include + +// Each Table Object has a name, rows and table_lock. +struct MememTable { + std::vector> rows; + std::string name; + THR_LOCK lock; +}; + +class ha_memem : public handler { +private: + THR_LOCK_DATA lock; + MememTable* mem_table; + uint current_position; + +public: + ha_memem(handlerton* hton, TABLE_SHARE* table_arg); + ~ha_memem() override; + + const char* table_type() const override; + ulonglong table_flags() const override; + ulong index_flags(uint inx, uint part, bool all_parts) const override; + + int create(const char* name, TABLE* form, HA_CREATE_INFO*, + dd::Table* table_def) override; + int open(const char* name, int mode, uint test_if_locked, + const dd::Table* table_def) override; + int close() override; + + int write_row(uchar* buf) override; + int rnd_init(bool scan) override; + int rnd_next(uchar* buf) override; + int rnd_pos(uchar* buf, uchar* pos) override; + void position(const uchar*) override; + int info(uint) override; + + int external_lock(THD*, int) override; + THR_LOCK_DATA** store_lock(THD*, THR_LOCK_DATA** to, + enum thr_lock_type lock_type) override; +}; From c8fd69831c428d33323534b1469d7f4341bdd1a5 Mon Sep 17 00:00:00 2001 From: ec2-user Date: Sat, 7 Jun 2025 16:21:23 +0000 Subject: [PATCH 4/6] Change Sysvar --- sql/sql_table.cc | 5 +++++ sql/sys_vars.cc | 8 ++++++++ sql/system_variables.h | 1 + 3 files changed, 14 insertions(+) diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 6adba7d15f04..25cf6542346f 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -10039,6 +10039,11 @@ bool mysql_create_table(THD *thd, Table_ref *create_table, Foreign_key_parents_invalidator fk_invalidator; DBUG_TRACE; + if (thd->variables.my_flag) { + my_error(ER_ILLEGAL_HA, MYF(0),"Fail on CREATE TABLE"); + return true; + } + handlerton *actual_hton = get_viable_handlerton_for_create( thd, create_table->table_name, *create_info); if (actual_hton == nullptr) return true; diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc index a72bb88d28dc..fcdbc73a57a1 100644 --- a/sql/sys_vars.cc +++ b/sql/sys_vars.cc @@ -3462,6 +3462,14 @@ static const char *optimizer_switch_names[] = { "derived_condition_pushdown", "default", NullS}; + + +static Sys_var_bool Sys_my_flag( + "my_flag", + "Custom flag to control CREATE TABLE behaviour", + HINT_UPDATEABLE SESSION_VAR(my_flag), CMD_LINE(OPT_ARG), + DEFAULT(false)); + static Sys_var_flagset Sys_optimizer_switch( "optimizer_switch", "optimizer_switch=option=val[,option=val...], where option is one of " diff --git a/sql/system_variables.h b/sql/system_variables.h index d092cba8155a..8c73d3a453ea 100644 --- a/sql/system_variables.h +++ b/sql/system_variables.h @@ -201,6 +201,7 @@ enum class Explain_format_type : ulong { */ struct System_variables { + bool my_flag; /* How dynamically allocated system variables are handled: From 702007d237fdb42ea8462cbe7cbe2f117d925c35 Mon Sep 17 00:00:00 2001 From: ec2-user Date: Sat, 7 Jun 2025 20:45:25 +0000 Subject: [PATCH 5/6] Add new SQRT_LOG Unary function --- sql/item_create.cc | 1 + sql/item_func.cc | 8 ++++++++ sql/item_func.h | 11 ++++++++++- 3 files changed, 19 insertions(+), 1 deletion(-) diff --git a/sql/item_create.cc b/sql/item_create.cc index 89d5d3b05d7f..e622481e19a8 100644 --- a/sql/item_create.cc +++ b/sql/item_create.cc @@ -1553,6 +1553,7 @@ static const std::pair func_array[] = { {"WAIT_UNTIL_SQL_THREAD_AFTER_GTIDS", SQL_FN_V(Item_master_gtid_set_wait, 1, 3)}, {"SQRT", SQL_FN(Item_func_sqrt, 1)}, + {"SQRT_LOG", SQL_FN(Item_func_sqrt_log, 1)}, {"STRCMP", SQL_FN(Item_func_strcmp, 2)}, {"STR_TO_DATE", SQL_FN(Item_func_str_to_date, 2)}, {"ST_AREA", SQL_FN(Item_func_st_area, 1)}, diff --git a/sql/item_func.cc b/sql/item_func.cc index ae5c0be53b67..ccdf0c76c030 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -2838,6 +2838,14 @@ double Item_func_sqrt::val_real() { return sqrt(value); } +double Item_func_sqrt_log::val_real() { + assert(fixed == 1); + double value = args[0]->val_real(); + if ((null_value = (args[0]->null_value || value < 0))) + return 0.0; /* purecov: inspected */ + return sqrt(log10(value)); +} + double Item_func_pow::val_real() { assert(fixed == 1); double value = args[0]->val_real(); diff --git a/sql/item_func.h b/sql/item_func.h index 45552ae545ce..6e47e8561ab4 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -247,6 +247,7 @@ class Item_func : public Item_result_field { ROUND_FUNC, TRUNCATE_FUNC, SQRT_FUNC, + SQRT_LOG_FUNC, ABS_FUNC, POW_FUNC, SIGN_FUNC, @@ -1294,13 +1295,21 @@ class Item_func_log10 final : public Item_dec_func { }; class Item_func_sqrt final : public Item_dec_func { - public: +public: Item_func_sqrt(const POS &pos, Item *a) : Item_dec_func(pos, a) {} double val_real() override; const char *func_name() const override { return "sqrt"; } enum Functype functype() const override { return SQRT_FUNC; } }; +class Item_func_sqrt_log final : public Item_dec_func { +public: + Item_func_sqrt_log(const POS &pos, Item *a) : Item_dec_func(pos, a) {} + double val_real() override; + const char *func_name() const override { return "sqrt_log"; } + enum Functype functype() const override { return SQRT_LOG_FUNC; } +}; + class Item_func_pow final : public Item_dec_func { public: Item_func_pow(const POS &pos, Item *a, Item *b) : Item_dec_func(pos, a, b) {} From 23b1f915e369e418d8abe8b2a23c4cc367093fb4 Mon Sep 17 00:00:00 2001 From: ec2-user Date: Sat, 7 Jun 2025 21:19:54 +0000 Subject: [PATCH 6/6] Add new STRCMP2 Binary Function --- sql/item_cmpfunc.cc | 21 +++++++++++++++++++++ sql/item_cmpfunc.h | 21 +++++++++++++++++++++ sql/item_create.cc | 3 ++- sql/item_func.h | 1 + 4 files changed, 45 insertions(+), 1 deletion(-) diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 8ce3d3b1ff8d..13c1c702fff2 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -2687,6 +2687,27 @@ longlong Item_func_strcmp::val_int() { return value == 0 ? 0 : value < 0 ? -1 : 1; } +longlong Item_func_strcmp2::val_int() { + assert(fixed); + const CHARSET_INFO *cs = cmp.cmp_collation.collation; + String *a = eval_string_arg(cs, args[0], &cmp.value1); + if (a == nullptr) { + if (current_thd->is_error()) return error_int(); + null_value = true; + return 0; + } + + String *b = eval_string_arg(cs, args[1], &cmp.value2); + if (b == nullptr) { + if (current_thd->is_error()) return error_int(); + null_value = true; + return 0; + } + int value = sortcmp(a, b, cs); + null_value = false; + return value == 0 ? 0 : value < 0 ? -1 : 1; +} + bool Item_func_opt_neg::eq(const Item *item, bool binary_cmp) const { /* Assume we don't have rtti */ if (this == item) return true; diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h index 51163d5c81ff..70c49396b621 100644 --- a/sql/item_cmpfunc.h +++ b/sql/item_cmpfunc.h @@ -1378,6 +1378,27 @@ class Item_func_strcmp final : public Item_bool_func2 { } }; +class Item_func_strcmp2 final : public Item_bool_func2 { +public: + Item_func_strcmp2(const POS &pos, Item *a, Item *b): Item_bool_func2(pos, a, b) {} + longlong val_int() override; + optimize_type select_optimize(const THD *) override { return OPTIMIZE_NONE; } + const char *func_name() const override { return "strcmp2"; } + enum Functype functype() const override { return STRCMP_FUNC2; } + + void print(const THD *thd, String *str,enum_query_type query_type) const override { + Item_func::print(thd, str, query_type); + } + // We derive (indirectly) from Item_bool_func, but this is not a true boolean. + // Override length and unsigned_flag set by set_data_type_bool(). + bool resolve_type(THD *thd) override { + if (Item_bool_func2::resolve_type(thd)) return true; + fix_char_length(2); // returns "1" or "0" or "-1" + unsigned_flag = false; + return false; + } +}; + struct interval_range { Item_result type; double dbl; diff --git a/sql/item_create.cc b/sql/item_create.cc index e622481e19a8..f335332ab397 100644 --- a/sql/item_create.cc +++ b/sql/item_create.cc @@ -1553,8 +1553,9 @@ static const std::pair func_array[] = { {"WAIT_UNTIL_SQL_THREAD_AFTER_GTIDS", SQL_FN_V(Item_master_gtid_set_wait, 1, 3)}, {"SQRT", SQL_FN(Item_func_sqrt, 1)}, - {"SQRT_LOG", SQL_FN(Item_func_sqrt_log, 1)}, +{"SQRT_LOG", SQL_FN(Item_func_sqrt_log, 1)}, {"STRCMP", SQL_FN(Item_func_strcmp, 2)}, +{"STRCMP2", SQL_FN(Item_func_strcmp2, 2)}, {"STR_TO_DATE", SQL_FN(Item_func_str_to_date, 2)}, {"ST_AREA", SQL_FN(Item_func_st_area, 1)}, {"ST_ASBINARY", SQL_FN_V(Item_func_as_wkb, 1, 2)}, diff --git a/sql/item_func.h b/sql/item_func.h index 6e47e8561ab4..6aa433b206b5 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -304,6 +304,7 @@ class Item_func : public Item_result_field { JSON_UNQUOTE_FUNC, MEMBER_OF_FUNC, STRCMP_FUNC, + STRCMP_FUNC2, TRUE_FUNC, FALSE_FUNC };