diff options
author | Alexander Barkov <bar@mariadb.com> | 2023-04-29 07:39:38 +0400 |
---|---|---|
committer | Alexander Barkov <bar@mariadb.com> | 2023-04-29 08:06:46 +0400 |
commit | ddcc9d2281de9fa68525a6808e9181bbd6bf98e0 (patch) | |
tree | e8c20afd5fff69240883728b63268ed682ebd8f8 | |
parent | 2e74f9d281b0251040aef2364f061c5f23e4ab21 (diff) | |
download | mariadb-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.cc | 27 | ||||
-rw-r--r-- | sql/sql_lex.h | 3 | ||||
-rw-r--r-- | sql/sql_schema.cc | 61 | ||||
-rw-r--r-- | sql/sql_schema.h | 11 | ||||
-rw-r--r-- | sql/sql_yacc.yy | 59 | ||||
-rw-r--r-- | sql/sql_yacc_ora.yy | 59 | ||||
-rw-r--r-- | sql/structs.h | 24 |
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 |