summaryrefslogtreecommitdiff
path: root/sql/sql_yacc.yy
diff options
context:
space:
mode:
authorNeeraj Bisht <neeraj.x.bisht@oracle.com>2013-03-18 13:48:53 +0530
committerNeeraj Bisht <neeraj.x.bisht@oracle.com>2013-03-18 13:48:53 +0530
commit13fdee190f780368771f4eaf47475a4f52d9099e (patch)
tree1b44c15f83f512f2d6a334972597b30e0881ba2b /sql/sql_yacc.yy
parent6d6af5477eddcd994d6b9bd295563a02359b735f (diff)
downloadmariadb-git-13fdee190f780368771f4eaf47475a4f52d9099e.tar.gz
Bug #16076289 : BACKPORT FIX FOR BUG #14786792 TO 5.5
Backport the changes for bug#14786792 which is regression of fix for bug#11761854.So backported both changes.
Diffstat (limited to 'sql/sql_yacc.yy')
-rw-r--r--sql/sql_yacc.yy49
1 files changed, 44 insertions, 5 deletions
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index cf0346d6c0e..3a76dbb310c 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -773,6 +773,7 @@ static bool add_create_index (LEX *lex, Key::Keytype type,
enum Foreign_key::fk_option m_fk_option;
enum enum_yes_no_unknown m_yes_no_unk;
Diag_condition_item_name diag_condition_item_name;
+ bool is_not_empty;
}
%{
@@ -1629,6 +1630,9 @@ 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 <is_not_empty> opt_union_order_or_limit
+
%%
/*
@@ -9448,10 +9452,12 @@ table_factor:
lex->pop_context();
lex->nest_level--;
}
- else if (($3->select_lex &&
- $3->select_lex->master_unit()->is_union()) || $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;
}
@@ -9464,8 +9470,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
@@ -9482,6 +9514,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. */
@@ -13953,8 +13992,8 @@ union_opt:
;
opt_union_order_or_limit:
- /* Empty */
- | union_order_or_limit
+ /* Empty */{ $$= false; }
+ | union_order_or_limit { $$= true; }
;
union_order_or_limit: