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)
}
/* Fall through */
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
if (c != ')')
next_state= MY_LEX_START; // Allow signed numbers
......@@ -1861,8 +1868,13 @@ int Lex_input_stream::lex_one_token(YYSTYPE *yylval, THD *thd)
case MY_LEX_SET_VAR: // Check if ':='
if (yyPeek() != '=')
{
state= MY_LEX_CHAR; // Return ':'
break;
next_state= MY_LEX_START;
if (m_thd->variables.sql_mode & MODE_ORACLE)
{
yylval->kwd.set_keyword(m_tok_start, 1);
return COLON_ORACLE_SYM;
}
return (int) ':';
}
yySkip();
return (SET_VAR);
......@@ -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,
enum_var_type type,
const LEX_CSTRING *name,
......
......@@ -182,6 +182,16 @@ enum enum_view_suid
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 */
class Table_ident;
class sql_exchange;
......@@ -3642,6 +3652,10 @@ struct LEX: public Query_tables_list
Item *make_item_colon_ident_ident(THD *thd,
const Lex_ident_cli_st *a,
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"
Item *make_item_sysvar(THD *thd,
enum_var_type type,
......
......@@ -790,11 +790,6 @@ 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;
struct
{
LEX_CSTRING name;
uint offset;
} sp_cursor_name_and_offset;
vers_history_point_t vers_history_point;
/* pointers */
......@@ -878,6 +873,7 @@ Virtual_column_info *add_virtual_expression(THD *thd, Item *expr)
DDL_options_st object_ddl_options;
enum vers_sys_type_t vers_range_unit;
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);
%token PARAM_MARKER
%token PARSE_VCOL_EXPR_SYM
%token PARTITION_SYM /* SQL-2003-R */
%token PERCENT_ORACLE_SYM /* INTERNAL */
%token PERCENT_RANK_SYM
%token PERCENTILE_CONT_SYM
%token PERCENTILE_DISC_SYM
......@@ -1278,6 +1275,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize);
%token <kwd> COALESCE /* SQL-2003-N */
%token <kwd> CODE_SYM
%token <kwd> COLLATION_SYM /* SQL-2003-N */
%token <kwd> COLON_ORACLE_SYM /* INTERNAL */
%token <kwd> COLUMNS
%token <kwd> COLUMN_ADD_SYM
%token <kwd> COLUMN_CHECK_SYM
......@@ -1933,7 +1931,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize);
geometry_function signed_literal expr_or_literal
opt_escape
sp_opt_default
simple_ident_nospvar simple_ident_q simple_ident_q2
simple_ident_nospvar
field_or_var limit_option
part_func_expr
window_func_expr
......@@ -1942,6 +1940,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize);
inverse_distribution_function
percentile_function
inverse_distribution_function_def
explicit_cursor_attr
function_call_keyword
function_call_keyword_timestamp
function_call_nonkeyword
......@@ -2144,6 +2143,8 @@ END_OF_INPUT
%type <num> view_algorithm view_check_option
%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_handler_type sp_hcond_list
%type <spcondvalue> sp_cond sp_hcond sqlstate signal_value opt_signal_value
......@@ -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:
expr { $$.set(TRIM_BOTH, $1); }
| LEADING expr FROM expr { $$.set(TRIM_LEADING, $2, $4); }
......@@ -10258,6 +10276,7 @@ column_default_non_parenthesized_expr:
primary_expr:
column_default_non_parenthesized_expr
| explicit_cursor_attr
| '(' parenthesized_expr ')' { $$= $2; }
;
......@@ -10444,6 +10463,14 @@ function_call_keyword:
if (unlikely($$ == NULL))
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 ')'
{
$$= new (thd->mem_root) Item_time_typecast(thd, $3,
......@@ -14956,6 +14983,19 @@ param_marker:
YYLIP->get_tok_start() + 1))))
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:
......@@ -15265,6 +15305,11 @@ simple_ident:
if (unlikely(!($$= Lex->create_item_ident(thd, &$1, &$3, &$5))))
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:
......@@ -15273,20 +15318,17 @@ simple_ident_nospvar:
if (unlikely(!($$= Lex->create_item_ident_nosp(thd, &$1))))
MYSQL_YYABORT;
}
| simple_ident_q { $$= $1; }
;
simple_ident_q:
ident '.' ident
| ident '.' ident
{
if (unlikely(!($$= Lex->create_item_ident_nospvar(thd, &$1, &$3))))
MYSQL_YYABORT;
}
| simple_ident_q2
;
simple_ident_q2:
'.' ident '.' ident
| COLON_ORACLE_SYM ident_cli '.' ident_cli
{
if (unlikely(!($$= Lex->make_item_colon_ident_ident(thd, &$2, &$4))))
MYSQL_YYABORT;
}
| '.' ident '.' ident
{
Lex_ident_sys none;
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