diff options
author | Neeraj Bisht <neeraj.x.bisht@oracle.com> | 2013-03-18 13:48:53 +0530 |
---|---|---|
committer | Neeraj Bisht <neeraj.x.bisht@oracle.com> | 2013-03-18 13:48:53 +0530 |
commit | 13fdee190f780368771f4eaf47475a4f52d9099e (patch) | |
tree | 1b44c15f83f512f2d6a334972597b30e0881ba2b /sql/sql_yacc.yy | |
parent | 6d6af5477eddcd994d6b9bd295563a02359b735f (diff) | |
download | mariadb-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.yy | 49 |
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: |