Commit 26188e8c authored by Michael Meskes's avatar Michael Meskes

- Enable FETCH without INTO.

- Compatibility functions for INFORMIX handling of DECLARE statement.
parent a2d08b99
...@@ -1482,6 +1482,11 @@ Wed Jun 11 08:30:41 CEST 2003 ...@@ -1482,6 +1482,11 @@ Wed Jun 11 08:30:41 CEST 2003
- Make sure a variable is no longer referenced when it is removed. - Make sure a variable is no longer referenced when it is removed.
- Fixed counting bug in parsing "->" operator. - 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 version to 2.12.0.
- Set ecpg library to 3.4.2. - Set ecpg library to 3.4.2.
- Set pgtypes library to 1.0.0 - Set pgtypes library to 1.0.0
......
...@@ -8,6 +8,8 @@ ...@@ -8,6 +8,8 @@
#include <pgtypes_error.h> #include <pgtypes_error.h>
#include <pgtypes_date.h> #include <pgtypes_date.h>
char * ECPGalloc(long, int);
/* we start with the numeric functions */ /* we start with the numeric functions */
int int
decadd(Numeric *arg1, Numeric *arg2, Numeric *sum) decadd(Numeric *arg1, Numeric *arg2, Numeric *sum)
...@@ -673,3 +675,56 @@ dtcvfmtasc (char *inbuf, char *fmtstr, dtime_t *dtvalue) ...@@ -673,3 +675,56 @@ dtcvfmtasc (char *inbuf, char *fmtstr, dtime_t *dtvalue)
return 0; 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" #include "postgres_fe.h"
...@@ -257,21 +257,6 @@ ECPGnoticeProcessor(void *arg, const char *message) ...@@ -257,21 +257,6 @@ ECPGnoticeProcessor(void *arg, const char *message)
sqlca.sqlwarn[0] = 'W'; 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 */ /* this contains some quick hacks, needs to be cleaned up, but it works */
bool bool
ECPGconnect(int lineno, const char *name, const char *user, const char *passwd, const char *connection_name, int autocommit) ECPGconnect(int lineno, const char *name, const char *user, const char *passwd, const char *connection_name, int autocommit)
...@@ -341,7 +326,7 @@ ECPGconnect(int lineno, const char *name, const char *user, const char *passwd, ...@@ -341,7 +326,7 @@ ECPGconnect(int lineno, const char *name, const char *user, const char *passwd,
*tmp = '\0'; *tmp = '\0';
} }
tmp = last_path_separator(dbname + offset); tmp = last_path_separator(dbname + offset);
if (tmp != NULL) /* database name given */ if (tmp != NULL) /* database name given */
{ {
realname = strdup(tmp + 1); 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. * The aim is to get a simpler inteface to the database routines.
...@@ -1239,7 +1239,7 @@ ECPGexecute(struct statement * stmt) ...@@ -1239,7 +1239,7 @@ ECPGexecute(struct statement * stmt)
{ {
ECPGlog("ECPGexecute line %d: ASYNC NOTIFY of '%s' from backend pid '%d' received\n", ECPGlog("ECPGexecute line %d: ASYNC NOTIFY of '%s' from backend pid '%d' received\n",
stmt->lineno, notify->relname, notify->be_pid); stmt->lineno, notify->relname, notify->be_pid);
PQfreemem(notify); PQfreemem(notify);
} }
return status; return status;
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
#include <decimal.h> #include <decimal.h>
#include <datetime.h> #include <datetime.h>
#include <ecpglib.h>
#define SQLNOTFOUND 100 #define SQLNOTFOUND 100
...@@ -31,4 +32,7 @@ extern void rupshift(char *); ...@@ -31,4 +32,7 @@ extern void rupshift(char *);
extern int byleng(char *, int); extern int byleng(char *, int);
extern void ldchar(char *, int, char *); 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);
...@@ -42,7 +42,6 @@ void ECPGdebug(int, FILE *); ...@@ -42,7 +42,6 @@ void ECPGdebug(int, FILE *);
bool ECPGstatus(int, const char *); bool ECPGstatus(int, const char *);
bool ECPGsetcommit(int, const char *, const char *); bool ECPGsetcommit(int, const char *, const char *);
bool ECPGsetconn(int, 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 ECPGconnect(int, const char *, const char *, const char *, const char *, int);
bool ECPGdo(int, const char *, char *,...); bool ECPGdo(int, const char *, char *,...);
bool ECPGtrans(int, const char *, const 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. */ /* New main for ecpg, the PostgreSQL embedded SQL precompiler. */
/* (C) Michael Meskes <meskes@postgresql.org> Feb 5th, 1998 */ /* (C) Michael Meskes <meskes@postgresql.org> Feb 5th, 1998 */
...@@ -359,6 +359,9 @@ main(int argc, char *const argv[]) ...@@ -359,6 +359,9 @@ main(int argc, char *const argv[])
/* and structure member lists */ /* and structure member lists */
memset(struct_member_list, 0, sizeof(struct_member_list)); memset(struct_member_list, 0, sizeof(struct_member_list));
/* and our variable counter for Informix compatibility */
ecpg_informix_var = 0;
/* finally the actual connection */ /* finally the actual connection */
connection = NULL; connection = NULL;
......
...@@ -17,7 +17,8 @@ extern int braces_open, ...@@ -17,7 +17,8 @@ extern int braces_open,
auto_create_c, auto_create_c,
system_includes, system_includes,
ret_value, ret_value,
struct_level; struct_level,
ecpg_informix_var;
extern char *descriptor_index; extern char *descriptor_index;
extern char *descriptor_name; extern char *descriptor_name;
extern char *connection; 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 */ /* Copyright comment */
%{ %{
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
*/ */
int struct_level = 0; int struct_level = 0;
int braces_open; /* brace level counter */ int braces_open; /* brace level counter */
int ecpg_informix_var = 0;
char errortext[128]; char errortext[128];
char *connection = NULL; char *connection = NULL;
char *input_filename = NULL; char *input_filename = NULL;
...@@ -141,6 +142,7 @@ make3_str(char *str1, char *str2, char *str3) ...@@ -141,6 +142,7 @@ make3_str(char *str1, char *str2, char *str3)
return(res_str); return(res_str);
} }
/* and the rest */
static char * static char *
make_name(void) make_name(void)
{ {
...@@ -186,6 +188,36 @@ create_questionmarks(char *name, bool array) ...@@ -186,6 +188,36 @@ create_questionmarks(char *name, bool array)
return(result); 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 { %union {
...@@ -1098,7 +1130,10 @@ opt_drop_behavior: CASCADE { $$ = make_str("cascade"); } ...@@ -1098,7 +1130,10 @@ opt_drop_behavior: CASCADE { $$ = make_str("cascade"); }
* *
*****************************************************************************/ *****************************************************************************/
ClosePortalStmt: CLOSE name { $$ = cat2_str(make_str("close"), $2); } ClosePortalStmt: CLOSE name
{
$$ = cat2_str(make_str("close"), $2);
}
; ;
/***************************************************************************** /*****************************************************************************
...@@ -1734,6 +1769,10 @@ FetchStmt: FETCH fetch_direction from_in name ecpg_into_using ...@@ -1734,6 +1769,10 @@ FetchStmt: FETCH fetch_direction from_in name ecpg_into_using
{ $$ = cat_str(4, make_str("fetch"), $2, $3, $4); } { $$ = cat_str(4, make_str("fetch"), $2, $3, $4); }
| FETCH name ecpg_into_using | FETCH name ecpg_into_using
{ $$ = cat2_str(make_str("fetch"), $2); } { $$ = 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 | MOVE fetch_direction from_in name
{ $$ = cat_str(4, make_str("move"), $2, $3, $4); } { $$ = cat_str(4, make_str("move"), $2, $3, $4); }
| MOVE name | MOVE name
...@@ -2630,10 +2669,12 @@ DeclareCursorStmt: DECLARE name cursor_options CURSOR opt_hold FOR SelectStmt ...@@ -2630,10 +2669,12 @@ DeclareCursorStmt: DECLARE name cursor_options CURSOR opt_hold FOR SelectStmt
this->argsinsert = argsinsert; this->argsinsert = argsinsert;
this->argsresult = argsresult; this->argsresult = argsresult;
argsinsert = argsresult = NULL; argsinsert = argsresult = NULL;
cur = this; 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("*/"));
} }
; ;
......
...@@ -12,6 +12,9 @@ typedef union { int integer; short smallint; } ind; ...@@ -12,6 +12,9 @@ typedef union { int integer; short smallint; } ind;
#define BUFFERSIZ 8 #define BUFFERSIZ 8
exec sql type str is varchar[BUFFERSIZ]; exec sql type str is varchar[BUFFERSIZ];
exec sql declare cur cursor for
select name, born, age, married, children from meskes;
int int
main () main ()
{ {
...@@ -34,9 +37,6 @@ exec sql end declare section; ...@@ -34,9 +37,6 @@ exec sql end declare section;
exec sql var ind_married is long; exec sql var ind_married is long;
exec sql declare cur cursor for
select name, born, age, married, children from meskes;
char msg[128]; char msg[128];
FILE *dbgs; FILE *dbgs;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment