ECPG fix for mixed case cursor names

Started by Boszormenyi Zoltanover 15 years ago3 messages
#1Boszormenyi Zoltan
zb@cybertec.at
1 attachment(s)

Hi,

PostgreSQL allows in plain SQL to declare a cursor
e.g. in all lower case and fetch from is in all upper case.
We need to allow this from ECPG, too, but strictly when
the cursor name is not in a variable. Otherwise this code
below doesn't notice the cursor's double declaration
and complains using an undeclared cursor:

======================================
#include <stdio.h>

#include <sqlda.h>

int main(void)
{
EXEC SQL BEGIN DECLARE SECTION;
char *connstr = "zozo@localhost:5555";
EXEC SQL END DECLARE SECTION;
sqlda_t *sqlda;

EXEC SQL CONNECT TO :connstr;

EXEC SQL DECLARE mycur CURSOR FOR SELECT * FROM t1;

EXEC SQL DECLARE MYCUR CURSOR FOR SELECT * FROM t1;

EXEC SQL OPEN mYCur;

EXEC SQL FETCH ALL FROM mYcUr INTO DESCRIPTOR sqlda;

EXEC SQL CLOSE MyCuR;

EXEC SQL DISCONNECT ALL;

return 0;
}
======================================

Patch is attached.

Best regards,
Zolt�n B�sz�rm�nyi

Attachments:

ecpg-fix-cursor-mixed-case.patchtext/x-patch; name=ecpg-fix-cursor-mixed-case.patchDownload
diff -dcrpN pgsql.orig/src/interfaces/ecpg/preproc/ecpg.addons pgsql/src/interfaces/ecpg/preproc/ecpg.addons
*** pgsql.orig/src/interfaces/ecpg/preproc/ecpg.addons	2010-03-31 10:45:18.000000000 +0200
--- pgsql/src/interfaces/ecpg/preproc/ecpg.addons	2010-08-25 12:53:07.000000000 +0200
*************** ECPG: DeclareCursorStmtDECLAREcursor_nam
*** 302,311 ****
  		struct cursor *ptr, *this;
  		char *cursor_marker = $2[0] == ':' ? make_str("$0") : mm_strdup($2);
  		char *comment, *c1, *c2;
  
  		for (ptr = cur; ptr != NULL; ptr = ptr->next)
  		{
! 			if (strcmp($2, ptr->name) == 0)
  			{
  				if ($2[0] == ':')
                                          mmerror(PARSE_ERROR, ET_ERROR, "using variable \"%s\" in different declare statements is not supported", $2+1);
--- 302,312 ----
  		struct cursor *ptr, *this;
  		char *cursor_marker = $2[0] == ':' ? make_str("$0") : mm_strdup($2);
  		char *comment, *c1, *c2;
+ 		int (* strcmp_fn)(const char *, const char *) = ($2[0] == ':' ? strcmp : pg_strcasecmp);
  
  		for (ptr = cur; ptr != NULL; ptr = ptr->next)
  		{
! 			if (strcmp_fn($2, ptr->name) == 0)
  			{
  				if ($2[0] == ':')
                                          mmerror(PARSE_ERROR, ET_ERROR, "using variable \"%s\" in different declare statements is not supported", $2+1);
diff -dcrpN pgsql.orig/src/interfaces/ecpg/preproc/ecpg.header pgsql/src/interfaces/ecpg/preproc/ecpg.header
*** pgsql.orig/src/interfaces/ecpg/preproc/ecpg.header	2010-05-28 08:44:14.000000000 +0200
--- pgsql/src/interfaces/ecpg/preproc/ecpg.header	2010-08-25 12:56:40.000000000 +0200
*************** add_additional_variables(char *name, boo
*** 386,395 ****
  {
  	struct cursor *ptr;
  	struct arguments *p;
  
  	for (ptr = cur; ptr != NULL; ptr=ptr->next)
  	{
! 		if (strcmp(ptr->name, name) == 0)
  			break;
  	}
  
--- 386,396 ----
  {
  	struct cursor *ptr;
  	struct arguments *p;
+ 	int (* strcmp_fn)(const char *, const char *) = (name[0] == ':' ? strcmp : pg_strcasecmp);
  
  	for (ptr = cur; ptr != NULL; ptr=ptr->next)
  	{
! 		if (strcmp_fn(ptr->name, name) == 0)
  			break;
  	}
  
diff -dcrpN pgsql.orig/src/interfaces/ecpg/preproc/ecpg.trailer pgsql/src/interfaces/ecpg/preproc/ecpg.trailer
*** pgsql.orig/src/interfaces/ecpg/preproc/ecpg.trailer	2010-05-28 08:44:14.000000000 +0200
--- pgsql/src/interfaces/ecpg/preproc/ecpg.trailer	2010-08-25 12:58:20.000000000 +0200
*************** ECPGCursorStmt:  DECLARE cursor_name cur
*** 289,301 ****
  		{
  			struct cursor *ptr, *this;
  			char *cursor_marker = $2[0] == ':' ? make_str("$0") : mm_strdup($2);
  			struct variable *thisquery = (struct variable *)mm_alloc(sizeof(struct variable));
  			const char *con = connection ? connection : "NULL";
  			char *comment;
  
  			for (ptr = cur; ptr != NULL; ptr = ptr->next)
  			{
! 				if (strcmp($2, ptr->name) == 0)
  				{
  					/* re-definition is a bug */
  					if ($2[0] == ':')
--- 289,302 ----
  		{
  			struct cursor *ptr, *this;
  			char *cursor_marker = $2[0] == ':' ? make_str("$0") : mm_strdup($2);
+ 			int (* strcmp_fn)(const char *, const char *) = ($2[0] == ':' ? strcmp : pg_strcasecmp);
  			struct variable *thisquery = (struct variable *)mm_alloc(sizeof(struct variable));
  			const char *con = connection ? connection : "NULL";
  			char *comment;
  
  			for (ptr = cur; ptr != NULL; ptr = ptr->next)
  			{
! 				if (strcmp_fn($2, ptr->name) == 0)
  				{
  					/* re-definition is a bug */
  					if ($2[0] == ':')
#2Robert Haas
robertmhaas@gmail.com
In reply to: Boszormenyi Zoltan (#1)
Re: ECPG fix for mixed case cursor names

2010/8/25 Boszormenyi Zoltan <zb@cybertec.at>:

PostgreSQL allows in plain SQL to declare a cursor
e.g. in all lower case and fetch from is in all upper case.
We need to allow this from ECPG, too, but strictly when
the cursor name is not in a variable. Otherwise this code
below doesn't notice the cursor's double declaration
and complains using an undeclared cursor:

It might be a good idea to add this to the open CommitFest so we don't
lose track of it.

https://commitfest.postgresql.org/action/commitfest_view/open

--
Robert Haas
EnterpriseDB: http://www.enterprisedb.com
The Enterprise Postgres Company

#3Michael Meskes
meskes@postgresql.org
In reply to: Boszormenyi Zoltan (#1)
Re: ECPG fix for mixed case cursor names

On Wed, Aug 25, 2010 at 01:30:41PM +0200, Boszormenyi Zoltan wrote:

PostgreSQL allows in plain SQL to declare a cursor
e.g. in all lower case and fetch from is in all upper case.
We need to allow this from ECPG, too, but strictly when
the cursor name is not in a variable. Otherwise this code
below doesn't notice the cursor's double declaration
and complains using an undeclared cursor:
...

Applied. Thanks for spotting and fixing this.

Michael
--
Michael Meskes
Michael at Fam-Meskes dot De, Michael at Meskes dot (De|Com|Net|Org)
Michael at BorussiaFan dot De, Meskes at (Debian|Postgresql) dot Org
Jabber: michael.meskes at googlemail dot com
VfL Borussia! Força Barça! Go SF 49ers! Use Debian GNU/Linux, PostgreSQL