Using a cursor argument name equal to another plpgsql variable results in the error:
cursor .. has no argument named ""

The attached patch fixes that.

Instead of solving the issue like is done in the patch, another way would be to expose internal_yylex() so that could be used instead of yylex() by read_cursor_args when reading the argument name, and would always return the argument name in yylval.str.

--
Yeb Havinga
http://www.mgrid.net/
Mastering Medical Data

>From 47c451cbf188ac2aff9784bff73bc7fb7b846d26 Mon Sep 17 00:00:00 2001
From: Willem & Yeb <w...@mgrid.net>
Date: Wed, 4 Apr 2012 11:30:41 +0200
Subject: [PATCH] Fix cursor has no argument named "" error.

When a cursor argument name coincided with another plpgsql variable name,
yylex() returns it not as str but as a wdatum.
---
 src/pl/plpgsql/src/gram.y             |    6 ++++--
 src/test/regress/expected/plpgsql.out |   18 ++++++++++++++++++
 src/test/regress/sql/plpgsql.sql      |   15 +++++++++++++++
 3 files changed, 37 insertions(+), 2 deletions(-)

diff --git a/src/pl/plpgsql/src/gram.y b/src/pl/plpgsql/src/gram.y
index 5a555af..2d52278 100644
--- a/src/pl/plpgsql/src/gram.y
+++ b/src/pl/plpgsql/src/gram.y
@@ -3447,8 +3447,10 @@ read_cursor_args(PLpgSQL_var *cursor, int until, const char *expected)
 			char   *argname;
 
 			/* Read the argument name, and find its position */
-			yylex();
-			argname = yylval.str;
+			if (yylex() == T_DATUM)
+				argname = yylval.wdatum.ident;
+			else
+				argname = yylval.str;
 
 			for (argpos = 0; argpos < row->nfields; argpos++)
 			{
diff --git a/src/test/regress/expected/plpgsql.out b/src/test/regress/expected/plpgsql.out
index 5455ade..56cfa57 100644
--- a/src/test/regress/expected/plpgsql.out
+++ b/src/test/regress/expected/plpgsql.out
@@ -2420,6 +2420,24 @@ select namedparmcursor_test8();
                      0
 (1 row)
 
+-- cursor parameter named the same as other plpgsql variables
+create or replace function namedparmcursor_test9(p1 int) returns int4 as $$
+declare
+  c1 cursor (p1 int, p2 int) for
+    select count(*) from tenk1 where thousand = p1 and tenthous = p2;
+  n int4;
+  p2 int4 := 1006;
+begin
+  open c1 (p1 := p1,  p2 := p2);
+  fetch c1 into n;
+  return n;
+end $$ language plpgsql;
+select namedparmcursor_test9(6);
+ namedparmcursor_test9 
+-----------------------
+                     1
+(1 row)
+
 --
 -- tests for "raise" processing
 --
diff --git a/src/test/regress/sql/plpgsql.sql b/src/test/regress/sql/plpgsql.sql
index f577dc3..6b9795d 100644
--- a/src/test/regress/sql/plpgsql.sql
+++ b/src/test/regress/sql/plpgsql.sql
@@ -2053,6 +2053,21 @@ begin
 end $$ language plpgsql;
 select namedparmcursor_test8();
 
+-- cursor parameter named the same as other plpgsql variables
+create or replace function namedparmcursor_test9(p1 int) returns int4 as $$
+declare
+  c1 cursor (p1 int, p2 int) for
+    select count(*) from tenk1 where thousand = p1 and tenthous = p2;
+  n int4;
+  p2 int4 := 1006;
+begin
+  open c1 (p1 := p1,  p2 := p2);
+  fetch c1 into n;
+  return n;
+end $$ language plpgsql;
+
+select namedparmcursor_test9(6);
+
 --
 -- tests for "raise" processing
 --
-- 
1.7.1

-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Reply via email to