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
#include
int main(void)
{
EXEC SQL BEGIN DECLARE SECTION;
char*connstr = "z...@localhost:";
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
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.0 +0200
--- pgsql/src/interfaces/ecpg/preproc/ecpg.addons 2010-08-25 12:53:07.0 +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.0 +0200
--- pgsql/src/interfaces/ecpg/preproc/ecpg.header 2010-08-25 12:56:40.0 +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.0 +0200
--- pgsql/src/interfaces/ecpg/preproc/ecpg.trailer 2010-08-25 12:58:20.0 +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] == ':')
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers