Commit ddcc9d22 authored by Alexander Barkov's avatar Alexander Barkov

MDEV-31153 New methods Schema::make_item_func_* for REPLACE, SUBSTRING, TRIM

Adding virtual methods to class Schema:

  make_item_func_replace()
  make_item_func_substr()
  make_item_func_trim()

This is a non-functional preparatory change for MDEV-27744.
parent 2e74f9d2
...@@ -8639,33 +8639,6 @@ bool LEX::add_grant_command(THD *thd, enum_sql_command sql_command_arg, ...@@ -8639,33 +8639,6 @@ bool LEX::add_grant_command(THD *thd, enum_sql_command sql_command_arg,
} }
Item *LEX::make_item_func_substr(THD *thd, Item *a, Item *b, Item *c)
{
return (thd->variables.sql_mode & MODE_ORACLE) ?
new (thd->mem_root) Item_func_substr_oracle(thd, a, b, c) :
new (thd->mem_root) Item_func_substr(thd, a, b, c);
}
Item *LEX::make_item_func_substr(THD *thd, Item *a, Item *b)
{
return (thd->variables.sql_mode & MODE_ORACLE) ?
new (thd->mem_root) Item_func_substr_oracle(thd, a, b) :
new (thd->mem_root) Item_func_substr(thd, a, b);
}
Item *LEX::make_item_func_replace(THD *thd,
Item *org,
Item *find,
Item *replace)
{
return (thd->variables.sql_mode & MODE_ORACLE) ?
new (thd->mem_root) Item_func_replace_oracle(thd, org, find, replace) :
new (thd->mem_root) Item_func_replace(thd, org, find, replace);
}
bool SELECT_LEX::vers_push_field(THD *thd, TABLE_LIST *table, bool SELECT_LEX::vers_push_field(THD *thd, TABLE_LIST *table,
const LEX_CSTRING field_name) const LEX_CSTRING field_name)
{ {
......
...@@ -4033,9 +4033,6 @@ struct LEX: public Query_tables_list ...@@ -4033,9 +4033,6 @@ struct LEX: public Query_tables_list
Item *create_item_query_expression(THD *thd, st_select_lex_unit *unit); Item *create_item_query_expression(THD *thd, st_select_lex_unit *unit);
Item *make_item_func_replace(THD *thd, Item *org, Item *find, Item *replace);
Item *make_item_func_substr(THD *thd, Item *a, Item *b, Item *c);
Item *make_item_func_substr(THD *thd, Item *a, Item *b);
Item *make_item_func_call_generic(THD *thd, Lex_ident_cli_st *db, Item *make_item_func_call_generic(THD *thd, Lex_ident_cli_st *db,
Lex_ident_cli_st *name, List<Item> *args); Lex_ident_cli_st *name, List<Item> *args);
Item *make_item_func_call_generic(THD *thd, Item *make_item_func_call_generic(THD *thd,
......
...@@ -32,6 +32,14 @@ class Schema_oracle: public Schema ...@@ -32,6 +32,14 @@ class Schema_oracle: public Schema
return thd->type_handler_for_datetime(); return thd->type_handler_for_datetime();
return src; return src;
} }
Item *make_item_func_replace(THD *thd,
Item *subj,
Item *find,
Item *replace) const;
Item *make_item_func_substr(THD *thd,
const Lex_substring_spec_st &spec) const;
Item *make_item_func_trim(THD *thd, const Lex_trim_st &spec) const;
}; };
...@@ -78,3 +86,56 @@ Schema *Schema::find_implied(THD *thd) ...@@ -78,3 +86,56 @@ Schema *Schema::find_implied(THD *thd)
return &maxdb_schema; return &maxdb_schema;
return &mariadb_schema; return &mariadb_schema;
} }
Item *Schema::make_item_func_replace(THD *thd,
Item *subj,
Item *find,
Item *replace) const
{
return new (thd->mem_root) Item_func_replace(thd, subj, find, replace);
}
Item *Schema::make_item_func_substr(THD *thd,
const Lex_substring_spec_st &spec) const
{
return spec.m_for ?
new (thd->mem_root) Item_func_substr(thd, spec.m_subject, spec.m_from,
spec.m_for) :
new (thd->mem_root) Item_func_substr(thd, spec.m_subject, spec.m_from);
}
Item *Schema::make_item_func_trim(THD *thd, const Lex_trim_st &spec) const
{
return spec.make_item_func_trim_std(thd);
}
Item *Schema_oracle::make_item_func_replace(THD *thd,
Item *subj,
Item *find,
Item *replace) const
{
return new (thd->mem_root) Item_func_replace_oracle(thd, subj, find, replace);
}
Item *Schema_oracle::make_item_func_substr(THD *thd,
const Lex_substring_spec_st &spec) const
{
return spec.m_for ?
new (thd->mem_root) Item_func_substr_oracle(thd, spec.m_subject,
spec.m_from,
spec.m_for) :
new (thd->mem_root) Item_func_substr_oracle(thd, spec.m_subject,
spec.m_from);
}
Item *Schema_oracle::make_item_func_trim(THD *thd,
const Lex_trim_st &spec) const
{
return spec.make_item_func_trim_oracle(thd);
}
...@@ -33,6 +33,17 @@ class Schema ...@@ -33,6 +33,17 @@ class Schema
{ {
return src; return src;
} }
// Builders for native SQL function with a special syntax in sql_yacc.yy
virtual Item *make_item_func_replace(THD *thd,
Item *subj,
Item *find,
Item *replace) const;
virtual Item *make_item_func_substr(THD *thd,
const Lex_substring_spec_st &spec) const;
virtual Item *make_item_func_trim(THD *thd, const Lex_trim_st &spec) const;
/* /*
For now we have *hard-coded* compatibility schemas: For now we have *hard-coded* compatibility schemas:
schema_mariadb, schema_oracle, schema_maxdb. schema_mariadb, schema_oracle, schema_maxdb.
......
...@@ -718,6 +718,7 @@ Virtual_column_info *add_virtual_expression(THD *thd, Item *expr) ...@@ -718,6 +718,7 @@ Virtual_column_info *add_virtual_expression(THD *thd, Item *expr)
Lex_for_loop_st for_loop; Lex_for_loop_st for_loop;
Lex_for_loop_bounds_st for_loop_bounds; Lex_for_loop_bounds_st for_loop_bounds;
Lex_trim_st trim; Lex_trim_st trim;
Lex_substring_spec_st substring_spec;
vers_history_point_t vers_history_point; vers_history_point_t vers_history_point;
struct struct
{ {
...@@ -1077,7 +1078,6 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); ...@@ -1077,7 +1078,6 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize);
%token RELEASE_SYM /* SQL-2003-R */ %token RELEASE_SYM /* SQL-2003-R */
%token RENAME %token RENAME
%token REPEAT_SYM /* MYSQL-FUNC */ %token REPEAT_SYM /* MYSQL-FUNC */
%token REPLACE /* MYSQL-FUNC */
%token REQUIRE_SYM %token REQUIRE_SYM
%token RESIGNAL_SYM /* SQL-2003-R */ %token RESIGNAL_SYM /* SQL-2003-R */
%token RESTRICT %token RESTRICT
...@@ -1117,7 +1117,6 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); ...@@ -1117,7 +1117,6 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize);
%token STDDEV_SAMP_SYM /* SQL-2003-N */ %token STDDEV_SAMP_SYM /* SQL-2003-N */
%token STD_SYM %token STD_SYM
%token STRAIGHT_JOIN %token STRAIGHT_JOIN
%token SUBSTRING /* SQL-2003-N */
%token SUM_SYM /* SQL-2003-N */ %token SUM_SYM /* SQL-2003-N */
%token SYSDATE %token SYSDATE
%token TABLE_REF_PRIORITY %token TABLE_REF_PRIORITY
...@@ -1131,7 +1130,6 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); ...@@ -1131,7 +1130,6 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize);
%token TO_SYM /* SQL-2003-R */ %token TO_SYM /* SQL-2003-R */
%token TRAILING /* SQL-2003-R */ %token TRAILING /* SQL-2003-R */
%token TRIGGER_SYM /* SQL-2003-R */ %token TRIGGER_SYM /* SQL-2003-R */
%token TRIM /* SQL-2003-N */
%token TRUE_SYM /* SQL-2003-R */ %token TRUE_SYM /* SQL-2003-R */
%token ULONGLONG_NUM %token ULONGLONG_NUM
%token UNDERSCORE_CHARSET %token UNDERSCORE_CHARSET
...@@ -1182,6 +1180,14 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); ...@@ -1182,6 +1180,14 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize);
%token <kwd> RAISE_MARIADB_SYM // PLSQL-R %token <kwd> RAISE_MARIADB_SYM // PLSQL-R
%token <kwd> ROWTYPE_MARIADB_SYM // PLSQL-R %token <kwd> ROWTYPE_MARIADB_SYM // PLSQL-R
/*
SQL functions with a special syntax
*/
%token <kwd> REPLACE /* MYSQL-FUNC */
%token <kwd> SUBSTRING /* SQL-2003-N */
%token <kwd> TRIM /* SQL-2003-N */
/* /*
Non-reserved keywords Non-reserved keywords
*/ */
...@@ -2172,6 +2178,7 @@ END_OF_INPUT ...@@ -2172,6 +2178,7 @@ END_OF_INPUT
%type <for_loop> sp_for_loop_index_and_bounds %type <for_loop> sp_for_loop_index_and_bounds
%type <for_loop_bounds> sp_for_loop_bounds %type <for_loop_bounds> sp_for_loop_bounds
%type <trim> trim_operands %type <trim> trim_operands
%type <substring_spec> substring_operands
%type <num> opt_sp_for_loop_direction %type <num> opt_sp_for_loop_direction
%type <spvar_mode> sp_opt_inout %type <spvar_mode> sp_opt_inout
%type <index_hint> index_hint_type %type <index_hint> index_hint_type
...@@ -10916,7 +10923,8 @@ function_call_keyword: ...@@ -10916,7 +10923,8 @@ function_call_keyword:
} }
| TRIM '(' trim_operands ')' | TRIM '(' trim_operands ')'
{ {
if (unlikely(!($$= $3.make_item_func_trim(thd)))) if (unlikely(!($$= Schema::find_implied(thd)->
make_item_func_trim(thd, $3))))
MYSQL_YYABORT; MYSQL_YYABORT;
} }
| USER_SYM '(' ')' | USER_SYM '(' ')'
...@@ -10935,6 +10943,26 @@ function_call_keyword: ...@@ -10935,6 +10943,26 @@ function_call_keyword:
} }
; ;
substring_operands:
expr ',' expr ',' expr
{
$$= Lex_substring_spec_st::init($1, $3, $5);
}
| expr ',' expr
{
$$= Lex_substring_spec_st::init($1, $3);
}
| expr FROM expr FOR_SYM expr
{
$$= Lex_substring_spec_st::init($1, $3, $5);
}
| expr FROM expr
{
$$= Lex_substring_spec_st::init($1, $3);
}
;
/* /*
Function calls using non reserved keywords, with special syntaxic forms. Function calls using non reserved keywords, with special syntaxic forms.
Dedicated grammar rules are needed because of the syntax, Dedicated grammar rules are needed because of the syntax,
...@@ -11049,24 +11077,10 @@ function_call_nonkeyword: ...@@ -11049,24 +11077,10 @@ function_call_nonkeyword:
if (unlikely($$ == NULL)) if (unlikely($$ == NULL))
MYSQL_YYABORT; MYSQL_YYABORT;
} }
| SUBSTRING '(' expr ',' expr ',' expr ')' | SUBSTRING '(' substring_operands ')'
{
if (unlikely(!($$= Lex->make_item_func_substr(thd, $3, $5, $7))))
MYSQL_YYABORT;
}
| SUBSTRING '(' expr ',' expr ')'
{
if (unlikely(!($$= Lex->make_item_func_substr(thd, $3, $5))))
MYSQL_YYABORT;
}
| SUBSTRING '(' expr FROM expr FOR_SYM expr ')'
{
if (unlikely(!($$= Lex->make_item_func_substr(thd, $3, $5, $7))))
MYSQL_YYABORT;
}
| SUBSTRING '(' expr FROM expr ')'
{ {
if (unlikely(!($$= Lex->make_item_func_substr(thd, $3, $5)))) if (unlikely(!($$= Schema::find_implied(thd)->
make_item_func_substr(thd, $3))))
MYSQL_YYABORT; MYSQL_YYABORT;
} }
| SYSDATE opt_time_precision | SYSDATE opt_time_precision
...@@ -11282,7 +11296,8 @@ function_call_conflict: ...@@ -11282,7 +11296,8 @@ function_call_conflict:
} }
| REPLACE '(' expr ',' expr ',' expr ')' | REPLACE '(' expr ',' expr ',' expr ')'
{ {
if (unlikely(!($$= Lex->make_item_func_replace(thd, $3, $5, $7)))) if (unlikely(!($$= Schema::find_implied(thd)->
make_item_func_replace(thd, $3, $5, $7))))
MYSQL_YYABORT; MYSQL_YYABORT;
} }
| REVERSE_SYM '(' expr ')' | REVERSE_SYM '(' expr ')'
......
...@@ -196,6 +196,7 @@ void ORAerror(THD *thd, const char *s) ...@@ -196,6 +196,7 @@ void ORAerror(THD *thd, const char *s)
Lex_for_loop_st for_loop; Lex_for_loop_st for_loop;
Lex_for_loop_bounds_st for_loop_bounds; Lex_for_loop_bounds_st for_loop_bounds;
Lex_trim_st trim; Lex_trim_st trim;
Lex_substring_spec_st substring_spec;
vers_history_point_t vers_history_point; vers_history_point_t vers_history_point;
struct struct
{ {
...@@ -553,7 +554,6 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); ...@@ -553,7 +554,6 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize);
%token RELEASE_SYM /* SQL-2003-R */ %token RELEASE_SYM /* SQL-2003-R */
%token RENAME %token RENAME
%token REPEAT_SYM /* MYSQL-FUNC */ %token REPEAT_SYM /* MYSQL-FUNC */
%token REPLACE /* MYSQL-FUNC */
%token REQUIRE_SYM %token REQUIRE_SYM
%token RESIGNAL_SYM /* SQL-2003-R */ %token RESIGNAL_SYM /* SQL-2003-R */
%token RESTRICT %token RESTRICT
...@@ -593,7 +593,6 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); ...@@ -593,7 +593,6 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize);
%token STDDEV_SAMP_SYM /* SQL-2003-N */ %token STDDEV_SAMP_SYM /* SQL-2003-N */
%token STD_SYM %token STD_SYM
%token STRAIGHT_JOIN %token STRAIGHT_JOIN
%token SUBSTRING /* SQL-2003-N */
%token SUM_SYM /* SQL-2003-N */ %token SUM_SYM /* SQL-2003-N */
%token SYSDATE %token SYSDATE
%token TABLE_REF_PRIORITY %token TABLE_REF_PRIORITY
...@@ -607,7 +606,6 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); ...@@ -607,7 +606,6 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize);
%token TO_SYM /* SQL-2003-R */ %token TO_SYM /* SQL-2003-R */
%token TRAILING /* SQL-2003-R */ %token TRAILING /* SQL-2003-R */
%token TRIGGER_SYM /* SQL-2003-R */ %token TRIGGER_SYM /* SQL-2003-R */
%token TRIM /* SQL-2003-N */
%token TRUE_SYM /* SQL-2003-R */ %token TRUE_SYM /* SQL-2003-R */
%token ULONGLONG_NUM %token ULONGLONG_NUM
%token UNDERSCORE_CHARSET %token UNDERSCORE_CHARSET
...@@ -658,6 +656,14 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); ...@@ -658,6 +656,14 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize);
%token <kwd> RAISE_MARIADB_SYM // PLSQL-R %token <kwd> RAISE_MARIADB_SYM // PLSQL-R
%token <kwd> ROWTYPE_MARIADB_SYM // PLSQL-R %token <kwd> ROWTYPE_MARIADB_SYM // PLSQL-R
/*
SQL functions with a special syntax
*/
%token <kwd> REPLACE /* MYSQL-FUNC */
%token <kwd> SUBSTRING /* SQL-2003-N */
%token <kwd> TRIM /* SQL-2003-N */
/* /*
Non-reserved keywords Non-reserved keywords
*/ */
...@@ -1673,6 +1679,7 @@ END_OF_INPUT ...@@ -1673,6 +1679,7 @@ END_OF_INPUT
%type <for_loop> sp_for_loop_index_and_bounds %type <for_loop> sp_for_loop_index_and_bounds
%type <for_loop_bounds> sp_for_loop_bounds %type <for_loop_bounds> sp_for_loop_bounds
%type <trim> trim_operands %type <trim> trim_operands
%type <substring_spec> substring_operands
%type <num> opt_sp_for_loop_direction %type <num> opt_sp_for_loop_direction
%type <spvar_mode> sp_opt_inout %type <spvar_mode> sp_opt_inout
%type <index_hint> index_hint_type %type <index_hint> index_hint_type
...@@ -11031,7 +11038,8 @@ function_call_keyword: ...@@ -11031,7 +11038,8 @@ function_call_keyword:
} }
| TRIM '(' trim_operands ')' | TRIM '(' trim_operands ')'
{ {
if (unlikely(!($$= $3.make_item_func_trim(thd)))) if (unlikely(!($$= Schema::find_implied(thd)->
make_item_func_trim(thd, $3))))
MYSQL_YYABORT; MYSQL_YYABORT;
} }
| USER_SYM '(' ')' | USER_SYM '(' ')'
...@@ -11050,6 +11058,26 @@ function_call_keyword: ...@@ -11050,6 +11058,26 @@ function_call_keyword:
} }
; ;
substring_operands:
expr ',' expr ',' expr
{
$$= Lex_substring_spec_st::init($1, $3, $5);
}
| expr ',' expr
{
$$= Lex_substring_spec_st::init($1, $3);
}
| expr FROM expr FOR_SYM expr
{
$$= Lex_substring_spec_st::init($1, $3, $5);
}
| expr FROM expr
{
$$= Lex_substring_spec_st::init($1, $3);
}
;
/* /*
Function calls using non reserved keywords, with special syntaxic forms. Function calls using non reserved keywords, with special syntaxic forms.
Dedicated grammar rules are needed because of the syntax, Dedicated grammar rules are needed because of the syntax,
...@@ -11164,24 +11192,10 @@ function_call_nonkeyword: ...@@ -11164,24 +11192,10 @@ function_call_nonkeyword:
if (unlikely($$ == NULL)) if (unlikely($$ == NULL))
MYSQL_YYABORT; MYSQL_YYABORT;
} }
| SUBSTRING '(' expr ',' expr ',' expr ')' | SUBSTRING '(' substring_operands ')'
{
if (unlikely(!($$= Lex->make_item_func_substr(thd, $3, $5, $7))))
MYSQL_YYABORT;
}
| SUBSTRING '(' expr ',' expr ')'
{
if (unlikely(!($$= Lex->make_item_func_substr(thd, $3, $5))))
MYSQL_YYABORT;
}
| SUBSTRING '(' expr FROM expr FOR_SYM expr ')'
{
if (unlikely(!($$= Lex->make_item_func_substr(thd, $3, $5, $7))))
MYSQL_YYABORT;
}
| SUBSTRING '(' expr FROM expr ')'
{ {
if (unlikely(!($$= Lex->make_item_func_substr(thd, $3, $5)))) if (unlikely(!($$= Schema::find_implied(thd)->
make_item_func_substr(thd, $3))))
MYSQL_YYABORT; MYSQL_YYABORT;
} }
| SYSDATE opt_time_precision | SYSDATE opt_time_precision
...@@ -11397,7 +11411,8 @@ function_call_conflict: ...@@ -11397,7 +11411,8 @@ function_call_conflict:
} }
| REPLACE '(' expr ',' expr ',' expr ')' | REPLACE '(' expr ',' expr ',' expr ')'
{ {
if (unlikely(!($$= Lex->make_item_func_replace(thd, $3, $5, $7)))) if (unlikely(!($$= Schema::find_implied(thd)->
make_item_func_replace(thd, $3, $5, $7))))
MYSQL_YYABORT; MYSQL_YYABORT;
} }
| REVERSE_SYM '(' expr ')' | REVERSE_SYM '(' expr ')'
......
...@@ -779,6 +779,11 @@ struct Lex_trim_st ...@@ -779,6 +779,11 @@ struct Lex_trim_st
} }
Item *make_item_func_trim_std(THD *thd) const; Item *make_item_func_trim_std(THD *thd) const;
Item *make_item_func_trim_oracle(THD *thd) const; Item *make_item_func_trim_oracle(THD *thd) const;
/*
This method is still used to handle LTRIM and RTRIM,
while the special syntax TRIM(... BOTH|LEADING|TRAILING)
is now handled by Schema::make_item_func_trim().
*/
Item *make_item_func_trim(THD *thd) const; Item *make_item_func_trim(THD *thd) const;
}; };
...@@ -790,6 +795,25 @@ class Lex_trim: public Lex_trim_st ...@@ -790,6 +795,25 @@ class Lex_trim: public Lex_trim_st
}; };
class Lex_substring_spec_st
{
public:
Item *m_subject;
Item *m_from;
Item *m_for;
static Lex_substring_spec_st init(Item *subject,
Item *from,
Item *xfor= NULL)
{
Lex_substring_spec_st res;
res.m_subject= subject;
res.m_from= from;
res.m_for= xfor;
return res;
}
};
class st_select_lex; class st_select_lex;
class Lex_select_lock class Lex_select_lock
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment