summaryrefslogtreecommitdiff
path: root/sql/sql_yacc.yy
diff options
context:
space:
mode:
authorSergei Golubchik <sergii@pisem.net>2013-07-17 21:24:29 +0200
committerSergei Golubchik <sergii@pisem.net>2013-07-17 21:24:29 +0200
commit97e640b9ae83e07b444fceede6b0524256c7a3cc (patch)
tree8f48fbfaf88ea7895ce59fd3ac2fbe6184334387 /sql/sql_yacc.yy
parent2f6a2494a5eb2cf3ab06fbedd2584eca85d90230 (diff)
parentc7973615e723b13c6457b494b72be2fac35bfd18 (diff)
downloadmariadb-git-97e640b9ae83e07b444fceede6b0524256c7a3cc.tar.gz
5.5 merge
Diffstat (limited to 'sql/sql_yacc.yy')
-rw-r--r--sql/sql_yacc.yy92
1 files changed, 74 insertions, 18 deletions
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index 1a12a11eae7..f3abc872587 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -781,6 +781,7 @@ static bool add_create_index (LEX *lex, Key::Keytype type,
Diag_condition_item_name diag_condition_item_name;
DYNCALL_CREATE_DEF *dyncol_def;
List<DYNCALL_CREATE_DEF> *dyncol_def_list;
+ bool is_not_empty;
}
%{
@@ -1677,7 +1678,7 @@ END_OF_INPUT
%type <lex> sp_cursor_stmt
%type <spname> sp_name
%type <index_hint> index_hint_type
-%type <num> index_hint_clause
+%type <num> index_hint_clause normal_join inner_join
%type <filetype> data_or_xml
%type <NONE> signal_stmt resignal_stmt
@@ -1688,7 +1689,7 @@ END_OF_INPUT
',' '!' '{' '}' '&' '|' AND_SYM OR_SYM OR_OR_SYM BETWEEN_SYM CASE_SYM
THEN_SYM WHEN_SYM DIV_SYM MOD_SYM OR2_SYM AND_AND_SYM DELETE_SYM
-%type <num> normal_join inner_join
+%type <is_not_empty> opt_union_order_or_limit
%%
@@ -9563,6 +9564,7 @@ sum_expr:
if ($$ == NULL)
MYSQL_YYABORT;
$5->empty();
+ sel->gorder_list.empty();
}
;
@@ -9632,18 +9634,27 @@ opt_gconcat_separator:
opt_gorder_clause:
/* empty */
+ | ORDER_SYM BY
{
- Select->gorder_list = NULL;
- }
- | order_clause
- {
- SELECT_LEX *select= Select;
- select->gorder_list= new (YYTHD->mem_root)
- SQL_I_List<ORDER>(select->order_list);
- if (select->gorder_list == NULL)
+ LEX *lex= Lex;
+ SELECT_LEX *sel= lex->current_select;
+ if (sel->linkage != GLOBAL_OPTIONS_TYPE &&
+ sel->olap != UNSPECIFIED_OLAP_TYPE &&
+ (sel->linkage != UNION_TYPE || sel->braces))
+ {
+ my_error(ER_WRONG_USAGE, MYF(0),
+ "CUBE/ROLLUP", "ORDER BY");
MYSQL_YYABORT;
- select->order_list.empty();
+ }
}
+ gorder_list;
+ ;
+
+gorder_list:
+ gorder_list ',' order_ident order_dir
+ { if (add_gorder_to_list(YYTHD, $3,(bool) $4)) MYSQL_YYABORT; }
+ | order_ident order_dir
+ { if (add_gorder_to_list(YYTHD, $1,(bool) $2)) MYSQL_YYABORT; }
;
in_sum_expr:
@@ -9776,7 +9787,10 @@ table_ref:
{
LEX *lex= Lex;
if (!($$= lex->current_select->nest_last_join(lex->thd)))
+ {
+ my_parse_error(ER(ER_SYNTAX_ERROR));
MYSQL_YYABORT;
+ }
}
;
@@ -10041,12 +10055,16 @@ table_factor:
lex->pop_context();
lex->nest_level--;
}
- else if (($3->select_lex &&
+ /*else if (($3->select_lex &&
$3->select_lex->master_unit()->is_union() &&
($3->select_lex->master_unit()->first_select() ==
- $3->select_lex || !$3->lifted)) || $5)
+ $3->select_lex || !$3->lifted)) || $5)*/
+ else if ($5 != NULL)
{
- /* simple nested joins cannot have aliases or unions */
+ /*
+ Tables with or without joins within parentheses cannot
+ have aliases, and we ruled out derived tables above.
+ */
my_parse_error(ER(ER_SYNTAX_ERROR));
MYSQL_YYABORT;
}
@@ -10059,8 +10077,34 @@ table_factor:
}
;
+/*
+ This rule accepts just about anything. The reason is that we have
+ empty-producing rules in the beginning of rules, in this case
+ subselect_start. This forces bison to take a decision which rules to
+ reduce by long before it has seen any tokens. This approach ties us
+ to a very limited class of parseable languages, and unfortunately
+ SQL is not one of them. The chosen 'solution' was this rule, which
+ produces just about anything, even complete bogus statements, for
+ instance ( table UNION SELECT 1 ).
+ Fortunately, we know that the semantic value returned by
+ select_derived is NULL if it contained a derived table, and a pointer to
+ the base table's TABLE_LIST if it was a base table. So in the rule
+ regarding union's, we throw a parse error manually and pretend it
+ was bison that did it.
+
+ Also worth noting is that this rule concerns query expressions in
+ the from clause only. Top level select statements and other types of
+ subqueries have their own union rules.
+*/
select_derived_union:
select_derived opt_union_order_or_limit
+ {
+ if ($1 && $2)
+ {
+ my_parse_error(ER(ER_SYNTAX_ERROR));
+ MYSQL_YYABORT;
+ }
+ }
| select_derived_union
UNION_SYM
union_option
@@ -10077,6 +10121,13 @@ select_derived_union:
Lex->pop_context();
}
opt_union_order_or_limit
+ {
+ if ($1 != NULL)
+ {
+ my_parse_error(ER(ER_SYNTAX_ERROR));
+ MYSQL_YYABORT;
+ }
+ }
;
/* The equivalent of select_init2 for nested queries. */
@@ -11550,7 +11601,9 @@ show:
bzero((char*) &lex->create_info,sizeof(lex->create_info));
}
show_param
- {}
+ {
+ Select->parsing_place= NO_MATTER;
+ }
;
show_param:
@@ -11963,7 +12016,10 @@ describe:
if (prepare_schema_table(YYTHD, lex, $2, SCH_COLUMNS))
MYSQL_YYABORT;
}
- opt_describe_column {}
+ opt_describe_column
+ {
+ Select->parsing_place= NO_MATTER;
+ }
| describe_command opt_extended_describe
{ Lex->describe|= DESCRIBE_NORMAL; }
select
@@ -14746,8 +14802,8 @@ union_opt:
;
opt_union_order_or_limit:
- /* Empty */
- | union_order_or_limit
+ /* Empty */{ $$= false; }
+ | union_order_or_limit { $$= true; }
;
union_order_or_limit: