- Compatibility functions for INFORMIX handling of DECLARE statement.
- Make sure a variable is no longer referenced when it is removed.
- Fixed counting bug in parsing "->" operator.
+
+Fri Jun 13 10:11:12 CEST 2003
+
+ - Enable FETCH without INTO.
+ - Compatibility functions for INFORMIX handling of DECLARE statement.
- Set ecpg version to 2.12.0.
- Set ecpg library to 3.4.2.
- Set pgtypes library to 1.0.0
#include <pgtypes_error.h>
#include <pgtypes_date.h>
+char * ECPGalloc(long, int);
+
/* we start with the numeric functions */
int
decadd(Numeric *arg1, Numeric *arg2, Numeric *sum)
return 0;
}
+bool
+ECPGconnect_informix(int lineno, const char *name, const char *user, const char *passwd, const char *connection_name, int autocommit)
+{
+ char *informix_name = (char *)name, *envname;
+
+ /* Informix uses an environment variable DBPATH that overrides
+ * the connection parameters given here.
+ * We do the same with PG_DBPATH as the syntax is different. */
+ envname = getenv("PG_DBPATH");
+ if (envname)
+ informix_name = envname;
+ return (ECPGconnect(lineno, informix_name, user, passwd, connection_name , autocommit));
+}
+
+static struct var_list
+{
+ int number;
+ void *pointer;
+ struct var_list *next;
+} *ivlist = NULL;
+
+void
+ECPG_informix_set_var(int number, void *pointer, int lineno)
+{
+ struct var_list *ptr;
+
+ for (ptr = ivlist; ptr != NULL; ptr = ptr->next)
+ {
+ if (ptr->number == number)
+ {
+ /* already known => just change pointer value */
+ ptr->pointer = pointer;
+ return;
+ }
+ }
+
+ /* a new one has to be added */
+ ptr = (struct var_list *) ECPGalloc (sizeof(struct var_list), lineno);
+ ptr->number = number;
+ ptr->pointer = pointer;
+ ptr->next = ivlist;
+ ivlist = ptr;
+}
+
+void *
+ECPG_informix_get_var(int number)
+{
+ struct var_list *ptr;
+
+ for (ptr = ivlist; ptr != NULL && ptr->number != number; ptr = ptr->next);
+ return (ptr) ? ptr->pointer : NULL;
+}
+
-/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/ecpglib/connect.c,v 1.5 2003/05/20 11:05:27 meskes Exp $ */
+/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/ecpglib/connect.c,v 1.6 2003/06/13 10:50:57 meskes Exp $ */
#include "postgres_fe.h"
sqlca.sqlwarn[0] = 'W';
}
-/* this contains some quick hacks, needs to be cleaned up, but it works */
-bool
-ECPGconnect_informix(int lineno, const char *name, const char *user, const char *passwd, const char *connection_name, int autocommit)
-{
- char *informix_name = (char *)name, *envname;
-
- /* Informix uses an environment variable DBPATH that overrides
- * the connection parameters given here.
- * We do the same with PG_DBPATH as the syntax is different. */
- envname = getenv("PG_DBPATH");
- if (envname)
- informix_name = envname;
- return (ECPGconnect(lineno, informix_name, user, passwd, connection_name, autocommit));
-}
-
/* this contains some quick hacks, needs to be cleaned up, but it works */
bool
ECPGconnect(int lineno, const char *name, const char *user, const char *passwd, const char *connection_name, int autocommit)
*tmp = '\0';
}
- tmp = last_path_separator(dbname + offset);
+ tmp = last_path_separator(dbname + offset);
if (tmp != NULL) /* database name given */
{
realname = strdup(tmp + 1);
-/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/ecpglib/execute.c,v 1.8 2003/04/01 14:37:25 meskes Exp $ */
+/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/ecpglib/execute.c,v 1.9 2003/06/13 10:50:57 meskes Exp $ */
/*
* The aim is to get a simpler inteface to the database routines.
{
ECPGlog("ECPGexecute line %d: ASYNC NOTIFY of '%s' from backend pid '%d' received\n",
stmt->lineno, notify->relname, notify->be_pid);
- PQfreemem(notify);
+ PQfreemem(notify);
}
return status;
#include <decimal.h>
#include <datetime.h>
+#include <ecpglib.h>
#define SQLNOTFOUND 100
extern int byleng(char *, int);
extern void ldchar(char *, int, char *);
-
+
+extern bool ECPGconnect_informix(int, const char *, const char *, const char *, const char *, int);
+extern void ECPG_informix_set_var(int, void *, int);
+extern void *ECPG_informix_get_var(int);
bool ECPGstatus(int, const char *);
bool ECPGsetcommit(int, const char *, const char *);
bool ECPGsetconn(int, const char *);
-bool ECPGconnect_informix(int, const char *, const char *, const char *, const char *, int);
bool ECPGconnect(int, const char *, const char *, const char *, const char *, int);
bool ECPGdo(int, const char *, char *,...);
bool ECPGtrans(int, const char *, const char *);
-/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/preproc/ecpg.c,v 1.72 2003/05/30 08:39:00 meskes Exp $ */
+/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/preproc/ecpg.c,v 1.73 2003/06/13 10:50:57 meskes Exp $ */
/* New main for ecpg, the PostgreSQL embedded SQL precompiler. */
/* (C) Michael Meskes <meskes@postgresql.org> Feb 5th, 1998 */
/* and structure member lists */
memset(struct_member_list, 0, sizeof(struct_member_list));
+ /* and our variable counter for Informix compatibility */
+ ecpg_informix_var = 0;
+
/* finally the actual connection */
connection = NULL;
auto_create_c,
system_includes,
ret_value,
- struct_level;
+ struct_level,
+ ecpg_informix_var;
extern char *descriptor_index;
extern char *descriptor_name;
extern char *connection;
-/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/preproc/Attic/preproc.y,v 1.230 2003/06/11 06:39:12 meskes Exp $ */
+/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/preproc/Attic/preproc.y,v 1.231 2003/06/13 10:50:57 meskes Exp $ */
/* Copyright comment */
%{
*/
int struct_level = 0;
int braces_open; /* brace level counter */
+int ecpg_informix_var = 0;
char errortext[128];
char *connection = NULL;
char *input_filename = NULL;
return(res_str);
}
+/* and the rest */
static char *
make_name(void)
{
return(result);
}
+static char *
+adjust_informix(struct arguments *list)
+{
+ /* Informix accepts DECLARE with variables that are out of scope when OPEN is called.
+ * This breaks standard and leads to some very dangerous programming.
+ * Since they do, we have to work around and accept their syntax as well.
+ * But we will do so ONLY in Informix mode.
+ * We have to change the variables to our own struct and just store the pointer instead of the variable */
+
+ struct arguments *ptr;
+ char *result = make_str("");
+
+ for (ptr = list; ptr != NULL; ptr = ptr->next)
+ {
+ char temp[sizeof(int)+sizeof(", &()")];
+ char *original_var;
+
+ /* change variable name to "ECPG_informix_get_var(<counter>)" */
+ original_var = ptr->variable->name;
+ sprintf(temp, "%d))", ecpg_informix_var);
+ ptr->variable = new_variable(cat_str(4, make_str("*("), mm_strdup(ECPGtype_name(ptr->variable->type->type)), make_str(" *)(ECPG_informix_get_var("), mm_strdup(temp)), ECPGmake_simple_type(ptr->variable->type->type, ptr->variable->type->size), 0);
+
+ /* create call to "ECPG_informix_set_var(<counter>, <pointer>. <linen number>)" */
+ sprintf(temp, "%d, &(", ecpg_informix_var++);
+ result = cat_str(5, result, make_str("ECPG_informix_set_var("), mm_strdup(temp), mm_strdup(original_var), make_str("), __LINE__);\n"));
+ }
+
+ return result;
+}
+
%}
%union {
*
*****************************************************************************/
-ClosePortalStmt: CLOSE name { $$ = cat2_str(make_str("close"), $2); }
+ClosePortalStmt: CLOSE name
+ {
+ $$ = cat2_str(make_str("close"), $2);
+ }
;
/*****************************************************************************
{ $$ = cat_str(4, make_str("fetch"), $2, $3, $4); }
| FETCH name ecpg_into_using
{ $$ = cat2_str(make_str("fetch"), $2); }
+ | FETCH fetch_direction from_in name
+ { $$ = cat_str(4, make_str("fetch"), $2, $3, $4); }
+ | FETCH name
+ { $$ = cat2_str(make_str("fetch"), $2); }
| MOVE fetch_direction from_in name
{ $$ = cat_str(4, make_str("move"), $2, $3, $4); }
| MOVE name
this->argsinsert = argsinsert;
this->argsresult = argsresult;
argsinsert = argsresult = NULL;
-
cur = this;
- $$ = cat_str(3, make_str("/*"), mm_strdup(this->command), make_str("*/"));
+ if (compat == ECPG_COMPAT_INFORMIX)
+ $$ = cat_str(5, adjust_informix(this->argsinsert), adjust_informix(this->argsresult), make_str("/*"), mm_strdup(this->command), make_str("*/"));
+ else
+ $$ = cat_str(3, make_str("/*"), mm_strdup(this->command), make_str("*/"));
}
;
#define BUFFERSIZ 8
exec sql type str is varchar[BUFFERSIZ];
+exec sql declare cur cursor for
+ select name, born, age, married, children from meskes;
+
int
main ()
{
exec sql var ind_married is long;
- exec sql declare cur cursor for
- select name, born, age, married, children from meskes;
-
char msg[128];
FILE *dbgs;