diff --git a/src/interfaces/ecpg/ecpglib/Makefile b/src/interfaces/ecpg/ecpglib/Makefile
index fbb1407..132e53a 100644
--- a/src/interfaces/ecpg/ecpglib/Makefile
+++ b/src/interfaces/ecpg/ecpglib/Makefile
@@ -26,7 +26,7 @@ override CFLAGS += $(PTHREAD_CFLAGS)
LIBS := $(filter-out -lpgport, $(LIBS))
OBJS= execute.o typename.o descriptor.o sqlda.o data.o error.o prepare.o memory.o \
- connect.o misc.o path.o pgstrcasecmp.o \
+ connect.o misc.o path.o pgstrcasecmp.o cursor.o \
$(filter snprintf.o strlcpy.o win32setlocale.o isinf.o, $(LIBOBJS)) $(WIN32RES)
# thread.c is needed only for non-WIN32 implementation of path.c
diff --git a/src/interfaces/ecpg/ecpglib/connect.c b/src/interfaces/ecpg/ecpglib/connect.c
index c90f13d..ddbc08c 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 */
@@ -684,12 +686,15 @@ ECPGdisconnect(int lineno, const char *connection_name)
if (strcmp(connection_name, "ALL") == 0)
{
+ struct connection *f = NULL;
+
ecpg_init_sqlca(sqlca);
for (con = all_connections; con;)
{
- struct connection *f = con;
+ f = con;
con = con->next;
+ ecpg_release_declared_statement(f->name);
ecpg_finish(f);
}
}
@@ -705,7 +710,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 0000000..4391ec3
--- /dev/null
+++ b/src/interfaces/ecpg/ecpglib/cursor.c
@@ -0,0 +1,260 @@
+/* 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 "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 (false == find_cursor(cursor_name, con))
+ {
+ 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
+ */
+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)
+ return ;
+
+ con = ecpg_get_connection(connection_name);
+ if (!con)
+ {
+ return;
+ }
+
+ if (find_cursor(cursor_name, con))
+ {
+ /*
+ * Should never goto here, because ECPG has checked the duplication of
+ * the cursor in pre-compile stage.
+ */
+ 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: Find whether the cursor exists in the connection or not
+ * 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;
+}
\ No newline at end of file
diff --git a/src/interfaces/ecpg/ecpglib/descriptor.c b/src/interfaces/ecpg/ecpglib/descriptor.c
index 15fd7a0..858be01 100644
--- a/src/interfaces/ecpg/ecpglib/descriptor.c
+++ b/src/interfaces/ecpg/ecpglib/descriptor.c
@@ -818,6 +818,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)
@@ -826,13 +827,20 @@ ECPGdescribe(int line, int compat, bool input, const char *connection_name, cons
return ret;
}
- con = ecpg_get_connection(connection_name);
- if (!con)
+ real_connection_name = ecpg_get_con_name_by_declared_name(stmt_name);
+ if (real_connection_name == NULL)
{
- ecpg_raise(line, ECPG_NO_CONN, ECPG_SQLSTATE_CONNECTION_DOES_NOT_EXIST,
- connection_name ? connection_name : ecpg_gettext("NULL"));
- return ret;
+ /*
+ * 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, real_connection_name, line))
+ return false;
+
prep = ecpg_find_prepared_statement(stmt_name, con, NULL);
if (!prep)
{
diff --git a/src/interfaces/ecpg/ecpglib/error.c b/src/interfaces/ecpg/ecpglib/error.c
index 656b2c4..11a1a7c 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 d5a463d..1a50307 100644
--- a/src/interfaces/ecpg/ecpglib/execute.c
+++ b/src/interfaces/ecpg/ecpglib/execute.c
@@ -2032,9 +2032,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 69e9617..08fa1bb 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/extern.h b/src/interfaces/ecpg/ecpglib/extern.h
index c3082be..13d978c 100644
--- a/src/interfaces/ecpg/ecpglib/extern.h
+++ b/src/interfaces/ecpg/ecpglib/extern.h
@@ -66,6 +66,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
{
@@ -75,6 +84,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
{
@@ -83,6 +98,7 @@ struct connection
bool autocommit;
struct ECPGtype_information_cache *cache_head;
struct prepared_statement *prep_stmts;
+ struct cursor_statement *cursor_stmts;
struct connection *next;
};
@@ -165,6 +181,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);
@@ -220,4 +241,4 @@ void ecpg_set_native_sqlda(int, struct sqlda_struct **, const PGresult *, int,
#define ECPG_SQLSTATE_ECPG_INTERNAL_ERROR "YE000"
#define ECPG_SQLSTATE_ECPG_OUT_OF_MEMORY "YE001"
-#endif /* _ECPG_LIB_EXTERN_H */
+#endif /* _ECPG_LIB_EXTERN_H */
\ No newline at end of file
diff --git a/src/interfaces/ecpg/ecpglib/prepare.c b/src/interfaces/ecpg/ecpglib/prepare.c
index 983b242..0a939cd 100644
--- a/src/interfaces/ecpg/ecpglib/prepare.c
+++ b/src/interfaces/ecpg/ecpglib/prepare.c
@@ -26,9 +26,11 @@ static int nextStmtID = 1;
static const int stmtCacheNBuckets = 2039; /* # buckets - a prime # */
static const int stmtCacheEntPerBucket = 8; /* # entries/bucket */
static stmtCacheEntry stmtCacheEntries[16384] = {{0, {0}, 0, 0, 0}};
+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)
@@ -117,6 +119,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;
@@ -163,11 +166,22 @@ ECPGprepare(int lineno, const char *connection_name, const bool questionmarks, c
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);
- if (!ecpg_init(con, connection_name, lineno))
+ 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, real_connection_name, lineno))
return false;
/* check if we already have prepared this statement */
@@ -255,9 +269,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;
@@ -305,8 +329,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));
}
/*
@@ -513,3 +550,196 @@ 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
+ * We don't allocate a node to store the declared name because the
+ * DECLARE STATEMENT without using AT clause will be ignored.
+ */
+ 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 declared name referred by the cursor,
+ * then return the connection name used by the declared 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;
+ struct declared_statement *next = NULL;
+
+ if(connection_name == NULL)
+ return;
+
+ cur = g_declared_list;
+ while(cur)
+ {
+ next = cur->next;
+ if (strcmp(cur->connection_name, connection_name) == 0)
+ {
+ /* If find then release the declared node from the list */
+ if(prev)
+ prev->next = next;
+ else
+ g_declared_list = 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;
+
+ cur = next;
+ }
+}
\ No newline at end of file
diff --git a/src/interfaces/ecpg/include/ecpgerrno.h b/src/interfaces/ecpg/include/ecpgerrno.h
index 36b15b7..fae9440 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 c32df6c..8c91212 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 7cc47e9..2c3f348 100644
--- a/src/interfaces/ecpg/include/ecpgtype.h
+++ b/src/interfaces/ecpg/include/ecpgtype.h
@@ -99,8 +99,15 @@ enum ECPG_statement_type
ECPGst_prepnormal
};
+enum ECPG_cursor_statement_type
+{
+ ECPGcst_declare,
+ ECPGcst_open,
+ ECPGcst_fetch,
+ ECPGcst_close
+};
#ifdef __cplusplus
}
#endif
-#endif /* _ECPGTYPE_H */
+#endif /* _ECPGTYPE_H */