Michael Meskes írta:
> On Wed, Aug 12, 2009 at 07:13:44PM +0200, Boszormenyi Zoltan wrote:
>   
>> a customer of us complained a behavioural difference
>> ...
>> The attached patch implements this. The only downside
>> is that now DECLARE CURSOR cannot appear outside
>> of a function, a change in test/preproc/variable.pgc reflects
>>     
>
> DECLARE by definition is a declarative command and as such should be able to
> live outside a function.
>   

Okay, so it's a declarative command. But if we're in a function,
we should still emit a call to ecpg_init, to be able to follow
the Informix behaviour. We can limit it it compat mode, though.
The attached patch does this, and detects being inside of a function
by braces_open > 0. Short of rewriting ECPG into a flull-fledged
C/C++ preprocessor, we can't do better currently.

In compat mode, you cannot do
    DECLARE mycur CURSOR FOR SELECT ... INTO :var, ...
or
    DECLARE mycur CURSOR FOR SELECT ... WHERE field = ?
in the global scope because adjust_informix() emits function calls
outside of a function. Or is this declaration illegal?
At least it should be documented in PostgreSQL.

Best regards,
Zoltán Böszörményi

-- 
Bible has answers for everything. Proof:
"But let your communication be, Yea, yea; Nay, nay: for whatsoever is more
than these cometh of evil." (Matthew 5:37) - basics of digital technology.
"May your kingdom come" - superficial description of plate tectonics

----------------------------------
Zoltán Böszörményi
Cybertec Schönig & Schönig GmbH
http://www.postgresql.at/

diff -dcrpN pgsql.describe/src/interfaces/ecpg/ecpglib/exports.txt pgsql.declare-reset-sqlca/src/interfaces/ecpg/ecpglib/exports.txt
*** pgsql.describe/src/interfaces/ecpg/ecpglib/exports.txt	2008-03-25 13:58:49.000000000 +0100
--- pgsql.declare-reset-sqlca/src/interfaces/ecpg/ecpglib/exports.txt	2009-08-12 18:13:11.000000000 +0200
*************** ECPGstatus                       23
*** 26,28 ****
--- 26,29 ----
  ECPGtrans                        24
  sqlprint                         25
  ECPGget_PGconn			 26
+ ECPGreset_sqlca			 27
diff -dcrpN pgsql.describe/src/interfaces/ecpg/ecpglib/misc.c pgsql.declare-reset-sqlca/src/interfaces/ecpg/ecpglib/misc.c
*** pgsql.describe/src/interfaces/ecpg/ecpglib/misc.c	2009-08-07 13:06:28.000000000 +0200
--- pgsql.declare-reset-sqlca/src/interfaces/ecpg/ecpglib/misc.c	2009-08-12 18:22:35.000000000 +0200
*************** ecpg_gettext(const char *msgid)
*** 489,491 ****
--- 489,499 ----
  }
  
  #endif   /* ENABLE_NLS */
+ 
+ bool
+ ECPGreset_sqlca(int lineno, const char *connection_name)
+ {
+ 	struct connection *con = ecpg_get_connection(connection_name);
+ 
+ 	return ecpg_init(con, connection_name, lineno);
+ }
diff -dcrpN pgsql.describe/src/interfaces/ecpg/include/ecpglib.h pgsql.declare-reset-sqlca/src/interfaces/ecpg/include/ecpglib.h
*** pgsql.describe/src/interfaces/ecpg/include/ecpglib.h	2009-08-11 14:34:03.000000000 +0200
--- pgsql.declare-reset-sqlca/src/interfaces/ecpg/include/ecpglib.h	2009-08-12 18:21:06.000000000 +0200
*************** bool		ECPGset_desc(int, const char *, in
*** 84,89 ****
--- 84,90 ----
  void		ECPGset_noind_null(enum ECPGttype, void *);
  bool		ECPGis_noind_null(enum ECPGttype, void *);
  bool		ECPGdescribe(int, bool, const char *, const char *, ...);
+ bool		ECPGreset_sqlca(int, const char *);
  
  /* dynamic result allocation */
  void		ECPGfree_auto_mem(void);
diff -dcrpN pgsql.describe/src/interfaces/ecpg/preproc/ecpg.addons pgsql.declare-reset-sqlca/src/interfaces/ecpg/preproc/ecpg.addons
*** pgsql.describe/src/interfaces/ecpg/preproc/ecpg.addons	2009-08-11 14:34:03.000000000 +0200
--- pgsql.declare-reset-sqlca/src/interfaces/ecpg/preproc/ecpg.addons	2009-08-13 17:40:41.000000000 +0200
*************** ECPG: DeclareCursorStmtDECLAREcursor_nam
*** 318,324 ****
  		cur = this;
  
  		if (INFORMIX_MODE)
! 			$$ = cat_str(5, adjust_informix(this->argsinsert), adjust_informix(this->argsresult), make_str("/*"), mm_strdup(this->command), make_str("*/"));
  		else
  			$$ = cat_str(3, make_str("/*"), mm_strdup(this->command), make_str("*/"));
  	}
