From 952e2cd42af99102c74d16abc61b37e2c42055b0 Mon Sep 17 00:00:00 2001
From: unknown <pem@mysql.comhem.se>
Date: Thu, 8 Jan 2004 09:27:29 +0100
Subject: [PATCH] Fix BUG#2272: Crash if update with variable name in stored
 procedure. Parse column names (and not variables) only in UPDATE ... SET ...

mysql-test/r/sp-error.result:
  New test case for BUG#2272
mysql-test/t/sp-error.test:
  New test case for BUG#2272
sql/sql_yacc.yy:
  "UPDATE table SET id = val" should only recognize column names, and not
  local SP variables for 'id'.
  (Also removed "as locator" syntax which is not supported.)
---
 mysql-test/r/sp-error.result |  9 +++++++++
 mysql-test/t/sp-error.test   | 14 ++++++++++++++
 sql/sql_yacc.yy              | 30 +++++++++++++++++++++---------
 3 files changed, 44 insertions(+), 9 deletions(-)

diff --git a/mysql-test/r/sp-error.result b/mysql-test/r/sp-error.result
index 748fda6c4e..c2b8460d61 100644
--- a/mysql-test/r/sp-error.result
+++ b/mysql-test/r/sp-error.result
@@ -283,4 +283,13 @@ create table t3 (column_1 int)|
 call bug1653()|
 drop procedure bug1653|
 drop table t3|
+create procedure bug2272()
+begin
+declare v int;
+update t1 set v = 42;
+end|
+insert into t1 values (666, 51.3)|
+call bug2272()|
+ERROR 42S22: Unknown column 'v' in 'field list'
+delete from t1|
 drop table t1|
diff --git a/mysql-test/t/sp-error.test b/mysql-test/t/sp-error.test
index b8b60ac8dd..e33d4d36be 100644
--- a/mysql-test/t/sp-error.test
+++ b/mysql-test/t/sp-error.test
@@ -388,6 +388,20 @@ call bug1653()|
 drop procedure bug1653|
 drop table t3|
 
+#
+# BUG#2272
+#
+create procedure bug2272()
+begin
+  declare v int;
+
+  update t1 set v = 42;
+end|
+
+insert into t1 values (666, 51.3)|
+--error 1054
+call bug2272()|
+delete from t1|
 
 drop table t1|
 
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index a5ec1a2095..cec85db8ca 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -679,6 +679,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
 	param_marker singlerow_subselect singlerow_subselect_init
 	signed_literal NUM_literal
 	exists_subselect exists_subselect_init sp_opt_default
+	simple_ident_nospvar simple_ident_q
 
 %type <item_list>
 	expr_list sp_expr_list udf_expr_list udf_expr_list2 when_list
@@ -1257,7 +1258,7 @@ sp_fdparams:
 	;
 
 sp_fdparam:
-	  ident type sp_opt_locator
+	  ident type
 	  {
 	    LEX *lex= Lex;
 	    sp_pcontext *spc= lex->spcont;
@@ -1283,7 +1284,7 @@ sp_pdparams:
 	;
 
 sp_pdparam:
-	  sp_opt_inout ident type sp_opt_locator
+	  sp_opt_inout ident type
 	  {
 	    LEX *lex= Lex;
 	    sp_pcontext *spc= lex->spcont;
@@ -1305,11 +1306,6 @@ sp_opt_inout:
 	| INOUT_SYM   { $$= sp_param_inout; }
 	;
 
-sp_opt_locator:
-	  /* Empty */
-	| AS LOCATOR_SYM
-	;
-
 sp_proc_stmts:
 	  /* Empty */ {}
 	| sp_proc_stmts sp_proc_stmt ';'
@@ -4999,7 +4995,7 @@ update_list:
 	  if (add_item_to_list(YYTHD, $3) || add_value_to_list(YYTHD, $5))
 	    YYABORT;
 	}
-	| simple_ident equal expr_or_default
+	| simple_ident_nospvar equal expr_or_default
 	  {
 	    if (add_item_to_list(YYTHD, $1) || add_value_to_list(YYTHD, $3))
 	      YYABORT;
@@ -5680,7 +5676,23 @@ simple_ident:
 	         (Item*) new Item_ref(NullS,NullS,$1.str);
 	  }
 	}
-	| ident '.' ident
+        | simple_ident_q { $$= $1; }
+	;
+
+simple_ident_nospvar:
+	ident
+	{
+	  SELECT_LEX *sel=Select;
+	  $$= (sel->parsing_place != SELECT_LEX_NODE::IN_HAVING ||
+	       sel->get_in_sum_expr() > 0) ?
+              (Item*) new Item_field(NullS,NullS,$1.str) :
+	      (Item*) new Item_ref(NullS,NullS,$1.str);
+	}
+	| simple_ident_q { $$= $1; }
+	;	
+
+simple_ident_q:
+	ident '.' ident
 	{
 	  THD *thd= YYTHD;
 	  LEX *lex= thd->lex;
-- 
2.30.9