Commit f5855ba0 authored by Alexander Barkov's avatar Alexander Barkov

MDEV-17664 Add sql_mode specific tokens for ':' and '%'

parent 8e6f1033
...@@ -1423,6 +1423,13 @@ int Lex_input_stream::lex_one_token(YYSTYPE *yylval, THD *thd) ...@@ -1423,6 +1423,13 @@ int Lex_input_stream::lex_one_token(YYSTYPE *yylval, THD *thd)
} }
/* Fall through */ /* Fall through */
case MY_LEX_CHAR: // Unknown or single char token case MY_LEX_CHAR: // Unknown or single char token
{
if (c == '%' && (m_thd->variables.sql_mode & MODE_ORACLE))
{
next_state= MY_LEX_START;
return PERCENT_ORACLE_SYM;
}
}
case MY_LEX_SKIP: // This should not happen case MY_LEX_SKIP: // This should not happen
if (c != ')') if (c != ')')
next_state= MY_LEX_START; // Allow signed numbers next_state= MY_LEX_START; // Allow signed numbers
...@@ -1861,8 +1868,13 @@ int Lex_input_stream::lex_one_token(YYSTYPE *yylval, THD *thd) ...@@ -1861,8 +1868,13 @@ int Lex_input_stream::lex_one_token(YYSTYPE *yylval, THD *thd)
case MY_LEX_SET_VAR: // Check if ':=' case MY_LEX_SET_VAR: // Check if ':='
if (yyPeek() != '=') if (yyPeek() != '=')
{ {
state= MY_LEX_CHAR; // Return ':' next_state= MY_LEX_START;
break; if (m_thd->variables.sql_mode & MODE_ORACLE)
{
yylval->kwd.set_keyword(m_tok_start, 1);
return COLON_ORACLE_SYM;
}
return (int) ':';
} }
yySkip(); yySkip();
return (SET_VAR); return (SET_VAR);
...@@ -6655,6 +6667,30 @@ Item *LEX::make_item_colon_ident_ident(THD *thd, ...@@ -6655,6 +6667,30 @@ Item *LEX::make_item_colon_ident_ident(THD *thd,
} }
Item *LEX::make_item_plsql_cursor_attr(THD *thd, const LEX_CSTRING *name,
plsql_cursor_attr_t attr)
{
uint offset;
if (unlikely(!spcont || !spcont->find_cursor(name, &offset, false)))
{
my_error(ER_SP_CURSOR_MISMATCH, MYF(0), name->str);
return NULL;
}
switch (attr) {
case PLSQL_CURSOR_ATTR_ISOPEN:
return new (thd->mem_root) Item_func_cursor_isopen(thd, name, offset);
case PLSQL_CURSOR_ATTR_FOUND:
return new (thd->mem_root) Item_func_cursor_found(thd, name, offset);
case PLSQL_CURSOR_ATTR_NOTFOUND:
return new (thd->mem_root) Item_func_cursor_notfound(thd, name, offset);
case PLSQL_CURSOR_ATTR_ROWCOUNT:
return new (thd->mem_root) Item_func_cursor_rowcount(thd, name, offset);
}
DBUG_ASSERT(0);
return NULL;
}
Item *LEX::make_item_sysvar(THD *thd, Item *LEX::make_item_sysvar(THD *thd,
enum_var_type type, enum_var_type type,
const LEX_CSTRING *name, const LEX_CSTRING *name,
......
...@@ -182,6 +182,16 @@ enum enum_view_suid ...@@ -182,6 +182,16 @@ enum enum_view_suid
VIEW_SUID_DEFAULT= 2 VIEW_SUID_DEFAULT= 2
}; };
enum plsql_cursor_attr_t
{
PLSQL_CURSOR_ATTR_ISOPEN,
PLSQL_CURSOR_ATTR_FOUND,
PLSQL_CURSOR_ATTR_NOTFOUND,
PLSQL_CURSOR_ATTR_ROWCOUNT
};
/* These may not be declared yet */ /* These may not be declared yet */
class Table_ident; class Table_ident;
class sql_exchange; class sql_exchange;
...@@ -3642,6 +3652,10 @@ struct LEX: public Query_tables_list ...@@ -3642,6 +3652,10 @@ struct LEX: public Query_tables_list
Item *make_item_colon_ident_ident(THD *thd, Item *make_item_colon_ident_ident(THD *thd,
const Lex_ident_cli_st *a, const Lex_ident_cli_st *a,
const Lex_ident_cli_st *b); const Lex_ident_cli_st *b);
// PLSQL: cursor%ISOPEN etc
Item *make_item_plsql_cursor_attr(THD *thd, const LEX_CSTRING *name,
plsql_cursor_attr_t attr);
// For "SELECT @@var", "SELECT @@var.field" // For "SELECT @@var", "SELECT @@var.field"
Item *make_item_sysvar(THD *thd, Item *make_item_sysvar(THD *thd,
enum_var_type type, enum_var_type type,
......
...@@ -790,11 +790,6 @@ Virtual_column_info *add_virtual_expression(THD *thd, Item *expr) ...@@ -790,11 +790,6 @@ 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;
struct
{
LEX_CSTRING name;
uint offset;
} sp_cursor_name_and_offset;
vers_history_point_t vers_history_point; vers_history_point_t vers_history_point;
/* pointers */ /* pointers */
...@@ -878,6 +873,7 @@ Virtual_column_info *add_virtual_expression(THD *thd, Item *expr) ...@@ -878,6 +873,7 @@ Virtual_column_info *add_virtual_expression(THD *thd, Item *expr)
DDL_options_st object_ddl_options; DDL_options_st object_ddl_options;
enum vers_sys_type_t vers_range_unit; enum vers_sys_type_t vers_range_unit;
enum Column_definition::enum_column_versioning vers_column_versioning; enum Column_definition::enum_column_versioning vers_column_versioning;
enum plsql_cursor_attr_t plsql_cursor_attr;
} }
%{ %{
...@@ -1104,6 +1100,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); ...@@ -1104,6 +1100,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize);
%token PARAM_MARKER %token PARAM_MARKER
%token PARSE_VCOL_EXPR_SYM %token PARSE_VCOL_EXPR_SYM
%token PARTITION_SYM /* SQL-2003-R */ %token PARTITION_SYM /* SQL-2003-R */
%token PERCENT_ORACLE_SYM /* INTERNAL */
%token PERCENT_RANK_SYM %token PERCENT_RANK_SYM
%token PERCENTILE_CONT_SYM %token PERCENTILE_CONT_SYM
%token PERCENTILE_DISC_SYM %token PERCENTILE_DISC_SYM
...@@ -1278,6 +1275,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); ...@@ -1278,6 +1275,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize);
%token <kwd> COALESCE /* SQL-2003-N */ %token <kwd> COALESCE /* SQL-2003-N */
%token <kwd> CODE_SYM %token <kwd> CODE_SYM
%token <kwd> COLLATION_SYM /* SQL-2003-N */ %token <kwd> COLLATION_SYM /* SQL-2003-N */
%token <kwd> COLON_ORACLE_SYM /* INTERNAL */
%token <kwd> COLUMNS %token <kwd> COLUMNS
%token <kwd> COLUMN_ADD_SYM %token <kwd> COLUMN_ADD_SYM
%token <kwd> COLUMN_CHECK_SYM %token <kwd> COLUMN_CHECK_SYM
...@@ -1933,7 +1931,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); ...@@ -1933,7 +1931,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize);
geometry_function signed_literal expr_or_literal geometry_function signed_literal expr_or_literal
opt_escape opt_escape
sp_opt_default sp_opt_default
simple_ident_nospvar simple_ident_q simple_ident_q2 simple_ident_nospvar
field_or_var limit_option field_or_var limit_option
part_func_expr part_func_expr
window_func_expr window_func_expr
...@@ -1942,6 +1940,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); ...@@ -1942,6 +1940,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize);
inverse_distribution_function inverse_distribution_function
percentile_function percentile_function
inverse_distribution_function_def inverse_distribution_function_def
explicit_cursor_attr
function_call_keyword function_call_keyword
function_call_keyword_timestamp function_call_keyword_timestamp
function_call_nonkeyword function_call_nonkeyword
...@@ -2144,6 +2143,8 @@ END_OF_INPUT ...@@ -2144,6 +2143,8 @@ END_OF_INPUT
%type <num> view_algorithm view_check_option %type <num> view_algorithm view_check_option
%type <view_suid> view_suid opt_view_suid %type <view_suid> view_suid opt_view_suid
%type <plsql_cursor_attr> plsql_cursor_attr
%type <num> sp_decl_idents sp_decl_idents_init_vars %type <num> sp_decl_idents sp_decl_idents_init_vars
%type <num> sp_handler_type sp_hcond_list %type <num> sp_handler_type sp_hcond_list
%type <spcondvalue> sp_cond sp_hcond sqlstate signal_value opt_signal_value %type <spcondvalue> sp_cond sp_hcond sqlstate signal_value opt_signal_value
...@@ -10095,6 +10096,23 @@ dyncall_create_list: ...@@ -10095,6 +10096,23 @@ dyncall_create_list:
} }
; ;
plsql_cursor_attr:
ISOPEN_SYM { $$= PLSQL_CURSOR_ATTR_ISOPEN; }
| FOUND_SYM { $$= PLSQL_CURSOR_ATTR_FOUND; }
| NOTFOUND_SYM { $$= PLSQL_CURSOR_ATTR_NOTFOUND; }
| ROWCOUNT_SYM { $$= PLSQL_CURSOR_ATTR_ROWCOUNT; }
;
explicit_cursor_attr:
ident PERCENT_ORACLE_SYM plsql_cursor_attr
{
if (unlikely(!($$= Lex->make_item_plsql_cursor_attr(thd, &$1, $3))))
MYSQL_YYABORT;
}
;
trim_operands: trim_operands:
expr { $$.set(TRIM_BOTH, $1); } expr { $$.set(TRIM_BOTH, $1); }
| LEADING expr FROM expr { $$.set(TRIM_LEADING, $2, $4); } | LEADING expr FROM expr { $$.set(TRIM_LEADING, $2, $4); }
...@@ -10258,6 +10276,7 @@ column_default_non_parenthesized_expr: ...@@ -10258,6 +10276,7 @@ column_default_non_parenthesized_expr:
primary_expr: primary_expr:
column_default_non_parenthesized_expr column_default_non_parenthesized_expr
| explicit_cursor_attr
| '(' parenthesized_expr ')' { $$= $2; } | '(' parenthesized_expr ')' { $$= $2; }
; ;
...@@ -10444,6 +10463,14 @@ function_call_keyword: ...@@ -10444,6 +10463,14 @@ function_call_keyword:
if (unlikely($$ == NULL)) if (unlikely($$ == NULL))
MYSQL_YYABORT; MYSQL_YYABORT;
} }
| SQL_SYM PERCENT_ORACLE_SYM ROWCOUNT_SYM
{
$$= new (thd->mem_root) Item_func_oracle_sql_rowcount(thd);
if (unlikely($$ == NULL))
MYSQL_YYABORT;
Lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_SYSTEM_FUNCTION);
Lex->safe_to_cache_query= 0;
}
| TIME_SYM '(' expr ')' | TIME_SYM '(' expr ')'
{ {
$$= new (thd->mem_root) Item_time_typecast(thd, $3, $$= new (thd->mem_root) Item_time_typecast(thd, $3,
...@@ -14956,6 +14983,19 @@ param_marker: ...@@ -14956,6 +14983,19 @@ param_marker:
YYLIP->get_tok_start() + 1)))) YYLIP->get_tok_start() + 1))))
MYSQL_YYABORT; MYSQL_YYABORT;
} }
| COLON_ORACLE_SYM ident_cli
{
if (unlikely(!($$= Lex->add_placeholder(thd, &null_clex_str,
$1.pos(), $2.end()))))
MYSQL_YYABORT;
}
| COLON_ORACLE_SYM NUM
{
if (unlikely(!($$= Lex->add_placeholder(thd, &null_clex_str,
$1.pos(),
YYLIP->get_ptr()))))
MYSQL_YYABORT;
}
; ;
signed_literal: signed_literal:
...@@ -15265,6 +15305,11 @@ simple_ident: ...@@ -15265,6 +15305,11 @@ simple_ident:
if (unlikely(!($$= Lex->create_item_ident(thd, &$1, &$3, &$5)))) if (unlikely(!($$= Lex->create_item_ident(thd, &$1, &$3, &$5))))
MYSQL_YYABORT; MYSQL_YYABORT;
} }
| COLON_ORACLE_SYM ident_cli '.' ident_cli
{
if (unlikely(!($$= Lex->make_item_colon_ident_ident(thd, &$2, &$4))))
MYSQL_YYABORT;
}
; ;
simple_ident_nospvar: simple_ident_nospvar:
...@@ -15273,20 +15318,17 @@ simple_ident_nospvar: ...@@ -15273,20 +15318,17 @@ simple_ident_nospvar:
if (unlikely(!($$= Lex->create_item_ident_nosp(thd, &$1)))) if (unlikely(!($$= Lex->create_item_ident_nosp(thd, &$1))))
MYSQL_YYABORT; MYSQL_YYABORT;
} }
| simple_ident_q { $$= $1; } | ident '.' ident
;
simple_ident_q:
ident '.' ident
{ {
if (unlikely(!($$= Lex->create_item_ident_nospvar(thd, &$1, &$3)))) if (unlikely(!($$= Lex->create_item_ident_nospvar(thd, &$1, &$3))))
MYSQL_YYABORT; MYSQL_YYABORT;
} }
| simple_ident_q2 | COLON_ORACLE_SYM ident_cli '.' ident_cli
; {
if (unlikely(!($$= Lex->make_item_colon_ident_ident(thd, &$2, &$4))))
simple_ident_q2: MYSQL_YYABORT;
'.' ident '.' ident }
| '.' ident '.' ident
{ {
Lex_ident_sys none; Lex_ident_sys none;
if (unlikely(!($$= Lex->create_item_ident(thd, &none, &$2, &$4)))) if (unlikely(!($$= Lex->create_item_ident(thd, &none, &$2, &$4))))
......
This diff is collapsed.
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