--- 318,338 ----
  		cur = this;
  
  		if (INFORMIX_MODE)
! 		{
! 			char *comment;
! 			const char *con = connection ? connection : "NULL";
! 
! 			comment = cat_str(3, make_str("/*"), mm_strdup(this->command), make_str("*/"));
! 
! 			if (braces_open > 0) /* we're in a function */
! 			{
! 				char *command = (char *)mm_alloc(sizeof("ECPGreset_sqlca(__LINE__, );") + strlen(con));
! 				sprintf(command, "ECPGreset_sqlca(__LINE__, %s);", con);
! 				$$ = cat_str(4, adjust_informix(this->argsinsert), adjust_informix(this->argsresult), command, comment);
! 			}
! 			else
! 				$$ = cat_str(3, adjust_informix(this->argsinsert), adjust_informix(this->argsresult), comment);
! 		}
  		else
  			$$ = cat_str(3, make_str("/*"), mm_strdup(this->command), make_str("*/"));
  	}
diff -dcrpN pgsql.describe/src/interfaces/ecpg/preproc/ecpg.trailer pgsql.declare-reset-sqlca/src/interfaces/ecpg/preproc/ecpg.trailer
*** pgsql.describe/src/interfaces/ecpg/preproc/ecpg.trailer	2009-08-11 17:18:31.000000000 +0200
--- pgsql.declare-reset-sqlca/src/interfaces/ecpg/preproc/ecpg.trailer	2009-08-13 17:48:27.000000000 +0200
*************** ECPGCursorStmt:  DECLARE cursor_name cur
*** 356,362 ****
  			add_variable_to_head(&(this->argsinsert), thisquery, &no_indicator);
  			cur = this;
  
! 			$$ = cat_str(3, make_str("/*"), mm_strdup(this->command), make_str("*/"));
  		}
  		;
  
--- 356,374 ----
  			add_variable_to_head(&(this->argsinsert), thisquery, &no_indicator);
  			cur = this;
  
! 			if (INFORMIX_MODE)
! 			{
! 				if (braces_open > 0) /* we're in a function */
! 				{
! 					char *command = (char *)mm_alloc(sizeof("ECPGreset_sqlca(__LINE__, );") + strlen(con));
! 					sprintf(command, "ECPGreset_sqlca(__LINE__, %s);", con);
! 					$$ = cat_str(4, command, make_str("/*"), mm_strdup(this->command), make_str("*/"));
! 				}
! 				else
! 					$$ = cat_str(3, make_str("/*"), mm_strdup(this->command), make_str("*/"));
! 			}
! 			else
! 				$$ = cat_str(3, make_str("/*"), mm_strdup(this->command), make_str("*/"));
  		}
  		;
  
diff -dcrpN pgsql.describe/src/interfaces/ecpg/test/expected/compat_informix-cursor.c pgsql.declare-reset-sqlca/src/interfaces/ecpg/test/expected/compat_informix-cursor.c
*** pgsql.describe/src/interfaces/ecpg/test/expected/compat_informix-cursor.c	2009-08-10 18:06:56.000000000 +0200
--- pgsql.declare-reset-sqlca/src/interfaces/ecpg/test/expected/compat_informix-cursor.c	2009-08-13 17:00:25.000000000 +0200
*************** if (sqlca.sqlcode < 0) exit (1);}
*** 156,162 ****
  
  	strcpy(msg, "declare");
  	ECPG_informix_set_var( 0, &( curname1 ), __LINE__);\
!  /* declare $0 cursor for select id , t from t1 */
  #line 59 "cursor.pgc"
  
  
--- 156,162 ----
  
  	strcpy(msg, "declare");
  	ECPG_informix_set_var( 0, &( curname1 ), __LINE__);\
!  ECPGreset_sqlca(__LINE__, NULL); /* declare $0 cursor for select id , t from t1 */
  #line 59 "cursor.pgc"
  
  
