summaryrefslogtreecommitdiff
path: root/sql/sql_yacc.yy
diff options
context:
space:
mode:
Diffstat (limited to 'sql/sql_yacc.yy')
-rw-r--r--sql/sql_yacc.yy135
1 files changed, 93 insertions, 42 deletions
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index 88afab0bbe8..edca9cf3c5f 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -52,7 +52,7 @@ const LEX_STRING null_lex_str={0,0};
ER_WARN_DEPRECATED_SYNTAX, \
ER(ER_WARN_DEPRECATED_SYNTAX), (A), (B));
-#define TEST_ASSERT(A) \
+#define YYERROR_UNLESS(A) \
if (!(A)) \
{ \
yyerror(ER(ER_SYNTAX_ERROR)); \
@@ -721,7 +721,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
signed_literal now_or_signed_literal opt_escape
sp_opt_default
simple_ident_nospvar simple_ident_q
- field_or_var
+ field_or_var limit_option
%type <item_num>
NUM_literal
@@ -914,11 +914,16 @@ deallocate:
{
THD *thd=YYTHD;
LEX *lex= thd->lex;
- if (thd->command == COM_PREPARE)
+ if (thd->command == COM_STMT_PREPARE)
{
yyerror(ER(ER_SYNTAX_ERROR));
YYABORT;
}
+ if (lex->sphead)
+ {
+ my_error(ER_SP_BADSTATEMENT, MYF(0), "DEALLOCATE");
+ YYABORT;
+ }
lex->sql_command= SQLCOM_DEALLOCATE_PREPARE;
lex->prepared_stmt_name= $3;
};
@@ -934,11 +939,16 @@ prepare:
{
THD *thd=YYTHD;
LEX *lex= thd->lex;
- if (thd->command == COM_PREPARE)
+ if (thd->command == COM_STMT_PREPARE)
{
yyerror(ER(ER_SYNTAX_ERROR));
YYABORT;
}
+ if (lex->sphead)
+ {
+ my_error(ER_SP_BADSTATEMENT, MYF(0), "PREPARE");
+ YYABORT;
+ }
lex->sql_command= SQLCOM_PREPARE;
lex->prepared_stmt_name= $2;
};
@@ -964,11 +974,16 @@ execute:
{
THD *thd=YYTHD;
LEX *lex= thd->lex;
- if (thd->command == COM_PREPARE)
+ if (thd->command == COM_STMT_PREPARE)
{
yyerror(ER(ER_SYNTAX_ERROR));
YYABORT;
}
+ if (lex->sphead)
+ {
+ my_error(ER_SP_BADSTATEMENT, MYF(0), "EXECUTE");
+ YYABORT;
+ }
lex->sql_command= SQLCOM_EXECUTE;
lex->prepared_stmt_name= $2;
}
@@ -4014,7 +4029,7 @@ select_options:
/* empty*/
| select_option_list
{
- if (Select->options & SELECT_DISTINCT && Select->options2 & SELECT_ALL)
+ if (Select->options & SELECT_DISTINCT && Select->options & SELECT_ALL)
{
my_error(ER_WRONG_USAGE, MYF(0), "ALL", "DISTINCT");
YYABORT;
@@ -4054,7 +4069,7 @@ select_option:
{
Lex->select_lex.options|= OPTION_TO_QUERY_CACHE;
}
- | ALL { Select->options2|= SELECT_ALL; }
+ | ALL { Select->options|= SELECT_ALL; }
;
select_lock_type:
@@ -4092,7 +4107,10 @@ select_item:
if (add_item_to_list(YYTHD, $2))
YYABORT;
if ($4.str)
- $2->set_name($4.str,$4.length,system_charset_info);
+ {
+ $2->set_name($4.str, $4.length, system_charset_info);
+ $2->is_autogenerated_name= FALSE;
+ }
else if (!$2->name) {
char *str = $1;
if (str[-1] == '`')
@@ -4898,9 +4916,12 @@ udf_expr:
remember_name expr remember_end select_alias
{
if ($4.str)
- $2->set_name($4.str,$4.length,system_charset_info);
+ {
+ $2->set_name($4.str, $4.length, system_charset_info);
+ $2->is_autogenerated_name= FALSE;
+ }
else
- $2->set_name($1,(uint) ($3 - $1), YYTHD->charset());
+ $2->set_name($1, (uint) ($3 - $1), YYTHD->charset());
$$= $2;
}
;
@@ -5079,7 +5100,7 @@ table_ref:
;
join_table_list:
- derived_table_list { TEST_ASSERT($$=$1); }
+ derived_table_list { YYERROR_UNLESS($$=$1); }
;
/* Warning - may return NULL in case of incomplete SELECT */
@@ -5087,39 +5108,41 @@ derived_table_list:
table_ref { $$=$1; }
| derived_table_list ',' table_ref
{
- TEST_ASSERT($1 && ($$=$3));
+ YYERROR_UNLESS($1 && ($$=$3));
}
;
join_table:
- table_ref normal_join table_ref { TEST_ASSERT($1 && ($$=$3)); }
+ table_ref normal_join table_ref { YYERROR_UNLESS($1 && ($$=$3)); }
| table_ref STRAIGHT_JOIN table_factor
- { TEST_ASSERT($1 && ($$=$3)); $3->straight=1; }
+ { YYERROR_UNLESS($1 && ($$=$3)); $3->straight=1; }
| table_ref normal_join table_ref ON expr
- { TEST_ASSERT($1 && ($$=$3)); add_join_on($3,$5); }
+ { YYERROR_UNLESS($1 && ($$=$3)); add_join_on($3,$5); }
+ | table_ref STRAIGHT_JOIN table_factor ON expr
+ { YYERROR_UNLESS($1 && ($$=$3)); $3->straight=1; add_join_on($3,$5); }
| table_ref normal_join table_ref
USING
{
SELECT_LEX *sel= Select;
- TEST_ASSERT($1 && $3);
+ YYERROR_UNLESS($1 && $3);
sel->save_names_for_using_list($1, $3);
}
'(' using_list ')'
{ add_join_on($3,$7); $$=$3; }
| table_ref LEFT opt_outer JOIN_SYM table_ref ON expr
- { TEST_ASSERT($1 && $5); add_join_on($5,$7); $5->outer_join|=JOIN_TYPE_LEFT; $$=$5; }
+ { YYERROR_UNLESS($1 && $5); add_join_on($5,$7); $5->outer_join|=JOIN_TYPE_LEFT; $$=$5; }
| table_ref LEFT opt_outer JOIN_SYM table_factor
{
SELECT_LEX *sel= Select;
- TEST_ASSERT($1 && $5);
+ YYERROR_UNLESS($1 && $5);
sel->save_names_for_using_list($1, $5);
}
USING '(' using_list ')'
{ add_join_on($5,$9); $5->outer_join|=JOIN_TYPE_LEFT; $$=$5; }
| table_ref NATURAL LEFT opt_outer JOIN_SYM table_factor
{
- TEST_ASSERT($1 && $6);
+ YYERROR_UNLESS($1 && $6);
add_join_natural($1,$6);
$6->outer_join|=JOIN_TYPE_LEFT;
$$=$6;
@@ -5127,7 +5150,7 @@ join_table:
| table_ref RIGHT opt_outer JOIN_SYM table_ref ON expr
{
LEX *lex= Lex;
- TEST_ASSERT($1 && $5);
+ YYERROR_UNLESS($1 && $5);
if (!($$= lex->current_select->convert_right_join()))
YYABORT;
add_join_on($$, $7);
@@ -5135,7 +5158,7 @@ join_table:
| table_ref RIGHT opt_outer JOIN_SYM table_factor
{
SELECT_LEX *sel= Select;
- TEST_ASSERT($1 && $5);
+ YYERROR_UNLESS($1 && $5);
sel->save_names_for_using_list($1, $5);
}
USING '(' using_list ')'
@@ -5147,14 +5170,14 @@ join_table:
}
| table_ref NATURAL RIGHT opt_outer JOIN_SYM table_factor
{
- TEST_ASSERT($1 && $6);
+ YYERROR_UNLESS($1 && $6);
add_join_natural($6,$1);
LEX *lex= Lex;
if (!($$= lex->current_select->convert_right_join()))
YYABORT;
}
| table_ref NATURAL JOIN_SYM table_factor
- { TEST_ASSERT($1 && ($$=$4)); add_join_natural($1,$4); };
+ { YYERROR_UNLESS($1 && ($$=$4)); add_join_natural($1,$4); };
normal_join:
@@ -5183,7 +5206,7 @@ table_factor:
sel->add_joined_table($$);
}
| '{' ident table_ref LEFT OUTER JOIN_SYM table_ref ON expr '}'
- { TEST_ASSERT($3 && $7); add_join_on($7,$9); $7->outer_join|=JOIN_TYPE_LEFT; $$=$7; }
+ { YYERROR_UNLESS($3 && $7); add_join_on($7,$9); $7->outer_join|=JOIN_TYPE_LEFT; $$=$7; }
| select_derived_init get_select_lex select_derived2
{
LEX *lex= Lex;
@@ -5564,8 +5587,8 @@ opt_limit_clause_init:
{
LEX *lex= Lex;
SELECT_LEX *sel= lex->current_select;
- sel->offset_limit= 0L;
- sel->select_limit= HA_POS_ERROR;
+ sel->offset_limit= 0;
+ sel->select_limit= 0;
}
| limit_clause {}
;
@@ -5580,21 +5603,21 @@ limit_clause:
;
limit_options:
- ulong_num
+ limit_option
{
SELECT_LEX *sel= Select;
sel->select_limit= $1;
- sel->offset_limit= 0L;
+ sel->offset_limit= 0;
sel->explicit_limit= 1;
}
- | ulong_num ',' ulong_num
+ | limit_option ',' limit_option
{
SELECT_LEX *sel= Select;
sel->select_limit= $3;
sel->offset_limit= $1;
sel->explicit_limit= 1;
}
- | ulong_num OFFSET_SYM ulong_num
+ | limit_option OFFSET_SYM limit_option
{
SELECT_LEX *sel= Select;
sel->select_limit= $1;
@@ -5602,18 +5625,23 @@ limit_options:
sel->explicit_limit= 1;
}
;
-
+limit_option:
+ param_marker
+ | ULONGLONG_NUM { $$= new Item_uint($1.str, $1.length); }
+ | LONG_NUM { $$= new Item_uint($1.str, $1.length); }
+ | NUM { $$= new Item_uint($1.str, $1.length); }
+ ;
delete_limit_clause:
/* empty */
{
LEX *lex=Lex;
- lex->current_select->select_limit= HA_POS_ERROR;
+ lex->current_select->select_limit= 0;
}
- | LIMIT ulonglong_num
+ | LIMIT limit_option
{
SELECT_LEX *sel= Select;
- sel->select_limit= (ha_rows) $2;
+ sel->select_limit= $2;
sel->explicit_limit= 1;
};
@@ -5669,7 +5697,8 @@ procedure_item:
if (add_proc_to_list(lex->thd, $2))
YYABORT;
if (!$2->name)
- $2->set_name($1,(uint) ((char*) lex->tok_end - $1), YYTHD->charset());
+ $2->set_name($1,(uint) ((char*) lex->tok_end - $1),
+ YYTHD->charset());
}
;
@@ -6091,9 +6120,24 @@ insert_update_elem:
simple_ident_nospvar equal expr_or_default
{
LEX *lex= Lex;
+ uint8 tmp= MY_ITEM_PREFER_1ST_TABLE;
if (lex->update_list.push_back($1) ||
lex->value_list.push_back($3))
YYABORT;
+ /*
+ INSERT INTO a1(a) SELECT b1.a FROM b1 ON DUPLICATE KEY
+ UPDATE a= a + b1.b
+
+ Set MY_ITEM_PREFER_1ST_TABLE flag to $1 and $3 items
+ to prevent find_field_in_tables() doing further item searching
+ if it finds item occurence in first table in insert_table_list.
+ This allows to avoid ambiguity in resolving 'a' field in
+ example above.
+ */
+ $1->walk(&Item::set_flags_processor,
+ (byte *) &tmp);
+ $3->walk(&Item::set_flags_processor,
+ (byte *) &tmp);
};
opt_low_priority:
@@ -6127,10 +6171,17 @@ single_multi:
| table_wild_list
{ mysql_init_multi_delete(Lex); }
FROM join_table_list where_clause
+ {
+ if (multi_delete_set_locks_and_link_aux_tables(Lex))
+ YYABORT;
+ }
| FROM table_wild_list
{ mysql_init_multi_delete(Lex); }
USING join_table_list where_clause
- {}
+ {
+ if (multi_delete_set_locks_and_link_aux_tables(Lex))
+ YYABORT;
+ }
;
table_wild_list:
@@ -6873,7 +6924,7 @@ param_marker:
{
THD *thd=YYTHD;
LEX *lex= thd->lex;
- if (thd->command == COM_PREPARE)
+ if (thd->command == COM_STMT_PREPARE)
{
Item_param *item= new Item_param((uint) (lex->tok_start -
(uchar *) thd->query));
@@ -7980,8 +8031,8 @@ handler:
LEX *lex=Lex;
lex->sql_command = SQLCOM_HA_READ;
lex->ha_rkey_mode= HA_READ_KEY_EXACT; /* Avoid purify warnings */
- lex->current_select->select_limit= 1;
- lex->current_select->offset_limit= 0L;
+ lex->current_select->select_limit= new Item_int((int32) 1);
+ lex->current_select->offset_limit= 0;
if (!lex->current_select->add_table_to_list(lex->thd, $2, 0, 0))
YYABORT;
}
@@ -8702,21 +8753,21 @@ xa: XA_SYM begin_or_start xid opt_join_or_resume
xid: text_string
{
- TEST_ASSERT($1->length() <= MAXGTRIDSIZE);
+ YYERROR_UNLESS($1->length() <= MAXGTRIDSIZE);
if (!(Lex->xid=(XID *)YYTHD->alloc(sizeof(XID))))
YYABORT;
Lex->xid->set(1L, $1->ptr(), $1->length(), 0, 0);
}
| text_string ',' text_string
{
- TEST_ASSERT($1->length() <= MAXGTRIDSIZE && $3->length() <= MAXBQUALSIZE);
+ YYERROR_UNLESS($1->length() <= MAXGTRIDSIZE && $3->length() <= MAXBQUALSIZE);
if (!(Lex->xid=(XID *)YYTHD->alloc(sizeof(XID))))
YYABORT;
Lex->xid->set(1L, $1->ptr(), $1->length(), $3->ptr(), $3->length());
}
| text_string ',' text_string ',' ulong_num
{
- TEST_ASSERT($1->length() <= MAXGTRIDSIZE && $3->length() <= MAXBQUALSIZE);
+ YYERROR_UNLESS($1->length() <= MAXGTRIDSIZE && $3->length() <= MAXBQUALSIZE);
if (!(Lex->xid=(XID *)YYTHD->alloc(sizeof(XID))))
YYABORT;
Lex->xid->set($5, $1->ptr(), $1->length(), $3->ptr(), $3->length());