diff options
Diffstat (limited to 'sql/sql_yacc.yy')
-rw-r--r-- | sql/sql_yacc.yy | 135 |
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()); |