From bd7c95f0c1a38becffceb3ea7234d57167f6d4bf Mon Sep 17 00:00:00 2001 From: Michael Meskes Date: Sat, 16 Feb 2019 10:55:17 +0100 Subject: [PATCH] Add DECLARE STATEMENT support to ECPG. DECLARE STATEMENT is a statement that lets users declare an identifier pointing at a connection. This identifier will be used in other embedded dynamic SQL statement such as PREPARE, EXECUTE, DECLARE CURSOR and so on. When connecting to a non-default connection, the AT clause can be used in a DECLARE STATEMENT once and is no longer needed in every dynamic SQL statement. This makes ECPG applications easier and more efficient. Moreover, writing code without designating connection explicitly improves portability. Authors: Ideriha-san ("Ideriha, Takeshi" ) Kuroda-san ("Kuroda, Hayato" ) Discussion: https://postgr.es/m4E72940DA2BF16479384A86D54D0988A565669DF@G01JPEXMBKW04 --- doc/src/sgml/ecpg.sgml | 192 +++++- src/interfaces/ecpg/ecpglib/Makefile | 4 +- src/interfaces/ecpg/ecpglib/connect.c | 6 + src/interfaces/ecpg/ecpglib/cursor.c | 258 ++++++++ src/interfaces/ecpg/ecpglib/descriptor.c | 15 +- src/interfaces/ecpg/ecpglib/ecpglib_extern.h | 21 + src/interfaces/ecpg/ecpglib/error.c | 7 + src/interfaces/ecpg/ecpglib/execute.c | 25 +- src/interfaces/ecpg/ecpglib/exports.txt | 4 + src/interfaces/ecpg/ecpglib/prepare.c | 242 ++++++- src/interfaces/ecpg/include/ecpgerrno.h | 1 + src/interfaces/ecpg/include/ecpglib.h | 4 + src/interfaces/ecpg/include/ecpgtype.h | 7 + src/interfaces/ecpg/preproc/ecpg.addons | 77 ++- src/interfaces/ecpg/preproc/ecpg.c | 86 ++- src/interfaces/ecpg/preproc/ecpg.header | 1 + src/interfaces/ecpg/preproc/ecpg.trailer | 34 + src/interfaces/ecpg/preproc/ecpg.type | 1 + src/interfaces/ecpg/preproc/output.c | 157 ++++- src/interfaces/ecpg/preproc/preproc_extern.h | 3 + src/interfaces/ecpg/preproc/type.h | 8 + src/interfaces/ecpg/test/ecpg_schedule | 1 + .../test/expected/compat_informix-sqlda.c | 12 +- .../expected/compat_informix-test_informix.c | 4 +- .../test/expected/compat_oracle-char_array.c | 6 +- .../ecpg/test/expected/pgtypeslib-nan_test.c | 18 +- .../ecpg/test/expected/preproc-autoprep.c | 12 +- .../ecpg/test/expected/preproc-cursor.c | 76 +-- .../ecpg/test/expected/preproc-outofscope.c | 6 +- .../ecpg/test/expected/preproc-variable.c | 6 +- .../expected/preproc-whenever_do_continue.c | 6 +- .../ecpg/test/expected/sql-binary.c | 18 +- .../ecpg/test/expected/sql-declare.c | 595 ++++++++++++++++++ .../ecpg/test/expected/sql-declare.stderr | 288 +++++++++ .../ecpg/test/expected/sql-declare.stdout | 20 + src/interfaces/ecpg/test/expected/sql-desc.c | 12 +- .../ecpg/test/expected/sql-dyntest.c | 6 +- .../ecpg/test/expected/sql-execute.c | 12 +- src/interfaces/ecpg/test/expected/sql-fetch.c | 16 +- .../ecpg/test/expected/sql-oldexec.c | 12 +- src/interfaces/ecpg/test/expected/sql-quote.c | 4 +- src/interfaces/ecpg/test/expected/sql-sqlda.c | 12 +- src/interfaces/ecpg/test/sql/.gitignore | 2 + src/interfaces/ecpg/test/sql/Makefile | 3 +- src/interfaces/ecpg/test/sql/declare.pgc | 207 ++++++ 45 files changed, 2334 insertions(+), 173 deletions(-) create mode 100644 src/interfaces/ecpg/ecpglib/cursor.c create mode 100644 src/interfaces/ecpg/test/expected/sql-declare.c create mode 100644 src/interfaces/ecpg/test/expected/sql-declare.stderr create mode 100644 src/interfaces/ecpg/test/expected/sql-declare.stdout create mode 100644 src/interfaces/ecpg/test/sql/declare.pgc diff --git a/doc/src/sgml/ecpg.sgml b/doc/src/sgml/ecpg.sgml index fac45400b0..d2319c8b32 100644 --- a/doc/src/sgml/ecpg.sgml +++ b/doc/src/sgml/ecpg.sgml @@ -236,7 +236,7 @@ EXEC SQL CONNECT TO :target USER :user USING :passwd; SQL statements in embedded SQL programs are by default executed on the current connection, that is, the most recently opened one. If an application needs to manage multiple connections, then there are - two ways to handle this. + three ways to handle this. @@ -310,6 +310,17 @@ current=testdb2 (should be testdb2) current=testdb1 (should be testdb1) + + + The third option is to declare a sql identifier linked to + the connection, for example: + +EXEC SQL AT connection-name DECLARE statement-name STATEMENT; +EXEC SQL PREPARE statement-name FROM :dyn-string; + + Once you link a sql identifier to a connection, you execute a dynamic SQL + without AT clause. + @@ -6766,6 +6777,185 @@ EXEC SQL DECLARE cur1 CURSOR FOR stmt1; + + + DECLARE STATEMENT + declares SQL statement identifier associated with connection + + + + +EXEC SQL [ AT connection_name ] DECLARE statement_name STATEMENT + + + + + Description + + + DECLARE STATEMENT declares SQL statement identifier. + SQL statement identifier is associated with connection. + + + + DELARE CURSOR with a SQL statement identifier can be written before PREPARE. + + + + + Parameters + + + + connection_name + + + A database connection name established by the CONNECT command. + + + If AT clause is omitted, an SQL statement identifier is associated with the DEFAULT connection. + + + + + + + + statement_name + + + The name of a SQL statement identifier, either as an SQL identifier or a host variable. + + + + + + + + Notes + + AT clause can be used at other dynamic SQL statements. The following table + gives the connected database when AT clause is used at DECLARE STATEMENT + and other dynamic statements. + + + Scenario + + + + + Using Scenario + + + Declare Statement + + + Other Dynamic Statements + + + Executed Database + + + + + + + 1 + + + Without AT clause + + + Without AT clause + + + Default connection + + + + + 2 + + + Using AT clause connecting at con1 + + + Without AT clause + + + con1 + + + + + 3 + + + Using AT clause connecting at con1 + + + Using AT clause connecting at con2 + + + con1 + + + + + 4 + + + Without AT clause + + + Using AT clause connecting at con2 + + + con2 + + + + +
+ + In scenario 4, DECLARE STATEMENT will be ignored. + +
+ + + Examples + + +EXEC SQL CONNECT TO postgres AS con1; +EXEC SQL AT con1 DECLARE sql_stmt STATEMENT; +EXEC SQL DECLARE cursor_name CURSOR FOR sql_stmt; +EXEC SQL PREPARE sql_stmt FROM :dyn_string; +EXEC SQL OPEN cursor_name; +EXEC SQL FETCH cursor_name INTO :column1; +EXEC SQL CLOSE cursor_name; + + + + + Compatibility + + + DECLARE STATEMENT is a PostgreSQL extension of the SQL standard, + but can be used in Oracle and DB2. + + + + + See Also + + + + + + + +
+ DESCRIBE diff --git a/src/interfaces/ecpg/ecpglib/Makefile b/src/interfaces/ecpg/ecpglib/Makefile index 8827a17fec..abe5050360 100644 --- a/src/interfaces/ecpg/ecpglib/Makefile +++ b/src/interfaces/ecpg/ecpglib/Makefile @@ -15,7 +15,7 @@ include $(top_builddir)/src/Makefile.global PGFILEDESC = "ECPG - embedded SQL in C" NAME= ecpg -SO_MAJOR_VERSION= 6 +SO_MAJOR_VERSION= 7 SO_MINOR_VERSION= $(MAJORVERSION) override CPPFLAGS := -I../include -I$(top_srcdir)/src/interfaces/ecpg/include \ @@ -23,7 +23,7 @@ override CPPFLAGS := -I../include -I$(top_srcdir)/src/interfaces/ecpg/include \ override CFLAGS += $(PTHREAD_CFLAGS) OBJS= execute.o typename.o descriptor.o sqlda.o data.o error.o prepare.o \ - memory.o connect.o misc.o $(WIN32RES) + memory.o connect.o misc.o cursor.o $(WIN32RES) SHLIB_LINK_INTERNAL = -L../pgtypeslib -lpgtypes $(libpq_pgport_shlib) SHLIB_LINK = $(filter -lintl -lm, $(LIBS)) $(PTHREAD_LIBS) diff --git a/src/interfaces/ecpg/ecpglib/connect.c b/src/interfaces/ecpg/ecpglib/connect.c index 5f8455020e..ec01f67b61 100644 --- a/src/interfaces/ecpg/ecpglib/connect.c +++ b/src/interfaces/ecpg/ecpglib/connect.c @@ -340,6 +340,8 @@ ECPGconnect(int lineno, int c, const char *name, const char *user, const char *p return false; } + memset(this, 0, sizeof(struct connection)); + if (dbname != NULL) { /* get the detail information from dbname */ @@ -690,6 +692,7 @@ ECPGdisconnect(int lineno, const char *connection_name) struct connection *f = con; con = con->next; + ecpg_release_declared_statement(f->name); ecpg_finish(f); } } @@ -705,7 +708,10 @@ ECPGdisconnect(int lineno, const char *connection_name) return false; } else + { + ecpg_release_declared_statement(connection_name); ecpg_finish(con); + } } #ifdef ENABLE_THREAD_SAFETY diff --git a/src/interfaces/ecpg/ecpglib/cursor.c b/src/interfaces/ecpg/ecpglib/cursor.c new file mode 100644 index 0000000000..ae67bfe8e0 --- /dev/null +++ b/src/interfaces/ecpg/ecpglib/cursor.c @@ -0,0 +1,258 @@ +/* src/interfaces/ecpg/ecpglib/cursor.c */ + +#define POSTGRES_ECPG_INTERNAL +#include "postgres_fe.h" + +#include +#include +#include + +#include "ecpgtype.h" +#include "ecpglib.h" +#include "ecpgerrno.h" +#include "ecpglib_extern.h" +#include "sqlca.h" + +static void add_cursor(const int, const char *, const char *); +static void remove_cursor(const char *, struct connection *); +static bool find_cursor(const char *, const struct connection *); + +/* + * Function: Handle the EXEC SQL OPEN cursor statement: + * Input: + * cursor_name --- cursor name + * prepared_name --- prepared name + * others --- keep same as the parameters in ECPGdo() function + */ +bool +ECPGopen(const char *cursor_name,const char *prepared_name, + const int lineno, const int compat,const int force_indicator, + const char *connection_name, const bool questionmarks, + const int st, const char *query,...) +{ + va_list args; + bool status; + const char *real_connection_name = NULL; + + if (!query) + { + ecpg_raise(lineno, ECPG_EMPTY, ECPG_SQLSTATE_ECPG_INTERNAL_ERROR, NULL); + return false; + } + + /* + * If the declared name is referred by the PREPARE statement then the + * prepared_name is same as declared name + */ + real_connection_name = ecpg_get_con_name_by_declared_name(prepared_name); + if (real_connection_name) + { + /* Add the cursor name into the declared node */ + ecpg_update_declare_statement(prepared_name, cursor_name, lineno); + } + else + { + /* + * If can't get the connection name by declared name then using connection name + * coming from the parameter connection_name + */ + real_connection_name = connection_name; + } + + + /* Add the cursor into the connection */ + add_cursor(lineno, cursor_name, real_connection_name); + + va_start(args, query); + + status = ecpg_do(lineno, compat, force_indicator, real_connection_name, questionmarks, st, query, args); + + va_end(args); + + return status; +} + + +/* + * Function: Handle the EXEC SQL FETCH/MOVE CURSOR statements: + * Input: + * cursor_name --- cursor name + * others --- keep same as the parameters in ECPGdo() function + */ +bool +ECPGfetch(const char *cursor_name, + const int lineno, const int compat,const int force_indicator, + const char *connection_name, const bool questionmarks, + const int st, const char *query,...) +{ + va_list args; + bool status; + const char *real_connection_name = NULL; + + if (!query) + { + ecpg_raise(lineno, ECPG_EMPTY, ECPG_SQLSTATE_ECPG_INTERNAL_ERROR, NULL); + return (false); + } + + real_connection_name = ecpg_get_con_name_by_cursor_name(cursor_name); + if (real_connection_name == NULL) + { + /* + * If can't get the connection name by cursor name then using connection name + * coming from the parameter connection_name + */ + real_connection_name = connection_name; + } + + va_start(args, query); + + status = ecpg_do(lineno, compat, force_indicator, real_connection_name, questionmarks, st, query, args); + + va_end(args); + + return status; +} + + +/* + * Function: Handle the EXEC SQL CLOSE CURSOR statements: + * Input: + * cursor_name --- cursor name + * others --- keep same as the parameters in ECPGdo() function + */ +bool +ECPGclose(const char *cursor_name, + const int lineno, const int compat,const int force_indicator, + const char *connection_name, const bool questionmarks, + const int st, const char *query,...) +{ + va_list args; + bool status; + const char *real_connection_name = NULL; + struct connection *con = NULL; + + if (!query) + { + ecpg_raise(lineno, ECPG_EMPTY, ECPG_SQLSTATE_ECPG_INTERNAL_ERROR, NULL); + return false; + } + + real_connection_name = ecpg_get_con_name_by_cursor_name(cursor_name); + if (real_connection_name == NULL) + { + /* + * If can't get the connection name by cursor name then using connection name + * coming from the parameter connection_name + */ + real_connection_name = connection_name; + } + + con = ecpg_get_connection(real_connection_name); + + /* check the existence of the cursor in the connection */ + if (find_cursor(cursor_name, con) == false) + { + ecpg_raise(lineno, ECPG_INVALID_CURSOR, ECPG_SQLSTATE_ECPG_INTERNAL_ERROR, NULL); + return false; + } + + va_start(args, query); + + status = ecpg_do(lineno, compat, force_indicator, real_connection_name, questionmarks, st, query, args); + + va_end(args); + + remove_cursor(cursor_name, con); + + return status; +} + +/* + * Function: Add a cursor into the connection + * The duplication of cursor_name is checked at ecpg.trailer, + * so we don't check here. + */ +static void +add_cursor(const int lineno, const char *cursor_name, const char *connection_name) +{ + struct connection *con; + struct cursor_statement *new = NULL; + + if (!cursor_name) + { + ecpg_raise(lineno, ECPG_INVALID_CURSOR, ECPG_SQLSTATE_ECPG_INTERNAL_ERROR, NULL); + return; + } + + con = ecpg_get_connection(connection_name); + if (!con) + { + ecpg_raise(lineno, ECPG_NO_CONN, ECPG_SQLSTATE_CONNECTION_DOES_NOT_EXIST, + connection_name ? connection_name : ecpg_gettext("NULL")); + return; + } + + /* allocate a node to store the new cursor */ + new = (struct cursor_statement *)ecpg_alloc(sizeof(struct cursor_statement), lineno); + if (new) + { + new->name = ecpg_strdup(cursor_name, lineno); + new->next = con->cursor_stmts; + con->cursor_stmts = new; + } +} + +/* + * Function: Remove the cursor from the connection + */ +static void +remove_cursor(const char *cursor_name, struct connection *connection) +{ + struct cursor_statement *cur = NULL; + struct cursor_statement *prev = NULL; + + if (!connection || !cursor_name) + return; + + cur = connection->cursor_stmts; + while (cur) + { + if (strcmp(cur->name, cursor_name) == 0) + { + if (!prev) + connection->cursor_stmts = cur->next; + else + prev->next = cur->next; + + ecpg_free(cur->name); + ecpg_free(cur); + + break; + } + prev = cur; + cur = cur->next; + } +} + +/* + * Function: check the existence of the cursor in the connection + * Return: true ---Found + * false --- Not found + */ +static bool +find_cursor(const char *cursor_name, const struct connection *connection) +{ + struct cursor_statement *cur = NULL; + + if (!connection || !cursor_name) + return false; + + for (cur = connection->cursor_stmts; cur != NULL; cur = cur->next) + { + if (strcmp(cur->name, cursor_name) == 0) + return true; + } + + return false; +} diff --git a/src/interfaces/ecpg/ecpglib/descriptor.c b/src/interfaces/ecpg/ecpglib/descriptor.c index 5fca4dde20..d19dce2110 100644 --- a/src/interfaces/ecpg/ecpglib/descriptor.c +++ b/src/interfaces/ecpg/ecpglib/descriptor.c @@ -842,6 +842,7 @@ ECPGdescribe(int line, int compat, bool input, const char *connection_name, cons struct prepared_statement *prep; PGresult *res; va_list args; + const char *real_connection_name = NULL; /* DESCRIBE INPUT is not yet supported */ if (input) @@ -850,11 +851,21 @@ ECPGdescribe(int line, int compat, bool input, const char *connection_name, cons return ret; } - con = ecpg_get_connection(connection_name); + real_connection_name = ecpg_get_con_name_by_declared_name(stmt_name); + if (real_connection_name == NULL) + { + /* + * If can't get the connection name by declared name then using connection name + * coming from the parameter connection_name + */ + real_connection_name = connection_name; + } + + con = ecpg_get_connection(real_connection_name); if (!con) { ecpg_raise(line, ECPG_NO_CONN, ECPG_SQLSTATE_CONNECTION_DOES_NOT_EXIST, - connection_name ? connection_name : ecpg_gettext("NULL")); + real_connection_name ? real_connection_name : ecpg_gettext("NULL")); return ret; } prep = ecpg_find_prepared_statement(stmt_name, con, NULL); diff --git a/src/interfaces/ecpg/ecpglib/ecpglib_extern.h b/src/interfaces/ecpg/ecpglib/ecpglib_extern.h index ae2dcfc617..f3e41d3eec 100644 --- a/src/interfaces/ecpg/ecpglib/ecpglib_extern.h +++ b/src/interfaces/ecpg/ecpglib/ecpglib_extern.h @@ -78,6 +78,15 @@ struct statement PGresult *results; }; +/* structure to store declared statements */ +struct declared_statement +{ + char *name; /* declared name */ + char *connection_name; + char *cursor_name; + struct declared_statement *next; +}; + /* structure to store prepared statements for a connection */ struct prepared_statement { @@ -87,6 +96,12 @@ struct prepared_statement struct prepared_statement *next; }; +struct cursor_statement +{ + char *name; /*cursor name*/ + struct cursor_statement *next; +}; + /* structure to store connections */ struct connection { @@ -95,6 +110,7 @@ struct connection bool autocommit; struct ECPGtype_information_cache *cache_head; struct prepared_statement *prep_stmts; + struct cursor_statement *cursor_stmts; struct connection *next; }; @@ -177,6 +193,11 @@ struct descriptor *ecpg_find_desc(int line, const char *name); struct prepared_statement *ecpg_find_prepared_statement(const char *, struct connection *, struct prepared_statement **); +void ecpg_update_declare_statement(const char *, const char *, const int); +char *ecpg_get_con_name_by_declared_name(const char *); +const char *ecpg_get_con_name_by_cursor_name(const char *); +void ecpg_release_declared_statement(const char *); + bool ecpg_store_result(const PGresult *results, int act_field, const struct statement *stmt, struct variable *var); bool ecpg_store_input(const int, const bool, const struct variable *, char **, bool); diff --git a/src/interfaces/ecpg/ecpglib/error.c b/src/interfaces/ecpg/ecpglib/error.c index 9c56991a1e..397aa28190 100644 --- a/src/interfaces/ecpg/ecpglib/error.c +++ b/src/interfaces/ecpg/ecpglib/error.c @@ -200,6 +200,13 @@ ecpg_raise(int line, int code, const char *sqlstate, const char *str) ecpg_gettext("could not connect to database \"%s\" on line %d"), str, line); break; + case ECPG_INVALID_CURSOR: + snprintf(sqlca->sqlerrm.sqlerrmc, sizeof(sqlca->sqlerrm.sqlerrmc), + /*------ + translator: this string will be truncated at 149 characters expanded. */ + ecpg_gettext("The cursor is invalid on line %d"),line); + break; + default: snprintf(sqlca->sqlerrm.sqlerrmc, sizeof(sqlca->sqlerrm.sqlerrmc), /*------ diff --git a/src/interfaces/ecpg/ecpglib/execute.c b/src/interfaces/ecpg/ecpglib/execute.c index 4c499fb457..2bdb558fab 100644 --- a/src/interfaces/ecpg/ecpglib/execute.c +++ b/src/interfaces/ecpg/ecpglib/execute.c @@ -2074,9 +2074,32 @@ ECPGdo(const int lineno, const int compat, const int force_indicator, const char { va_list args; bool ret; + const char *real_connection_name = NULL; + + real_connection_name = connection_name; + + if (!query) + { + ecpg_raise(lineno, ECPG_EMPTY, ECPG_SQLSTATE_ECPG_INTERNAL_ERROR, NULL); + return false; + } + + /* Handle the EXEC SQL EXECUTE... statement */ + if (ECPGst_execute == st) + { + real_connection_name = ecpg_get_con_name_by_declared_name(query); + if (real_connection_name == NULL) + { + /* + * If can't get the connection name by declared name then using connection name + * coming from the parameter connection_name + */ + real_connection_name = connection_name; + } + } va_start(args, query); - ret = ecpg_do(lineno, compat, force_indicator, connection_name, + ret = ecpg_do(lineno, compat, force_indicator, real_connection_name, questionmarks, st, query, args); va_end(args); diff --git a/src/interfaces/ecpg/ecpglib/exports.txt b/src/interfaces/ecpg/ecpglib/exports.txt index 69e96179d5..08fa1bbf19 100644 --- a/src/interfaces/ecpg/ecpglib/exports.txt +++ b/src/interfaces/ecpg/ecpglib/exports.txt @@ -29,3 +29,7 @@ ECPGget_PGconn 26 ECPGtransactionStatus 27 ECPGset_var 28 ECPGget_var 29 +ECPGdeclare 30 +ECPGopen 31 +ECPGfetch 32 +ECPGclose 33 \ No newline at end of file diff --git a/src/interfaces/ecpg/ecpglib/prepare.c b/src/interfaces/ecpg/ecpglib/prepare.c index 2dd56b02df..85c61d23f2 100644 --- a/src/interfaces/ecpg/ecpglib/prepare.c +++ b/src/interfaces/ecpg/ecpglib/prepare.c @@ -36,10 +36,11 @@ typedef struct static int nextStmtID = 1; static stmtCacheEntry *stmtCacheEntries = NULL; +static struct declared_statement *g_declared_list; static bool deallocate_one(int lineno, enum COMPAT_MODE c, struct connection *con, struct prepared_statement *prev, struct prepared_statement *this); - +static struct declared_statement *ecpg_find_declared_statement(const char *); static bool isvarchar(unsigned char c) { @@ -128,6 +129,7 @@ prepare_common(int lineno, struct connection *con, const char *name, const char ecpg_free(this); return false; } + memset(stmt, 0, sizeof(struct statement)); /* create statement */ stmt->lineno = lineno; @@ -175,12 +177,22 @@ ECPGprepare(int lineno, const char *connection_name, const bool questionmarks, struct connection *con; struct prepared_statement *this, *prev; + const char *real_connection_name = NULL; (void) questionmarks; /* quiet the compiler */ - con = ecpg_get_connection(connection_name); + real_connection_name = ecpg_get_con_name_by_declared_name(name); + if (real_connection_name == NULL) + { + /* + * If can't get the connection name by declared name then using connection name + * coming from the parameter connection_name + */ + real_connection_name = connection_name; + } - if (!ecpg_init(con, connection_name, lineno)) + con = ecpg_get_connection(real_connection_name); + if (!ecpg_init(con, real_connection_name, lineno)) return false; /* check if we already have prepared this statement */ @@ -273,9 +285,19 @@ ECPGdeallocate(int lineno, int c, const char *connection_name, const char *name) struct connection *con; struct prepared_statement *this, *prev; + const char *real_connection_name = NULL; - con = ecpg_get_connection(connection_name); + real_connection_name = ecpg_get_con_name_by_declared_name(name); + if (real_connection_name == NULL) + { + /* + * If can't get the connection name by declared name then using connection name + * coming from the parameter connection_name + */ + real_connection_name = connection_name; + } + con = ecpg_get_connection(real_connection_name); if (!ecpg_init(con, connection_name, lineno)) return false; @@ -324,8 +346,21 @@ ecpg_prepared(const char *name, struct connection *con) char * ECPGprepared_statement(const char *connection_name, const char *name, int lineno) { + const char *real_connection_name = NULL; + (void) lineno; /* keep the compiler quiet */ - return ecpg_prepared(name, ecpg_get_connection(connection_name)); + + real_connection_name = ecpg_get_con_name_by_declared_name(name); + if (real_connection_name == NULL) + { + /* + * If can't get the connection name by declared name then using connection name + * coming from the parameter connection_name + */ + real_connection_name = connection_name; + } + + return ecpg_prepared(name, ecpg_get_connection(real_connection_name)); } /* @@ -556,3 +591,200 @@ ecpg_auto_prepare(int lineno, const char *connection_name, const int compat, cha return true; } + +/* + * handle the EXEC SQL DECLARE STATEMENT + * Input: connection_name -- connection name + * name -- declared name + */ +bool +ECPGdeclare(int lineno, const char *connection_name, const char *name) +{ + struct connection *con = NULL; + struct declared_statement *p = NULL; + + if (name == NULL) + { + /* Should never go to here because ECPG pre-compiler will check it */ + return false; + } + + if (connection_name == NULL) + { + /* + * Going to here means not using AT clause in the DECLARE STATEMENT + * ECPG pre-processor allows this case. + * However, we don't allocate a node to store the declared name + * because the DECLARE STATEMENT without using AT clause will be ignored. + * The following statement such as PREPARE, EXECUTE are executed + * as usual on the current connection. + */ + return true; + } + + con = ecpg_get_connection(connection_name); + if (!ecpg_init(con, connection_name, lineno)) + return false; + + if (ecpg_find_declared_statement(name)) + { + /* Should not go to here because the pre-compiler has check the duplicate name */ + return false; + } + + /* allocate a declared_statement as a new node */ + p = (struct declared_statement *) ecpg_alloc(sizeof(struct declared_statement), lineno); + if (!p) + return false; + + memset(p, 0, sizeof(struct declared_statement)); + + ecpg_log("ECPGdeclare on line %d: declared name %s on connection: \"%s\"\n", lineno, name, connection_name); + + p->name = ecpg_strdup(name, lineno); + p->connection_name = ecpg_strdup(connection_name, lineno); + + /* Add the new node into the g_declared_list */ + if (g_declared_list != NULL) + { + p->next = g_declared_list; + g_declared_list = p; + } + else + g_declared_list = p; + + return true; +} + +/* + * Find a declared node by declared name + * Input: name -- declared name + * Return: Found -- The pointer points to the declared node + * Not found -- NULL + */ +static struct declared_statement * +ecpg_find_declared_statement(const char *name) +{ + struct declared_statement *p; + + if (name == NULL) + return NULL; + + p = g_declared_list; + while (p) + { + if (strcmp(p->name, name) == 0) + return p; + p = p->next; + } + + return NULL; +} + +/* + * Build the relationship between the declared name and cursor name + * Input: declared_name -- the name declared in the DECLARE STATEMENT + * cursor_name -- cursor name declared in the DECLARE/OPEN CURSOR statement + */ +void +ecpg_update_declare_statement(const char *declared_name, const char *cursor_name, const int lineno) +{ + struct declared_statement *p = NULL; + + if (!declared_name || !cursor_name) + return; + + /* Find the declared node by declared name */ + p = ecpg_find_declared_statement(declared_name); + if (p) + p->cursor_name = ecpg_strdup(cursor_name,lineno); +} + +/* + * Find and return the connection name referred by the declared name + * Input: declared_name -- the name declared in the DECLARE STATEMENT + * Return: Found -- The connection name + * Not found -- NULL + */ +char * +ecpg_get_con_name_by_declared_name(const char *declared_name) +{ + struct declared_statement *p; + + p = ecpg_find_declared_statement(declared_name); + if (p) + return p->connection_name; + + return NULL; +} + +/* + * Find the connection name by referring the declared statements + * cursors by using the provided cursor name + * Input: cursor_name -- the cursor name + * Return: Found -- The connection name + * Not found -- NULL + */ +const char * +ecpg_get_con_name_by_cursor_name(const char *cursor_name) +{ + struct declared_statement *p; + + if (cursor_name == NULL) + return NULL; + + p = g_declared_list; + while (p) + { + /* Search the cursor name in the declared list */ + if (p->cursor_name && (strcmp(p->cursor_name, cursor_name) == 0)) + return p->connection_name; + + p = p->next; + } + + return NULL; +} + +/* + * Release the declare node from the g_declared_list which refers the connection_name + * Input: connection_name -- connection name + */ +void +ecpg_release_declared_statement(const char *connection_name) +{ + struct declared_statement *cur = NULL; + struct declared_statement *prev = NULL; + + if (connection_name == NULL) + return; + + cur = g_declared_list; + while (cur) + { + if (strcmp(cur->connection_name, connection_name) == 0) + { + /* If find then release the declared node from the list */ + if (prev) + prev->next = cur->next; + else + g_declared_list = cur->next; + + ecpg_log("ecpg_release_declared_statement: declared name %s is released\n", cur->name); + + ecpg_free(cur->name); + ecpg_free(cur->connection_name); + ecpg_free(cur->cursor_name); + ecpg_free(cur); + + /* One connection can be used by multiple declared name, so no break here */ + } + else + prev = cur; + + if (prev) + cur = prev->next; + else + cur = g_declared_list; + } +} diff --git a/src/interfaces/ecpg/include/ecpgerrno.h b/src/interfaces/ecpg/include/ecpgerrno.h index c4bc526463..a37956aa1b 100644 --- a/src/interfaces/ecpg/include/ecpgerrno.h +++ b/src/interfaces/ecpg/include/ecpgerrno.h @@ -44,6 +44,7 @@ #define ECPG_UNKNOWN_DESCRIPTOR_ITEM -242 #define ECPG_VAR_NOT_NUMERIC -243 #define ECPG_VAR_NOT_CHAR -244 +#define ECPG_INVALID_CURSOR -245 /* finally the backend error messages, they start at 400 */ #define ECPG_PGSQL -400 diff --git a/src/interfaces/ecpg/include/ecpglib.h b/src/interfaces/ecpg/include/ecpglib.h index 8a601996d2..1edf272ada 100644 --- a/src/interfaces/ecpg/include/ecpglib.h +++ b/src/interfaces/ecpg/include/ecpglib.h @@ -55,6 +55,10 @@ bool ECPGdisconnect(int, const char *); bool ECPGprepare(int, const char *, const bool, const char *, const char *); bool ECPGdeallocate(int, int, const char *, const char *); bool ECPGdeallocate_all(int, int, const char *); +bool ECPGdeclare(int, const char *, const char *); +bool ECPGopen(const char*, const char*, const int, const int, const int, const char *, const bool, const int, const char *,...); +bool ECPGfetch(const char*, const int, const int, const int, const char *, const bool, const int, const char *,...); +bool ECPGclose(const char*, const int, const int, const int, const char *, const bool, const int, const char *,...); char *ECPGprepared_statement(const char *, const char *, int); PGconn *ECPGget_PGconn(const char *); PGTransactionStatusType ECPGtransactionStatus(const char *); diff --git a/src/interfaces/ecpg/include/ecpgtype.h b/src/interfaces/ecpg/include/ecpgtype.h index 38fb3b6eaf..9b1f3a8066 100644 --- a/src/interfaces/ecpg/include/ecpgtype.h +++ b/src/interfaces/ecpg/include/ecpgtype.h @@ -99,6 +99,13 @@ enum ECPG_statement_type ECPGst_prepnormal }; +enum ECPG_cursor_statement_type +{ + ECPGcst_declare, + ECPGcst_open, + ECPGcst_fetch, + ECPGcst_close +}; #ifdef __cplusplus } #endif diff --git a/src/interfaces/ecpg/preproc/ecpg.addons b/src/interfaces/ecpg/preproc/ecpg.addons index 86be5041e9..e8052819b0 100644 --- a/src/interfaces/ecpg/preproc/ecpg.addons +++ b/src/interfaces/ecpg/preproc/ecpg.addons @@ -1,22 +1,6 @@ /* src/interfaces/ecpg/preproc/ecpg.addons */ ECPG: stmtClosePortalStmt block - { - if (INFORMIX_MODE) - { - if (pg_strcasecmp($1+strlen("close "), "database") == 0) - { - if (connection) - mmerror(PARSE_ERROR, ET_ERROR, "AT option not allowed in CLOSE DATABASE statement"); - - fprintf(base_yyout, "{ ECPGdisconnect(__LINE__, \"CURRENT\");"); - whenever_action(2); - free($1); - break; - } - } - - output_statement($1, 0, ECPGst_normal); - } + { $$ = $1;} ECPG: stmtDeallocateStmt block { output_deallocate_prepare_statement($1); @@ -25,7 +9,11 @@ ECPG: stmtDeclareCursorStmt block { output_simple_statement($1, (strncmp($1, "ECPGset_var", strlen("ECPGset_var")) == 0) ? 4 : 0); } ECPG: stmtDiscardStmt block ECPG: stmtFetchStmt block - { output_statement($1, 1, ECPGst_normal); } + { + /* g_cursor_name is set in the fetch_args block and freed in the output_cursor_statement */ + output_cursor_statement(ECPGcst_fetch, g_cursor_name, NULL, $1, 1, ECPGst_normal); + g_cursor_name = NULL; + } ECPG: stmtDeleteStmt block ECPG: stmtInsertStmt block ECPG: stmtSelectStmt block @@ -63,6 +51,10 @@ ECPG: stmtViewStmt rule whenever_action(2); free($1); } + | ECPGDeclareStmt + { + output_declare_statement($1); + } | ECPGCursorStmt { output_simple_statement($1, (strncmp($1, "ECPGset_var", strlen("ECPGset_var")) == 0) ? 4 : 0); @@ -132,7 +124,14 @@ ECPG: stmtViewStmt rule if ((ptr = add_additional_variables($1, true)) != NULL) { connection = ptr->connection ? mm_strdup(ptr->connection) : NULL; - output_statement(mm_strdup(ptr->command), 0, ECPGst_normal); + if (ptr->prepared_name) + { + output_cursor_statement(ECPGcst_open, $1, mm_strdup(ptr->prepared_name), mm_strdup(ptr->command), 0, ECPGst_normal); + } + else + { + output_cursor_statement(ECPGcst_open, $1, NULL, mm_strdup(ptr->command), 0, ECPGst_normal); + } ptr->opened = true; } } @@ -204,6 +203,7 @@ ECPG: var_valueNumericOnly addon } ECPG: fetch_argscursor_name addon add_additional_variables($1, false); + g_cursor_name = mm_strdup($1); if ($1[0] == ':') { free($1); @@ -211,6 +211,7 @@ ECPG: fetch_argscursor_name addon } ECPG: fetch_argsfrom_incursor_name addon add_additional_variables($2, false); + g_cursor_name = mm_strdup($2); if ($2[0] == ':') { free($2); @@ -222,6 +223,7 @@ ECPG: fetch_argsFIRST_Popt_from_incursor_name addon ECPG: fetch_argsLAST_Popt_from_incursor_name addon ECPG: fetch_argsALLopt_from_incursor_name addon add_additional_variables($3, false); + g_cursor_name = mm_strdup($3); if ($3[0] == ':') { free($3); @@ -229,6 +231,7 @@ ECPG: fetch_argsALLopt_from_incursor_name addon } ECPG: fetch_argsSignedIconstopt_from_incursor_name addon add_additional_variables($3, false); + g_cursor_name = mm_strdup($3); if ($3[0] == ':') { free($3); @@ -242,6 +245,7 @@ ECPG: fetch_argsSignedIconstopt_from_incursor_name addon ECPG: fetch_argsFORWARDALLopt_from_incursor_name addon ECPG: fetch_argsBACKWARDALLopt_from_incursor_name addon add_additional_variables($4, false); + g_cursor_name = mm_strdup($4); if ($4[0] == ':') { free($4); @@ -252,6 +256,7 @@ ECPG: fetch_argsRELATIVE_PSignedIconstopt_from_incursor_name addon ECPG: fetch_argsFORWARDSignedIconstopt_from_incursor_name addon ECPG: fetch_argsBACKWARDSignedIconstopt_from_incursor_name addon add_additional_variables($4, false); + g_cursor_name = mm_strdup($4); if ($4[0] == ':') { free($4); @@ -304,6 +309,7 @@ ECPG: DeclareCursorStmtDECLAREcursor_namecursor_optionsCURSORopt_holdFORSelectSt } this = (struct cursor *) mm_alloc(sizeof(struct cursor)); + memset(this, 0 ,sizeof(struct cursor)); this->next = cur; this->name = $2; @@ -331,8 +337,31 @@ ECPG: DeclareCursorStmtDECLAREcursor_namecursor_optionsCURSORopt_holdFORSelectSt } ECPG: ClosePortalStmtCLOSEcursor_name block { + char *stmt = NULL; + char *cursor_name = NULL; char *cursor_marker = $2[0] == ':' ? mm_strdup("$0") : $2; - $$ = cat2_str(mm_strdup("close"), cursor_marker); + + cursor_name = mm_strdup($2); + + stmt = cat2_str(mm_strdup("close"), cursor_marker); + + if (INFORMIX_MODE) + { + if (pg_strcasecmp(stmt+strlen("close "), "database") == 0) + { + if (connection) + mmerror(PARSE_ERROR, ET_ERROR, "AT option not allowed in CLOSE DATABASE statement"); + + fprintf(base_yyout, "{ ECPGdisconnect(__LINE__, \"CURRENT\");"); + whenever_action(2); + free(stmt); + break; + } + } + + output_cursor_statement(ECPGcst_close, cursor_name, NULL, stmt, 0, ECPGst_normal); + + $$ = EMPTY; } ECPG: opt_hold block { @@ -411,48 +440,56 @@ ECPG: FetchStmtMOVEfetch_args rule { char *cursor_marker = $3[0] == ':' ? mm_strdup("$0") : $3; add_additional_variables($3, false); + g_cursor_name = mm_strdup($3); $$ = cat_str(2, mm_strdup("fetch forward"), cursor_marker); } | FETCH FORWARD from_in cursor_name opt_ecpg_fetch_into { char *cursor_marker = $4[0] == ':' ? mm_strdup("$0") : $4; add_additional_variables($4, false); + g_cursor_name = mm_strdup($4); $$ = cat_str(2, mm_strdup("fetch forward from"), cursor_marker); } | FETCH BACKWARD cursor_name opt_ecpg_fetch_into { char *cursor_marker = $3[0] == ':' ? mm_strdup("$0") : $3; add_additional_variables($3, false); + g_cursor_name = mm_strdup($3); $$ = cat_str(2, mm_strdup("fetch backward"), cursor_marker); } | FETCH BACKWARD from_in cursor_name opt_ecpg_fetch_into { char *cursor_marker = $4[0] == ':' ? mm_strdup("$0") : $4; add_additional_variables($4, false); + g_cursor_name = mm_strdup($4); $$ = cat_str(2, mm_strdup("fetch backward from"), cursor_marker); } | MOVE FORWARD cursor_name { char *cursor_marker = $3[0] == ':' ? mm_strdup("$0") : $3; add_additional_variables($3, false); + g_cursor_name = mm_strdup($3); $$ = cat_str(2, mm_strdup("move forward"), cursor_marker); } | MOVE FORWARD from_in cursor_name { char *cursor_marker = $4[0] == ':' ? mm_strdup("$0") : $4; add_additional_variables($4, false); + g_cursor_name = mm_strdup($4); $$ = cat_str(2, mm_strdup("move forward from"), cursor_marker); } | MOVE BACKWARD cursor_name { char *cursor_marker = $3[0] == ':' ? mm_strdup("$0") : $3; add_additional_variables($3, false); + g_cursor_name = mm_strdup($3); $$ = cat_str(2, mm_strdup("move backward"), cursor_marker); } | MOVE BACKWARD from_in cursor_name { char *cursor_marker = $4[0] == ':' ? mm_strdup("$0") : $4; add_additional_variables($4, false); + g_cursor_name = mm_strdup($4); $$ = cat_str(2, mm_strdup("move backward from"), cursor_marker); } ECPG: limit_clauseLIMITselect_limit_value','select_offset_value block diff --git a/src/interfaces/ecpg/preproc/ecpg.c b/src/interfaces/ecpg/preproc/ecpg.c index 4e4528b0aa..a6a43f5a3f 100644 --- a/src/interfaces/ecpg/preproc/ecpg.c +++ b/src/interfaces/ecpg/preproc/ecpg.c @@ -28,6 +28,7 @@ struct _include_path *include_paths = NULL; struct cursor *cur = NULL; struct typedefs *types = NULL; struct _defines *defines = NULL; +struct declared_name_st *g_declared_list = NULL; static void help(const char *progname) @@ -111,6 +112,48 @@ add_preprocessor_define(char *define) defines->next = pd; } +static void +free_argument(struct arguments *arg) +{ + if (arg == NULL) + return; + + free_argument(arg->next); + + /* + * Don't free variables in it because the original codes don't free it either + * variables are static structures instead of allocating + */ + free(arg); +} + +static void +free_cursor(struct cursor *c) +{ + if (c == NULL) + return; + + free_cursor(c->next); + free_argument(c->argsinsert); + free_argument(c->argsresult); + + free(c->name); + free(c->function); + free(c->command); + free(c->prepared_name); + free(c); +} + +static void +free_declared_stmt(struct declared_name_st *st) +{ + if (st == NULL) + return; + + free_declared_stmt(st->next); + free(st); +} + #define ECPG_GETOPT_LONG_REGRESSION 1 int main(int argc, char *const argv[]) @@ -348,29 +391,18 @@ main(int argc, char *const argv[]) struct typedefs *typeptr; /* remove old cursor definitions if any are still there */ - for (ptr = cur; ptr != NULL;) + if (cur) { - struct cursor *this = ptr; - struct arguments *l1, - *l2; - - free(ptr->command); - free(ptr->connection); - free(ptr->name); - for (l1 = ptr->argsinsert; l1; l1 = l2) - { - l2 = l1->next; - free(l1); - } - for (l1 = ptr->argsresult; l1; l1 = l2) - { - l2 = l1->next; - free(l1); - } - ptr = ptr->next; - free(this); + free_cursor(cur); + cur = NULL; + } + + /* remove old declared statements if any are still there */ + if (g_declared_list) + { + free_declared_stmt(g_declared_list); + g_declared_list = NULL; } - cur = NULL; /* remove non-pertinent old defines as well */ while (defines && !defines->pertinent) @@ -487,6 +519,18 @@ main(int argc, char *const argv[]) free(input_filename); } + + if(g_declared_list) + { + free_declared_stmt(g_declared_list); + g_declared_list = NULL; + } + + if(cur) + { + free_cursor(cur); + cur = NULL; + } } return ret_value; } diff --git a/src/interfaces/ecpg/preproc/ecpg.header b/src/interfaces/ecpg/preproc/ecpg.header index 00143a7934..a6f870dcda 100644 --- a/src/interfaces/ecpg/preproc/ecpg.header +++ b/src/interfaces/ecpg/preproc/ecpg.header @@ -38,6 +38,7 @@ char *current_function; int ecpg_internal_var = 0; char *connection = NULL; char *input_filename = NULL; +char *g_cursor_name = NULL; static int FoundInto = 0; static int initializer = 0; diff --git a/src/interfaces/ecpg/preproc/ecpg.trailer b/src/interfaces/ecpg/preproc/ecpg.trailer index 60e1f53e9d..6755d4a0d2 100644 --- a/src/interfaces/ecpg/preproc/ecpg.trailer +++ b/src/interfaces/ecpg/preproc/ecpg.trailer @@ -283,6 +283,38 @@ prepared_name: name | char_variable { $$ = $1; } ; +/* + * Declare Statement + */ +ECPGDeclareStmt: DECLARE prepared_name STATEMENT + { + struct declared_name_st *ptr = NULL; + + /* Check whether the declared name has been defined or not */ + for (ptr = g_declared_list; ptr != NULL; ptr = ptr->next) + { + if (strcmp($2, ptr->name) == 0) + { + /* re-definition is a bug */ + mmerror(PARSE_ERROR, ET_ERROR, "declared name %s is already defined", ptr->name); + } + } + + /* Add a new declared name into the g_declared_list */ + ptr = NULL; + ptr = (struct declared_name_st *) mm_alloc(sizeof(struct declared_name_st)); + if (ptr) + { + /* initial definition */ + ptr->name = $2; + ptr->next = g_declared_list; + g_declared_list = ptr; + } + + $$ = mm_strdup($2); + } +; + /* * Declare a prepared cursor. The syntax is different from the standard * declare statement, so we create a new rule. @@ -309,6 +341,7 @@ ECPGCursorStmt: DECLARE cursor_name cursor_options CURSOR opt_hold FOR prepared } this = (struct cursor *) mm_alloc(sizeof(struct cursor)); + memset(this, 0 ,sizeof(struct cursor)); /* initial definition */ this->next = cur; @@ -318,6 +351,7 @@ ECPGCursorStmt: DECLARE cursor_name cursor_options CURSOR opt_hold FOR prepared this->command = cat_str(6, mm_strdup("declare"), cursor_marker, $3, mm_strdup("cursor"), $5, mm_strdup("for $1")); this->argsresult = NULL; this->argsresult_oos = NULL; + this->prepared_name = $7; thisquery->type = &ecpg_query; thisquery->brace_level = 0; diff --git a/src/interfaces/ecpg/preproc/ecpg.type b/src/interfaces/ecpg/preproc/ecpg.type index 9497b91b9d..519b737dde 100644 --- a/src/interfaces/ecpg/preproc/ecpg.type +++ b/src/interfaces/ecpg/preproc/ecpg.type @@ -9,6 +9,7 @@ %type ECPGDeallocateDescr %type ECPGDeclaration %type ECPGDeclare +%type ECPGDeclareStmt %type ECPGDescribe %type ECPGDisconnect %type ECPGExecuteImmediateStmt diff --git a/src/interfaces/ecpg/preproc/output.c b/src/interfaces/ecpg/preproc/output.c index f778bbe35f..6b46ae6cca 100644 --- a/src/interfaces/ecpg/preproc/output.c +++ b/src/interfaces/ecpg/preproc/output.c @@ -5,6 +5,7 @@ #include "preproc_extern.h" static void output_escaped_str(char *cmd, bool quoted); +static void output_cursor_name(char *str); void output_line_number(void) @@ -203,7 +204,16 @@ static void output_escaped_str(char *str, bool quoted) { int i = 0; - int len = strlen(str); + int len = 0; + + if (str == NULL) + { + fputs("NULL", base_yyout); + + return; + } + + len = strlen(str); if (quoted && str[0] == '"' && str[len - 1] == '"') /* do not escape quotes * at beginning and end @@ -252,3 +262,148 @@ output_escaped_str(char *str, bool quoted) if (quoted && str[0] == '"' && str[len] == '"') fputs("\"", base_yyout); } + +/* + * This is a tool function used by the output_cursor_statement function to print + * cursor name after the string such as "ECPGopen(","ECPGfetch(","ECPGclose(". + * This function filters escaped sequences such as \t, \n, \r to print cursor name cleanly + */ +static void +output_cursor_name(char *str) +{ + int i = 0; + int len = 0; + + if (str == NULL) + { + fputs("NULL", base_yyout); + + return; + } + + len = strlen(str); + fputs("\"", base_yyout); + if (str[0] == '\"' && str[len - 1] == '\"') + { + i = 1; + len--; + fputs("\\\"", base_yyout); + + /* output this char by char as we have to filter " and \n */ + for (; i < len; i++) + { + if (str[i] == '"') + fputs("\\\"", base_yyout); + else if (str[i] == '\n') + fputs("\\\n", base_yyout); + else if (str[i] == '\\') + { + int j = i; + + /* + * check whether this is a continuation line if it is, do not + * output anything because newlines are escaped anyway + */ + + /* accept blanks after the '\' as some other compilers do too */ + do + { + j++; + } while (str[j] == ' ' || str[j] == '\t'); + + if ((str[j] != '\n') && (str[j] != '\r' || str[j + 1] != '\n')) /* not followed by a + * newline */ + fputs("\\\\",base_yyout); + } + else if (str[i] == '\r' && str[i + 1] == '\n') + { + fputs("\\\r\n", base_yyout); + i++; + } + else + fputc(str[i], base_yyout); + } + + fputs("\\\"", base_yyout); + } + else + fputs(str, base_yyout); + + fputs("\"", base_yyout); +} + +/* + * Transform the EXEC SQL DECLARE STATEMENT into ECPGdeclare function + */ +void +output_declare_statement(char *name) +{ + /* connection is set in "at:" token in ecpg.trailer file */ + fprintf(base_yyout, "{ ECPGdeclare(__LINE__, %s, ", connection ? connection : "NULL"); + output_escaped_str(name, true); + fputs(");", base_yyout); + + whenever_action(2); + free(name); + if (connection != NULL) + free(connection); +} + +/* + * Transform the EXEC SQL CURSOR STATEMENT such as OPEN/FETCH/CLOSE cursor into + * ECPGopen/ECPGfetch/ECPGclose function + */ +void +output_cursor_statement(int cursor_stmt, char *cursor_name, char *prepared_name, char *stmt, int whenever_mode, enum ECPG_statement_type st) +{ + switch(cursor_stmt) + { + case ECPGcst_open: + fprintf(base_yyout, "{ ECPGopen("); + output_cursor_name(cursor_name); + fprintf(base_yyout, ", "); + output_escaped_str(prepared_name, true); + fprintf(base_yyout, ", __LINE__, %d, %d, %s, %d, ", + compat, force_indicator, connection ? connection : "NULL", questionmarks); + break; + case ECPGcst_fetch: + fprintf(base_yyout, "{ ECPGfetch("); + output_cursor_name(cursor_name); + fprintf(base_yyout, ", __LINE__, %d, %d, %s, %d, ", + compat, force_indicator, connection ? connection : "NULL", questionmarks); + break; + case ECPGcst_close: + fprintf(base_yyout, "{ ECPGclose("); + output_cursor_name(cursor_name); + fprintf(base_yyout, ", __LINE__, %d, %d, %s, %d, ", + compat, force_indicator, connection ? connection : "NULL", questionmarks); + break; + } + + if (st == ECPGst_execute || st == ECPGst_exec_immediate) + fprintf(base_yyout, "%s, %s, ", ecpg_statement_type_name[st], stmt); + else + { + if (st == ECPGst_prepnormal && auto_prepare) + fputs("ECPGst_prepnormal, \"", base_yyout); + else + fputs("ECPGst_normal, \"", base_yyout); + + output_escaped_str(stmt, false); + fputs("\", ", base_yyout); + } + + /* dump variables to C file */ + dump_variables(argsinsert, 1); + fputs("ECPGt_EOIT, ", base_yyout); + dump_variables(argsresult, 1); + fputs("ECPGt_EORT);", base_yyout); + reset_variables(); + + whenever_action(whenever_mode | 2); + free(cursor_name); + free(prepared_name); + free(stmt); + if (connection != NULL) + free(connection); +} diff --git a/src/interfaces/ecpg/preproc/preproc_extern.h b/src/interfaces/ecpg/preproc/preproc_extern.h index 3cdbdabaa3..8ccfdf0d1f 100644 --- a/src/interfaces/ecpg/preproc/preproc_extern.h +++ b/src/interfaces/ecpg/preproc/preproc_extern.h @@ -49,6 +49,7 @@ extern struct _include_path *include_paths; extern struct cursor *cur; extern struct typedefs *types; extern struct _defines *defines; +extern struct declared_name_st *g_declared_list; extern struct ECPGtype ecpg_no_indicator; extern struct variable no_indicator; extern struct arguments *argsinsert; @@ -70,6 +71,8 @@ extern void output_statement(char *, int, enum ECPG_statement_type); extern void output_prepare_statement(char *, char *); extern void output_deallocate_prepare_statement(char *); extern void output_simple_statement(char *, int); +extern void output_declare_statement(char *); +extern void output_cursor_statement(int , char *, char *, char *, int , enum ECPG_statement_type); extern char *hashline_number(void); extern int base_yyparse(void); extern int base_yylex(void); diff --git a/src/interfaces/ecpg/preproc/type.h b/src/interfaces/ecpg/preproc/type.h index fc70d7d218..94377ff806 100644 --- a/src/interfaces/ecpg/preproc/type.h +++ b/src/interfaces/ecpg/preproc/type.h @@ -128,6 +128,7 @@ struct cursor char *command; char *connection; bool opened; + char *prepared_name; struct arguments *argsinsert; struct arguments *argsinsert_oos; struct arguments *argsresult; @@ -135,6 +136,13 @@ struct cursor struct cursor *next; }; +/* structure to store declared name */ +struct declared_name_st +{ + char *name; /* declared name */ + struct declared_name_st *next; +}; + struct typedefs { char *name; diff --git a/src/interfaces/ecpg/test/ecpg_schedule b/src/interfaces/ecpg/test/ecpg_schedule index 991b8cb5e2..81afc5d974 100644 --- a/src/interfaces/ecpg/test/ecpg_schedule +++ b/src/interfaces/ecpg/test/ecpg_schedule @@ -50,6 +50,7 @@ test: sql/quote test: sql/show test: sql/insupd test: sql/parser +test: sql/declare test: thread/thread test: thread/thread_implicit test: thread/prep diff --git a/src/interfaces/ecpg/test/expected/compat_informix-sqlda.c b/src/interfaces/ecpg/test/expected/compat_informix-sqlda.c index 7e19319d27..fee16595ec 100644 --- a/src/interfaces/ecpg/test/expected/compat_informix-sqlda.c +++ b/src/interfaces/ecpg/test/expected/compat_informix-sqlda.c @@ -241,7 +241,7 @@ if (sqlca.sqlcode < 0) exit (1);} strcpy(msg, "open"); - { ECPGdo(__LINE__, 1, 1, NULL, 0, ECPGst_normal, "declare mycur1 cursor for $1", + { ECPGopen("mycur1", "st_id1", __LINE__, 1, 1, NULL, 0, ECPGst_normal, "declare mycur1 cursor for $1", ECPGt_char_variable,(ECPGprepared_statement(NULL, "st_id1", __LINE__)),(long)1,(long)1,(1)*sizeof(char), ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT); #line 101 "sqlda.pgc" @@ -258,7 +258,7 @@ if (sqlca.sqlcode < 0) exit (1);} while (1) { strcpy(msg, "fetch"); - { ECPGdo(__LINE__, 1, 1, NULL, 0, ECPGst_normal, "fetch 1 from mycur1", ECPGt_EOIT, + { ECPGfetch("mycur1", __LINE__, 1, 1, NULL, 0, ECPGst_normal, "fetch 1 from mycur1", ECPGt_EOIT, ECPGt_sqlda, &outp_sqlda, 0L, 0L, 0L, ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT); #line 109 "sqlda.pgc" @@ -279,7 +279,7 @@ if (sqlca.sqlcode < 0) exit (1);} strcpy(msg, "close"); - { ECPGdo(__LINE__, 1, 1, NULL, 0, ECPGst_normal, "close mycur1", ECPGt_EOIT, ECPGt_EORT); + { ECPGclose("mycur1", __LINE__, 1, 1, NULL, 0, ECPGst_normal, "close mycur1", ECPGt_EOIT, ECPGt_EORT); #line 118 "sqlda.pgc" if (sqlca.sqlcode < 0) exit (1);} @@ -316,7 +316,7 @@ if (sqlca.sqlcode < 0) exit (1);} strcpy(msg, "open"); - { ECPGdo(__LINE__, 1, 1, NULL, 0, ECPGst_normal, "declare mycur2 cursor for $1", + { ECPGopen("mycur2", "st_id2", __LINE__, 1, 1, NULL, 0, ECPGst_normal, "declare mycur2 cursor for $1", ECPGt_char_variable,(ECPGprepared_statement(NULL, "st_id2", __LINE__)),(long)1,(long)1,(1)*sizeof(char), ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT); #line 138 "sqlda.pgc" @@ -333,7 +333,7 @@ if (sqlca.sqlcode < 0) exit (1);} while (1) { strcpy(msg, "fetch"); - { ECPGdo(__LINE__, 1, 1, NULL, 0, ECPGst_normal, "fetch from mycur2", ECPGt_EOIT, + { ECPGfetch("mycur2", __LINE__, 1, 1, NULL, 0, ECPGst_normal, "fetch from mycur2", ECPGt_EOIT, ECPGt_sqlda, &outp_sqlda, 0L, 0L, 0L, ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT); #line 146 "sqlda.pgc" @@ -354,7 +354,7 @@ if (sqlca.sqlcode < 0) exit (1);} strcpy(msg, "close"); - { ECPGdo(__LINE__, 1, 1, NULL, 0, ECPGst_normal, "close mycur2", ECPGt_EOIT, ECPGt_EORT); + { ECPGclose("mycur2", __LINE__, 1, 1, NULL, 0, ECPGst_normal, "close mycur2", ECPGt_EOIT, ECPGt_EORT); #line 155 "sqlda.pgc" if (sqlca.sqlcode < 0) exit (1);} diff --git a/src/interfaces/ecpg/test/expected/compat_informix-test_informix.c b/src/interfaces/ecpg/test/expected/compat_informix-test_informix.c index cc6504992d..368626c393 100644 --- a/src/interfaces/ecpg/test/expected/compat_informix-test_informix.c +++ b/src/interfaces/ecpg/test/expected/compat_informix-test_informix.c @@ -163,7 +163,7 @@ if (sqlca.sqlcode < 0) dosqlprint ( ); for (loopcount = 0; loopcount < 100; loopcount++) { - { ECPGdo(__LINE__, 1, 1, NULL, 0, ECPGst_normal, "fetch forward c", ECPGt_EOIT, + { ECPGfetch("c", __LINE__, 1, 1, NULL, 0, ECPGst_normal, "fetch forward c", ECPGt_EOIT, ECPGt_int,&(i),(long)1,(long)1,sizeof(int), ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_decimal,&(j),(long)1,(long)1,sizeof(decimal), @@ -248,7 +248,7 @@ if (sqlca.sqlcode < 0) dosqlprint ( );} static void openit(void) { - { ECPGdo(__LINE__, 1, 1, NULL, 0, ECPGst_normal, "declare c cursor for select * from test where i <= $1 ", + { ECPGopen("c", NULL, __LINE__, 1, 1, NULL, 0, ECPGst_normal, "declare c cursor for select * from test where i <= $1 ", ECPGt_int,&(*( int *)(ECPGget_var( 0))),(long)1,(long)1,sizeof(int), ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT); #line 94 "test_informix.pgc" diff --git a/src/interfaces/ecpg/test/expected/compat_oracle-char_array.c b/src/interfaces/ecpg/test/expected/compat_oracle-char_array.c index 04d4e1969e..d0638f056d 100644 --- a/src/interfaces/ecpg/test/expected/compat_oracle-char_array.c +++ b/src/interfaces/ecpg/test/expected/compat_oracle-char_array.c @@ -141,7 +141,7 @@ if (sqlca.sqlcode < 0) exit (1);} /* declare C cursor for select strval , strval from strdbase */ #line 41 "char_array.pgc" - { ECPGdo(__LINE__, 3, 1, NULL, 0, ECPGst_normal, "declare C cursor for select strval , strval from strdbase", ECPGt_EOIT, ECPGt_EORT); + { ECPGopen("C", NULL, __LINE__, 3, 1, NULL, 0, ECPGst_normal, "declare C cursor for select strval , strval from strdbase", ECPGt_EOIT, ECPGt_EORT); #line 42 "char_array.pgc" if (sqlca.sqlwarn[0] == 'W') warn ( ); @@ -159,7 +159,7 @@ if (sqlca.sqlcode < 0) exit (1);} for (loopcount = 0; loopcount < 100; loopcount++) { strncpy(shortstr, ppppp, sizeof shortstr); memset(bigstr, 0, sizeof bigstr); - { ECPGdo(__LINE__, 3, 1, NULL, 0, ECPGst_normal, "fetch C", ECPGt_EOIT, + { ECPGfetch("C", __LINE__, 3, 1, NULL, 0, ECPGst_normal, "fetch C", ECPGt_EOIT, ECPGt_char,(bigstr),(long)11,(long)1,(11)*sizeof(char), ECPGt_short,&(bigstr_ind),(long)1,(long)1,sizeof(short), ECPGt_char,(shortstr),(long)5,(long)1,(5)*sizeof(char), @@ -178,7 +178,7 @@ if (sqlca.sqlcode < 0) exit (1);} printf("\"%s\": \"%s\" %d\n", bigstr, shortstr, shstr_ind); } - { ECPGdo(__LINE__, 3, 1, NULL, 0, ECPGst_normal, "close C", ECPGt_EOIT, ECPGt_EORT); + { ECPGclose("C", __LINE__, 3, 1, NULL, 0, ECPGst_normal, "close C", ECPGt_EOIT, ECPGt_EORT); #line 54 "char_array.pgc" if (sqlca.sqlwarn[0] == 'W') warn ( ); diff --git a/src/interfaces/ecpg/test/expected/pgtypeslib-nan_test.c b/src/interfaces/ecpg/test/expected/pgtypeslib-nan_test.c index b7e8054795..1b81b16361 100644 --- a/src/interfaces/ecpg/test/expected/pgtypeslib-nan_test.c +++ b/src/interfaces/ecpg/test/expected/pgtypeslib-nan_test.c @@ -84,7 +84,7 @@ if (sqlca.sqlcode < 0) sqlprint ( );} /* declare cur cursor for select id , d , d from nantest1 */ #line 35 "nan_test.pgc" - { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare cur cursor for select id , d , d from nantest1", ECPGt_EOIT, ECPGt_EORT); + { ECPGopen("cur", NULL, __LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare cur cursor for select id , d , d from nantest1", ECPGt_EOIT, ECPGt_EORT); #line 36 "nan_test.pgc" if (sqlca.sqlcode < 0) sqlprint ( );} @@ -92,7 +92,7 @@ if (sqlca.sqlcode < 0) sqlprint ( );} for (loopcount = 0; loopcount < 100; loopcount++) { - { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch from cur", ECPGt_EOIT, + { ECPGfetch("cur", __LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch from cur", ECPGt_EOIT, ECPGt_int,&(id),(long)1,(long)1,sizeof(int), ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_double,&(d),(long)1,(long)1,sizeof(double), @@ -132,14 +132,14 @@ if (sqlca.sqlcode < 0) sqlprint ( );} #line 48 "nan_test.pgc" } - { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "close cur", ECPGt_EOIT, ECPGt_EORT); + { ECPGclose("cur", __LINE__, 0, 1, NULL, 0, ECPGst_normal, "close cur", ECPGt_EOIT, ECPGt_EORT); #line 50 "nan_test.pgc" if (sqlca.sqlcode < 0) sqlprint ( );} #line 50 "nan_test.pgc" - { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare cur cursor for select id , d , d from nantest1", ECPGt_EOIT, ECPGt_EORT); + { ECPGopen("cur", NULL, __LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare cur cursor for select id , d , d from nantest1", ECPGt_EOIT, ECPGt_EORT); #line 52 "nan_test.pgc" if (sqlca.sqlcode < 0) sqlprint ( );} @@ -147,7 +147,7 @@ if (sqlca.sqlcode < 0) sqlprint ( );} for (loopcount = 0; loopcount < 100; loopcount++) { - { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch from cur", ECPGt_EOIT, + { ECPGfetch("cur", __LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch from cur", ECPGt_EOIT, ECPGt_int,&(id),(long)1,(long)1,sizeof(int), ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_double,&(d),(long)1,(long)1,sizeof(double), @@ -166,7 +166,7 @@ if (sqlca.sqlcode < 0) sqlprint ( );} if (isnan(d)) printf("%d NaN '%s'\n", id, val); } - { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "close cur", ECPGt_EOIT, ECPGt_EORT); + { ECPGclose("cur", __LINE__, 0, 1, NULL, 0, ECPGst_normal, "close cur", ECPGt_EOIT, ECPGt_EORT); #line 63 "nan_test.pgc" if (sqlca.sqlcode < 0) sqlprint ( );} @@ -223,7 +223,7 @@ if (sqlca.sqlcode < 0) sqlprint ( );} /* declare cur1 cursor for select id , d , d from nantest2 */ #line 77 "nan_test.pgc" - { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare cur1 cursor for select id , d , d from nantest2", ECPGt_EOIT, ECPGt_EORT); + { ECPGopen("cur1", NULL, __LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare cur1 cursor for select id , d , d from nantest2", ECPGt_EOIT, ECPGt_EORT); #line 78 "nan_test.pgc" if (sqlca.sqlcode < 0) sqlprint ( );} @@ -231,7 +231,7 @@ if (sqlca.sqlcode < 0) sqlprint ( );} for (loopcount = 0; loopcount < 100; loopcount++) { - { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch from cur1", ECPGt_EOIT, + { ECPGfetch("cur1", __LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch from cur1", ECPGt_EOIT, ECPGt_int,&(id),(long)1,(long)1,sizeof(int), ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_numeric,&(num),(long)1,(long)0,sizeof(numeric), @@ -247,7 +247,7 @@ if (sqlca.sqlcode < 0) sqlprint ( );} break; printf("%d %s '%s'\n", id, (num->sign == NUMERIC_NAN ? "NaN" : "not NaN"), val); } - { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "close cur1", ECPGt_EOIT, ECPGt_EORT); + { ECPGclose("cur1", __LINE__, 0, 1, NULL, 0, ECPGst_normal, "close cur1", ECPGt_EOIT, ECPGt_EORT); #line 86 "nan_test.pgc" if (sqlca.sqlcode < 0) sqlprint ( );} diff --git a/src/interfaces/ecpg/test/expected/preproc-autoprep.c b/src/interfaces/ecpg/test/expected/preproc-autoprep.c index 8ed5a2ca2c..9d8711c4b6 100644 --- a/src/interfaces/ecpg/test/expected/preproc-autoprep.c +++ b/src/interfaces/ecpg/test/expected/preproc-autoprep.c @@ -133,7 +133,7 @@ if (sqlca.sqlcode < 0) sqlprint();} #line 35 "autoprep.pgc" - { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare C cursor for select Item1 from T", ECPGt_EOIT, ECPGt_EORT); + { ECPGopen("C", NULL, __LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare C cursor for select Item1 from T", ECPGt_EOIT, ECPGt_EORT); #line 37 "autoprep.pgc" if (sqlca.sqlwarn[0] == 'W') sqlprint(); @@ -143,7 +143,7 @@ if (sqlca.sqlcode < 0) sqlprint();} #line 37 "autoprep.pgc" - { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch 1 in C", ECPGt_EOIT, + { ECPGfetch("C", __LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch 1 in C", ECPGt_EOIT, ECPGt_int,&(i),(long)1,(long)1,sizeof(int), ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT); #line 39 "autoprep.pgc" @@ -156,7 +156,7 @@ if (sqlca.sqlcode < 0) sqlprint();} printf("i = %d\n", i); - { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "close C", ECPGt_EOIT, ECPGt_EORT); + { ECPGclose("C", __LINE__, 0, 1, NULL, 0, ECPGst_normal, "close C", ECPGt_EOIT, ECPGt_EORT); #line 42 "autoprep.pgc" if (sqlca.sqlwarn[0] == 'W') sqlprint(); @@ -180,7 +180,7 @@ if (sqlca.sqlcode < 0) sqlprint();} #line 46 "autoprep.pgc" - { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare cur1 cursor for $1", + { ECPGopen("cur1", "stmt1", __LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare cur1 cursor for $1", ECPGt_char_variable,(ECPGprepared_statement(NULL, "stmt1", __LINE__)),(long)1,(long)1,(1)*sizeof(char), ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT); #line 48 "autoprep.pgc" @@ -199,7 +199,7 @@ if (sqlca.sqlcode < 0) sqlprint();} i = 0; while (i < 100) { - { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch cur1", ECPGt_EOIT, + { ECPGfetch("cur1", __LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch cur1", ECPGt_EOIT, ECPGt_int,&(item1),(long)1,(long)1,sizeof(int), ECPGt_int,&(ind1),(long)1,(long)1,sizeof(int), ECPGt_EORT); #line 55 "autoprep.pgc" @@ -217,7 +217,7 @@ if (sqlca.sqlcode < 0) sqlprint();} i++; } - { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "close cur1", ECPGt_EOIT, ECPGt_EORT); + { ECPGclose("cur1", __LINE__, 0, 1, NULL, 0, ECPGst_normal, "close cur1", ECPGt_EOIT, ECPGt_EORT); #line 60 "autoprep.pgc" if (sqlca.sqlwarn[0] == 'W') sqlprint(); diff --git a/src/interfaces/ecpg/test/expected/preproc-cursor.c b/src/interfaces/ecpg/test/expected/preproc-cursor.c index a4e7b12c17..54c9960ce6 100644 --- a/src/interfaces/ecpg/test/expected/preproc-cursor.c +++ b/src/interfaces/ecpg/test/expected/preproc-cursor.c @@ -192,7 +192,7 @@ if (sqlca.sqlcode < 0) exit (1); strcpy(msg, "open"); - { ECPGdo(__LINE__, 0, 1, "test1", 0, ECPGst_normal, "declare $0 cursor for select id , t from t1", + { ECPGopen(":curname1", NULL, __LINE__, 0, 1, "test1", 0, ECPGst_normal, "declare $0 cursor for select id , t from t1", ECPGt_char,&(curname1),(long)0,(long)1,(1)*sizeof(char), ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT); #line 67 "cursor.pgc" @@ -202,7 +202,7 @@ if (sqlca.sqlcode < 0) exit (1);} strcpy(msg, "fetch from"); - { ECPGdo(__LINE__, 0, 1, "test1", 0, ECPGst_normal, "fetch forward from $0", + { ECPGfetch(":curname1", __LINE__, 0, 1, "test1", 0, ECPGst_normal, "fetch forward from $0", ECPGt_char,&(curname1),(long)0,(long)1,(1)*sizeof(char), ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_int,&(id),(long)1,(long)1,sizeof(int), @@ -217,7 +217,7 @@ if (sqlca.sqlcode < 0) exit (1);} printf("%d %s\n", id, t); strcpy(msg, "fetch"); - { ECPGdo(__LINE__, 0, 1, "test1", 0, ECPGst_normal, "fetch forward $0", + { ECPGfetch(":curname1", __LINE__, 0, 1, "test1", 0, ECPGst_normal, "fetch forward $0", ECPGt_char,&(curname1),(long)0,(long)1,(1)*sizeof(char), ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_int,&(id),(long)1,(long)1,sizeof(int), @@ -232,7 +232,7 @@ if (sqlca.sqlcode < 0) exit (1);} printf("%d %s\n", id, t); strcpy(msg, "fetch 1 from"); - { ECPGdo(__LINE__, 0, 1, "test1", 0, ECPGst_normal, "fetch 1 from $0", + { ECPGfetch(":curname1", __LINE__, 0, 1, "test1", 0, ECPGst_normal, "fetch 1 from $0", ECPGt_char,&(curname1),(long)0,(long)1,(1)*sizeof(char), ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_int,&(id),(long)1,(long)1,sizeof(int), @@ -248,7 +248,7 @@ if (sqlca.sqlcode < 0) exit (1);} strcpy(msg, "fetch :count from"); count = 1; - { ECPGdo(__LINE__, 0, 1, "test1", 0, ECPGst_normal, "fetch $0 from $0", + { ECPGfetch(":curname1", __LINE__, 0, 1, "test1", 0, ECPGst_normal, "fetch $0 from $0", ECPGt_int,&(count),(long)1,(long)1,sizeof(int), ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_char,&(curname1),(long)0,(long)1,(1)*sizeof(char), @@ -265,7 +265,7 @@ if (sqlca.sqlcode < 0) exit (1);} printf("%d %s\n", id, t); strcpy(msg, "move in"); - { ECPGdo(__LINE__, 0, 1, "test1", 0, ECPGst_normal, "move absolute 0 in $0", + { ECPGfetch(":curname1", __LINE__, 0, 1, "test1", 0, ECPGst_normal, "move absolute 0 in $0", ECPGt_char,&(curname1),(long)0,(long)1,(1)*sizeof(char), ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT); #line 87 "cursor.pgc" @@ -275,7 +275,7 @@ if (sqlca.sqlcode < 0) exit (1);} strcpy(msg, "fetch 1"); - { ECPGdo(__LINE__, 0, 1, "test1", 0, ECPGst_normal, "fetch 1 $0", + { ECPGfetch(":curname1", __LINE__, 0, 1, "test1", 0, ECPGst_normal, "fetch 1 $0", ECPGt_char,&(curname1),(long)0,(long)1,(1)*sizeof(char), ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_int,&(id),(long)1,(long)1,sizeof(int), @@ -291,7 +291,7 @@ if (sqlca.sqlcode < 0) exit (1);} strcpy(msg, "fetch :count"); count = 1; - { ECPGdo(__LINE__, 0, 1, "test1", 0, ECPGst_normal, "fetch $0 $0", + { ECPGfetch(":curname1", __LINE__, 0, 1, "test1", 0, ECPGst_normal, "fetch $0 $0", ECPGt_int,&(count),(long)1,(long)1,sizeof(int), ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_char,&(curname1),(long)0,(long)1,(1)*sizeof(char), @@ -308,7 +308,7 @@ if (sqlca.sqlcode < 0) exit (1);} printf("%d %s\n", id, t); strcpy(msg, "close"); - { ECPGdo(__LINE__, 0, 1, "test1", 0, ECPGst_normal, "close $0", + { ECPGclose(":curname1", __LINE__, 0, 1, "test1", 0, ECPGst_normal, "close $0", ECPGt_char,&(curname1),(long)0,(long)1,(1)*sizeof(char), ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT); #line 99 "cursor.pgc" @@ -333,7 +333,7 @@ if (sqlca.sqlcode < 0) exit (1); strcpy(msg, "open"); - { ECPGdo(__LINE__, 0, 1, "test1", 0, ECPGst_normal, "declare $0 cursor for select id , t from t1", + { ECPGopen(":curname2", NULL, __LINE__, 0, 1, "test1", 0, ECPGst_normal, "declare $0 cursor for select id , t from t1", ECPGt_char,&(curname2),(long)0,(long)1,(1)*sizeof(char), ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_int,&(id),(long)1,(long)1,sizeof(int), @@ -347,7 +347,7 @@ if (sqlca.sqlcode < 0) exit (1);} strcpy(msg, "fetch from"); - { ECPGdo(__LINE__, 0, 1, "test1", 0, ECPGst_normal, "fetch from $0", + { ECPGfetch(":curname2", __LINE__, 0, 1, "test1", 0, ECPGst_normal, "fetch from $0", ECPGt_char,&(curname2),(long)0,(long)1,(1)*sizeof(char), ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_int,&(id),(long)1,(long)1,sizeof(int), @@ -362,7 +362,7 @@ if (sqlca.sqlcode < 0) exit (1);} printf("%d %s\n", id, t); strcpy(msg, "fetch"); - { ECPGdo(__LINE__, 0, 1, "test1", 0, ECPGst_normal, "fetch $0", + { ECPGfetch(":curname2", __LINE__, 0, 1, "test1", 0, ECPGst_normal, "fetch $0", ECPGt_char,&(curname2),(long)0,(long)1,(1)*sizeof(char), ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_int,&(id),(long)1,(long)1,sizeof(int), @@ -377,7 +377,7 @@ if (sqlca.sqlcode < 0) exit (1);} printf("%d %s\n", id, t); strcpy(msg, "fetch 1 from"); - { ECPGdo(__LINE__, 0, 1, "test1", 0, ECPGst_normal, "fetch 1 from $0", + { ECPGfetch(":curname2", __LINE__, 0, 1, "test1", 0, ECPGst_normal, "fetch 1 from $0", ECPGt_char,&(curname2),(long)0,(long)1,(1)*sizeof(char), ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_int,&(id),(long)1,(long)1,sizeof(int), @@ -393,7 +393,7 @@ if (sqlca.sqlcode < 0) exit (1);} strcpy(msg, "fetch :count from"); count = 1; - { ECPGdo(__LINE__, 0, 1, "test1", 0, ECPGst_normal, "fetch $0 from $0", + { ECPGfetch(":curname2", __LINE__, 0, 1, "test1", 0, ECPGst_normal, "fetch $0 from $0", ECPGt_int,&(count),(long)1,(long)1,sizeof(int), ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_char,&(curname2),(long)0,(long)1,(1)*sizeof(char), @@ -410,7 +410,7 @@ if (sqlca.sqlcode < 0) exit (1);} printf("%d %s\n", id, t); strcpy(msg, "move"); - { ECPGdo(__LINE__, 0, 1, "test1", 0, ECPGst_normal, "move absolute 0 $0", + { ECPGfetch(":curname2", __LINE__, 0, 1, "test1", 0, ECPGst_normal, "move absolute 0 $0", ECPGt_char,&(curname2),(long)0,(long)1,(1)*sizeof(char), ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_int,&(id),(long)1,(long)1,sizeof(int), @@ -424,7 +424,7 @@ if (sqlca.sqlcode < 0) exit (1);} strcpy(msg, "fetch 1"); - { ECPGdo(__LINE__, 0, 1, "test1", 0, ECPGst_normal, "fetch 1 $0", + { ECPGfetch(":curname2", __LINE__, 0, 1, "test1", 0, ECPGst_normal, "fetch 1 $0", ECPGt_char,&(curname2),(long)0,(long)1,(1)*sizeof(char), ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_int,&(id),(long)1,(long)1,sizeof(int), @@ -440,7 +440,7 @@ if (sqlca.sqlcode < 0) exit (1);} strcpy(msg, "fetch :count"); count = 1; - { ECPGdo(__LINE__, 0, 1, "test1", 0, ECPGst_normal, "fetch $0 $0", + { ECPGfetch(":curname2", __LINE__, 0, 1, "test1", 0, ECPGst_normal, "fetch $0 $0", ECPGt_int,&(count),(long)1,(long)1,sizeof(int), ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_char,&(curname2),(long)0,(long)1,(1)*sizeof(char), @@ -457,7 +457,7 @@ if (sqlca.sqlcode < 0) exit (1);} printf("%d %s\n", id, t); strcpy(msg, "close"); - { ECPGdo(__LINE__, 0, 1, "test1", 0, ECPGst_normal, "close $0", + { ECPGclose(":curname2", __LINE__, 0, 1, "test1", 0, ECPGst_normal, "close $0", ECPGt_char,&(curname2),(long)0,(long)1,(1)*sizeof(char), ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT); #line 140 "cursor.pgc" @@ -503,7 +503,7 @@ if (sqlca.sqlcode < 0) exit (1); strcpy(msg, "open"); - { ECPGdo(__LINE__, 0, 1, "test1", 0, ECPGst_normal, "declare $0 cursor for $1", + { ECPGopen(":curname3", "st_id1", __LINE__, 0, 1, "test1", 0, ECPGst_normal, "declare $0 cursor for $1", ECPGt_char,&(curname3),(long)0,(long)1,(1)*sizeof(char), ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_char_variable,(ECPGprepared_statement("test1", "st_id1", __LINE__)),(long)1,(long)1,(1)*sizeof(char), @@ -513,7 +513,7 @@ if (sqlca.sqlcode < 0) exit (1); if (sqlca.sqlcode < 0) exit (1);} #line 153 "cursor.pgc" - { ECPGdo(__LINE__, 0, 1, "test2", 0, ECPGst_normal, "declare $0 cursor for $1", + { ECPGopen(":curname5", "st_id1", __LINE__, 0, 1, "test2", 0, ECPGst_normal, "declare $0 cursor for $1", ECPGt_char,&(curname5),(long)0,(long)1,(1)*sizeof(char), ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_char_variable,(ECPGprepared_statement("test2", "st_id1", __LINE__)),(long)1,(long)1,(1)*sizeof(char), @@ -525,7 +525,7 @@ if (sqlca.sqlcode < 0) exit (1);} strcpy(msg, "fetch"); - { ECPGdo(__LINE__, 0, 1, "test2", 0, ECPGst_normal, "fetch $0", + { ECPGfetch(":curname5", __LINE__, 0, 1, "test2", 0, ECPGst_normal, "fetch $0", ECPGt_char,&(curname5),(long)0,(long)1,(1)*sizeof(char), ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_int,&(id),(long)1,(long)1,sizeof(int), @@ -540,7 +540,7 @@ if (sqlca.sqlcode < 0) exit (1);} printf("%d %s\n", id, t); strcpy(msg, "fetch from"); - { ECPGdo(__LINE__, 0, 1, "test1", 0, ECPGst_normal, "fetch from $0", + { ECPGfetch(":curname3", __LINE__, 0, 1, "test1", 0, ECPGst_normal, "fetch from $0", ECPGt_char,&(curname3),(long)0,(long)1,(1)*sizeof(char), ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_int,&(id),(long)1,(long)1,sizeof(int), @@ -555,7 +555,7 @@ if (sqlca.sqlcode < 0) exit (1);} printf("%d %s\n", id, t); strcpy(msg, "fetch 1 from"); - { ECPGdo(__LINE__, 0, 1, "test1", 0, ECPGst_normal, "fetch 1 from $0", + { ECPGfetch(":curname3", __LINE__, 0, 1, "test1", 0, ECPGst_normal, "fetch 1 from $0", ECPGt_char,&(curname3),(long)0,(long)1,(1)*sizeof(char), ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_int,&(id),(long)1,(long)1,sizeof(int), @@ -571,7 +571,7 @@ if (sqlca.sqlcode < 0) exit (1);} strcpy(msg, "fetch :count from"); count = 1; - { ECPGdo(__LINE__, 0, 1, "test1", 0, ECPGst_normal, "fetch $0 from $0", + { ECPGfetch(":curname3", __LINE__, 0, 1, "test1", 0, ECPGst_normal, "fetch $0 from $0", ECPGt_int,&(count),(long)1,(long)1,sizeof(int), ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_char,&(curname3),(long)0,(long)1,(1)*sizeof(char), @@ -588,7 +588,7 @@ if (sqlca.sqlcode < 0) exit (1);} printf("%d %s\n", id, t); strcpy(msg, "move"); - { ECPGdo(__LINE__, 0, 1, "test1", 0, ECPGst_normal, "move absolute 0 $0", + { ECPGfetch(":curname3", __LINE__, 0, 1, "test1", 0, ECPGst_normal, "move absolute 0 $0", ECPGt_char,&(curname3),(long)0,(long)1,(1)*sizeof(char), ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT); #line 174 "cursor.pgc" @@ -598,7 +598,7 @@ if (sqlca.sqlcode < 0) exit (1);} strcpy(msg, "fetch 1"); - { ECPGdo(__LINE__, 0, 1, "test1", 0, ECPGst_normal, "fetch 1 $0", + { ECPGfetch(":curname3", __LINE__, 0, 1, "test1", 0, ECPGst_normal, "fetch 1 $0", ECPGt_char,&(curname3),(long)0,(long)1,(1)*sizeof(char), ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_int,&(id),(long)1,(long)1,sizeof(int), @@ -614,7 +614,7 @@ if (sqlca.sqlcode < 0) exit (1);} strcpy(msg, "fetch :count"); count = 1; - { ECPGdo(__LINE__, 0, 1, "test1", 0, ECPGst_normal, "fetch $0 $0", + { ECPGfetch(":curname3", __LINE__, 0, 1, "test1", 0, ECPGst_normal, "fetch $0 $0", ECPGt_int,&(count),(long)1,(long)1,sizeof(int), ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_char,&(curname3),(long)0,(long)1,(1)*sizeof(char), @@ -631,7 +631,7 @@ if (sqlca.sqlcode < 0) exit (1);} printf("%d %s\n", id, t); strcpy(msg, "close"); - { ECPGdo(__LINE__, 0, 1, "test1", 0, ECPGst_normal, "close $0", + { ECPGclose(":curname3", __LINE__, 0, 1, "test1", 0, ECPGst_normal, "close $0", ECPGt_char,&(curname3),(long)0,(long)1,(1)*sizeof(char), ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT); #line 186 "cursor.pgc" @@ -639,7 +639,7 @@ if (sqlca.sqlcode < 0) exit (1);} if (sqlca.sqlcode < 0) exit (1);} #line 186 "cursor.pgc" - { ECPGdo(__LINE__, 0, 1, "test2", 0, ECPGst_normal, "close $0", + { ECPGclose(":curname5", __LINE__, 0, 1, "test2", 0, ECPGst_normal, "close $0", ECPGt_char,&(curname5),(long)0,(long)1,(1)*sizeof(char), ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT); #line 187 "cursor.pgc" @@ -688,7 +688,7 @@ if (sqlca.sqlcode < 0) exit (1); strcpy(msg, "open"); - { ECPGdo(__LINE__, 0, 1, "test1", 0, ECPGst_normal, "declare $0 cursor for $1", + { ECPGopen(":curname4", "st_id2", __LINE__, 0, 1, "test1", 0, ECPGst_normal, "declare $0 cursor for $1", ECPGt_varchar,&(curname4),(long)50,(long)1,sizeof(struct varchar_1), ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_char_variable,(ECPGprepared_statement("test1", "st_id2", __LINE__)),(long)1,(long)1,(1)*sizeof(char), @@ -700,7 +700,7 @@ if (sqlca.sqlcode < 0) exit (1);} strcpy(msg, "fetch from"); - { ECPGdo(__LINE__, 0, 1, "test1", 0, ECPGst_normal, "fetch from $0", + { ECPGfetch(":curname4", __LINE__, 0, 1, "test1", 0, ECPGst_normal, "fetch from $0", ECPGt_varchar,&(curname4),(long)50,(long)1,sizeof(struct varchar_1), ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_int,&(id),(long)1,(long)1,sizeof(int), @@ -715,7 +715,7 @@ if (sqlca.sqlcode < 0) exit (1);} printf("%d %s\n", id, t); strcpy(msg, "fetch"); - { ECPGdo(__LINE__, 0, 1, "test1", 0, ECPGst_normal, "fetch $0", + { ECPGfetch(":curname4", __LINE__, 0, 1, "test1", 0, ECPGst_normal, "fetch $0", ECPGt_varchar,&(curname4),(long)50,(long)1,sizeof(struct varchar_1), ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_int,&(id),(long)1,(long)1,sizeof(int), @@ -730,7 +730,7 @@ if (sqlca.sqlcode < 0) exit (1);} printf("%d %s\n", id, t); strcpy(msg, "fetch 1 from"); - { ECPGdo(__LINE__, 0, 1, "test1", 0, ECPGst_normal, "fetch 1 from $0", + { ECPGfetch(":curname4", __LINE__, 0, 1, "test1", 0, ECPGst_normal, "fetch 1 from $0", ECPGt_varchar,&(curname4),(long)50,(long)1,sizeof(struct varchar_1), ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_int,&(id),(long)1,(long)1,sizeof(int), @@ -746,7 +746,7 @@ if (sqlca.sqlcode < 0) exit (1);} strcpy(msg, "fetch :count from"); count = 1; - { ECPGdo(__LINE__, 0, 1, "test1", 0, ECPGst_normal, "fetch $0 from $0", + { ECPGfetch(":curname4", __LINE__, 0, 1, "test1", 0, ECPGst_normal, "fetch $0 from $0", ECPGt_int,&(count),(long)1,(long)1,sizeof(int), ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_varchar,&(curname4),(long)50,(long)1,sizeof(struct varchar_1), @@ -763,7 +763,7 @@ if (sqlca.sqlcode < 0) exit (1);} printf("%d %s\n", id, t); strcpy(msg, "move"); - { ECPGdo(__LINE__, 0, 1, "test1", 0, ECPGst_normal, "move absolute 0 $0", + { ECPGfetch(":curname4", __LINE__, 0, 1, "test1", 0, ECPGst_normal, "move absolute 0 $0", ECPGt_varchar,&(curname4),(long)50,(long)1,sizeof(struct varchar_1), ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT); #line 226 "cursor.pgc" @@ -773,7 +773,7 @@ if (sqlca.sqlcode < 0) exit (1);} strcpy(msg, "fetch 1"); - { ECPGdo(__LINE__, 0, 1, "test1", 0, ECPGst_normal, "fetch 1 $0", + { ECPGfetch(":curname4", __LINE__, 0, 1, "test1", 0, ECPGst_normal, "fetch 1 $0", ECPGt_varchar,&(curname4),(long)50,(long)1,sizeof(struct varchar_1), ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_int,&(id),(long)1,(long)1,sizeof(int), @@ -789,7 +789,7 @@ if (sqlca.sqlcode < 0) exit (1);} strcpy(msg, "fetch :count"); count = 1; - { ECPGdo(__LINE__, 0, 1, "test1", 0, ECPGst_normal, "fetch $0 $0", + { ECPGfetch(":curname4", __LINE__, 0, 1, "test1", 0, ECPGst_normal, "fetch $0 $0", ECPGt_int,&(count),(long)1,(long)1,sizeof(int), ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_varchar,&(curname4),(long)50,(long)1,sizeof(struct varchar_1), @@ -806,7 +806,7 @@ if (sqlca.sqlcode < 0) exit (1);} printf("%d %s\n", id, t); strcpy(msg, "close"); - { ECPGdo(__LINE__, 0, 1, "test1", 0, ECPGst_normal, "close $0", + { ECPGclose(":curname4", __LINE__, 0, 1, "test1", 0, ECPGst_normal, "close $0", ECPGt_varchar,&(curname4),(long)50,(long)1,sizeof(struct varchar_1), ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT); #line 238 "cursor.pgc" diff --git a/src/interfaces/ecpg/test/expected/preproc-outofscope.c b/src/interfaces/ecpg/test/expected/preproc-outofscope.c index 3a27c53e17..49fc8dbf0d 100644 --- a/src/interfaces/ecpg/test/expected/preproc-outofscope.c +++ b/src/interfaces/ecpg/test/expected/preproc-outofscope.c @@ -208,7 +208,7 @@ if (sqlca.sqlcode < 0) exit (1); static void open_cur1(void) { - { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare mycur cursor for select * from a1", ECPGt_EOIT, + { ECPGopen("mycur", NULL, __LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare mycur cursor for select * from a1", ECPGt_EOIT, ECPGt_int,&((*( MYTYPE *)(ECPGget_var( 0)) ).id),(long)1,(long)1,sizeof( struct mytype ), ECPGt_int,&((*( MYNULLTYPE *)(ECPGget_var( 1)) ).id),(long)1,(long)1,sizeof( struct mynulltype ), ECPGt_char,&((*( MYTYPE *)(ECPGget_var( 0)) ).t),(long)64,(long)1,sizeof( struct mytype ), @@ -229,7 +229,7 @@ if (sqlca.sqlcode < 0) exit (1);} static void get_record1(void) { - { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch mycur", ECPGt_EOIT, + { ECPGfetch("mycur", __LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch mycur", ECPGt_EOIT, ECPGt_int,&((*( MYTYPE *)(ECPGget_var( 0)) ).id),(long)1,(long)1,sizeof( struct mytype ), ECPGt_int,&((*( MYNULLTYPE *)(ECPGget_var( 1)) ).id),(long)1,(long)1,sizeof( struct mynulltype ), ECPGt_char,&((*( MYTYPE *)(ECPGget_var( 0)) ).t),(long)64,(long)1,sizeof( struct mytype ), @@ -250,7 +250,7 @@ if (sqlca.sqlcode < 0) exit (1);} static void close_cur1(void) { - { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "close mycur", ECPGt_EOIT, ECPGt_EORT); + { ECPGclose("mycur", __LINE__, 0, 1, NULL, 0, ECPGst_normal, "close mycur", ECPGt_EOIT, ECPGt_EORT); #line 52 "outofscope.pgc" if (sqlca.sqlcode < 0) exit (1);} diff --git a/src/interfaces/ecpg/test/expected/preproc-variable.c b/src/interfaces/ecpg/test/expected/preproc-variable.c index 3954f83769..83dbc462e7 100644 --- a/src/interfaces/ecpg/test/expected/preproc-variable.c +++ b/src/interfaces/ecpg/test/expected/preproc-variable.c @@ -190,7 +190,7 @@ if (sqlca.sqlcode < 0) exit (1);} strcpy(msg, "open"); - { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare cur cursor for select name , born , age , married , children from family", ECPGt_EOIT, ECPGt_EORT); + { ECPGopen("cur", NULL, __LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare cur cursor for select name , born , age , married , children from family", ECPGt_EOIT, ECPGt_EORT); #line 63 "variable.pgc" if (sqlca.sqlcode < 0) exit (1);} @@ -206,7 +206,7 @@ if (sqlca.sqlcode < 0) exit (1);} memset(i, 0, sizeof(ind_personal)); for (loopcount = 0; loopcount < 100; loopcount++) { strcpy(msg, "fetch"); - { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch cur", ECPGt_EOIT, + { ECPGfetch("cur", __LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch cur", ECPGt_EOIT, ECPGt_varchar,&(p->name),(long)BUFFERSIZ,(long)-1,sizeof( struct birthinfo ), ECPGt_int,&(i->ind_name),(long)1,(long)-1,sizeof( struct birthinfo ), ECPGt_long,&(p->birth.born),(long)1,(long)1,sizeof( struct birthinfo ), @@ -241,7 +241,7 @@ if (sqlca.sqlcode < 0) exit (1);} } strcpy(msg, "close"); - { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "close cur", ECPGt_EOIT, ECPGt_EORT); + { ECPGclose("cur", __LINE__, 0, 1, NULL, 0, ECPGst_normal, "close cur", ECPGt_EOIT, ECPGt_EORT); #line 89 "variable.pgc" if (sqlca.sqlcode < 0) exit (1);} diff --git a/src/interfaces/ecpg/test/expected/preproc-whenever_do_continue.c b/src/interfaces/ecpg/test/expected/preproc-whenever_do_continue.c index 56354ba201..77d4360a1d 100644 --- a/src/interfaces/ecpg/test/expected/preproc-whenever_do_continue.c +++ b/src/interfaces/ecpg/test/expected/preproc-whenever_do_continue.c @@ -105,7 +105,7 @@ if (sqlca.sqlcode < 0) exit (1);} #line 34 "whenever_do_continue.pgc" - { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare c cursor for select ename , sal , comm from emp order by ename collate \"C\" asc", ECPGt_EOIT, ECPGt_EORT); + { ECPGopen("c", NULL, __LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare c cursor for select ename , sal , comm from emp order by ename collate \"C\" asc", ECPGt_EOIT, ECPGt_EORT); #line 36 "whenever_do_continue.pgc" if (sqlca.sqlcode < 0) exit (1);} @@ -124,7 +124,7 @@ if (sqlca.sqlcode < 0) exit (1);} for (loopcount = 0; loopcount < 100; loopcount++) { - { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch c", ECPGt_EOIT, + { ECPGfetch("c", __LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch c", ECPGt_EOIT, ECPGt_char,&(emp.ename),(long)12,(long)1,(12)*sizeof(char), ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_float,&(emp.sal),(long)1,(long)1,sizeof(float), @@ -151,7 +151,7 @@ if (sqlca.sqlcode < 0) continue;} #line 55 "whenever_do_continue.pgc" - { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "close c", ECPGt_EOIT, ECPGt_EORT);} + { ECPGclose("c", __LINE__, 0, 1, NULL, 0, ECPGst_normal, "close c", ECPGt_EOIT, ECPGt_EORT);} #line 57 "whenever_do_continue.pgc" diff --git a/src/interfaces/ecpg/test/expected/sql-binary.c b/src/interfaces/ecpg/test/expected/sql-binary.c index 6d92ce344b..66b1ae884b 100644 --- a/src/interfaces/ecpg/test/expected/sql-binary.c +++ b/src/interfaces/ecpg/test/expected/sql-binary.c @@ -108,7 +108,7 @@ if (sqlca.sqlcode < 0) exit (1); #line 36 "binary.pgc" - { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare C cursor for select name , accs , byte from empl where idnum = $1 ", + { ECPGopen("C", NULL, __LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare C cursor for select name , accs , byte from empl where idnum = $1 ", ECPGt_long,&(empl.idnum),(long)1,(long)1,sizeof(long), ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT); #line 37 "binary.pgc" @@ -116,7 +116,7 @@ if (sqlca.sqlcode < 0) exit (1); if (sqlca.sqlcode < 0) exit (1);} #line 37 "binary.pgc" - { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch C", ECPGt_EOIT, + { ECPGfetch("C", __LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch C", ECPGt_EOIT, ECPGt_char,(empl.name),(long)21,(long)1,(21)*sizeof(char), ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_short,&(empl.accs),(long)1,(long)1,sizeof(short), @@ -130,7 +130,7 @@ if (sqlca.sqlcode < 0) exit (1);} printf ("name=%s, accs=%d byte=%s\n", empl.name, empl.accs, empl.byte); - { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "close C", ECPGt_EOIT, ECPGt_EORT); + { ECPGclose("C", __LINE__, 0, 1, NULL, 0, ECPGst_normal, "close C", ECPGt_EOIT, ECPGt_EORT); #line 41 "binary.pgc" if (sqlca.sqlcode < 0) exit (1);} @@ -147,7 +147,7 @@ if (sqlca.sqlcode < 0) exit (1); #line 44 "binary.pgc" - { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare B binary cursor for select name , accs , byte from empl where idnum = $1 ", + { ECPGopen("B", NULL, __LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare B binary cursor for select name , accs , byte from empl where idnum = $1 ", ECPGt_long,&(empl.idnum),(long)1,(long)1,sizeof(long), ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT); #line 45 "binary.pgc" @@ -155,7 +155,7 @@ if (sqlca.sqlcode < 0) exit (1); if (sqlca.sqlcode < 0) exit (1);} #line 45 "binary.pgc" - { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch B", ECPGt_EOIT, + { ECPGfetch("B", __LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch B", ECPGt_EOIT, ECPGt_char,(empl.name),(long)21,(long)1,(21)*sizeof(char), ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_short,&(empl.accs),(long)1,(long)1,sizeof(short), @@ -167,7 +167,7 @@ if (sqlca.sqlcode < 0) exit (1);} if (sqlca.sqlcode < 0) exit (1);} #line 46 "binary.pgc" - { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "close B", ECPGt_EOIT, ECPGt_EORT); + { ECPGclose("B", __LINE__, 0, 1, NULL, 0, ECPGst_normal, "close B", ECPGt_EOIT, ECPGt_EORT); #line 47 "binary.pgc" if (sqlca.sqlcode < 0) exit (1);} @@ -189,7 +189,7 @@ if (sqlca.sqlcode < 0) exit (1); #line 55 "binary.pgc" - { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare A binary cursor for select byte from empl where idnum = $1 ", + { ECPGopen("A", NULL, __LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare A binary cursor for select byte from empl where idnum = $1 ", ECPGt_long,&(empl.idnum),(long)1,(long)1,sizeof(long), ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT); #line 56 "binary.pgc" @@ -197,7 +197,7 @@ if (sqlca.sqlcode < 0) exit (1); if (sqlca.sqlcode < 0) exit (1);} #line 56 "binary.pgc" - { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch A", ECPGt_EOIT, + { ECPGfetch("A", __LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch A", ECPGt_EOIT, ECPGt_char,&(pointer),(long)0,(long)1,(1)*sizeof(char), ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT); #line 57 "binary.pgc" @@ -205,7 +205,7 @@ if (sqlca.sqlcode < 0) exit (1);} if (sqlca.sqlcode < 0) exit (1);} #line 57 "binary.pgc" - { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "close A", ECPGt_EOIT, ECPGt_EORT); + { ECPGclose("A", __LINE__, 0, 1, NULL, 0, ECPGst_normal, "close A", ECPGt_EOIT, ECPGt_EORT); #line 58 "binary.pgc" if (sqlca.sqlcode < 0) exit (1);} diff --git a/src/interfaces/ecpg/test/expected/sql-declare.c b/src/interfaces/ecpg/test/expected/sql-declare.c new file mode 100644 index 0000000000..9c808daa61 --- /dev/null +++ b/src/interfaces/ecpg/test/expected/sql-declare.c @@ -0,0 +1,595 @@ +/* Processed by ecpg (regression mode) */ +/* These include files are added by the preprocessor */ +#include +#include +#include +/* End of automatic include section */ +#define ECPGdebug(X,Y) ECPGdebug((X)+100,(Y)) + +#line 1 "declare.pgc" +#include +#include +#include + +/* exec sql whenever sqlerror sqlprint ; */ +#line 5 "declare.pgc" + + + +#line 1 "sqlca.h" +#ifndef POSTGRES_SQLCA_H +#define POSTGRES_SQLCA_H + +#ifndef PGDLLIMPORT +#if defined(WIN32) || defined(__CYGWIN__) +#define PGDLLIMPORT __declspec (dllimport) +#else +#define PGDLLIMPORT +#endif /* __CYGWIN__ */ +#endif /* PGDLLIMPORT */ + +#define SQLERRMC_LEN 150 + +#ifdef __cplusplus +extern "C" +{ +#endif + +struct sqlca_t +{ + char sqlcaid[8]; + long sqlabc; + long sqlcode; + struct + { + int sqlerrml; + char sqlerrmc[SQLERRMC_LEN]; + } sqlerrm; + char sqlerrp[8]; + long sqlerrd[6]; + /* Element 0: empty */ + /* 1: OID of processed tuple if applicable */ + /* 2: number of rows processed */ + /* after an INSERT, UPDATE or */ + /* DELETE statement */ + /* 3: empty */ + /* 4: empty */ + /* 5: empty */ + char sqlwarn[8]; + /* Element 0: set to 'W' if at least one other is 'W' */ + /* 1: if 'W' at least one character string */ + /* value was truncated when it was */ + /* stored into a host variable. */ + + /* + * 2: if 'W' a (hopefully) non-fatal notice occurred + */ /* 3: empty */ + /* 4: empty */ + /* 5: empty */ + /* 6: empty */ + /* 7: empty */ + + char sqlstate[5]; +}; + +struct sqlca_t *ECPGget_sqlca(void); + +#ifndef POSTGRES_ECPG_INTERNAL +#define sqlca (*ECPGget_sqlca()) +#endif + +#ifdef __cplusplus +} +#endif + +#endif + +#line 7 "declare.pgc" + + +#line 1 "regression.h" + + + + + + +#line 8 "declare.pgc" + + +#define ARRAY_SZIE 20 + +void execute_test(void); +void commitTable(void); +void reset(void); +void printResult(char *tc_name, int loop); + +/* exec sql begin declare section */ + + + + +#line 18 "declare.pgc" + int f1 [ ARRAY_SZIE ] ; + +#line 19 "declare.pgc" + int f2 [ ARRAY_SZIE ] ; + +#line 20 "declare.pgc" + char f3 [ ARRAY_SZIE ] [ 20 ] ; +/* exec sql end declare section */ +#line 21 "declare.pgc" + + +int main(void) +{ + setlocale(LC_ALL, "C"); + + ECPGdebug(1, stderr); + + { ECPGconnect(__LINE__, 0, "ecpg1_regression" , NULL, NULL , "con1", 0); +#line 29 "declare.pgc" + +if (sqlca.sqlcode < 0) sqlprint();} +#line 29 "declare.pgc" + + { ECPGconnect(__LINE__, 0, "ecpg2_regression" , NULL, NULL , "con2", 0); +#line 30 "declare.pgc" + +if (sqlca.sqlcode < 0) sqlprint();} +#line 30 "declare.pgc" + + + { ECPGdo(__LINE__, 0, 1, "con1", 0, ECPGst_normal, "create table source ( f1 integer , f2 integer , f3 varchar ( 20 ) )", ECPGt_EOIT, ECPGt_EORT); +#line 32 "declare.pgc" + +if (sqlca.sqlcode < 0) sqlprint();} +#line 32 "declare.pgc" + + { ECPGdo(__LINE__, 0, 1, "con2", 0, ECPGst_normal, "create table source ( f1 integer , f2 integer , f3 varchar ( 20 ) )", ECPGt_EOIT, ECPGt_EORT); +#line 33 "declare.pgc" + +if (sqlca.sqlcode < 0) sqlprint();} +#line 33 "declare.pgc" + + + { ECPGdo(__LINE__, 0, 1, "con1", 0, ECPGst_normal, "insert into source values ( 1 , 10 , 'db on con1' )", ECPGt_EOIT, ECPGt_EORT); +#line 35 "declare.pgc" + +if (sqlca.sqlcode < 0) sqlprint();} +#line 35 "declare.pgc" + + { ECPGdo(__LINE__, 0, 1, "con1", 0, ECPGst_normal, "insert into source values ( 2 , 20 , 'db on con1' )", ECPGt_EOIT, ECPGt_EORT); +#line 36 "declare.pgc" + +if (sqlca.sqlcode < 0) sqlprint();} +#line 36 "declare.pgc" + + + { ECPGdo(__LINE__, 0, 1, "con2", 0, ECPGst_normal, "insert into source values ( 1 , 10 , 'db on con2' )", ECPGt_EOIT, ECPGt_EORT); +#line 38 "declare.pgc" + +if (sqlca.sqlcode < 0) sqlprint();} +#line 38 "declare.pgc" + + { ECPGdo(__LINE__, 0, 1, "con2", 0, ECPGst_normal, "insert into source values ( 2 , 20 , 'db on con2' )", ECPGt_EOIT, ECPGt_EORT); +#line 39 "declare.pgc" + +if (sqlca.sqlcode < 0) sqlprint();} +#line 39 "declare.pgc" + + + commitTable(); + + execute_test(); + + { ECPGdo(__LINE__, 0, 1, "con1", 0, ECPGst_normal, "drop table if exists source", ECPGt_EOIT, ECPGt_EORT); +#line 45 "declare.pgc" + +if (sqlca.sqlcode < 0) sqlprint();} +#line 45 "declare.pgc" + + { ECPGdo(__LINE__, 0, 1, "con2", 0, ECPGst_normal, "drop table if exists source", ECPGt_EOIT, ECPGt_EORT); +#line 46 "declare.pgc" + +if (sqlca.sqlcode < 0) sqlprint();} +#line 46 "declare.pgc" + + + commitTable(); + + { ECPGdisconnect(__LINE__, "ALL"); +#line 50 "declare.pgc" + +if (sqlca.sqlcode < 0) sqlprint();} +#line 50 "declare.pgc" + + + return 0; +} + +/* + * default connection: con2 + * Non-default connection: con1 + * + */ +void execute_test(void) +{ + /* exec sql begin declare section */ + + + +#line 63 "declare.pgc" + int i ; + +#line 64 "declare.pgc" + char * selectString = "SELECT f1,f2,f3 FROM source" ; +/* exec sql end declare section */ +#line 65 "declare.pgc" + + + /* + * testcase1. using DECLARE STATEMENT without using AT clause, + * using PREPARE and CURSOR statement without using AT clause + */ + reset(); + + { ECPGdeclare(__LINE__, NULL, "stmt_1"); +#line 73 "declare.pgc" + +if (sqlca.sqlcode < 0) sqlprint();} +#line 73 "declare.pgc" + + { ECPGprepare(__LINE__, NULL, 0, "stmt_1", selectString); +#line 74 "declare.pgc" + +if (sqlca.sqlcode < 0) sqlprint();} +#line 74 "declare.pgc" + + /* declare cur_1 cursor for $1 */ +#line 75 "declare.pgc" + + { ECPGopen("cur_1", "stmt_1", __LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare cur_1 cursor for $1", + ECPGt_char_variable,(ECPGprepared_statement(NULL, "stmt_1", __LINE__)),(long)1,(long)1,(1)*sizeof(char), + ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT); +#line 76 "declare.pgc" + +if (sqlca.sqlcode < 0) sqlprint();} +#line 76 "declare.pgc" + + + /* exec sql whenever not found break ; */ +#line 78 "declare.pgc" + + i = 0; + while (1) + { + { ECPGfetch("cur_1", __LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch cur_1", ECPGt_EOIT, + ECPGt_int,&(f1[i]),(long)1,(long)1,sizeof(int), + ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, + ECPGt_int,&(f2[i]),(long)1,(long)1,sizeof(int), + ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, + ECPGt_char,(f3[i]),(long)20,(long)1,(20)*sizeof(char), + ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT); +#line 82 "declare.pgc" + +if (sqlca.sqlcode == ECPG_NOT_FOUND) break; +#line 82 "declare.pgc" + +if (sqlca.sqlcode < 0) sqlprint();} +#line 82 "declare.pgc" + + i++; + } + { ECPGclose("cur_1", __LINE__, 0, 1, NULL, 0, ECPGst_normal, "close cur_1", ECPGt_EOIT, ECPGt_EORT); +#line 85 "declare.pgc" + +if (sqlca.sqlcode < 0) sqlprint();} +#line 85 "declare.pgc" + + { ECPGdeallocate(__LINE__, 0, NULL, "stmt_1"); +#line 86 "declare.pgc" + +if (sqlca.sqlcode < 0) sqlprint();} +#line 86 "declare.pgc" + + /* exec sql whenever not found continue ; */ +#line 87 "declare.pgc" + + + printResult("testcase1", 2); + + + /* + * testcase2. using DECLARE STATEMENT at con1, + * using PREPARE and CURSOR statement without using AT clause + */ + reset(); + + { ECPGdeclare(__LINE__, "con1", "stmt_2"); +#line 98 "declare.pgc" + +if (sqlca.sqlcode < 0) sqlprint();} +#line 98 "declare.pgc" + + { ECPGprepare(__LINE__, NULL, 0, "stmt_2", selectString); +#line 99 "declare.pgc" + +if (sqlca.sqlcode < 0) sqlprint();} +#line 99 "declare.pgc" + + /* declare cur_2 cursor for $1 */ +#line 100 "declare.pgc" + + { ECPGopen("cur_2", "stmt_2", __LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare cur_2 cursor for $1", + ECPGt_char_variable,(ECPGprepared_statement(NULL, "stmt_2", __LINE__)),(long)1,(long)1,(1)*sizeof(char), + ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT); +#line 101 "declare.pgc" + +if (sqlca.sqlcode < 0) sqlprint();} +#line 101 "declare.pgc" + + + /* exec sql whenever not found break ; */ +#line 103 "declare.pgc" + + i = 0; + while (1) + { + { ECPGfetch("cur_2", __LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch cur_2", ECPGt_EOIT, + ECPGt_int,&(f1[i]),(long)1,(long)1,sizeof(int), + ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, + ECPGt_int,&(f2[i]),(long)1,(long)1,sizeof(int), + ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, + ECPGt_char,(f3[i]),(long)20,(long)1,(20)*sizeof(char), + ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT); +#line 107 "declare.pgc" + +if (sqlca.sqlcode == ECPG_NOT_FOUND) break; +#line 107 "declare.pgc" + +if (sqlca.sqlcode < 0) sqlprint();} +#line 107 "declare.pgc" + + i++; + } + { ECPGclose("cur_2", __LINE__, 0, 1, NULL, 0, ECPGst_normal, "close cur_2", ECPGt_EOIT, ECPGt_EORT); +#line 110 "declare.pgc" + +if (sqlca.sqlcode < 0) sqlprint();} +#line 110 "declare.pgc" + + { ECPGdeallocate(__LINE__, 0, NULL, "stmt_2"); +#line 111 "declare.pgc" + +if (sqlca.sqlcode < 0) sqlprint();} +#line 111 "declare.pgc" + + /* exec sql whenever not found continue ; */ +#line 112 "declare.pgc" + + + printResult("testcase2", 2); + + /* + * testcase3. using DECLARE STATEMENT at con1, + * using PREPARE and CURSOR statement at con2 + */ + reset(); + + { ECPGdeclare(__LINE__, "con1", "stmt_3"); +#line 122 "declare.pgc" + +if (sqlca.sqlcode < 0) sqlprint();} +#line 122 "declare.pgc" + + { ECPGprepare(__LINE__, "con2", 0, "stmt_3", selectString); +#line 123 "declare.pgc" + +if (sqlca.sqlcode < 0) sqlprint();} +#line 123 "declare.pgc" + + /* declare cur_3 cursor for $1 */ +#line 124 "declare.pgc" + + { ECPGopen("cur_3", "stmt_3", __LINE__, 0, 1, "con2", 0, ECPGst_normal, "declare cur_3 cursor for $1", + ECPGt_char_variable,(ECPGprepared_statement("con2", "stmt_3", __LINE__)),(long)1,(long)1,(1)*sizeof(char), + ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT); +#line 125 "declare.pgc" + +if (sqlca.sqlcode < 0) sqlprint();} +#line 125 "declare.pgc" + + + /* exec sql whenever not found break ; */ +#line 127 "declare.pgc" + + i = 0; + while (1) + { + { ECPGfetch("cur_3", __LINE__, 0, 1, "con2", 0, ECPGst_normal, "fetch cur_3", ECPGt_EOIT, + ECPGt_int,&(f1[i]),(long)1,(long)1,sizeof(int), + ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, + ECPGt_int,&(f2[i]),(long)1,(long)1,sizeof(int), + ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, + ECPGt_char,(f3[i]),(long)20,(long)1,(20)*sizeof(char), + ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT); +#line 131 "declare.pgc" + +if (sqlca.sqlcode == ECPG_NOT_FOUND) break; +#line 131 "declare.pgc" + +if (sqlca.sqlcode < 0) sqlprint();} +#line 131 "declare.pgc" + + i++; + } + { ECPGclose("cur_3", __LINE__, 0, 1, "con2", 0, ECPGst_normal, "close cur_3", ECPGt_EOIT, ECPGt_EORT); +#line 134 "declare.pgc" + +if (sqlca.sqlcode < 0) sqlprint();} +#line 134 "declare.pgc" + + { ECPGdeallocate(__LINE__, 0, "con2", "stmt_3"); +#line 135 "declare.pgc" + +if (sqlca.sqlcode < 0) sqlprint();} +#line 135 "declare.pgc" + + /* exec sql whenever not found continue ; */ +#line 136 "declare.pgc" + + + printResult("testcase3", 2); + + + /* + * testcase4. using DECLARE STATEMENT without using AT clause, + * using PREPARE and CURSOR statement at con2 + */ + reset(); + + { ECPGdeclare(__LINE__, NULL, "stmt_4"); +#line 147 "declare.pgc" + +if (sqlca.sqlcode < 0) sqlprint();} +#line 147 "declare.pgc" + + { ECPGprepare(__LINE__, "con2", 0, "stmt_4", selectString); +#line 148 "declare.pgc" + +if (sqlca.sqlcode < 0) sqlprint();} +#line 148 "declare.pgc" + + /* declare cur_4 cursor for $1 */ +#line 149 "declare.pgc" + + { ECPGopen("cur_4", "stmt_4", __LINE__, 0, 1, "con2", 0, ECPGst_normal, "declare cur_4 cursor for $1", + ECPGt_char_variable,(ECPGprepared_statement("con2", "stmt_4", __LINE__)),(long)1,(long)1,(1)*sizeof(char), + ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT); +#line 150 "declare.pgc" + +if (sqlca.sqlcode < 0) sqlprint();} +#line 150 "declare.pgc" + + + /* exec sql whenever not found break ; */ +#line 152 "declare.pgc" + + i = 0; + while (1) + { + { ECPGfetch("cur_4", __LINE__, 0, 1, "con2", 0, ECPGst_normal, "fetch cur_4", ECPGt_EOIT, + ECPGt_int,&(f1[i]),(long)1,(long)1,sizeof(int), + ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, + ECPGt_int,&(f2[i]),(long)1,(long)1,sizeof(int), + ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, + ECPGt_char,(f3[i]),(long)20,(long)1,(20)*sizeof(char), + ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT); +#line 156 "declare.pgc" + +if (sqlca.sqlcode == ECPG_NOT_FOUND) break; +#line 156 "declare.pgc" + +if (sqlca.sqlcode < 0) sqlprint();} +#line 156 "declare.pgc" + + i++; + } + { ECPGclose("cur_4", __LINE__, 0, 1, "con2", 0, ECPGst_normal, "close cur_4", ECPGt_EOIT, ECPGt_EORT); +#line 159 "declare.pgc" + +if (sqlca.sqlcode < 0) sqlprint();} +#line 159 "declare.pgc" + + { ECPGdeallocate(__LINE__, 0, "con2", "stmt_4"); +#line 160 "declare.pgc" + +if (sqlca.sqlcode < 0) sqlprint();} +#line 160 "declare.pgc" + + /* exec sql whenever not found continue ; */ +#line 161 "declare.pgc" + + + printResult("testcase4", 2); + + /* + * testcase5. using DECLARE STATEMENT without using AT clause, + * using PREPARE and EXECUTE statement without using AT clause + */ + reset(); + + { ECPGdeclare(__LINE__, NULL, "stmt_5"); +#line 171 "declare.pgc" + +if (sqlca.sqlcode < 0) sqlprint();} +#line 171 "declare.pgc" + + { ECPGprepare(__LINE__, NULL, 0, "stmt_5", selectString); +#line 172 "declare.pgc" + +if (sqlca.sqlcode < 0) sqlprint();} +#line 172 "declare.pgc" + + { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_execute, "stmt_5", ECPGt_EOIT, + ECPGt_int,(f1),(long)1,(long)ARRAY_SZIE,sizeof(int), + ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, + ECPGt_int,(f2),(long)1,(long)ARRAY_SZIE,sizeof(int), + ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, + ECPGt_char,(f3),(long)20,(long)ARRAY_SZIE,(20)*sizeof(char), + ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT); +#line 173 "declare.pgc" + +if (sqlca.sqlcode < 0) sqlprint();} +#line 173 "declare.pgc" + + + { ECPGdeallocate(__LINE__, 0, NULL, "stmt_5"); +#line 175 "declare.pgc" + +if (sqlca.sqlcode < 0) sqlprint();} +#line 175 "declare.pgc" + + + printResult("testcase5", 2); +} + +void commitTable() +{ + { ECPGtrans(__LINE__, "con1", "commit"); +#line 182 "declare.pgc" + +if (sqlca.sqlcode < 0) sqlprint();} +#line 182 "declare.pgc" + + { ECPGtrans(__LINE__, "con2", "commit"); +#line 183 "declare.pgc" + +if (sqlca.sqlcode < 0) sqlprint();} +#line 183 "declare.pgc" + +} + +/* + * reset all the output variables + */ +void reset() +{ + memset(f1, 0, sizeof(f1)); + memset(f2, 0, sizeof(f2)); + memset(f3, 0, sizeof(f3)); +} + +void printResult(char *tc_name, int loop) +{ + int i; + + if (tc_name) + printf("****%s test results:****\n", tc_name); + + for (i = 0; i < loop; i++) + printf("f1=%d, f2=%d, f3=%s\n", f1[i], f2[i], f3[i]); + + printf("\n"); +} diff --git a/src/interfaces/ecpg/test/expected/sql-declare.stderr b/src/interfaces/ecpg/test/expected/sql-declare.stderr new file mode 100644 index 0000000000..e70253a044 --- /dev/null +++ b/src/interfaces/ecpg/test/expected/sql-declare.stderr @@ -0,0 +1,288 @@ +[NO_PID]: ECPGdebug: set to 1 +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ECPGconnect: opening database ecpg1_regression on port +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ECPGconnect: opening database ecpg2_regression on port +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 32: query: create table source ( f1 integer , f2 integer , f3 varchar ( 20 ) ); with 0 parameter(s) on connection con1 +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 32: using PQexec +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_process_output on line 32: OK: CREATE TABLE +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 33: query: create table source ( f1 integer , f2 integer , f3 varchar ( 20 ) ); with 0 parameter(s) on connection con2 +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 33: using PQexec +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_process_output on line 33: OK: CREATE TABLE +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 35: query: insert into source values ( 1 , 10 , 'db on con1' ); with 0 parameter(s) on connection con1 +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 35: using PQexec +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_process_output on line 35: OK: INSERT 0 1 +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 36: query: insert into source values ( 2 , 20 , 'db on con1' ); with 0 parameter(s) on connection con1 +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 36: using PQexec +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_process_output on line 36: OK: INSERT 0 1 +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 38: query: insert into source values ( 1 , 10 , 'db on con2' ); with 0 parameter(s) on connection con2 +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 38: using PQexec +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_process_output on line 38: OK: INSERT 0 1 +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 39: query: insert into source values ( 2 , 20 , 'db on con2' ); with 0 parameter(s) on connection con2 +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 39: using PQexec +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_process_output on line 39: OK: INSERT 0 1 +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ECPGtrans on line 182: action "commit"; connection "con1" +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ECPGtrans on line 183: action "commit"; connection "con2" +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: prepare_common on line 74: name stmt_1; query: "SELECT f1,f2,f3 FROM source" +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 76: query: declare cur_1 cursor for SELECT f1,f2,f3 FROM source; with 0 parameter(s) on connection con2 +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 76: using PQexec +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_process_output on line 76: OK: DECLARE CURSOR +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 82: query: fetch cur_1; with 0 parameter(s) on connection con2 +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 82: using PQexec +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_process_output on line 82: correctly got 1 tuples with 3 fields +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_get_data on line 82: RESULT: 1 offset: -1; array: no +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_get_data on line 82: RESULT: 10 offset: -1; array: no +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_get_data on line 82: RESULT: db on con2 offset: -1; array: no +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 82: query: fetch cur_1; with 0 parameter(s) on connection con2 +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 82: using PQexec +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_process_output on line 82: correctly got 1 tuples with 3 fields +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_get_data on line 82: RESULT: 2 offset: -1; array: no +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_get_data on line 82: RESULT: 20 offset: -1; array: no +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_get_data on line 82: RESULT: db on con2 offset: -1; array: no +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 82: query: fetch cur_1; with 0 parameter(s) on connection con2 +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 82: using PQexec +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_process_output on line 82: correctly got 0 tuples with 3 fields +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: raising sqlcode 100 on line 82: no data found on line 82 +[NO_PID]: sqlca: code: 100, state: 02000 +[NO_PID]: ecpg_execute on line 85: query: close cur_1; with 0 parameter(s) on connection con2 +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 85: using PQexec +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_process_output on line 85: OK: CLOSE CURSOR +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: deallocate_one on line 86: name stmt_1 +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ECPGdeclare on line 98: declared name stmt_2 on connection: "con1" +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: prepare_common on line 99: name stmt_2; query: "SELECT f1,f2,f3 FROM source" +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 101: query: declare cur_2 cursor for SELECT f1,f2,f3 FROM source; with 0 parameter(s) on connection con1 +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 101: using PQexec +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_process_output on line 101: OK: DECLARE CURSOR +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 107: query: fetch cur_2; with 0 parameter(s) on connection con1 +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 107: using PQexec +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_process_output on line 107: correctly got 1 tuples with 3 fields +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_get_data on line 107: RESULT: 1 offset: -1; array: no +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_get_data on line 107: RESULT: 10 offset: -1; array: no +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_get_data on line 107: RESULT: db on con1 offset: -1; array: no +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 107: query: fetch cur_2; with 0 parameter(s) on connection con1 +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 107: using PQexec +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_process_output on line 107: correctly got 1 tuples with 3 fields +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_get_data on line 107: RESULT: 2 offset: -1; array: no +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_get_data on line 107: RESULT: 20 offset: -1; array: no +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_get_data on line 107: RESULT: db on con1 offset: -1; array: no +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 107: query: fetch cur_2; with 0 parameter(s) on connection con1 +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 107: using PQexec +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_process_output on line 107: correctly got 0 tuples with 3 fields +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: raising sqlcode 100 on line 107: no data found on line 107 +[NO_PID]: sqlca: code: 100, state: 02000 +[NO_PID]: ecpg_execute on line 110: query: close cur_2; with 0 parameter(s) on connection con1 +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 110: using PQexec +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_process_output on line 110: OK: CLOSE CURSOR +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: deallocate_one on line 111: name stmt_2 +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ECPGdeclare on line 122: declared name stmt_3 on connection: "con1" +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: prepare_common on line 123: name stmt_3; query: "SELECT f1,f2,f3 FROM source" +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 125: query: declare cur_3 cursor for SELECT f1,f2,f3 FROM source; with 0 parameter(s) on connection con1 +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 125: using PQexec +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_process_output on line 125: OK: DECLARE CURSOR +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 131: query: fetch cur_3; with 0 parameter(s) on connection con1 +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 131: using PQexec +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_process_output on line 131: correctly got 1 tuples with 3 fields +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_get_data on line 131: RESULT: 1 offset: -1; array: no +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_get_data on line 131: RESULT: 10 offset: -1; array: no +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_get_data on line 131: RESULT: db on con1 offset: -1; array: no +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 131: query: fetch cur_3; with 0 parameter(s) on connection con1 +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 131: using PQexec +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_process_output on line 131: correctly got 1 tuples with 3 fields +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_get_data on line 131: RESULT: 2 offset: -1; array: no +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_get_data on line 131: RESULT: 20 offset: -1; array: no +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_get_data on line 131: RESULT: db on con1 offset: -1; array: no +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 131: query: fetch cur_3; with 0 parameter(s) on connection con1 +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 131: using PQexec +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_process_output on line 131: correctly got 0 tuples with 3 fields +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: raising sqlcode 100 on line 131: no data found on line 131 +[NO_PID]: sqlca: code: 100, state: 02000 +[NO_PID]: ecpg_execute on line 134: query: close cur_3; with 0 parameter(s) on connection con1 +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 134: using PQexec +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_process_output on line 134: OK: CLOSE CURSOR +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: deallocate_one on line 135: name stmt_3 +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: prepare_common on line 148: name stmt_4; query: "SELECT f1,f2,f3 FROM source" +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 150: query: declare cur_4 cursor for SELECT f1,f2,f3 FROM source; with 0 parameter(s) on connection con2 +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 150: using PQexec +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_process_output on line 150: OK: DECLARE CURSOR +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 156: query: fetch cur_4; with 0 parameter(s) on connection con2 +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 156: using PQexec +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_process_output on line 156: correctly got 1 tuples with 3 fields +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_get_data on line 156: RESULT: 1 offset: -1; array: no +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_get_data on line 156: RESULT: 10 offset: -1; array: no +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_get_data on line 156: RESULT: db on con2 offset: -1; array: no +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 156: query: fetch cur_4; with 0 parameter(s) on connection con2 +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 156: using PQexec +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_process_output on line 156: correctly got 1 tuples with 3 fields +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_get_data on line 156: RESULT: 2 offset: -1; array: no +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_get_data on line 156: RESULT: 20 offset: -1; array: no +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_get_data on line 156: RESULT: db on con2 offset: -1; array: no +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 156: query: fetch cur_4; with 0 parameter(s) on connection con2 +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 156: using PQexec +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_process_output on line 156: correctly got 0 tuples with 3 fields +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: raising sqlcode 100 on line 156: no data found on line 156 +[NO_PID]: sqlca: code: 100, state: 02000 +[NO_PID]: ecpg_execute on line 159: query: close cur_4; with 0 parameter(s) on connection con2 +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 159: using PQexec +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_process_output on line 159: OK: CLOSE CURSOR +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: deallocate_one on line 160: name stmt_4 +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: prepare_common on line 172: name stmt_5; query: "SELECT f1,f2,f3 FROM source" +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 173: query: SELECT f1,f2,f3 FROM source; with 0 parameter(s) on connection con2 +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 173: using PQexecPrepared for "SELECT f1,f2,f3 FROM source" +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_process_output on line 173: correctly got 2 tuples with 3 fields +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_get_data on line 173: RESULT: 1 offset: -1; array: no +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_get_data on line 173: RESULT: 2 offset: -1; array: no +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_get_data on line 173: RESULT: 10 offset: -1; array: no +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_get_data on line 173: RESULT: 20 offset: -1; array: no +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_get_data on line 173: RESULT: db on con2 offset: -1; array: no +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_get_data on line 173: RESULT: db on con2 offset: -1; array: no +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: deallocate_one on line 175: name stmt_5 +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 45: query: drop table if exists source; with 0 parameter(s) on connection con1 +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 45: using PQexec +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_process_output on line 45: OK: DROP TABLE +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 46: query: drop table if exists source; with 0 parameter(s) on connection con2 +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 46: using PQexec +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_process_output on line 46: OK: DROP TABLE +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ECPGtrans on line 182: action "commit"; connection "con1" +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ECPGtrans on line 183: action "commit"; connection "con2" +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_finish: connection con2 closed +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_release_declared_statement: declared name stmt_3 is released +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_release_declared_statement: declared name stmt_2 is released +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_finish: connection con1 closed +[NO_PID]: sqlca: code: 0, state: 00000 diff --git a/src/interfaces/ecpg/test/expected/sql-declare.stdout b/src/interfaces/ecpg/test/expected/sql-declare.stdout new file mode 100644 index 0000000000..3352d47cc4 --- /dev/null +++ b/src/interfaces/ecpg/test/expected/sql-declare.stdout @@ -0,0 +1,20 @@ +****testcase1 test results:**** +f1=1, f2=10, f3=db on con2 +f1=2, f2=20, f3=db on con2 + +****testcase2 test results:**** +f1=1, f2=10, f3=db on con1 +f1=2, f2=20, f3=db on con1 + +****testcase3 test results:**** +f1=1, f2=10, f3=db on con1 +f1=2, f2=20, f3=db on con1 + +****testcase4 test results:**** +f1=1, f2=10, f3=db on con2 +f1=2, f2=20, f3=db on con2 + +****testcase5 test results:**** +f1=1, f2=10, f3=db on con2 +f1=2, f2=20, f3=db on con2 + diff --git a/src/interfaces/ecpg/test/expected/sql-desc.c b/src/interfaces/ecpg/test/expected/sql-desc.c index bdd12a506b..bcfe1bdf8b 100644 --- a/src/interfaces/ecpg/test/expected/sql-desc.c +++ b/src/interfaces/ecpg/test/expected/sql-desc.c @@ -249,7 +249,7 @@ if (sqlca.sqlcode < 0) sqlprint();} /* declare c1 cursor for $1 */ #line 58 "desc.pgc" - { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare c1 cursor for $1", + { ECPGopen("c1", "foo2", __LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare c1 cursor for $1", ECPGt_char_variable,(ECPGprepared_statement(NULL, "foo2", __LINE__)),(long)1,(long)1,(1)*sizeof(char), ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_descriptor, "indesc", 1L, 1L, 1L, @@ -260,7 +260,7 @@ if (sqlca.sqlcode < 0) sqlprint();} #line 59 "desc.pgc" - { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch next from c1", ECPGt_EOIT, + { ECPGfetch("c1", __LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch next from c1", ECPGt_EOIT, ECPGt_int,&(val1output),(long)1,(long)1,sizeof(int), ECPGt_int,&(ind1),(long)1,(long)1,sizeof(int), ECPGt_char,(val2output),(long)sizeof("AAA"),(long)1,(sizeof("AAA"))*sizeof(char), @@ -273,7 +273,7 @@ if (sqlca.sqlcode < 0) sqlprint();} printf("val1=%d (ind1: %d) val2=%s (ind2: %d)\n", val1output, ind1, val2output, ind2); - { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "close c1", ECPGt_EOIT, ECPGt_EORT); + { ECPGclose("c1", __LINE__, 0, 1, NULL, 0, ECPGst_normal, "close c1", ECPGt_EOIT, ECPGt_EORT); #line 65 "desc.pgc" if (sqlca.sqlcode < 0) sqlprint();} @@ -299,7 +299,7 @@ if (sqlca.sqlcode < 0) sqlprint();} /* declare c2 cursor for $1 */ #line 70 "desc.pgc" - { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare c2 cursor for $1", + { ECPGopen("c2", "foo3", __LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare c2 cursor for $1", ECPGt_char_variable,(ECPGprepared_statement(NULL, "foo3", __LINE__)),(long)1,(long)1,(1)*sizeof(char), ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_descriptor, "indesc", 1L, 1L, 1L, @@ -310,7 +310,7 @@ if (sqlca.sqlcode < 0) sqlprint();} #line 71 "desc.pgc" - { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch next from c2", ECPGt_EOIT, + { ECPGfetch("c2", __LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch next from c2", ECPGt_EOIT, ECPGt_int,&(val1output),(long)1,(long)1,sizeof(int), ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_char,(val2output),(long)sizeof("AAA"),(long)1,(sizeof("AAA"))*sizeof(char), @@ -322,7 +322,7 @@ if (sqlca.sqlcode < 0) sqlprint();} printf("val1=%d val2=%s\n", val1output, val2i ? "null" : val2output); - { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "close c2", ECPGt_EOIT, ECPGt_EORT); + { ECPGclose("c2", __LINE__, 0, 1, NULL, 0, ECPGst_normal, "close c2", ECPGt_EOIT, ECPGt_EORT); #line 76 "desc.pgc" if (sqlca.sqlcode < 0) sqlprint();} diff --git a/src/interfaces/ecpg/test/expected/sql-dyntest.c b/src/interfaces/ecpg/test/expected/sql-dyntest.c index 513d44c630..f5a8ef09d4 100644 --- a/src/interfaces/ecpg/test/expected/sql-dyntest.c +++ b/src/interfaces/ecpg/test/expected/sql-dyntest.c @@ -261,7 +261,7 @@ if (sqlca.sqlcode < 0) error ( );} #line 58 "dyntest.pgc" - { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare MYCURS cursor for $1", + { ECPGopen("MYCURS", "myquery", __LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare MYCURS cursor for $1", ECPGt_char_variable,(ECPGprepared_statement(NULL, "myquery", __LINE__)),(long)1,(long)1,(1)*sizeof(char), ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT); #line 60 "dyntest.pgc" @@ -272,7 +272,7 @@ if (sqlca.sqlcode < 0) error ( );} while (1) { - { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch in MYCURS", ECPGt_EOIT, + { ECPGfetch("MYCURS", __LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch in MYCURS", ECPGt_EOIT, ECPGt_descriptor, "MYDESC", 1L, 1L, 1L, ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT); #line 64 "dyntest.pgc" @@ -468,7 +468,7 @@ if (sqlca.sqlcode < 0) error ( );} } } - { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "close MYCURS", ECPGt_EOIT, ECPGt_EORT); + { ECPGclose("MYCURS", __LINE__, 0, 1, NULL, 0, ECPGst_normal, "close MYCURS", ECPGt_EOIT, ECPGt_EORT); #line 194 "dyntest.pgc" if (sqlca.sqlcode < 0) error ( );} diff --git a/src/interfaces/ecpg/test/expected/sql-execute.c b/src/interfaces/ecpg/test/expected/sql-execute.c index cac91dc599..e791621ad9 100644 --- a/src/interfaces/ecpg/test/expected/sql-execute.c +++ b/src/interfaces/ecpg/test/expected/sql-execute.c @@ -140,7 +140,7 @@ if (sqlca.sqlcode < 0) sqlprint();} #line 50 "execute.pgc" - { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare CUR cursor for $1", + { ECPGopen("CUR", "f", __LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare CUR cursor for $1", ECPGt_char_variable,(ECPGprepared_statement(NULL, "f", __LINE__)),(long)1,(long)1,(1)*sizeof(char), ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT); #line 52 "execute.pgc" @@ -148,7 +148,7 @@ if (sqlca.sqlcode < 0) sqlprint();} if (sqlca.sqlcode < 0) sqlprint();} #line 52 "execute.pgc" - { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch 8 in CUR", ECPGt_EOIT, + { ECPGfetch("CUR", __LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch 8 in CUR", ECPGt_EOIT, ECPGt_char,(name),(long)8,(long)8,(8)*sizeof(char), ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_int,(amount),(long)1,(long)8,sizeof(int), @@ -180,7 +180,7 @@ if (sqlca.sqlcode < 0) sqlprint();} printf("name[%d]=%8.8s\tamount[%d]=%d\tletter[%d]=%c\n", i, n, i, a, i, l); } - { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "close CUR", ECPGt_EOIT, ECPGt_EORT); + { ECPGclose("CUR", __LINE__, 0, 1, NULL, 0, ECPGst_normal, "close CUR", ECPGt_EOIT, ECPGt_EORT); #line 66 "execute.pgc" if (sqlca.sqlcode < 0) sqlprint();} @@ -205,7 +205,7 @@ if (sqlca.sqlcode < 0) sqlprint();} #line 72 "execute.pgc" - { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare CUR2 cursor for $1", + { ECPGopen("CUR2", "f", __LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare CUR2 cursor for $1", ECPGt_char_variable,(ECPGprepared_statement(NULL, "f", __LINE__)),(long)1,(long)1,(1)*sizeof(char), ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_const,"1",(long)1,(long)1,strlen("1"), @@ -215,7 +215,7 @@ if (sqlca.sqlcode < 0) sqlprint();} if (sqlca.sqlcode < 0) sqlprint();} #line 74 "execute.pgc" - { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch in CUR2", ECPGt_EOIT, + { ECPGfetch("CUR2", __LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch in CUR2", ECPGt_EOIT, ECPGt_char,(name),(long)8,(long)8,(8)*sizeof(char), ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_int,(amount),(long)1,(long)8,sizeof(int), @@ -247,7 +247,7 @@ if (sqlca.sqlcode < 0) sqlprint();} printf("name[%d]=%8.8s\tamount[%d]=%d\tletter[%d]=%c\n", i, n, i, a, i, l); } - { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "close CUR2", ECPGt_EOIT, ECPGt_EORT); + { ECPGclose("CUR2", __LINE__, 0, 1, NULL, 0, ECPGst_normal, "close CUR2", ECPGt_EOIT, ECPGt_EORT); #line 88 "execute.pgc" if (sqlca.sqlcode < 0) sqlprint();} diff --git a/src/interfaces/ecpg/test/expected/sql-fetch.c b/src/interfaces/ecpg/test/expected/sql-fetch.c index ca7d14e97c..a265bce989 100644 --- a/src/interfaces/ecpg/test/expected/sql-fetch.c +++ b/src/interfaces/ecpg/test/expected/sql-fetch.c @@ -99,7 +99,7 @@ if (sqlca.sqlcode < 0) exit (1);} #line 26 "fetch.pgc" - { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare C cursor for select * from My_Table", ECPGt_EOIT, ECPGt_EORT); + { ECPGopen("C", NULL, __LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare C cursor for select * from My_Table", ECPGt_EOIT, ECPGt_EORT); #line 28 "fetch.pgc" if (sqlca.sqlwarn[0] == 'W') sqlprint(); @@ -113,7 +113,7 @@ if (sqlca.sqlcode < 0) exit (1);} #line 30 "fetch.pgc" for (loopcount = 0; loopcount < 100; loopcount++) { - { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch 1 in C", ECPGt_EOIT, + { ECPGfetch("C", __LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch 1 in C", ECPGt_EOIT, ECPGt_int,&(i),(long)1,(long)1,sizeof(int), ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_char,(str),(long)25,(long)1,(25)*sizeof(char), @@ -135,7 +135,7 @@ if (sqlca.sqlcode < 0) exit (1);} /* exec sql whenever not found continue ; */ #line 36 "fetch.pgc" - { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "move backward 2 in C", ECPGt_EOIT, ECPGt_EORT); + { ECPGfetch("C", __LINE__, 0, 1, NULL, 0, ECPGst_normal, "move backward 2 in C", ECPGt_EOIT, ECPGt_EORT); #line 37 "fetch.pgc" if (sqlca.sqlwarn[0] == 'W') sqlprint(); @@ -145,7 +145,7 @@ if (sqlca.sqlcode < 0) exit (1);} #line 37 "fetch.pgc" - { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch $0 in C", + { ECPGfetch("C", __LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch $0 in C", ECPGt_int,&(count),(long)1,(long)1,sizeof(int), ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_int,&(i),(long)1,(long)1,sizeof(int), @@ -162,7 +162,7 @@ if (sqlca.sqlcode < 0) exit (1);} printf("%d: %s\n", i, str); - { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "close C", ECPGt_EOIT, ECPGt_EORT); + { ECPGclose("C", __LINE__, 0, 1, NULL, 0, ECPGst_normal, "close C", ECPGt_EOIT, ECPGt_EORT); #line 42 "fetch.pgc" if (sqlca.sqlwarn[0] == 'W') sqlprint(); @@ -176,7 +176,7 @@ if (sqlca.sqlcode < 0) exit (1);} #line 44 "fetch.pgc" - { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare D cursor for select * from My_Table where Item1 = $1", + { ECPGopen("D", NULL, __LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare D cursor for select * from My_Table where Item1 = $1", ECPGt_const,"1",(long)1,(long)1,strlen("1"), ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT); #line 46 "fetch.pgc" @@ -188,7 +188,7 @@ if (sqlca.sqlcode < 0) exit (1);} #line 46 "fetch.pgc" - { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch 1 in D", ECPGt_EOIT, + { ECPGfetch("D", __LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch 1 in D", ECPGt_EOIT, ECPGt_int,&(i),(long)1,(long)1,sizeof(int), ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_char,(str),(long)25,(long)1,(25)*sizeof(char), @@ -203,7 +203,7 @@ if (sqlca.sqlcode < 0) exit (1);} printf("%d: %s\n", i, str); - { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "close D", ECPGt_EOIT, ECPGt_EORT); + { ECPGclose("D", __LINE__, 0, 1, NULL, 0, ECPGst_normal, "close D", ECPGt_EOIT, ECPGt_EORT); #line 51 "fetch.pgc" if (sqlca.sqlwarn[0] == 'W') sqlprint(); diff --git a/src/interfaces/ecpg/test/expected/sql-oldexec.c b/src/interfaces/ecpg/test/expected/sql-oldexec.c index d6a661e3fb..b98de49f59 100644 --- a/src/interfaces/ecpg/test/expected/sql-oldexec.c +++ b/src/interfaces/ecpg/test/expected/sql-oldexec.c @@ -141,7 +141,7 @@ if (sqlca.sqlcode < 0) sqlprint();} #line 51 "oldexec.pgc" - { ECPGdo(__LINE__, 0, 1, NULL, 1, ECPGst_normal, "declare CUR cursor for $1", + { ECPGopen("CUR", "f", __LINE__, 0, 1, NULL, 1, ECPGst_normal, "declare CUR cursor for $1", ECPGt_char_variable,(ECPGprepared_statement(NULL, "f", __LINE__)),(long)1,(long)1,(1)*sizeof(char), ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT); #line 53 "oldexec.pgc" @@ -149,7 +149,7 @@ if (sqlca.sqlcode < 0) sqlprint();} if (sqlca.sqlcode < 0) sqlprint();} #line 53 "oldexec.pgc" - { ECPGdo(__LINE__, 0, 1, NULL, 1, ECPGst_normal, "fetch 8 in CUR", ECPGt_EOIT, + { ECPGfetch("CUR", __LINE__, 0, 1, NULL, 1, ECPGst_normal, "fetch 8 in CUR", ECPGt_EOIT, ECPGt_char,(name),(long)8,(long)8,(8)*sizeof(char), ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_int,(amount),(long)1,(long)8,sizeof(int), @@ -171,7 +171,7 @@ if (sqlca.sqlcode < 0) sqlprint();} printf("name[%d]=%8.8s\tamount[%d]=%d\tletter[%d]=%c\n", i, n, i, a, i, l); } - { ECPGdo(__LINE__, 0, 1, NULL, 1, ECPGst_normal, "close CUR", ECPGt_EOIT, ECPGt_EORT); + { ECPGclose("CUR", __LINE__, 0, 1, NULL, 1, ECPGst_normal, "close CUR", ECPGt_EOIT, ECPGt_EORT); #line 65 "oldexec.pgc" if (sqlca.sqlcode < 0) sqlprint();} @@ -190,7 +190,7 @@ if (sqlca.sqlcode < 0) sqlprint();} #line 70 "oldexec.pgc" - { ECPGdo(__LINE__, 0, 1, NULL, 1, ECPGst_normal, "declare CUR3 cursor for $1", + { ECPGopen("CUR3", "f", __LINE__, 0, 1, NULL, 1, ECPGst_normal, "declare CUR3 cursor for $1", ECPGt_char_variable,(ECPGprepared_statement(NULL, "f", __LINE__)),(long)1,(long)1,(1)*sizeof(char), ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_const,"1",(long)1,(long)1,strlen("1"), @@ -200,7 +200,7 @@ if (sqlca.sqlcode < 0) sqlprint();} if (sqlca.sqlcode < 0) sqlprint();} #line 72 "oldexec.pgc" - { ECPGdo(__LINE__, 0, 1, NULL, 1, ECPGst_normal, "fetch in CUR3", ECPGt_EOIT, + { ECPGfetch("CUR3", __LINE__, 0, 1, NULL, 1, ECPGst_normal, "fetch in CUR3", ECPGt_EOIT, ECPGt_char,(name),(long)8,(long)8,(8)*sizeof(char), ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_int,(amount),(long)1,(long)8,sizeof(int), @@ -222,7 +222,7 @@ if (sqlca.sqlcode < 0) sqlprint();} printf("name[%d]=%8.8s\tamount[%d]=%d\tletter[%d]=%c\n", i, n, i, a, i, l); } - { ECPGdo(__LINE__, 0, 1, NULL, 1, ECPGst_normal, "close CUR3", ECPGt_EOIT, ECPGt_EORT); + { ECPGclose("CUR3", __LINE__, 0, 1, NULL, 1, ECPGst_normal, "close CUR3", ECPGt_EOIT, ECPGt_EORT); #line 84 "oldexec.pgc" if (sqlca.sqlcode < 0) sqlprint();} diff --git a/src/interfaces/ecpg/test/expected/sql-quote.c b/src/interfaces/ecpg/test/expected/sql-quote.c index 05841bd699..a6f501c2ec 100644 --- a/src/interfaces/ecpg/test/expected/sql-quote.c +++ b/src/interfaces/ecpg/test/expected/sql-quote.c @@ -162,7 +162,7 @@ if (sqlca.sqlcode < 0) exit (1);} #line 43 "quote.pgc" - { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare C cursor for select * from \"My_Table\"", ECPGt_EOIT, ECPGt_EORT); + { ECPGopen("C", NULL, __LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare C cursor for select * from \"My_Table\"", ECPGt_EOIT, ECPGt_EORT); #line 45 "quote.pgc" if (sqlca.sqlwarn[0] == 'W') sqlprint(); @@ -178,7 +178,7 @@ if (sqlca.sqlcode < 0) exit (1);} for (loopcount = 0; loopcount < 100; loopcount++) { - { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch C", ECPGt_EOIT, + { ECPGfetch("C", __LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch C", ECPGt_EOIT, ECPGt_int,&(i),(long)1,(long)1,sizeof(int), ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_char,(var),(long)25,(long)1,(25)*sizeof(char), diff --git a/src/interfaces/ecpg/test/expected/sql-sqlda.c b/src/interfaces/ecpg/test/expected/sql-sqlda.c index 6bd9d5527a..d1c7e3adf1 100644 --- a/src/interfaces/ecpg/test/expected/sql-sqlda.c +++ b/src/interfaces/ecpg/test/expected/sql-sqlda.c @@ -261,7 +261,7 @@ if (sqlca.sqlcode < 0) exit (1);} strcpy(msg, "open"); - { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare mycur1 cursor for $1", + { ECPGopen("mycur1", "st_id1", __LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare mycur1 cursor for $1", ECPGt_char_variable,(ECPGprepared_statement(NULL, "st_id1", __LINE__)),(long)1,(long)1,(1)*sizeof(char), ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT); #line 115 "sqlda.pgc" @@ -278,7 +278,7 @@ if (sqlca.sqlcode < 0) exit (1);} while (1) { strcpy(msg, "fetch"); - { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch 1 from mycur1", ECPGt_EOIT, + { ECPGfetch("mycur1", __LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch 1 from mycur1", ECPGt_EOIT, ECPGt_sqlda, &outp_sqlda, 0L, 0L, 0L, ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT); #line 123 "sqlda.pgc" @@ -299,7 +299,7 @@ if (sqlca.sqlcode < 0) exit (1);} strcpy(msg, "close"); - { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "close mycur1", ECPGt_EOIT, ECPGt_EORT); + { ECPGclose("mycur1", __LINE__, 0, 1, NULL, 0, ECPGst_normal, "close mycur1", ECPGt_EOIT, ECPGt_EORT); #line 132 "sqlda.pgc" if (sqlca.sqlcode < 0) exit (1);} @@ -334,7 +334,7 @@ if (sqlca.sqlcode < 0) exit (1);} strcpy(msg, "open"); - { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare mycur2 cursor for $1", + { ECPGopen("mycur2", "st_id2", __LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare mycur2 cursor for $1", ECPGt_char_variable,(ECPGprepared_statement(NULL, "st_id2", __LINE__)),(long)1,(long)1,(1)*sizeof(char), ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT); #line 150 "sqlda.pgc" @@ -344,7 +344,7 @@ if (sqlca.sqlcode < 0) exit (1);} strcpy(msg, "fetch"); - { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch all from mycur2", ECPGt_EOIT, + { ECPGfetch("mycur2", __LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch all from mycur2", ECPGt_EOIT, ECPGt_sqlda, &outp_sqlda, 0L, 0L, 0L, ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT); #line 153 "sqlda.pgc" @@ -367,7 +367,7 @@ if (sqlca.sqlcode < 0) exit (1);} } strcpy(msg, "close"); - { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "close mycur2", ECPGt_EOIT, ECPGt_EORT); + { ECPGclose("mycur2", __LINE__, 0, 1, NULL, 0, ECPGst_normal, "close mycur2", ECPGt_EOIT, ECPGt_EORT); #line 169 "sqlda.pgc" if (sqlca.sqlcode < 0) exit (1);} diff --git a/src/interfaces/ecpg/test/sql/.gitignore b/src/interfaces/ecpg/test/sql/.gitignore index bbdada9edb..d68362912a 100644 --- a/src/interfaces/ecpg/test/sql/.gitignore +++ b/src/interfaces/ecpg/test/sql/.gitignore @@ -6,6 +6,8 @@ /code100.c /copystdout /copystdout.c +/declare +/declare.c /define /define.c /desc diff --git a/src/interfaces/ecpg/test/sql/Makefile b/src/interfaces/ecpg/test/sql/Makefile index b7bc034e4e..c3d86ae4f3 100644 --- a/src/interfaces/ecpg/test/sql/Makefile +++ b/src/interfaces/ecpg/test/sql/Makefile @@ -22,8 +22,9 @@ TESTS = array array.c \ parser parser.c \ quote quote.c \ show show.c \ + insupd insupd.c \ twophase twophase.c \ - insupd insupd.c + declare declare.c all: $(TESTS) diff --git a/src/interfaces/ecpg/test/sql/declare.pgc b/src/interfaces/ecpg/test/sql/declare.pgc new file mode 100644 index 0000000000..f9ef468741 --- /dev/null +++ b/src/interfaces/ecpg/test/sql/declare.pgc @@ -0,0 +1,207 @@ +#include +#include +#include + +EXEC SQL WHENEVER SQLERROR SQLPRINT; + +EXEC SQL INCLUDE sqlca; +EXEC SQL INCLUDE ../regression; + +#define ARRAY_SZIE 20 + +void execute_test(void); +void commitTable(void); +void reset(void); +void printResult(char *tc_name, int loop); + +EXEC SQL BEGIN DECLARE SECTION; +int f1[ARRAY_SZIE]; +int f2[ARRAY_SZIE]; +char f3[ARRAY_SZIE][20]; +EXEC SQL END DECLARE SECTION; + +int main(void) +{ + setlocale(LC_ALL, "C"); + + ECPGdebug(1, stderr); + + EXEC SQL CONNECT TO REGRESSDB1 AS con1; + EXEC SQL CONNECT TO REGRESSDB2 AS con2; + + EXEC SQL AT con1 CREATE TABLE source(f1 integer, f2 integer, f3 varchar(20)); + EXEC SQL AT con2 CREATE TABLE source(f1 integer, f2 integer, f3 varchar(20)); + + EXEC SQL AT con1 INSERT INTO source VALUES(1, 10, 'db on con1'); + EXEC SQL AT con1 INSERT INTO source VALUES(2, 20, 'db on con1'); + + EXEC SQL AT con2 INSERT INTO source VALUES(1, 10, 'db on con2'); + EXEC SQL AT con2 INSERT INTO source VALUES(2, 20, 'db on con2'); + + commitTable(); + + execute_test(); + + EXEC SQL AT con1 DROP TABLE IF EXISTS source; + EXEC SQL AT con2 DROP TABLE IF EXISTS source; + + commitTable(); + + EXEC SQL DISCONNECT ALL; + + return 0; +} + +/* + * default connection: con2 + * Non-default connection: con1 + * + */ +void execute_test(void) +{ + EXEC SQL BEGIN DECLARE SECTION; + int i; + char *selectString = "SELECT f1,f2,f3 FROM source"; + EXEC SQL END DECLARE SECTION; + + /* + * testcase1. using DECLARE STATEMENT without using AT clause, + * using PREPARE and CURSOR statement without using AT clause + */ + reset(); + + EXEC SQL DECLARE stmt_1 STATEMENT; + EXEC SQL PREPARE stmt_1 FROM :selectString; + EXEC SQL DECLARE cur_1 CURSOR FOR stmt_1; + EXEC SQL OPEN cur_1; + + EXEC SQL WHENEVER NOT FOUND DO BREAK; + i = 0; + while (1) + { + EXEC SQL FETCH cur_1 INTO :f1[i], :f2[i], :f3[i]; + i++; + } + EXEC SQL CLOSE cur_1; + EXEC SQL DEALLOCATE PREPARE stmt_1; + EXEC SQL WHENEVER NOT FOUND CONTINUE; + + printResult("testcase1", 2); + + + /* + * testcase2. using DECLARE STATEMENT at con1, + * using PREPARE and CURSOR statement without using AT clause + */ + reset(); + + EXEC SQL AT con1 DECLARE stmt_2 STATEMENT; + EXEC SQL PREPARE stmt_2 FROM :selectString; + EXEC SQL DECLARE cur_2 CURSOR FOR stmt_2; + EXEC SQL OPEN cur_2; + + EXEC SQL WHENEVER NOT FOUND DO BREAK; + i = 0; + while (1) + { + EXEC SQL FETCH cur_2 INTO :f1[i], :f2[i], :f3[i]; + i++; + } + EXEC SQL CLOSE cur_2; + EXEC SQL DEALLOCATE PREPARE stmt_2; + EXEC SQL WHENEVER NOT FOUND CONTINUE; + + printResult("testcase2", 2); + + /* + * testcase3. using DECLARE STATEMENT at con1, + * using PREPARE and CURSOR statement at con2 + */ + reset(); + + EXEC SQL AT con1 DECLARE stmt_3 STATEMENT; + EXEC SQL AT con2 PREPARE stmt_3 FROM :selectString; + EXEC SQL AT con2 DECLARE cur_3 CURSOR FOR stmt_3; + EXEC SQL AT con2 OPEN cur_3; + + EXEC SQL WHENEVER NOT FOUND DO BREAK; + i = 0; + while (1) + { + EXEC SQL AT con2 FETCH cur_3 INTO :f1[i], :f2[i], :f3[i]; + i++; + } + EXEC SQL AT con2 CLOSE cur_3; + EXEC SQL AT con2 DEALLOCATE PREPARE stmt_3; + EXEC SQL WHENEVER NOT FOUND CONTINUE; + + printResult("testcase3", 2); + + + /* + * testcase4. using DECLARE STATEMENT without using AT clause, + * using PREPARE and CURSOR statement at con2 + */ + reset(); + + EXEC SQL DECLARE stmt_4 STATEMENT; + EXEC SQL AT con2 PREPARE stmt_4 FROM :selectString; + EXEC SQL AT con2 DECLARE cur_4 CURSOR FOR stmt_4; + EXEC SQL AT con2 OPEN cur_4; + + EXEC SQL WHENEVER NOT FOUND DO BREAK; + i = 0; + while (1) + { + EXEC SQL AT con2 FETCH cur_4 INTO :f1[i], :f2[i], :f3[i]; + i++; + } + EXEC SQL AT con2 CLOSE cur_4; + EXEC SQL AT con2 DEALLOCATE PREPARE stmt_4; + EXEC SQL WHENEVER NOT FOUND CONTINUE; + + printResult("testcase4", 2); + + /* + * testcase5. using DECLARE STATEMENT without using AT clause, + * using PREPARE and EXECUTE statement without using AT clause + */ + reset(); + + EXEC SQL DECLARE stmt_5 STATEMENT; + EXEC SQL PREPARE stmt_5 FROM :selectString; + EXEC SQL EXECUTE stmt_5 INTO :f1, :f2, :f3; + + EXEC SQL DEALLOCATE PREPARE stmt_5; + + printResult("testcase5", 2); +} + +void commitTable() +{ + EXEC SQL AT con1 COMMIT; + EXEC SQL AT con2 COMMIT; +} + +/* + * reset all the output variables + */ +void reset() +{ + memset(f1, 0, sizeof(f1)); + memset(f2, 0, sizeof(f2)); + memset(f3, 0, sizeof(f3)); +} + +void printResult(char *tc_name, int loop) +{ + int i; + + if (tc_name) + printf("****%s test results:****\n", tc_name); + + for (i = 0; i < loop; i++) + printf("f1=%d, f2=%d, f3=%s\n", f1[i], f2[i], f3[i]); + + printf("\n"); +}