*************** if (sqlca.sqlcode < 0) exit (1);}
*** 292,298 ****
  	ECPG_informix_set_var( 3, &( curname2 ), __LINE__);\
   ECPG_informix_set_var( 1, ( t ), __LINE__);\
   ECPG_informix_set_var( 2, &( id ), __LINE__);\
!  /* declare $0 cursor for select id , t from t1 */
  #line 100 "cursor.pgc"
  
  
--- 292,298 ----
  	ECPG_informix_set_var( 3, &( curname2 ), __LINE__);\
   ECPG_informix_set_var( 1, ( t ), __LINE__);\
   ECPG_informix_set_var( 2, &( id ), __LINE__);\
!  ECPGreset_sqlca(__LINE__, NULL); /* declare $0 cursor for select id , t from t1 */
  #line 100 "cursor.pgc"
  
  
*************** if (sqlca.sqlcode < 0) exit (1);}
*** 441,447 ****
  
  
  	strcpy(msg, "declare");
! 	/* declare $0 cursor for $1 */
  #line 143 "cursor.pgc"
  
  
--- 441,447 ----
  
  
  	strcpy(msg, "declare");
! 	ECPGreset_sqlca(__LINE__, NULL); /* declare $0 cursor for $1 */
  #line 143 "cursor.pgc"
  
  
*************** if (sqlca.sqlcode < 0) exit (1);}
*** 596,602 ****
  
  
  	strcpy(msg, "declare");
! 	/* declare $0 cursor for $1 */
  #line 193 "cursor.pgc"
  
  
--- 596,602 ----
  
  
  	strcpy(msg, "declare");
! 	ECPGreset_sqlca(__LINE__, NULL); /* declare $0 cursor for $1 */
  #line 193 "cursor.pgc"
  
  
diff -dcrpN pgsql.describe/src/interfaces/ecpg/test/expected/compat_informix-sqlda.c pgsql.declare-reset-sqlca/src/interfaces/ecpg/test/expected/compat_informix-sqlda.c
*** pgsql.describe/src/interfaces/ecpg/test/expected/compat_informix-sqlda.c	2009-08-11 14:24:20.000000000 +0200
--- pgsql.declare-reset-sqlca/src/interfaces/ecpg/test/expected/compat_informix-sqlda.c	2009-08-13 17:00:25.000000000 +0200
*************** if (sqlca.sqlcode < 0) exit (1);}
*** 291,297 ****
  
  
  	strcpy(msg, "declare");
! 	/* declare mycur1 cursor for $1 */
  #line 100 "sqlda.pgc"
  
  
--- 291,297 ----
  
  
  	strcpy(msg, "declare");
! 	ECPGreset_sqlca(__LINE__, NULL); /* declare mycur1 cursor for $1 */
  #line 100 "sqlda.pgc"
  
  
*************** if (sqlca.sqlcode < 0) exit (1);}
*** 366,372 ****
  
  
  	strcpy(msg, "declare");
! 	/* declare mycur2 cursor for $1 */
  #line 137 "sqlda.pgc"
  
  
--- 366,372 ----
  
  
  	strcpy(msg, "declare");
! 	ECPGreset_sqlca(__LINE__, NULL); /* declare mycur2 cursor for $1 */
  #line 137 "sqlda.pgc"
  
  
diff -dcrpN pgsql.describe/src/interfaces/ecpg/test/expected/compat_informix-test_informix.c pgsql.declare-reset-sqlca/src/interfaces/ecpg/test/expected/compat_informix-test_informix.c
*** pgsql.describe/src/interfaces/ecpg/test/expected/compat_informix-test_informix.c	2009-08-09 22:00:45.000000000 +0200
--- pgsql.declare-reset-sqlca/src/interfaces/ecpg/test/expected/compat_informix-test_informix.c	2009-08-13 17:00:26.000000000 +0200
*************** if (sqlca.sqlcode < 0) dosqlprint ( );}
*** 147,153 ****
  
  
  	ECPG_informix_set_var( 0, &( i ), __LINE__);\
!  /* declare c cursor for select * from test where i <= $1  */
  #line 48 "test_informix.pgc"
  
  	openit();
--- 147,153 ----
  
  
  	ECPG_informix_set_var( 0, &( i ), __LINE__);\
!  ECPGreset_sqlca(__LINE__, NULL); /* declare c cursor for select * from test where i <= $1  */
  #line 48 "test_informix.pgc"
  
  	openit();
-- 
Sent via pgsql-hackers mailing list ([email protected])
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Reply via email to