mirror of
https://github.com/MariaDB/server.git
synced 2025-08-01 03:47:19 +03:00
SQL: VTQ testing iface moved to plugin [closes #224]
This commit is contained in:
@ -16,3 +16,4 @@
|
|||||||
--innodb-sys-virtual
|
--innodb-sys-virtual
|
||||||
--innodb-vtq
|
--innodb-vtq
|
||||||
--versioning-hide=implicit
|
--versioning-hide=implicit
|
||||||
|
--plugin-load=versioning
|
||||||
|
@ -1 +1,2 @@
|
|||||||
--innodb --default-storage-engine=innodb
|
--innodb --default-storage-engine=innodb
|
||||||
|
--plugin-load=versioning
|
||||||
|
@ -1 +1,2 @@
|
|||||||
--innodb --default-storage-engine=innodb
|
--innodb --default-storage-engine=innodb
|
||||||
|
--plugin-load=versioning
|
||||||
|
@ -1 +1,2 @@
|
|||||||
--versioning-hide=implicit
|
--versioning-hide=implicit
|
||||||
|
--plugin-load=versioning
|
||||||
|
@ -14,10 +14,144 @@
|
|||||||
along with this program; if not, write to the Free Software
|
along with this program; if not, write to the Free Software
|
||||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
|
||||||
|
|
||||||
|
#define MYSQL_SERVER 1
|
||||||
#include <mysql_version.h>
|
#include <mysql_version.h>
|
||||||
#include <mysqld.h>
|
#include <mysqld.h>
|
||||||
|
#include <mysql/plugin.h>
|
||||||
#include "sql_plugin.h" // st_plugin_int
|
#include "sql_plugin.h" // st_plugin_int
|
||||||
#include "sql_class.h"
|
#include "sql_class.h"
|
||||||
|
#include "item.h"
|
||||||
|
#include "vtq.h"
|
||||||
|
#include "vers_utils.h"
|
||||||
|
|
||||||
|
plugin_ref innodb_plugin= NULL;
|
||||||
|
static handlerton* innodb_hton= NULL;
|
||||||
|
|
||||||
|
/* System Versioning: VTQ_TRX_ID(), VTQ_COMMIT_ID(), VTQ_BEGIN_TS(), VTQ_COMMIT_TS(), VTQ_ISO_LEVEL() */
|
||||||
|
template <vtq_field_t VTQ_FIELD>
|
||||||
|
class Create_func_vtq : public Create_native_func
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual Item *create_native(THD *thd, LEX_STRING name, List<Item> *item_list);
|
||||||
|
|
||||||
|
static Create_func_vtq<VTQ_FIELD> s_singleton;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
Create_func_vtq<VTQ_FIELD>() {}
|
||||||
|
virtual ~Create_func_vtq<VTQ_FIELD>() {}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<vtq_field_t VTQ_FIELD>
|
||||||
|
Create_func_vtq<VTQ_FIELD> Create_func_vtq<VTQ_FIELD>::s_singleton;
|
||||||
|
|
||||||
|
template <vtq_field_t VTQ_FIELD>
|
||||||
|
Item*
|
||||||
|
Create_func_vtq<VTQ_FIELD>::create_native(THD *thd, LEX_STRING name,
|
||||||
|
List<Item> *item_list)
|
||||||
|
{
|
||||||
|
Item *func= NULL;
|
||||||
|
int arg_count= 0;
|
||||||
|
|
||||||
|
if (item_list != NULL)
|
||||||
|
arg_count= item_list->elements;
|
||||||
|
|
||||||
|
switch (arg_count) {
|
||||||
|
case 1:
|
||||||
|
{
|
||||||
|
Item *param_1= item_list->pop();
|
||||||
|
switch (VTQ_FIELD)
|
||||||
|
{
|
||||||
|
case VTQ_BEGIN_TS:
|
||||||
|
case VTQ_COMMIT_TS:
|
||||||
|
func= new (thd->mem_root) Item_func_vtq_ts(thd, innodb_hton, param_1, VTQ_FIELD);
|
||||||
|
break;
|
||||||
|
case VTQ_TRX_ID:
|
||||||
|
case VTQ_COMMIT_ID:
|
||||||
|
case VTQ_ISO_LEVEL:
|
||||||
|
func= new (thd->mem_root) Item_func_vtq_id(thd, innodb_hton, param_1, VTQ_FIELD);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
DBUG_ASSERT(0);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 2:
|
||||||
|
{
|
||||||
|
Item *param_1= item_list->pop();
|
||||||
|
Item *param_2= item_list->pop();
|
||||||
|
switch (VTQ_FIELD)
|
||||||
|
{
|
||||||
|
case VTQ_TRX_ID:
|
||||||
|
case VTQ_COMMIT_ID:
|
||||||
|
func= new (thd->mem_root) Item_func_vtq_id(thd, innodb_hton, param_1, param_2, VTQ_FIELD);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
error:
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
my_error(ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT, MYF(0), name.str);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return func;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class Item_func_vtq_trx_seesX>
|
||||||
|
class Create_func_vtq_trx_sees : public Create_native_func
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual Item *create_native(THD *thd, LEX_STRING name, List<Item> *item_list)
|
||||||
|
{
|
||||||
|
Item *func= NULL;
|
||||||
|
int arg_count= 0;
|
||||||
|
|
||||||
|
if (item_list != NULL)
|
||||||
|
arg_count= item_list->elements;
|
||||||
|
|
||||||
|
switch (arg_count) {
|
||||||
|
case 2:
|
||||||
|
{
|
||||||
|
Item *param_1= item_list->pop();
|
||||||
|
Item *param_2= item_list->pop();
|
||||||
|
func= new (thd->mem_root) Item_func_vtq_trx_seesX(thd, innodb_hton, param_1, param_2);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
my_error(ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT, MYF(0), name.str);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return func;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Create_func_vtq_trx_sees<Item_func_vtq_trx_seesX> s_singleton;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
Create_func_vtq_trx_sees<Item_func_vtq_trx_seesX>() {}
|
||||||
|
virtual ~Create_func_vtq_trx_sees<Item_func_vtq_trx_seesX>() {}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class X>
|
||||||
|
Create_func_vtq_trx_sees<X> Create_func_vtq_trx_sees<X>::s_singleton;
|
||||||
|
|
||||||
|
#define BUILDER(F) & F::s_singleton
|
||||||
|
|
||||||
|
static Native_func_registry func_array[] =
|
||||||
|
{
|
||||||
|
{ { C_STRING_WITH_LEN("VTQ_BEGIN_TS") }, BUILDER(Create_func_vtq<VTQ_BEGIN_TS>)},
|
||||||
|
{ { C_STRING_WITH_LEN("VTQ_COMMIT_ID") }, BUILDER(Create_func_vtq<VTQ_COMMIT_ID>)},
|
||||||
|
{ { C_STRING_WITH_LEN("VTQ_COMMIT_TS") }, BUILDER(Create_func_vtq<VTQ_COMMIT_TS>)},
|
||||||
|
{ { C_STRING_WITH_LEN("VTQ_ISO_LEVEL") }, BUILDER(Create_func_vtq<VTQ_ISO_LEVEL>)},
|
||||||
|
{ { C_STRING_WITH_LEN("VTQ_TRX_ID") }, BUILDER(Create_func_vtq<VTQ_TRX_ID>)},
|
||||||
|
{ { C_STRING_WITH_LEN("VTQ_TRX_SEES") }, BUILDER(Create_func_vtq_trx_sees<Item_func_vtq_trx_sees>)},
|
||||||
|
{ { C_STRING_WITH_LEN("VTQ_TRX_SEES_EQ") }, BUILDER(Create_func_vtq_trx_sees<Item_func_vtq_trx_sees_eq>)}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Disable __attribute__() on non-gcc compilers.
|
Disable __attribute__() on non-gcc compilers.
|
||||||
@ -26,45 +160,61 @@
|
|||||||
#define __attribute__(A)
|
#define __attribute__(A)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static int forced_versioning_init(void *p __attribute__ ((unused)))
|
static int versioning_plugin_init(void *p __attribute__ ((unused)))
|
||||||
{
|
{
|
||||||
|
static LString InnoDB= "InnoDB";
|
||||||
|
|
||||||
|
DBUG_ENTER("versioning_plugin_init");
|
||||||
|
// No need in locking since we so far single-threaded
|
||||||
|
int res= item_create_append(func_array);
|
||||||
|
if (res)
|
||||||
|
{
|
||||||
|
my_message(ER_PLUGIN_IS_NOT_LOADED, "Can't append function array" , MYF(0));
|
||||||
|
DBUG_RETURN(res);
|
||||||
|
}
|
||||||
|
|
||||||
|
innodb_plugin= ha_resolve_by_name(NULL, &InnoDB.lex_string(), false);
|
||||||
|
if (!innodb_plugin)
|
||||||
|
{
|
||||||
|
my_error(ER_PLUGIN_IS_NOT_LOADED, MYF(0), InnoDB.ptr());
|
||||||
|
DBUG_RETURN(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
innodb_hton= plugin_hton(innodb_plugin);
|
||||||
|
if (!innodb_hton || (innodb_hton->flags & HTON_NOT_USER_SELECTABLE))
|
||||||
|
{
|
||||||
|
my_message(ER_PLUGIN_IS_NOT_LOADED, "Can't get handlerton" , MYF(0));
|
||||||
|
DBUG_RETURN(1);
|
||||||
|
}
|
||||||
|
|
||||||
DBUG_ENTER("forced_versioning_init");
|
|
||||||
mysql_mutex_lock(&LOCK_global_system_variables);
|
|
||||||
global_system_variables.vers_force= true;
|
|
||||||
global_system_variables.vers_hide= VERS_HIDE_FULL;
|
|
||||||
mysql_mutex_unlock(&LOCK_global_system_variables);
|
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int forced_versioning_deinit(void *p __attribute__ ((unused)))
|
static int versioning_plugin_deinit(void *p __attribute__ ((unused)))
|
||||||
{
|
{
|
||||||
DBUG_ENTER("forced_versioning_deinit");
|
DBUG_ENTER("versioning_plugin_deinit");
|
||||||
mysql_mutex_lock(&LOCK_global_system_variables);
|
if (innodb_plugin)
|
||||||
global_system_variables.vers_force= false;
|
plugin_unlock(NULL, innodb_plugin);
|
||||||
global_system_variables.vers_hide= VERS_HIDE_AUTO;
|
|
||||||
mysql_mutex_unlock(&LOCK_global_system_variables);
|
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct st_mysql_daemon versioning_plugin=
|
||||||
struct st_mysql_daemon forced_versioning_plugin=
|
{ MYSQL_REPLICATION_INTERFACE_VERSION };
|
||||||
{ MYSQL_DAEMON_INTERFACE_VERSION };
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Plugin library descriptor
|
Plugin library descriptor
|
||||||
*/
|
*/
|
||||||
|
|
||||||
maria_declare_plugin(forced_versioning)
|
maria_declare_plugin(versioning)
|
||||||
{
|
{
|
||||||
MYSQL_DAEMON_PLUGIN,
|
MYSQL_REPLICATION_PLUGIN, // initialized after MYSQL_STORAGE_ENGINE_PLUGIN
|
||||||
&forced_versioning_plugin,
|
&versioning_plugin,
|
||||||
"forced_versioning",
|
"versioning",
|
||||||
"Natsys Lab",
|
"MariaDB Corp",
|
||||||
"Enable System Vesioning for all newly created tables",
|
"System Vesioning testing features",
|
||||||
PLUGIN_LICENSE_GPL,
|
PLUGIN_LICENSE_GPL,
|
||||||
forced_versioning_init, /* Plugin Init */
|
versioning_plugin_init, /* Plugin Init */
|
||||||
forced_versioning_deinit, /* Plugin Deinit */
|
versioning_plugin_deinit, /* Plugin Deinit */
|
||||||
0x0100 /* 1.0 */,
|
0x0100 /* 1.0 */,
|
||||||
NULL, /* status variables */
|
NULL, /* status variables */
|
||||||
NULL, /* system variables */
|
NULL, /* system variables */
|
||||||
|
@ -104,36 +104,6 @@ bool get_length_and_scale(ulonglong length, ulonglong decimals,
|
|||||||
=============================================================================
|
=============================================================================
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
|
||||||
Adapter for native functions with a variable number of arguments.
|
|
||||||
The main use of this class is to discard the following calls:
|
|
||||||
<code>foo(expr1 AS name1, expr2 AS name2, ...)</code>
|
|
||||||
which are syntactically correct (the syntax can refer to a UDF),
|
|
||||||
but semantically invalid for native functions.
|
|
||||||
*/
|
|
||||||
|
|
||||||
class Create_native_func : public Create_func
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
virtual Item *create_func(THD *thd, LEX_STRING name, List<Item> *item_list);
|
|
||||||
|
|
||||||
/**
|
|
||||||
Builder method, with no arguments.
|
|
||||||
@param thd The current thread
|
|
||||||
@param name The native function name
|
|
||||||
@param item_list The function parameters, none of which are named
|
|
||||||
@return An item representing the function call
|
|
||||||
*/
|
|
||||||
virtual Item *create_native(THD *thd, LEX_STRING name,
|
|
||||||
List<Item> *item_list) = 0;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
/** Constructor. */
|
|
||||||
Create_native_func() {}
|
|
||||||
/** Destructor. */
|
|
||||||
virtual ~Create_native_func() {}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Adapter for functions that takes exactly zero arguments.
|
Adapter for functions that takes exactly zero arguments.
|
||||||
@ -6678,125 +6648,6 @@ Create_func_year_week::create_native(THD *thd, LEX_STRING name,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* System Versioning: VTQ_TRX_ID(), VTQ_COMMIT_ID(), VTQ_BEGIN_TS(), VTQ_COMMIT_TS(), VTQ_ISO_LEVEL() */
|
|
||||||
template <vtq_field_t VTQ_FIELD>
|
|
||||||
class Create_func_vtq : public Create_native_func
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
virtual Item *create_native(THD *thd, LEX_STRING name, List<Item> *item_list);
|
|
||||||
|
|
||||||
static Create_func_vtq<VTQ_FIELD> s_singleton;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
Create_func_vtq<VTQ_FIELD>() {}
|
|
||||||
virtual ~Create_func_vtq<VTQ_FIELD>() {}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<vtq_field_t VTQ_FIELD>
|
|
||||||
Create_func_vtq<VTQ_FIELD> Create_func_vtq<VTQ_FIELD>::s_singleton;
|
|
||||||
|
|
||||||
template <vtq_field_t VTQ_FIELD>
|
|
||||||
Item*
|
|
||||||
Create_func_vtq<VTQ_FIELD>::create_native(THD *thd, LEX_STRING name,
|
|
||||||
List<Item> *item_list)
|
|
||||||
{
|
|
||||||
Item *func= NULL;
|
|
||||||
int arg_count= 0;
|
|
||||||
|
|
||||||
if (item_list != NULL)
|
|
||||||
arg_count= item_list->elements;
|
|
||||||
|
|
||||||
switch (arg_count) {
|
|
||||||
case 1:
|
|
||||||
{
|
|
||||||
Item *param_1= item_list->pop();
|
|
||||||
switch (VTQ_FIELD)
|
|
||||||
{
|
|
||||||
case VTQ_BEGIN_TS:
|
|
||||||
case VTQ_COMMIT_TS:
|
|
||||||
func= new (thd->mem_root) Item_func_vtq_ts(thd, param_1, VTQ_FIELD);
|
|
||||||
break;
|
|
||||||
case VTQ_TRX_ID:
|
|
||||||
case VTQ_COMMIT_ID:
|
|
||||||
case VTQ_ISO_LEVEL:
|
|
||||||
func= new (thd->mem_root) Item_func_vtq_id(thd, param_1, VTQ_FIELD);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
DBUG_ASSERT(0);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 2:
|
|
||||||
{
|
|
||||||
Item *param_1= item_list->pop();
|
|
||||||
Item *param_2= item_list->pop();
|
|
||||||
switch (VTQ_FIELD)
|
|
||||||
{
|
|
||||||
case VTQ_TRX_ID:
|
|
||||||
case VTQ_COMMIT_ID:
|
|
||||||
func= new (thd->mem_root) Item_func_vtq_id(thd, param_1, param_2, VTQ_FIELD);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
error:
|
|
||||||
default:
|
|
||||||
{
|
|
||||||
my_error(ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT, MYF(0), name.str);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return func;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <class Item_func_vtq_trx_seesX>
|
|
||||||
class Create_func_vtq_trx_sees : public Create_native_func
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
virtual Item *create_native(THD *thd, LEX_STRING name, List<Item> *item_list)
|
|
||||||
{
|
|
||||||
Item *func= NULL;
|
|
||||||
int arg_count= 0;
|
|
||||||
|
|
||||||
if (item_list != NULL)
|
|
||||||
arg_count= item_list->elements;
|
|
||||||
|
|
||||||
switch (arg_count) {
|
|
||||||
case 2:
|
|
||||||
{
|
|
||||||
Item *param_1= item_list->pop();
|
|
||||||
Item *param_2= item_list->pop();
|
|
||||||
func= new (thd->mem_root) Item_func_vtq_trx_seesX(thd, param_1, param_2);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
my_error(ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT, MYF(0), name.str);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return func;
|
|
||||||
}
|
|
||||||
|
|
||||||
static Create_func_vtq_trx_sees<Item_func_vtq_trx_seesX> s_singleton;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
Create_func_vtq_trx_sees<Item_func_vtq_trx_seesX>() {}
|
|
||||||
virtual ~Create_func_vtq_trx_sees<Item_func_vtq_trx_seesX>() {}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<class X>
|
|
||||||
Create_func_vtq_trx_sees<X> Create_func_vtq_trx_sees<X>::s_singleton;
|
|
||||||
|
|
||||||
|
|
||||||
struct Native_func_registry
|
|
||||||
{
|
|
||||||
LEX_STRING name;
|
|
||||||
Create_func *builder;
|
|
||||||
};
|
|
||||||
|
|
||||||
#define BUILDER(F) & F::s_singleton
|
#define BUILDER(F) & F::s_singleton
|
||||||
|
|
||||||
#ifdef HAVE_SPATIAL
|
#ifdef HAVE_SPATIAL
|
||||||
@ -7146,13 +6997,6 @@ static Native_func_registry func_array[] =
|
|||||||
{ { C_STRING_WITH_LEN("UUID") }, BUILDER(Create_func_uuid)},
|
{ { C_STRING_WITH_LEN("UUID") }, BUILDER(Create_func_uuid)},
|
||||||
{ { C_STRING_WITH_LEN("UUID_SHORT") }, BUILDER(Create_func_uuid_short)},
|
{ { C_STRING_WITH_LEN("UUID_SHORT") }, BUILDER(Create_func_uuid_short)},
|
||||||
{ { C_STRING_WITH_LEN("VERSION") }, BUILDER(Create_func_version)},
|
{ { C_STRING_WITH_LEN("VERSION") }, BUILDER(Create_func_version)},
|
||||||
{ { C_STRING_WITH_LEN("VTQ_BEGIN_TS") }, BUILDER(Create_func_vtq<VTQ_BEGIN_TS>)},
|
|
||||||
{ { C_STRING_WITH_LEN("VTQ_COMMIT_ID") }, BUILDER(Create_func_vtq<VTQ_COMMIT_ID>)},
|
|
||||||
{ { C_STRING_WITH_LEN("VTQ_COMMIT_TS") }, BUILDER(Create_func_vtq<VTQ_COMMIT_TS>)},
|
|
||||||
{ { C_STRING_WITH_LEN("VTQ_ISO_LEVEL") }, BUILDER(Create_func_vtq<VTQ_ISO_LEVEL>)},
|
|
||||||
{ { C_STRING_WITH_LEN("VTQ_TRX_ID") }, BUILDER(Create_func_vtq<VTQ_TRX_ID>)},
|
|
||||||
{ { C_STRING_WITH_LEN("VTQ_TRX_SEES") }, BUILDER(Create_func_vtq_trx_sees<Item_func_vtq_trx_sees>)},
|
|
||||||
{ { C_STRING_WITH_LEN("VTQ_TRX_SEES_EQ") }, BUILDER(Create_func_vtq_trx_sees<Item_func_vtq_trx_sees_eq>)},
|
|
||||||
{ { C_STRING_WITH_LEN("WEEKDAY") }, BUILDER(Create_func_weekday)},
|
{ { C_STRING_WITH_LEN("WEEKDAY") }, BUILDER(Create_func_weekday)},
|
||||||
{ { C_STRING_WITH_LEN("WEEKOFYEAR") }, BUILDER(Create_func_weekofyear)},
|
{ { C_STRING_WITH_LEN("WEEKOFYEAR") }, BUILDER(Create_func_weekofyear)},
|
||||||
{ { C_STRING_WITH_LEN("WITHIN") }, GEOM_BUILDER(Create_func_within)},
|
{ { C_STRING_WITH_LEN("WITHIN") }, GEOM_BUILDER(Create_func_within)},
|
||||||
@ -7182,8 +7026,6 @@ get_native_fct_hash_key(const uchar *buff, size_t *length,
|
|||||||
|
|
||||||
int item_create_init()
|
int item_create_init()
|
||||||
{
|
{
|
||||||
Native_func_registry *func;
|
|
||||||
|
|
||||||
DBUG_ENTER("item_create_init");
|
DBUG_ENTER("item_create_init");
|
||||||
|
|
||||||
if (my_hash_init(& native_functions_hash,
|
if (my_hash_init(& native_functions_hash,
|
||||||
@ -7196,7 +7038,16 @@ int item_create_init()
|
|||||||
MYF(0)))
|
MYF(0)))
|
||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
|
|
||||||
for (func= func_array; func->builder != NULL; func++)
|
DBUG_RETURN(item_create_append(func_array));
|
||||||
|
}
|
||||||
|
|
||||||
|
int item_create_append(Native_func_registry array[])
|
||||||
|
{
|
||||||
|
Native_func_registry *func;
|
||||||
|
|
||||||
|
DBUG_ENTER("item_create_append");
|
||||||
|
|
||||||
|
for (func= array; func->builder != NULL; func++)
|
||||||
{
|
{
|
||||||
if (my_hash_insert(& native_functions_hash, (uchar*) func))
|
if (my_hash_insert(& native_functions_hash, (uchar*) func))
|
||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
|
@ -19,6 +19,8 @@
|
|||||||
#ifndef ITEM_CREATE_H
|
#ifndef ITEM_CREATE_H
|
||||||
#define ITEM_CREATE_H
|
#define ITEM_CREATE_H
|
||||||
|
|
||||||
|
#include "item_func.h" // Cast_target
|
||||||
|
|
||||||
typedef struct st_udf_func udf_func;
|
typedef struct st_udf_func udf_func;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -66,6 +68,37 @@ protected:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
Adapter for native functions with a variable number of arguments.
|
||||||
|
The main use of this class is to discard the following calls:
|
||||||
|
<code>foo(expr1 AS name1, expr2 AS name2, ...)</code>
|
||||||
|
which are syntactically correct (the syntax can refer to a UDF),
|
||||||
|
but semantically invalid for native functions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
class Create_native_func : public Create_func
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual Item *create_func(THD *thd, LEX_STRING name, List<Item> *item_list);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Builder method, with no arguments.
|
||||||
|
@param thd The current thread
|
||||||
|
@param name The native function name
|
||||||
|
@param item_list The function parameters, none of which are named
|
||||||
|
@return An item representing the function call
|
||||||
|
*/
|
||||||
|
virtual Item *create_native(THD *thd, LEX_STRING name,
|
||||||
|
List<Item> *item_list) = 0;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
/** Constructor. */
|
||||||
|
Create_native_func() {}
|
||||||
|
/** Destructor. */
|
||||||
|
virtual ~Create_native_func() {}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Function builder for qualified functions.
|
Function builder for qualified functions.
|
||||||
This builder is used with functions call using a qualified function name
|
This builder is used with functions call using a qualified function name
|
||||||
@ -183,7 +216,14 @@ Item *create_temporal_literal(THD *thd, const String *str,
|
|||||||
type, send_error);
|
type, send_error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct Native_func_registry
|
||||||
|
{
|
||||||
|
LEX_STRING name;
|
||||||
|
Create_func *builder;
|
||||||
|
};
|
||||||
|
|
||||||
int item_create_init();
|
int item_create_init();
|
||||||
|
int item_create_append(Native_func_registry array[]);
|
||||||
void item_create_cleanup();
|
void item_create_cleanup();
|
||||||
|
|
||||||
Item *create_func_dyncol_create(THD *thd, List<DYNCALL_CREATE_DEF> &list);
|
Item *create_func_dyncol_create(THD *thd, List<DYNCALL_CREATE_DEF> &list);
|
||||||
|
@ -30,6 +30,9 @@ extern "C" /* Bug in BSDI include file */
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include "sql_udf.h" // udf_handler
|
||||||
|
#include "my_decimal.h" // string2my_decimal
|
||||||
|
|
||||||
|
|
||||||
class Item_func :public Item_func_or_sum
|
class Item_func :public Item_func_or_sum
|
||||||
{
|
{
|
||||||
|
@ -25,58 +25,28 @@
|
|||||||
|
|
||||||
Item_func_vtq_ts::Item_func_vtq_ts(
|
Item_func_vtq_ts::Item_func_vtq_ts(
|
||||||
THD *thd,
|
THD *thd,
|
||||||
Item* a,
|
handlerton* hton,
|
||||||
vtq_field_t _vtq_field,
|
|
||||||
handlerton* hton) :
|
|
||||||
VTQ_common<Item_datetimefunc>(thd, a, hton),
|
|
||||||
vtq_field(_vtq_field)
|
|
||||||
{
|
|
||||||
decimals= 6;
|
|
||||||
null_value= true;
|
|
||||||
DBUG_ASSERT(arg_count == 1 && args[0]);
|
|
||||||
}
|
|
||||||
|
|
||||||
Item_func_vtq_ts::Item_func_vtq_ts(
|
|
||||||
THD *thd,
|
|
||||||
Item* a,
|
Item* a,
|
||||||
vtq_field_t _vtq_field) :
|
vtq_field_t _vtq_field) :
|
||||||
VTQ_common<Item_datetimefunc>(thd, a),
|
VTQ_common<Item_datetimefunc>(thd, hton, a),
|
||||||
vtq_field(_vtq_field)
|
vtq_field(_vtq_field)
|
||||||
{
|
{
|
||||||
decimals= 6;
|
decimals= 6;
|
||||||
null_value= true;
|
null_value= true;
|
||||||
DBUG_ASSERT(arg_count == 1 && args[0]);
|
DBUG_ASSERT(arg_count == 1 && args[0]);
|
||||||
|
check_hton();
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class Item_func_X>
|
template <class Item_func_X>
|
||||||
void
|
void
|
||||||
VTQ_common<Item_func_X>::init_hton()
|
VTQ_common<Item_func_X>::check_hton()
|
||||||
{
|
{
|
||||||
if (!hton)
|
|
||||||
{
|
|
||||||
if (Item_func_X::args[0]->type() == Item::FIELD_ITEM)
|
|
||||||
{
|
|
||||||
Item_field *f=
|
|
||||||
static_cast<Item_field *>(Item_func_X::args[0]);
|
|
||||||
DBUG_ASSERT(
|
|
||||||
f->field &&
|
|
||||||
f->field->table &&
|
|
||||||
f->field->table->s &&
|
|
||||||
f->field->table->s->db_plugin);
|
|
||||||
hton= f->field->table->file->partition_ht();
|
|
||||||
DBUG_ASSERT(hton);
|
DBUG_ASSERT(hton);
|
||||||
}
|
if (!(hton->flags & HTON_NATIVE_SYS_VERSIONING) && hton->db_type != DB_TYPE_HEAP)
|
||||||
else if (innodb_plugin)
|
|
||||||
{
|
|
||||||
hton= plugin_hton(plugin_int_to_ref(innodb_plugin));
|
|
||||||
DBUG_ASSERT(hton);
|
|
||||||
}
|
|
||||||
if (hton && !(hton->flags & HTON_NATIVE_SYS_VERSIONING))
|
|
||||||
{
|
{
|
||||||
my_error(ER_VERS_ENGINE_UNSUPPORTED, MYF(0), Item::name ? Item::name : this->func_name());
|
my_error(ER_VERS_ENGINE_UNSUPPORTED, MYF(0), Item::name ? Item::name : this->func_name());
|
||||||
hton= NULL;
|
hton= NULL;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
@ -92,8 +62,6 @@ Item_func_vtq_ts::get_date(MYSQL_TIME *res, ulonglong fuzzy_date)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
init_hton();
|
|
||||||
|
|
||||||
if (!hton)
|
if (!hton)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
@ -106,10 +74,11 @@ Item_func_vtq_ts::get_date(MYSQL_TIME *res, ulonglong fuzzy_date)
|
|||||||
|
|
||||||
Item_func_vtq_id::Item_func_vtq_id(
|
Item_func_vtq_id::Item_func_vtq_id(
|
||||||
THD *thd,
|
THD *thd,
|
||||||
|
handlerton *hton,
|
||||||
Item* a,
|
Item* a,
|
||||||
vtq_field_t _vtq_field,
|
vtq_field_t _vtq_field,
|
||||||
bool _backwards) :
|
bool _backwards) :
|
||||||
VTQ_common<Item_int_func>(thd, a),
|
VTQ_common<Item_int_func>(thd, hton, a),
|
||||||
vtq_field(_vtq_field),
|
vtq_field(_vtq_field),
|
||||||
backwards(_backwards)
|
backwards(_backwards)
|
||||||
{
|
{
|
||||||
@ -118,14 +87,16 @@ Item_func_vtq_id::Item_func_vtq_id(
|
|||||||
unsigned_flag= 1;
|
unsigned_flag= 1;
|
||||||
null_value= true;
|
null_value= true;
|
||||||
DBUG_ASSERT(arg_count == 1 && args[0]);
|
DBUG_ASSERT(arg_count == 1 && args[0]);
|
||||||
|
check_hton();
|
||||||
}
|
}
|
||||||
|
|
||||||
Item_func_vtq_id::Item_func_vtq_id(
|
Item_func_vtq_id::Item_func_vtq_id(
|
||||||
THD *thd,
|
THD *thd,
|
||||||
|
handlerton *hton,
|
||||||
Item* a,
|
Item* a,
|
||||||
Item* b,
|
Item* b,
|
||||||
vtq_field_t _vtq_field) :
|
vtq_field_t _vtq_field) :
|
||||||
VTQ_common<Item_int_func>(thd, a, b),
|
VTQ_common<Item_int_func>(thd, hton, a, b),
|
||||||
vtq_field(_vtq_field),
|
vtq_field(_vtq_field),
|
||||||
backwards(false)
|
backwards(false)
|
||||||
{
|
{
|
||||||
@ -134,6 +105,7 @@ Item_func_vtq_id::Item_func_vtq_id(
|
|||||||
unsigned_flag= 1;
|
unsigned_flag= 1;
|
||||||
null_value= true;
|
null_value= true;
|
||||||
DBUG_ASSERT(arg_count == 2 && args[0] && args[1]);
|
DBUG_ASSERT(arg_count == 2 && args[0] && args[1]);
|
||||||
|
check_hton();
|
||||||
}
|
}
|
||||||
|
|
||||||
longlong
|
longlong
|
||||||
@ -186,8 +158,6 @@ Item_func_vtq_id::get_by_commit_ts(MYSQL_TIME &commit_ts, bool backwards)
|
|||||||
longlong
|
longlong
|
||||||
Item_func_vtq_id::val_int()
|
Item_func_vtq_id::val_int()
|
||||||
{
|
{
|
||||||
init_hton();
|
|
||||||
|
|
||||||
if (!hton)
|
if (!hton)
|
||||||
{
|
{
|
||||||
null_value= true;
|
null_value= true;
|
||||||
@ -222,9 +192,10 @@ Item_func_vtq_id::val_int()
|
|||||||
|
|
||||||
Item_func_vtq_trx_sees::Item_func_vtq_trx_sees(
|
Item_func_vtq_trx_sees::Item_func_vtq_trx_sees(
|
||||||
THD *thd,
|
THD *thd,
|
||||||
|
handlerton *hton,
|
||||||
Item* a,
|
Item* a,
|
||||||
Item* b) :
|
Item* b) :
|
||||||
VTQ_common<Item_bool_func>(thd, a, b),
|
VTQ_common<Item_bool_func>(thd, hton, a, b),
|
||||||
accept_eq(false)
|
accept_eq(false)
|
||||||
{
|
{
|
||||||
null_value= true;
|
null_value= true;
|
||||||
@ -237,8 +208,6 @@ Item_func_vtq_trx_sees::val_int()
|
|||||||
THD *thd= current_thd;
|
THD *thd= current_thd;
|
||||||
DBUG_ASSERT(thd);
|
DBUG_ASSERT(thd);
|
||||||
|
|
||||||
init_hton();
|
|
||||||
|
|
||||||
if (!hton)
|
if (!hton)
|
||||||
{
|
{
|
||||||
null_value= true;
|
null_value= true;
|
||||||
|
@ -29,15 +29,12 @@ class VTQ_common : public Item_func_X
|
|||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
handlerton *hton;
|
handlerton *hton;
|
||||||
void init_hton();
|
void check_hton();
|
||||||
public:
|
public:
|
||||||
VTQ_common(THD *thd, Item* a) :
|
VTQ_common(THD *thd, handlerton* _hton, Item* a, Item* b) :
|
||||||
Item_func_X(thd, a),
|
|
||||||
hton(NULL) {}
|
|
||||||
VTQ_common(THD *thd, Item* a, Item* b) :
|
|
||||||
Item_func_X(thd, a, b),
|
Item_func_X(thd, a, b),
|
||||||
hton(NULL) {}
|
hton(_hton) {}
|
||||||
VTQ_common(THD *thd, Item* a, handlerton* _hton) :
|
VTQ_common(THD *thd, handlerton* _hton, Item* a) :
|
||||||
Item_func_X(thd, a),
|
Item_func_X(thd, a),
|
||||||
hton(_hton) {}
|
hton(_hton) {}
|
||||||
};
|
};
|
||||||
@ -47,8 +44,7 @@ class Item_func_vtq_ts :
|
|||||||
{
|
{
|
||||||
vtq_field_t vtq_field;
|
vtq_field_t vtq_field;
|
||||||
public:
|
public:
|
||||||
Item_func_vtq_ts(THD *thd, Item* a, vtq_field_t _vtq_field, handlerton *hton);
|
Item_func_vtq_ts(THD *thd, handlerton *hton, Item* a, vtq_field_t _vtq_field);
|
||||||
Item_func_vtq_ts(THD *thd, Item* a, vtq_field_t _vtq_field);
|
|
||||||
const char *func_name() const
|
const char *func_name() const
|
||||||
{
|
{
|
||||||
if (vtq_field == VTQ_BEGIN_TS)
|
if (vtq_field == VTQ_BEGIN_TS)
|
||||||
@ -73,8 +69,8 @@ class Item_func_vtq_id :
|
|||||||
longlong get_by_commit_ts(MYSQL_TIME &commit_ts, bool backwards);
|
longlong get_by_commit_ts(MYSQL_TIME &commit_ts, bool backwards);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Item_func_vtq_id(THD *thd, Item* a, vtq_field_t _vtq_field, bool _backwards= false);
|
Item_func_vtq_id(THD *thd, handlerton *hton, Item* a, vtq_field_t _vtq_field, bool _backwards= false);
|
||||||
Item_func_vtq_id(THD *thd, Item* a, Item* b, vtq_field_t _vtq_field);
|
Item_func_vtq_id(THD *thd, handlerton *hton, Item* a, Item* b, vtq_field_t _vtq_field);
|
||||||
|
|
||||||
vtq_record_t *vtq_cached_result() { return &cached_result; }
|
vtq_record_t *vtq_cached_result() { return &cached_result; }
|
||||||
|
|
||||||
@ -112,7 +108,7 @@ protected:
|
|||||||
bool accept_eq;
|
bool accept_eq;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Item_func_vtq_trx_sees(THD *thd, Item* a, Item* b);
|
Item_func_vtq_trx_sees(THD *thd, handlerton *hton, Item* a, Item* b);
|
||||||
const char *func_name() const
|
const char *func_name() const
|
||||||
{
|
{
|
||||||
return "vtq_trx_sees";
|
return "vtq_trx_sees";
|
||||||
@ -126,8 +122,8 @@ class Item_func_vtq_trx_sees_eq :
|
|||||||
public Item_func_vtq_trx_sees
|
public Item_func_vtq_trx_sees
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Item_func_vtq_trx_sees_eq(THD *thd, Item* a, Item* b) :
|
Item_func_vtq_trx_sees_eq(THD *thd, handlerton *hton, Item* a, Item* b) :
|
||||||
Item_func_vtq_trx_sees(thd, a, b)
|
Item_func_vtq_trx_sees(thd, hton, a, b)
|
||||||
{
|
{
|
||||||
accept_eq= true;
|
accept_eq= true;
|
||||||
}
|
}
|
||||||
|
@ -233,8 +233,6 @@ static int plugin_array_version=0;
|
|||||||
static bool initialized= 0;
|
static bool initialized= 0;
|
||||||
ulong dlopen_count;
|
ulong dlopen_count;
|
||||||
|
|
||||||
st_plugin_int* innodb_plugin= NULL;
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
write-lock on LOCK_system_variables_hash is required before modifying
|
write-lock on LOCK_system_variables_hash is required before modifying
|
||||||
@ -1424,18 +1422,6 @@ static int plugin_initialize(MEM_ROOT *tmp_root, struct st_plugin_int *plugin,
|
|||||||
}
|
}
|
||||||
state= PLUGIN_IS_READY; // plugin->init() succeeded
|
state= PLUGIN_IS_READY; // plugin->init() succeeded
|
||||||
|
|
||||||
{
|
|
||||||
static const char * INNODB= "InnoDB";
|
|
||||||
static const uint INNODB_LEN= strlen(INNODB);
|
|
||||||
|
|
||||||
if (!my_strnncoll(&my_charset_latin1,
|
|
||||||
(const uchar *) plugin->name.str, plugin->name.length,
|
|
||||||
(const uchar *) INNODB, INNODB_LEN))
|
|
||||||
{
|
|
||||||
innodb_plugin= plugin;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (plugin->plugin->status_vars)
|
if (plugin->plugin->status_vars)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
|
@ -160,8 +160,6 @@ extern ulong plugin_maturity;
|
|||||||
extern TYPELIB plugin_maturity_values;
|
extern TYPELIB plugin_maturity_values;
|
||||||
extern const char *plugin_maturity_names[];
|
extern const char *plugin_maturity_names[];
|
||||||
|
|
||||||
extern st_plugin_int* innodb_plugin;
|
|
||||||
|
|
||||||
extern int plugin_init(int *argc, char **argv, int init_flags);
|
extern int plugin_init(int *argc, char **argv, int init_flags);
|
||||||
extern void plugin_shutdown(void);
|
extern void plugin_shutdown(void);
|
||||||
void add_plugin_options(DYNAMIC_ARRAY *options, MEM_ROOT *mem_root);
|
void add_plugin_options(DYNAMIC_ARRAY *options, MEM_ROOT *mem_root);
|
||||||
|
@ -875,15 +875,14 @@ int vers_setup_select(THD *thd, TABLE_LIST *tables, COND **where_expr,
|
|||||||
DBUG_ASSERT(hton);
|
DBUG_ASSERT(hton);
|
||||||
row_start= newx Item_func_vtq_ts(
|
row_start= newx Item_func_vtq_ts(
|
||||||
thd,
|
thd,
|
||||||
|
hton,
|
||||||
row_start,
|
row_start,
|
||||||
VTQ_COMMIT_TS,
|
VTQ_COMMIT_TS);
|
||||||
// FIXME: is it needed to pass hton or it can be deduced from arg 'a'?
|
|
||||||
hton);
|
|
||||||
row_end= newx Item_func_vtq_ts(
|
row_end= newx Item_func_vtq_ts(
|
||||||
thd,
|
thd,
|
||||||
|
hton,
|
||||||
row_end,
|
row_end,
|
||||||
VTQ_COMMIT_TS,
|
VTQ_COMMIT_TS);
|
||||||
hton);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Item *cond1= 0, *cond2= 0, *curr= 0;
|
Item *cond1= 0, *cond2= 0, *curr= 0;
|
||||||
@ -952,17 +951,17 @@ int vers_setup_select(THD *thd, TABLE_LIST *tables, COND **where_expr,
|
|||||||
break;
|
break;
|
||||||
case FOR_SYSTEM_TIME_AS_OF:
|
case FOR_SYSTEM_TIME_AS_OF:
|
||||||
trx_id0= vers_conditions.unit == UNIT_TIMESTAMP ?
|
trx_id0= vers_conditions.unit == UNIT_TIMESTAMP ?
|
||||||
newx Item_func_vtq_id(thd, vers_conditions.start, VTQ_TRX_ID) :
|
newx Item_func_vtq_id(thd, hton, vers_conditions.start, VTQ_TRX_ID) :
|
||||||
vers_conditions.start;
|
vers_conditions.start;
|
||||||
cond1= newx Item_func_vtq_trx_sees_eq(thd, trx_id0, row_start);
|
cond1= newx Item_func_vtq_trx_sees_eq(thd, hton, trx_id0, row_start);
|
||||||
cond2= newx Item_func_vtq_trx_sees(thd, row_end, trx_id0);
|
cond2= newx Item_func_vtq_trx_sees(thd, hton, row_end, trx_id0);
|
||||||
break;
|
break;
|
||||||
case FOR_SYSTEM_TIME_FROM_TO:
|
case FOR_SYSTEM_TIME_FROM_TO:
|
||||||
case FOR_SYSTEM_TIME_BETWEEN:
|
case FOR_SYSTEM_TIME_BETWEEN:
|
||||||
if (vers_conditions.unit == UNIT_TIMESTAMP)
|
if (vers_conditions.unit == UNIT_TIMESTAMP)
|
||||||
{
|
{
|
||||||
trx_id0= newx Item_func_vtq_id(thd, vers_conditions.start, VTQ_TRX_ID, true);
|
trx_id0= newx Item_func_vtq_id(thd, hton, vers_conditions.start, VTQ_TRX_ID, true);
|
||||||
trx_id1= newx Item_func_vtq_id(thd, vers_conditions.end, VTQ_TRX_ID, false);
|
trx_id1= newx Item_func_vtq_id(thd, hton, vers_conditions.end, VTQ_TRX_ID, false);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -971,13 +970,13 @@ int vers_setup_select(THD *thd, TABLE_LIST *tables, COND **where_expr,
|
|||||||
}
|
}
|
||||||
|
|
||||||
cond1= vers_conditions.type == FOR_SYSTEM_TIME_FROM_TO ?
|
cond1= vers_conditions.type == FOR_SYSTEM_TIME_FROM_TO ?
|
||||||
newx Item_func_vtq_trx_sees(thd, trx_id1, row_start) :
|
newx Item_func_vtq_trx_sees(thd, hton, trx_id1, row_start) :
|
||||||
newx Item_func_vtq_trx_sees_eq(thd, trx_id1, row_start);
|
newx Item_func_vtq_trx_sees_eq(thd, hton, trx_id1, row_start);
|
||||||
cond2= newx Item_func_vtq_trx_sees_eq(thd, row_end, trx_id0);
|
cond2= newx Item_func_vtq_trx_sees_eq(thd, hton, row_end, trx_id0);
|
||||||
break;
|
break;
|
||||||
case FOR_SYSTEM_TIME_BEFORE:
|
case FOR_SYSTEM_TIME_BEFORE:
|
||||||
trx_id0= vers_conditions.unit == UNIT_TIMESTAMP ?
|
trx_id0= vers_conditions.unit == UNIT_TIMESTAMP ?
|
||||||
newx Item_func_vtq_id(thd, vers_conditions.start, VTQ_TRX_ID) :
|
newx Item_func_vtq_id(thd, hton, vers_conditions.start, VTQ_TRX_ID) :
|
||||||
vers_conditions.start;
|
vers_conditions.start;
|
||||||
cond1= newx Item_func_lt(thd, row_end, trx_id0);
|
cond1= newx Item_func_lt(thd, row_end, trx_id0);
|
||||||
break;
|
break;
|
||||||
|
@ -60,6 +60,10 @@ struct LEX_STRING_u : public Storage
|
|||||||
{
|
{
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
const LEX_STRING& lex_string() const
|
||||||
|
{
|
||||||
|
return *(LEX_STRING *)this;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class Compare= Compare_strncmp, class Storage= LEX_STRING_u<> >
|
template <class Compare= Compare_strncmp, class Storage= LEX_STRING_u<> >
|
||||||
|
Reference in New Issue
Block a user