summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Barkov <bar@mariadb.com>2023-04-29 07:39:38 +0400
committerAlexander Barkov <bar@mariadb.com>2023-04-29 08:06:46 +0400
commitddcc9d2281de9fa68525a6808e9181bbd6bf98e0 (patch)
treee8c20afd5fff69240883728b63268ed682ebd8f8
parent2e74f9d281b0251040aef2364f061c5f23e4ab21 (diff)
downloadmariadb-git-ddcc9d2281de9fa68525a6808e9181bbd6bf98e0.tar.gz
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.
-rw-r--r--sql/sql_lex.cc27
-rw-r--r--sql/sql_lex.h3
-rw-r--r--sql/sql_schema.cc61
-rw-r--r--sql/sql_schema.h11
-rw-r--r--sql/sql_yacc.yy59
-rw-r--r--sql/sql_yacc_ora.yy59
-rw-r--r--sql/structs.h24
7 files changed, 170 insertions, 74 deletions
diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc
index b51a4acc5f6..f77b98f04f1 100644
--- a/sql/sql_lex.cc
+++ b/sql/sql_lex.cc
@@ -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)
{
diff --git a/sql/sql_lex.h b/sql/sql_lex.h
index 052151f5352..a2c5fec03e5 100644
--- a/sql/sql_lex.h
+++ b/sql/sql_lex.h
@@ -4033,9 +4033,6 @@ public:
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,
diff --git a/sql/sql_schema.cc b/sql/sql_schema.cc
index 0bf4a63c2f8..f08204d272d 100644
--- a/sql/sql_schema.cc
+++ b/sql/sql_schema.cc
@@ -32,6 +32,14 @@ public:
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);
+}
diff --git a/sql/sql_schema.h b/sql/sql_schema.h
index 27ee0c10dce..1174bc7a83f 100644
--- a/sql/sql_schema.h
+++ b/sql/sql_schema.h
@@ -33,6 +33,17 @@ public:
{
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.
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index 20fc299624f..cf3927ac30c 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -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
@@ -1183,6 +1181,14 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize);
%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 ')'
diff --git a/sql/sql_yacc_ora.yy b/sql/sql_yacc_ora.yy
index afc1b007b11..87f71d8332b 100644
--- a/sql/sql_yacc_ora.yy
+++ b/sql/sql_yacc_ora.yy
@@ -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
@@ -659,6 +657,14 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize);
%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 ')'
diff --git a/sql/structs.h b/sql/structs.h
index 31601fee154..2e6683ec706 100644
--- a/sql/structs.h
+++ b/sql/structs.h
@@ -779,6 +779,11 @@ public:
}
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 @@ public:
};
+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