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,
}
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,
const LEX_CSTRING field_name)
{
......
......@@ -4033,9 +4033,6 @@ struct LEX: public Query_tables_list
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,
Lex_ident_cli_st *name, List<Item> *args);
Item *make_item_func_call_generic(THD *thd,
......
......@@ -32,6 +32,14 @@ class Schema_oracle: public Schema
return thd->type_handler_for_datetime();
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)
return &maxdb_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
{
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:
schema_mariadb, schema_oracle, schema_maxdb.
......
......@@ -718,6 +718,7 @@ Virtual_column_info *add_virtual_expression(THD *thd, Item *expr)
Lex_for_loop_st for_loop;
Lex_for_loop_bounds_st for_loop_bounds;
Lex_trim_st trim;
Lex_substring_spec_st substring_spec;
vers_history_point_t vers_history_point;
struct
{
......@@ -1077,7 +1078,6 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize);
%token RELEASE_SYM /* SQL-2003-R */
%token RENAME
%token REPEAT_SYM /* MYSQL-FUNC */
%token REPLACE /* MYSQL-FUNC */
%token REQUIRE_SYM
%token RESIGNAL_SYM /* SQL-2003-R */
%token RESTRICT
......@@ -1117,7 +1117,6 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize);
%token STDDEV_SAMP_SYM /* SQL-2003-N */
%token STD_SYM
%token STRAIGHT_JOIN
%token SUBSTRING /* SQL-2003-N */
%token SUM_SYM /* SQL-2003-N */
%token SYSDATE
%token TABLE_REF_PRIORITY
......@@ -1131,7 +1130,6 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize);
%token TO_SYM /* SQL-2003-R */
%token TRAILING /* SQL-2003-R */
%token TRIGGER_SYM /* SQL-2003-R */
%token TRIM /* SQL-2003-N */
%token TRUE_SYM /* SQL-2003-R */
%token ULONGLONG_NUM
%token UNDERSCORE_CHARSET
......@@ -1182,6 +1180,14 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize);
%token <kwd> RAISE_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
*/
......@@ -2172,6 +2178,7 @@ END_OF_INPUT
%type <for_loop> sp_for_loop_index_and_bounds
%type <for_loop_bounds> sp_for_loop_bounds
%type <trim> trim_operands
%type <substring_spec> substring_operands
%type <num> opt_sp_for_loop_direction
%type <spvar_mode> sp_opt_inout
%type <index_hint> index_hint_type
......@@ -10916,7 +10923,8 @@ function_call_keyword:
}
| 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;
}
| USER_SYM '(' ')'
......@@ -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.
Dedicated grammar rules are needed because of the syntax,
......@@ -11049,24 +11077,10 @@ function_call_nonkeyword:
if (unlikely($$ == NULL))
MYSQL_YYABORT;
}
| SUBSTRING '(' expr ',' expr ',' expr ')'
{
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 ')'
| SUBSTRING '(' substring_operands ')'
{
if (unlikely(!($$= Lex->make_item_func_substr(thd, $3, $5))))
if (unlikely(!($$= Schema::find_implied(thd)->
make_item_func_substr(thd, $3))))
MYSQL_YYABORT;
}
| SYSDATE opt_time_precision
......@@ -11282,7 +11296,8 @@ function_call_conflict:
}
| 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;
}
| REVERSE_SYM '(' expr ')'
......
......@@ -196,6 +196,7 @@ void ORAerror(THD *thd, const char *s)
Lex_for_loop_st for_loop;
Lex_for_loop_bounds_st for_loop_bounds;
Lex_trim_st trim;
Lex_substring_spec_st substring_spec;
vers_history_point_t vers_history_point;
struct
{
......@@ -553,7 +554,6 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize);
%token RELEASE_SYM /* SQL-2003-R */
%token RENAME
%token REPEAT_SYM /* MYSQL-FUNC */
%token REPLACE /* MYSQL-FUNC */
%token REQUIRE_SYM
%token RESIGNAL_SYM /* SQL-2003-R */
%token RESTRICT
......@@ -593,7 +593,6 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize);
%token STDDEV_SAMP_SYM /* SQL-2003-N */
%token STD_SYM
%token STRAIGHT_JOIN
%token SUBSTRING /* SQL-2003-N */
%token SUM_SYM /* SQL-2003-N */
%token SYSDATE
%token TABLE_REF_PRIORITY
......@@ -607,7 +606,6 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize);
%token TO_SYM /* SQL-2003-R */
%token TRAILING /* SQL-2003-R */
%token TRIGGER_SYM /* SQL-2003-R */
%token TRIM /* SQL-2003-N */
%token TRUE_SYM /* SQL-2003-R */
%token ULONGLONG_NUM
%token UNDERSCORE_CHARSET
......@@ -658,6 +656,14 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize);
%token <kwd> RAISE_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
*/
......@@ -1673,6 +1679,7 @@ END_OF_INPUT
%type <for_loop> sp_for_loop_index_and_bounds
%type <for_loop_bounds> sp_for_loop_bounds
%type <trim> trim_operands
%type <substring_spec> substring_operands
%type <num> opt_sp_for_loop_direction
%type <spvar_mode> sp_opt_inout
%type <index_hint> index_hint_type
......@@ -11031,7 +11038,8 @@ function_call_keyword:
}
| 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;
}
| USER_SYM '(' ')'
......@@ -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.
Dedicated grammar rules are needed because of the syntax,
......@@ -11164,24 +11192,10 @@ function_call_nonkeyword:
if (unlikely($$ == NULL))
MYSQL_YYABORT;
}
| SUBSTRING '(' expr ',' expr ',' expr ')'
{
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 ')'
| SUBSTRING '(' substring_operands ')'
{
if (unlikely(!($$= Lex->make_item_func_substr(thd, $3, $5))))
if (unlikely(!($$= Schema::find_implied(thd)->
make_item_func_substr(thd, $3))))
MYSQL_YYABORT;
}
| SYSDATE opt_time_precision
......@@ -11397,7 +11411,8 @@ function_call_conflict:
}
| 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;
}
| REVERSE_SYM '(' expr ')'
......
......@@ -779,6 +779,11 @@ struct Lex_trim_st
}
Item *make_item_func_trim_std(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;
};
......@@ -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 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