MDEV-19994 Add class Function_collection

This commit is contained in:
Alexander Barkov 2019-07-09 12:47:42 +04:00
parent 0940e25d69
commit 4dc85973b4
17 changed files with 1706 additions and 1816 deletions

View file

@ -489,3 +489,18 @@ SET SESSION debug_dbug="-d,cmp_item";
#
# End of 10.4 tests
#
#
# Start of 10.5 tests
#
#
# MDEV-19994 Add class Function_collection
#
SET SESSION debug_dbug="+d,make_item_func_call_native_simulate_not_found";
SELECT CONTAINS(POINT(1,1),POINT(1,1));
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '(POINT(1,1),POINT(1,1))' at line 1
SELECT WITHIN(POINT(1,1),POINT(1,1));
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '(POINT(1,1),POINT(1,1))' at line 1
SET SESSION debug_dbug="-d,make_item_func_call_native_simulate_not_found";
#
# End of 10.5 tests
#

View file

@ -153,3 +153,23 @@ SET SESSION debug_dbug="-d,cmp_item";
--echo #
--echo # End of 10.4 tests
--echo #
--echo #
--echo # Start of 10.5 tests
--echo #
--echo #
--echo # MDEV-19994 Add class Function_collection
--echo #
SET SESSION debug_dbug="+d,make_item_func_call_native_simulate_not_found";
--error ER_PARSE_ERROR
SELECT CONTAINS(POINT(1,1),POINT(1,1));
--error ER_PARSE_ERROR
SELECT WITHIN(POINT(1,1),POINT(1,1));
SET SESSION debug_dbug="-d,make_item_func_call_native_simulate_not_found";
--echo #
--echo # End of 10.5 tests
--echo #

View file

@ -5037,3 +5037,24 @@ DROP TABLE t1, t2;
#
# End of 10.4 tests
#
#
# Start of 10.5 tests
#
#
# MDEV-19994 Add class Function_collection
#
SELECT CONTAINS();
ERROR 42000: Incorrect parameter count in the call to native function 'CONTAINS()'
SELECT CONTAINS(POINT(1,1));
ERROR 42000: Incorrect parameter count in the call to native function 'CONTAINS(POINT(1,1))'
SELECT CONTAINS(POINT(1,1), POINT(1,1), POINT(1,1));
ERROR 42000: Incorrect parameter count in the call to native function 'CONTAINS(POINT(1,1), POINT(1,1), POINT(1,1))'
SELECT WITHIN();
ERROR 42000: Incorrect parameter count in the call to native function 'WITHIN()'
SELECT WITHIN(POINT(1,1));
ERROR 42000: Incorrect parameter count in the call to native function 'WITHIN(POINT(1,1))'
SELECT WITHIN(POINT(1,1), POINT(1,1), POINT(1,1));
ERROR 42000: Incorrect parameter count in the call to native function 'WITHIN(POINT(1,1), POINT(1,1), POINT(1,1))'
#
# End of 10.5 tests
#

View file

@ -3116,3 +3116,30 @@ DROP TABLE t1, t2;
--echo #
--echo # End of 10.4 tests
--echo #
--echo #
--echo # Start of 10.5 tests
--echo #
--echo #
--echo # MDEV-19994 Add class Function_collection
--echo #
--error ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT
SELECT CONTAINS();
--error ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT
SELECT CONTAINS(POINT(1,1));
--error ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT
SELECT CONTAINS(POINT(1,1), POINT(1,1), POINT(1,1));
--error ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT
SELECT WITHIN();
--error ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT
SELECT WITHIN(POINT(1,1));
--error ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT
SELECT WITHIN(POINT(1,1), POINT(1,1), POINT(1,1));
--echo #
--echo # End of 10.5 tests
--echo #

View file

@ -0,0 +1,16 @@
SET sql_mode=ORACLE;
#
# Start of 10.5 tests
#
#
# MDEV-19994 Add class Function_collection
#
SET SESSION debug_dbug="+d,make_item_func_call_native_simulate_not_found";
SELECT CONTAINS(POINT(1,1),POINT(1,1));
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '(POINT(1,1),POINT(1,1))' at line 1
SELECT WITHIN(POINT(1,1),POINT(1,1));
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '(POINT(1,1),POINT(1,1))' at line 1
SET SESSION debug_dbug="-d,make_item_func_call_native_simulate_not_found";
#
# End of 10.5 tests
#

View file

@ -1,6 +1,34 @@
SET sql_mode=ORACLE;
SELECT CONTAINS(POINT(1,1), POINT(1,1));
CONTAINS(POINT(1,1), POINT(1,1))
1
SELECT CONTAINS(POINT(1,1), POINT(0,0));
CONTAINS(POINT(1,1), POINT(0,0))
0
SELECT WITHIN(POINT(1,1), POINT(1,1));
WITHIN(POINT(1,1), POINT(1,1))
1
SELECT WITHIN(POINT(1,1), POINT(0,0));
WITHIN(POINT(1,1), POINT(0,0))
0
#
# Start of 10.5 tests
#
#
# MDEV-19994 Add class Function_collection
#
SELECT CONTAINS();
ERROR 42000: Incorrect parameter count in the call to native function 'CONTAINS()'
SELECT CONTAINS(POINT(1,1));
ERROR 42000: Incorrect parameter count in the call to native function 'CONTAINS(POINT(1,1))'
SELECT CONTAINS(POINT(1,1), POINT(1,1), POINT(1,1));
ERROR 42000: Incorrect parameter count in the call to native function 'CONTAINS(POINT(1,1), POINT(1,1), POINT(1,1))'
SELECT WITHIN();
ERROR 42000: Incorrect parameter count in the call to native function 'WITHIN()'
SELECT WITHIN(POINT(1,1));
ERROR 42000: Incorrect parameter count in the call to native function 'WITHIN(POINT(1,1))'
SELECT WITHIN(POINT(1,1), POINT(1,1), POINT(1,1));
ERROR 42000: Incorrect parameter count in the call to native function 'WITHIN(POINT(1,1), POINT(1,1), POINT(1,1))'
#
# End of 10.5 tests
#

View file

@ -0,0 +1,23 @@
--source include/have_geometry.inc
--source include/have_debug.inc
SET sql_mode=ORACLE;
--echo #
--echo # Start of 10.5 tests
--echo #
--echo #
--echo # MDEV-19994 Add class Function_collection
--echo #
SET SESSION debug_dbug="+d,make_item_func_call_native_simulate_not_found";
--error ER_PARSE_ERROR
SELECT CONTAINS(POINT(1,1),POINT(1,1));
--error ER_PARSE_ERROR
SELECT WITHIN(POINT(1,1),POINT(1,1));
SET SESSION debug_dbug="-d,make_item_func_call_native_simulate_not_found";
--echo #
--echo # End of 10.5 tests
--echo #

View file

@ -1,4 +1,36 @@
-- source include/have_geometry.inc
SET sql_mode=ORACLE;
SELECT CONTAINS(POINT(1,1), POINT(1,1));
SELECT CONTAINS(POINT(1,1), POINT(0,0));
SELECT WITHIN(POINT(1,1), POINT(1,1));
SELECT WITHIN(POINT(1,1), POINT(0,0));
--echo #
--echo # Start of 10.5 tests
--echo #
--echo #
--echo # MDEV-19994 Add class Function_collection
--echo #
--error ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT
SELECT CONTAINS();
--error ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT
SELECT CONTAINS(POINT(1,1));
--error ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT
SELECT CONTAINS(POINT(1,1), POINT(1,1), POINT(1,1));
--error ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT
SELECT WITHIN();
--error ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT
SELECT WITHIN(POINT(1,1));
--error ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT
SELECT WITHIN(POINT(1,1), POINT(1,1), POINT(1,1));
--echo #
--echo # End of 10.5 tests
--echo #

File diff suppressed because it is too large Load diff

View file

@ -68,6 +68,111 @@ protected:
};
/**
Adapter for functions that takes exactly zero arguments.
*/
class Create_func_arg0 : public Create_func
{
public:
virtual Item *create_func(THD *thd, LEX_CSTRING *name,
List<Item> *item_list);
/**
Builder method, with no arguments.
@param thd The current thread
@return An item representing the function call
*/
virtual Item *create_builder(THD *thd) = 0;
protected:
/** Constructor. */
Create_func_arg0() {}
/** Destructor. */
virtual ~Create_func_arg0() {}
};
/**
Adapter for functions that takes exactly one argument.
*/
class Create_func_arg1 : public Create_func
{
public:
virtual Item *create_func(THD *thd, LEX_CSTRING *name, List<Item> *item_list);
/**
Builder method, with one argument.
@param thd The current thread
@param arg1 The first argument of the function
@return An item representing the function call
*/
virtual Item *create_1_arg(THD *thd, Item *arg1) = 0;
protected:
/** Constructor. */
Create_func_arg1() {}
/** Destructor. */
virtual ~Create_func_arg1() {}
};
/**
Adapter for functions that takes exactly two arguments.
*/
class Create_func_arg2 : public Create_func
{
public:
virtual Item *create_func(THD *thd, LEX_CSTRING *name, List<Item> *item_list);
/**
Builder method, with two arguments.
@param thd The current thread
@param arg1 The first argument of the function
@param arg2 The second argument of the function
@return An item representing the function call
*/
virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2) = 0;
protected:
/** Constructor. */
Create_func_arg2() {}
/** Destructor. */
virtual ~Create_func_arg2() {}
};
/**
Adapter for functions that takes exactly three arguments.
*/
class Create_func_arg3 : public Create_func
{
public:
virtual Item *create_func(THD *thd, LEX_CSTRING *name, List<Item> *item_list);
/**
Builder method, with three arguments.
@param thd The current thread
@param arg1 The first argument of the function
@param arg2 The second argument of the function
@param arg3 The third argument of the function
@return An item representing the function call
*/
virtual Item *create_3_arg(THD *thd, Item *arg1, Item *arg2, Item *arg3) = 0;
protected:
/** Constructor. */
Create_func_arg3() {}
/** Destructor. */
virtual ~Create_func_arg3() {}
};
/**
Adapter for native functions with a variable number of arguments.
The main use of this class is to discard the following calls:

File diff suppressed because it is too large Load diff

View file

@ -8609,6 +8609,20 @@ Item *LEX::make_item_func_call_generic(THD *thd, Lex_ident_cli_st *cdb,
}
Item *LEX::make_item_func_call_native_or_parse_error(THD *thd,
Lex_ident_cli_st &name,
List<Item> *args)
{
Create_func *builder= find_native_function_builder(thd, &name);
DBUG_EXECUTE_IF("make_item_func_call_native_simulate_not_found",
builder= NULL;);
if (builder)
return builder->create_func(thd, &name, args);
thd->parse_error(ER_SYNTAX_ERROR, name.end());
return NULL;
}
Item *LEX::create_item_qualified_asterisk(THD *thd,
const Lex_ident_sys_st *name)
{

View file

@ -4012,6 +4012,9 @@ public:
Item *make_item_func_substr(THD *thd, Item *a, Item *b);
Item *make_item_func_call_generic(THD *thd, Lex_ident_cli_st *db,
Lex_ident_cli_st *name, List<Item> *args);
Item *make_item_func_call_native_or_parse_error(THD *thd,
Lex_ident_cli_st &name,
List<Item> *args);
my_var *create_outvar(THD *thd, const LEX_CSTRING *name);
/*

View file

@ -89,6 +89,7 @@ class Virtual_column_info;
class Conv_source;
class ST_FIELD_INFO;
class Type_collection;
class Create_func;
#define my_charset_numeric my_charset_latin1
@ -6524,6 +6525,18 @@ public:
};
class Function_collection
{
public:
virtual ~Function_collection() {}
virtual bool init()= 0;
virtual void cleanup()= 0;
virtual Create_func *find_native_function_builder(THD *thd,
const LEX_CSTRING &name)
const= 0;
};
class Type_collection
{
public:

View file

@ -258,6 +258,17 @@ extern MYSQL_PLUGIN_IMPORT Type_handler_multipolygon type_handler_multipolygo
extern MYSQL_PLUGIN_IMPORT Type_handler_geometrycollection type_handler_geometrycollection;
class Function_collection_geometry: public Function_collection
{
public:
bool init() override;
void cleanup() override;
Create_func *find_native_function_builder(THD *thd,
const LEX_CSTRING &name)
const override;
};
class Type_collection_geometry: public Type_collection
{
const Type_handler *aggregate_common(const Type_handler *a,
@ -299,6 +310,10 @@ public:
}
};
extern MYSQL_PLUGIN_IMPORT
Function_collection_geometry function_collection_geometry;
extern MYSQL_PLUGIN_IMPORT Type_collection_geometry type_collection_geometry;
#endif // HAVE_SPATIAL

View file

@ -1885,7 +1885,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize);
primary_expr string_factor_expr mysql_concatenation_expr
select_sublist_qualified_asterisk
expr_or_default set_expr_or_default
geometry_function signed_literal expr_or_literal
signed_literal expr_or_literal
opt_escape
sp_opt_default
simple_ident_nospvar
@ -11001,32 +11001,6 @@ function_call_conflict:
if (unlikely($$ == NULL))
MYSQL_YYABORT;
}
| geometry_function
{
#ifdef HAVE_SPATIAL
$$= $1;
/* $1 may be NULL, GEOM_NEW not tested for out of memory */
if (unlikely($$ == NULL))
MYSQL_YYABORT;
#else
my_yyabort_error((ER_FEATURE_DISABLED, MYF(0), sym_group_geom.name,
sym_group_geom.needed_define));
#endif
}
;
geometry_function:
CONTAINS_SYM '(' expr ',' expr ')'
{
$$= GEOM_NEW(thd,
Item_func_spatial_precise_rel(thd, $3, $5,
Item_func::SP_CONTAINS_FUNC));
}
| WITHIN '(' expr ',' expr ')'
{
$$= GEOM_NEW(thd, Item_func_spatial_precise_rel(thd, $3, $5,
Item_func::SP_WITHIN_FUNC));
}
;
/*
@ -11112,6 +11086,18 @@ function_call_generic:
if (unlikely(! ($$= item)))
MYSQL_YYABORT;
}
| CONTAINS_SYM '(' opt_expr_list ')'
{
if (!($$= Lex->make_item_func_call_native_or_parse_error(thd,
$1, $3)))
MYSQL_YYABORT;
}
| WITHIN '(' opt_expr_list ')'
{
if (!($$= Lex->make_item_func_call_native_or_parse_error(thd,
$1, $3)))
MYSQL_YYABORT;
}
| ident_cli '.' ident_cli '(' opt_expr_list ')'
{
if (unlikely(!($$= Lex->make_item_func_call_generic(thd, &$1, &$3, $5))))

View file

@ -1358,7 +1358,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize);
primary_expr string_factor_expr mysql_concatenation_expr
select_sublist_qualified_asterisk
expr_or_default set_expr_or_default
geometry_function signed_literal expr_or_literal
signed_literal expr_or_literal
opt_escape
sp_opt_default
simple_ident_nospvar
@ -11101,32 +11101,6 @@ function_call_conflict:
if (unlikely($$ == NULL))
MYSQL_YYABORT;
}
| geometry_function
{
#ifdef HAVE_SPATIAL
$$= $1;
/* $1 may be NULL, GEOM_NEW not tested for out of memory */
if (unlikely($$ == NULL))
MYSQL_YYABORT;
#else
my_yyabort_error((ER_FEATURE_DISABLED, MYF(0), sym_group_geom.name,
sym_group_geom.needed_define));
#endif
}
;
geometry_function:
CONTAINS_SYM '(' expr ',' expr ')'
{
$$= GEOM_NEW(thd,
Item_func_spatial_precise_rel(thd, $3, $5,
Item_func::SP_CONTAINS_FUNC));
}
| WITHIN '(' expr ',' expr ')'
{
$$= GEOM_NEW(thd, Item_func_spatial_precise_rel(thd, $3, $5,
Item_func::SP_WITHIN_FUNC));
}
;
/*
@ -11212,6 +11186,18 @@ function_call_generic:
if (unlikely(! ($$= item)))
MYSQL_YYABORT;
}
| CONTAINS_SYM '(' opt_expr_list ')'
{
if (!($$= Lex->make_item_func_call_native_or_parse_error(thd,
$1, $3)))
MYSQL_YYABORT;
}
| WITHIN '(' opt_expr_list ')'
{
if (!($$= Lex->make_item_func_call_native_or_parse_error(thd,
$1, $3)))
MYSQL_YYABORT;
}
| ident_cli '.' ident_cli '(' opt_expr_list ')'
{
if (unlikely(!($$= Lex->make_item_func_call_generic(thd, &$1, &$3, $5))))