Re: DECLARE doesn't set/reset sqlca after DECLARE cursor
От | Boszormenyi Zoltan |
---|---|
Тема | Re: DECLARE doesn't set/reset sqlca after DECLARE cursor |
Дата | |
Msg-id | 4A843789.2050202@cybertec.at обсуждение исходный текст |
Ответ на | Re: DECLARE doesn't set/reset sqlca after DECLARE cursor (Michael Meskes <meskes@postgresql.org>) |
Ответы |
Re: DECLARE doesn't set/reset sqlca after DECLARE cursor
|
Список | pgsql-hackers |
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();
В списке pgsql-hackers по дате отправления:
Следующее
От: Hitoshi HaradaДата:
Сообщение: Re: Implementation of GROUPING SETS (T431: Extended grouping capabilities)