Commit 988fdce5 authored by Michael Meskes's avatar Michael Meskes

- Removed space_or_nl and line_end from pgc.l.

- Fixed several bugs concerning arrays of structs including a memory
  allocation bug.
parent aed0c29f
...@@ -1175,5 +1175,14 @@ Sun Dec 9 16:21:30 CET 2001 ...@@ -1175,5 +1175,14 @@ Sun Dec 9 16:21:30 CET 2001
- Fixed several bugs concerning indicators and added error messages - Fixed several bugs concerning indicators and added error messages
instead of segfaults. instead of segfaults.
Thu Dec 20 14:15:56 CET 2001
- Removed space_or_nl and line_end from pgc.l.
Sun Dec 23 13:08:36 CET 2001
- Fixed several bugs concerning arrays of structs including a memory
allocation bug.
- Set ecpg version to 2.9.0. - Set ecpg version to 2.9.0.
- Set library version to 3.3.0. - Set library version to 3.3.0.
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
#define ECPG_MISSING_INDICATOR -209 #define ECPG_MISSING_INDICATOR -209
#define ECPG_NO_ARRAY -210 #define ECPG_NO_ARRAY -210
#define ECPG_DATA_NOT_ARRAY -211 #define ECPG_DATA_NOT_ARRAY -211
#define ECPG_ARRAY_INSERT -212
#define ECPG_NO_CONN -220 #define ECPG_NO_CONN -220
#define ECPG_NOT_CONN -221 #define ECPG_NOT_CONN -221
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
# #
# Copyright (c) 1994, Regents of the University of California # Copyright (c) 1994, Regents of the University of California
# #
# $Header: /cvsroot/pgsql/src/interfaces/ecpg/lib/Attic/Makefile,v 1.13 2001/09/19 14:09:32 meskes Exp $ # $Header: /cvsroot/pgsql/src/interfaces/ecpg/lib/Attic/Makefile,v 1.14 2001/12/23 12:17:41 meskes Exp $
# #
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
...@@ -12,6 +12,8 @@ subdir = src/interfaces/ecpg/lib ...@@ -12,6 +12,8 @@ subdir = src/interfaces/ecpg/lib
top_builddir = ../../../.. top_builddir = ../../../..
include $(top_builddir)/src/Makefile.global include $(top_builddir)/src/Makefile.global
CFLAGS=-g
NAME= ecpg NAME= ecpg
SO_MAJOR_VERSION= 3 SO_MAJOR_VERSION= 3
SO_MINOR_VERSION= 3.0 SO_MINOR_VERSION= 3.0
......
/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/lib/Attic/connect.c,v 1.16 2001/12/05 15:32:06 meskes Exp $ */ /* $Header: /cvsroot/pgsql/src/interfaces/ecpg/lib/Attic/connect.c,v 1.17 2001/12/23 12:17:41 meskes Exp $ */
#include "postgres_fe.h" #include "postgres_fe.h"
...@@ -52,9 +52,9 @@ ecpg_finish(struct connection * act) ...@@ -52,9 +52,9 @@ ecpg_finish(struct connection * act)
if (actual_connection == act) if (actual_connection == act)
actual_connection = all_connections; actual_connection = all_connections;
for (cache = act->cache_head; cache; ptr = cache, cache = cache->next, free(ptr)); for (cache = act->cache_head; cache; ptr = cache, cache = cache->next, ECPGfree(ptr));
free(act->name); ECPGfree(act->name);
free(act); ECPGfree(act);
} }
else else
ECPGlog("ecpg_finish: called an extra time.\n"); ECPGlog("ecpg_finish: called an extra time.\n");
...@@ -348,15 +348,15 @@ ECPGconnect(int lineno, const char *name, const char *user, const char *passwd, ...@@ -348,15 +348,15 @@ ECPGconnect(int lineno, const char *name, const char *user, const char *passwd,
ECPGlog("connect: socketname %s given for TCP connection in line %d\n", host, lineno); ECPGlog("connect: socketname %s given for TCP connection in line %d\n", host, lineno);
ECPGraise(lineno, ECPG_CONNECT, realname ? realname : "<DEFAULT>"); ECPGraise(lineno, ECPG_CONNECT, realname ? realname : "<DEFAULT>");
if (host) if (host)
free(host); ECPGfree(host);
if (port) if (port)
free(port); ECPGfree(port);
if (options) if (options)
free(options); ECPGfree(options);
if (realname) if (realname)
free(realname); ECPGfree(realname);
if (dbname) if (dbname)
free(dbname); ECPGfree(dbname);
return false; return false;
} }
} }
...@@ -371,15 +371,15 @@ ECPGconnect(int lineno, const char *name, const char *user, const char *passwd, ...@@ -371,15 +371,15 @@ ECPGconnect(int lineno, const char *name, const char *user, const char *passwd,
ECPGlog("connect: non-localhost access via sockets in line %d\n", lineno); ECPGlog("connect: non-localhost access via sockets in line %d\n", lineno);
ECPGraise(lineno, ECPG_CONNECT, realname ? realname : "<DEFAULT>"); ECPGraise(lineno, ECPG_CONNECT, realname ? realname : "<DEFAULT>");
if (host) if (host)
free(host); ECPGfree(host);
if (port) if (port)
free(port); ECPGfree(port);
if (options) if (options)
free(options); ECPGfree(options);
if (realname) if (realname)
free(realname); ECPGfree(realname);
if (dbname) if (dbname)
free(dbname); ECPGfree(dbname);
return false; return false;
} }
} }
...@@ -431,28 +431,28 @@ ECPGconnect(int lineno, const char *name, const char *user, const char *passwd, ...@@ -431,28 +431,28 @@ ECPGconnect(int lineno, const char *name, const char *user, const char *passwd,
lineno); lineno);
ECPGraise(lineno, ECPG_CONNECT, realname ? realname : "<DEFAULT>"); ECPGraise(lineno, ECPG_CONNECT, realname ? realname : "<DEFAULT>");
if (host) if (host)
free(host); ECPGfree(host);
if (port) if (port)
free(port); ECPGfree(port);
if (options) if (options)
free(options); ECPGfree(options);
if (realname) if (realname)
free(realname); ECPGfree(realname);
if (dbname) if (dbname)
free(dbname); ECPGfree(dbname);
return false; return false;
} }
if (host) if (host)
free(host); ECPGfree(host);
if (port) if (port)
free(port); ECPGfree(port);
if (options) if (options)
free(options); ECPGfree(options);
if (realname) if (realname)
free(realname); ECPGfree(realname);
if (dbname) if (dbname)
free(dbname); ECPGfree(dbname);
this->committed = true; this->committed = true;
this->autocommit = autocommit; this->autocommit = autocommit;
......
/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/lib/Attic/data.c,v 1.20 2001/12/05 15:32:06 meskes Exp $ */ /* $Header: /cvsroot/pgsql/src/interfaces/ecpg/lib/Attic/data.c,v 1.21 2001/12/23 12:17:41 meskes Exp $ */
#include "postgres_fe.h" #include "postgres_fe.h"
...@@ -15,11 +15,11 @@ bool ...@@ -15,11 +15,11 @@ bool
ECPGget_data(const PGresult *results, int act_tuple, int act_field, int lineno, ECPGget_data(const PGresult *results, int act_tuple, int act_field, int lineno,
enum ECPGttype type, enum ECPGttype ind_type, enum ECPGttype type, enum ECPGttype ind_type,
void *var, void *ind, long varcharsize, long offset, void *var, void *ind, long varcharsize, long offset,
bool isarray) long ind_offset, bool isarray)
{ {
char *pval = (char *) PQgetvalue(results, act_tuple, act_field); char *pval = (char *) PQgetvalue(results, act_tuple, act_field);
ECPGlog("ECPGget_data line %d: RESULT: %s\n", lineno, pval ? pval : ""); ECPGlog("ECPGget_data line %d: RESULT: %s offset: %ld\n", lineno, pval ? pval : "", offset);
/* pval is a pointer to the value */ /* pval is a pointer to the value */
/* let's check is it really is an array if it should be one */ /* let's check is it really is an array if it should be one */
...@@ -53,23 +53,28 @@ ECPGget_data(const PGresult *results, int act_tuple, int act_field, int lineno, ...@@ -53,23 +53,28 @@ ECPGget_data(const PGresult *results, int act_tuple, int act_field, int lineno,
{ {
case ECPGt_short: case ECPGt_short:
case ECPGt_unsigned_short: case ECPGt_unsigned_short:
((short *) ind)[act_tuple] = -PQgetisnull(results, act_tuple, act_field); /* ((short *) ind)[act_tuple] = -PQgetisnull(results, act_tuple, act_field);*/
*((short *) (ind + ind_offset*act_tuple)) = -PQgetisnull(results, act_tuple, act_field);
break; break;
case ECPGt_int: case ECPGt_int:
case ECPGt_unsigned_int: case ECPGt_unsigned_int:
((int *) ind)[act_tuple] = -PQgetisnull(results, act_tuple, act_field); /* ((int *) ind)[act_tuple] = -PQgetisnull(results, act_tuple, act_field);*/
*((int *) (ind + ind_offset*act_tuple)) = -PQgetisnull(results, act_tuple, act_field);
break; break;
case ECPGt_long: case ECPGt_long:
case ECPGt_unsigned_long: case ECPGt_unsigned_long:
((long *) ind)[act_tuple] = -PQgetisnull(results, act_tuple, act_field); /* ((long *) ind)[act_tuple] = -PQgetisnull(results, act_tuple, act_field);*/
*((long *) (ind + ind_offset*act_tuple)) = -PQgetisnull(results, act_tuple, act_field);
break; break;
#ifdef HAVE_LONG_LONG_INT_64 #ifdef HAVE_LONG_LONG_INT_64
case ECPGt_long_long: case ECPGt_long_long:
((long long int *) ind)[act_tuple] = -PQgetisnull(results, act_tuple, act_field);
break;
case ECPGt_unsigned_long_long: case ECPGt_unsigned_long_long:
((unsigned long long int *) ind)[act_tuple] = -PQgetisnull(results, act_tuple, act_field); /* ((long long int *) ind)[act_tuple] = -PQgetisnull(results, act_tuple, act_field);*/
*((long long int *) (ind + ind_offset*act_tuple)) = -PQgetisnull(results, act_tuple, act_field);
break; break;
/* case ECPGt_unsigned_long_long:
((unsigned long long int *) ind)[act_tuple] = -PQgetisnull(results, act_tuple, act_field);
break;*/
#endif /* HAVE_LONG_LONG_INT_64 */ #endif /* HAVE_LONG_LONG_INT_64 */
case ECPGt_NO_INDICATOR: case ECPGt_NO_INDICATOR:
if (PQgetisnull(results, act_tuple, act_field)) if (PQgetisnull(results, act_tuple, act_field))
...@@ -112,13 +117,16 @@ ECPGget_data(const PGresult *results, int act_tuple, int act_field, int lineno, ...@@ -112,13 +117,16 @@ ECPGget_data(const PGresult *results, int act_tuple, int act_field, int lineno,
switch (type) switch (type)
{ {
case ECPGt_short: case ECPGt_short:
((short *) var)[act_tuple] = (short) res; /* ((short *) var)[act_tuple] = (short) res;*/
*((short *) (var + offset*act_tuple)) = (short) res;
break; break;
case ECPGt_int: case ECPGt_int:
((int *) var)[act_tuple] = (int) res; /* ((int *) var)[act_tuple] = (int) res;*/
*((int *) (var + offset*act_tuple)) = (int) res;
break; break;
case ECPGt_long: case ECPGt_long:
((long *) var)[act_tuple] = res; /* ((long *) var)[act_tuple] = res;*/
*((long *) (var + offset*act_tuple)) = (long) res;
break; break;
default: default:
/* Cannot happen */ /* Cannot happen */
...@@ -145,13 +153,16 @@ ECPGget_data(const PGresult *results, int act_tuple, int act_field, int lineno, ...@@ -145,13 +153,16 @@ ECPGget_data(const PGresult *results, int act_tuple, int act_field, int lineno,
switch (type) switch (type)
{ {
case ECPGt_unsigned_short: case ECPGt_unsigned_short:
((unsigned short *) var)[act_tuple] = (unsigned short) ures; /* ((unsigned short *) var)[act_tuple] = (unsigned short) ures;*/
*((unsigned short *) (var + offset*act_tuple)) = (unsigned short) res;
break; break;
case ECPGt_unsigned_int: case ECPGt_unsigned_int:
((unsigned int *) var)[act_tuple] = (unsigned int) ures; /* ((unsigned int *) var)[act_tuple] = (unsigned int) ures;*/
*((unsigned int *) (var + offset*act_tuple)) = (unsigned int) res;
break; break;
case ECPGt_unsigned_long: case ECPGt_unsigned_long:
((unsigned long *) var)[act_tuple] = ures; /* ((unsigned long *) var)[act_tuple] = ures;*/
*((unsigned long *) (var + offset*act_tuple)) = (unsigned long) res;
break; break;
default: default:
/* Cannot happen */ /* Cannot happen */
...@@ -164,7 +175,8 @@ ECPGget_data(const PGresult *results, int act_tuple, int act_field, int lineno, ...@@ -164,7 +175,8 @@ ECPGget_data(const PGresult *results, int act_tuple, int act_field, int lineno,
case ECPGt_long_long: case ECPGt_long_long:
if (pval) if (pval)
{ {
((long long int *) var)[act_tuple] = strtoll(pval, &scan_length, 10); /* ((long long int *) var)[act_tuple] = strtoll(pval, &scan_length, 10);*/
*((long long int *) (var + offset*act_tuple)) = strtoll(pval, &scan_length, 10);
if ((isarray && *scan_length != ',' && *scan_length != '}') if ((isarray && *scan_length != ',' && *scan_length != '}')
|| (!isarray && *scan_length != '\0')) /* Garbage left */ || (!isarray && *scan_length != '\0')) /* Garbage left */
{ {
...@@ -173,7 +185,8 @@ ECPGget_data(const PGresult *results, int act_tuple, int act_field, int lineno, ...@@ -173,7 +185,8 @@ ECPGget_data(const PGresult *results, int act_tuple, int act_field, int lineno,
} }
} }
else else
((long long int *) var)[act_tuple] = (long long) 0; /* ((long long int *) var)[act_tuple] = (long long) 0;*/
*((long long int *) (var + offset*act_tuple)) = (long long) 0;
break; break;
#endif /* HAVE_STRTOLL */ #endif /* HAVE_STRTOLL */
...@@ -181,7 +194,8 @@ ECPGget_data(const PGresult *results, int act_tuple, int act_field, int lineno, ...@@ -181,7 +194,8 @@ ECPGget_data(const PGresult *results, int act_tuple, int act_field, int lineno,
case ECPGt_unsigned_long_long: case ECPGt_unsigned_long_long:
if (pval) if (pval)
{ {
((unsigned long long int *) var)[act_tuple] = strtoull(pval, &scan_length, 10); /* ((unsigned long long int *) var)[act_tuple] = strtoull(pval, &scan_length, 10);*/
*((unsigned long long int *) (var + offset*act_tuple)) = strtoull(pval, &scan_length, 10);
if ((isarray && *scan_length != ',' && *scan_length != '}') if ((isarray && *scan_length != ',' && *scan_length != '}')
|| (!isarray && *scan_length != '\0')) /* Garbage left */ || (!isarray && *scan_length != '\0')) /* Garbage left */
{ {
...@@ -190,7 +204,8 @@ ECPGget_data(const PGresult *results, int act_tuple, int act_field, int lineno, ...@@ -190,7 +204,8 @@ ECPGget_data(const PGresult *results, int act_tuple, int act_field, int lineno,
} }
} }
else else
((unsigned long long int *) var)[act_tuple] = (long long) 0; /* ((unsigned long long int *) var)[act_tuple] = (long long) 0;*/
*((unsigned long long int *) (var + offset*act_tuple)) = (long long) 0;
break; break;
#endif /* HAVE_STRTOULL */ #endif /* HAVE_STRTOULL */
...@@ -221,10 +236,12 @@ ECPGget_data(const PGresult *results, int act_tuple, int act_field, int lineno, ...@@ -221,10 +236,12 @@ ECPGget_data(const PGresult *results, int act_tuple, int act_field, int lineno,
switch (type) switch (type)
{ {
case ECPGt_float: case ECPGt_float:
((float *) var)[act_tuple] = dres; /* ((float *) var)[act_tuple] = dres;*/
*((float *) (var + offset*act_tuple)) = dres;
break; break;
case ECPGt_double: case ECPGt_double:
((double *) var)[act_tuple] = dres; /* ((double *) var)[act_tuple] = dres;*/
*((double *) (var + offset*act_tuple)) = dres;
break; break;
default: default:
/* Cannot happen */ /* Cannot happen */
...@@ -238,9 +255,11 @@ ECPGget_data(const PGresult *results, int act_tuple, int act_field, int lineno, ...@@ -238,9 +255,11 @@ ECPGget_data(const PGresult *results, int act_tuple, int act_field, int lineno,
if (pval[0] == 'f' && pval[1] == '\0') if (pval[0] == 'f' && pval[1] == '\0')
{ {
if (offset == sizeof(char)) if (offset == sizeof(char))
((char *) var)[act_tuple] = false; /* ((char *) var)[act_tuple] = false;*/
*((char *) (var + offset*act_tuple)) = false;
else if (offset == sizeof(int)) else if (offset == sizeof(int))
((int *) var)[act_tuple] = false; /* ((int *) var)[act_tuple] = false;*/
*((int *) (var + offset*act_tuple)) = false;
else else
ECPGraise(lineno, ECPG_CONVERT_BOOL, "different size"); ECPGraise(lineno, ECPG_CONVERT_BOOL, "different size");
break; break;
...@@ -248,9 +267,11 @@ ECPGget_data(const PGresult *results, int act_tuple, int act_field, int lineno, ...@@ -248,9 +267,11 @@ ECPGget_data(const PGresult *results, int act_tuple, int act_field, int lineno,
else if (pval[0] == 't' && pval[1] == '\0') else if (pval[0] == 't' && pval[1] == '\0')
{ {
if (offset == sizeof(char)) if (offset == sizeof(char))
((char *) var)[act_tuple] = true; /* ((char *) var)[act_tuple] = true;*/
*((char *) (var + offset*act_tuple)) = true;
else if (offset == sizeof(int)) else if (offset == sizeof(int))
((int *) var)[act_tuple] = true; /* ((int *) var)[act_tuple] = true;*/
*((int *) (var + offset*act_tuple)) = true;
else else
ECPGraise(lineno, ECPG_CONVERT_BOOL, "different size"); ECPGraise(lineno, ECPG_CONVERT_BOOL, "different size");
break; break;
...@@ -277,16 +298,25 @@ ECPGget_data(const PGresult *results, int act_tuple, int act_field, int lineno, ...@@ -277,16 +298,25 @@ ECPGget_data(const PGresult *results, int act_tuple, int act_field, int lineno,
{ {
case ECPGt_short: case ECPGt_short:
case ECPGt_unsigned_short: case ECPGt_unsigned_short:
((short *) ind)[act_tuple] = strlen(pval); /* ((short *) ind)[act_tuple] = strlen(pval);*/
*((short *) (ind + ind_offset*act_tuple)) = strlen(pval);
break; break;
case ECPGt_int: case ECPGt_int:
case ECPGt_unsigned_int: case ECPGt_unsigned_int:
((int *) ind)[act_tuple] = strlen(pval); /* ((int *) ind)[act_tuple] = strlen(pval);*/
*((int *) (ind + ind_offset*act_tuple)) = strlen(pval);
break; break;
case ECPGt_long: case ECPGt_long:
case ECPGt_unsigned_long: case ECPGt_unsigned_long:
((long *) ind)[act_tuple] = strlen(pval); /* ((long *) ind)[act_tuple] = strlen(pval);*/
*((long *) (ind + ind_offset*act_tuple)) = strlen(pval);
break;
#ifdef HAVE_LONG_LONG_INT_64
case ECPGt_long_long:
case ECPGt_unsigned_long_long:
*((long long int *) (ind + ind_offset*act_tuple)) = strlen(pval);
break; break;
#endif /* HAVE_LONG_LONG_INT_64 */
default: default:
break; break;
} }
...@@ -313,16 +343,25 @@ ECPGget_data(const PGresult *results, int act_tuple, int act_field, int lineno, ...@@ -313,16 +343,25 @@ ECPGget_data(const PGresult *results, int act_tuple, int act_field, int lineno,
{ {
case ECPGt_short: case ECPGt_short:
case ECPGt_unsigned_short: case ECPGt_unsigned_short:
((short *) ind)[act_tuple] = variable->len; /* ((short *) ind)[act_tuple] = variable->len;*/
*((short *) (ind + offset*act_tuple)) = variable->len;
break; break;
case ECPGt_int: case ECPGt_int:
case ECPGt_unsigned_int: case ECPGt_unsigned_int:
((int *) ind)[act_tuple] = variable->len; /* ((int *) ind)[act_tuple] = variable->len;*/
*((int *) (ind + offset*act_tuple)) = variable->len;
break; break;
case ECPGt_long: case ECPGt_long:
case ECPGt_unsigned_long: case ECPGt_unsigned_long:
((long *) ind)[act_tuple] = variable->len; /* ((long *) ind)[act_tuple] = variable->len;*/
*((long *) (ind + offset*act_tuple)) = variable->len;
break;
#ifdef HAVE_LONG_LONG_INT_64
case ECPGt_long_long:
case ECPGt_unsigned_long_long:
*((long long int *) (ind + ind_offset*act_tuple)) = variable->len;
break; break;
#endif /* HAVE_LONG_LONG_INT_64 */
default: default:
break; break;
} }
......
/* dynamic SQL support routines /* dynamic SQL support routines
* *
* $Header: /cvsroot/pgsql/src/interfaces/ecpg/lib/Attic/descriptor.c,v 1.19 2001/11/14 11:11:49 meskes Exp $ * $Header: /cvsroot/pgsql/src/interfaces/ecpg/lib/Attic/descriptor.c,v 1.20 2001/12/23 12:17:41 meskes Exp $
*/ */
#include "postgres_fe.h" #include "postgres_fe.h"
...@@ -374,9 +374,9 @@ ECPGdeallocate_desc(int line, const char *name) ...@@ -374,9 +374,9 @@ ECPGdeallocate_desc(int line, const char *name)
if (!strcmp(name, i->name)) if (!strcmp(name, i->name))
{ {
*lastptr = i->next; *lastptr = i->next;
free(i->name); ECPGfree(i->name);
PQclear(i->result); PQclear(i->result);
free(i); ECPGfree(i);
return true; return true;
} }
} }
......
/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/lib/Attic/error.c,v 1.13 2001/11/14 11:11:49 meskes Exp $ */ /* $Header: /cvsroot/pgsql/src/interfaces/ecpg/lib/Attic/error.c,v 1.14 2001/12/23 12:17:41 meskes Exp $ */
#include "postgres_fe.h" #include "postgres_fe.h"
...@@ -82,6 +82,11 @@ ECPGraise(int line, int code, const char *str) ...@@ -82,6 +82,11 @@ ECPGraise(int line, int code, const char *str)
"Data read from backend is not an array in line %d.", line); "Data read from backend is not an array in line %d.", line);
break; break;
case ECPG_ARRAY_INSERT:
snprintf(sqlca.sqlerrm.sqlerrmc, sizeof(sqlca.sqlerrm.sqlerrmc),
"Trying to insert an array of variables in line %d.", line);
break;
case ECPG_NO_CONN: case ECPG_NO_CONN:
snprintf(sqlca.sqlerrm.sqlerrmc, sizeof(sqlca.sqlerrm.sqlerrmc), snprintf(sqlca.sqlerrm.sqlerrmc, sizeof(sqlca.sqlerrm.sqlerrmc),
"No such connection %s in line %d.", str, line); "No such connection %s in line %d.", str, line);
......
/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/lib/Attic/execute.c,v 1.33 2001/11/21 22:57:01 tgl Exp $ */ /* $Header: /cvsroot/pgsql/src/interfaces/ecpg/lib/Attic/execute.c,v 1.34 2001/12/23 12:17:41 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.
...@@ -55,40 +55,6 @@ struct sqlca sqlca = ...@@ -55,40 +55,6 @@ struct sqlca sqlca =
} }
}; };
/* keep a list of memory we allocated for the user */
static struct auto_mem
{
void *pointer;
struct auto_mem *next;
} *auto_allocs = NULL;
void
ECPGadd_mem(void *ptr, int lineno)
{
struct auto_mem *am = (struct auto_mem *) ECPGalloc(sizeof(struct auto_mem), lineno);
am->pointer = ptr;
am->next = auto_allocs;
auto_allocs = am;
}
void
ECPGfree_auto_mem(void)
{
struct auto_mem *am;
/* free all memory we have allocated for the user */
for (am = auto_allocs; am;)
{
struct auto_mem *act = am;
am = am->next;
free(act->pointer);
free(act);
}
auto_allocs = NULL;
}
/* This function returns a newly malloced string that has the \ /* This function returns a newly malloced string that has the \
in the argument quoted with \ and the ' quote with ' as SQL92 says. in the argument quoted with \ and the ' quote with ' as SQL92 says.
*/ */
...@@ -182,7 +148,7 @@ create_statement(int lineno, struct connection * connection, struct statement ** ...@@ -182,7 +148,7 @@ create_statement(int lineno, struct connection * connection, struct statement **
if (var->pointer == NULL) if (var->pointer == NULL)
{ {
ECPGraise(lineno, ECPG_INVALID_STMT, NULL); ECPGraise(lineno, ECPG_INVALID_STMT, NULL);
free(var); ECPGfree(var);
return false; return false;
} }
...@@ -202,7 +168,7 @@ create_statement(int lineno, struct connection * connection, struct statement ** ...@@ -202,7 +168,7 @@ create_statement(int lineno, struct connection * connection, struct statement **
var->ind_offset = va_arg(ap, long); var->ind_offset = va_arg(ap, long);
var->next = NULL; var->next = NULL;
if (var->ind_type!=ECPGt_NO_INDICATOR if (var->ind_type != ECPGt_NO_INDICATOR
&& (var->ind_arrsize == 0 || var->ind_varcharsize == 0)) && (var->ind_arrsize == 0 || var->ind_varcharsize == 0))
var->ind_value = *((void **) (var->ind_pointer)); var->ind_value = *((void **) (var->ind_pointer));
else else
...@@ -230,13 +196,13 @@ free_variable(struct variable * var) ...@@ -230,13 +196,13 @@ free_variable(struct variable * var)
if (var == (struct variable *) NULL) if (var == (struct variable *) NULL)
return; return;
var_next = var->next; var_next = var->next;
free(var); ECPGfree(var);
while (var_next) while (var_next)
{ {
var = var_next; var = var_next;
var_next = var->next; var_next = var->next;
free(var); ECPGfree(var);
} }
} }
...@@ -247,7 +213,7 @@ free_statement(struct statement * stmt) ...@@ -247,7 +213,7 @@ free_statement(struct statement * stmt)
return; return;
free_variable(stmt->inlist); free_variable(stmt->inlist);
free_variable(stmt->outlist); free_variable(stmt->outlist);
free(stmt); ECPGfree(stmt);
} }
static char * static char *
...@@ -354,7 +320,7 @@ ECPGis_type_an_array(int type, const struct statement * stmt, const struct varia ...@@ -354,7 +320,7 @@ ECPGis_type_an_array(int type, const struct statement * stmt, const struct varia
array_query = (char *) ECPGalloc(strlen("select typelem from pg_type where oid=") + 11, stmt->lineno); array_query = (char *) ECPGalloc(strlen("select typelem from pg_type where oid=") + 11, stmt->lineno);
sprintf(array_query, "select typelem from pg_type where oid=%d", type); sprintf(array_query, "select typelem from pg_type where oid=%d", type);
query = PQexec(stmt->connection->connection, array_query); query = PQexec(stmt->connection->connection, array_query);
free(array_query); ECPGfree(array_query);
if (PQresultStatus(query) == PGRES_TUPLES_OK) if (PQresultStatus(query) == PGRES_TUPLES_OK)
{ {
isarray = atol((char *) PQgetvalue(query, 0, 0)); isarray = atol((char *) PQgetvalue(query, 0, 0));
...@@ -460,6 +426,7 @@ ECPGstore_result(const PGresult *results, int act_field, ...@@ -460,6 +426,7 @@ ECPGstore_result(const PGresult *results, int act_field,
*((void **) var->pointer) = var->value; *((void **) var->pointer) = var->value;
ECPGadd_mem(var->value, stmt->lineno); ECPGadd_mem(var->value, stmt->lineno);
} }
/* allocate indicator variable if needed */ /* allocate indicator variable if needed */
if ((var->ind_arrsize == 0 || var->ind_varcharsize == 0) && var->ind_value == NULL && var->ind_pointer!=NULL) if ((var->ind_arrsize == 0 || var->ind_varcharsize == 0) && var->ind_value == NULL && var->ind_pointer!=NULL)
{ {
...@@ -470,7 +437,6 @@ ECPGstore_result(const PGresult *results, int act_field, ...@@ -470,7 +437,6 @@ ECPGstore_result(const PGresult *results, int act_field,
} }
/* fill the variable with the tuple(s) */ /* fill the variable with the tuple(s) */
if (!var->varcharsize && !var->arrsize && if (!var->varcharsize && !var->arrsize &&
(var->type==ECPGt_char || var->type==ECPGt_unsigned_char)) (var->type==ECPGt_char || var->type==ECPGt_unsigned_char))
{ {
...@@ -486,7 +452,7 @@ ECPGstore_result(const PGresult *results, int act_field, ...@@ -486,7 +452,7 @@ ECPGstore_result(const PGresult *results, int act_field,
int len = strlen(PQgetvalue(results, act_tuple, act_field)) + 1; int len = strlen(PQgetvalue(results, act_tuple, act_field)) + 1;
if (!ECPGget_data(results, act_tuple, act_field, stmt->lineno, if (!ECPGget_data(results, act_tuple, act_field, stmt->lineno,
var->type, var->ind_type, current_data_location, var->type, var->ind_type, current_data_location,
var->ind_value, len, 0, isarray)) var->ind_value, len, 0, 0, isarray))
status = false; status = false;
else else
{ {
...@@ -505,7 +471,7 @@ ECPGstore_result(const PGresult *results, int act_field, ...@@ -505,7 +471,7 @@ ECPGstore_result(const PGresult *results, int act_field,
{ {
if (!ECPGget_data(results, act_tuple, act_field, stmt->lineno, if (!ECPGget_data(results, act_tuple, act_field, stmt->lineno,
var->type, var->ind_type, var->value, var->type, var->ind_type, var->value,
var->ind_value, var->varcharsize, var->offset, isarray)) var->ind_value, var->varcharsize, var->offset, var->ind_offset, isarray))
status = false; status = false;
} }
} }
...@@ -519,6 +485,16 @@ ECPGstore_input(const struct statement * stmt, const struct variable * var, ...@@ -519,6 +485,16 @@ ECPGstore_input(const struct statement * stmt, const struct variable * var,
char *mallocedval = NULL; char *mallocedval = NULL;
char *newcopy = NULL; char *newcopy = NULL;
/*
* arrays are not possible
*/
if (var->arrsize > 1)
{
ECPGraise(stmt->lineno, ECPG_ARRAY_INSERT, NULL);
return false;
}
/* /*
* Some special treatment is needed for records since we want their * Some special treatment is needed for records since we want their
* contents to arrive in a comma-separated list on insert (I think). * contents to arrive in a comma-separated list on insert (I think).
...@@ -816,7 +792,7 @@ ECPGstore_input(const struct statement * stmt, const struct variable * var, ...@@ -816,7 +792,7 @@ ECPGstore_input(const struct statement * stmt, const struct variable * var,
if (!mallocedval) if (!mallocedval)
return false; return false;
free(newcopy); ECPGfree(newcopy);
*tobeinserted_p = mallocedval; *tobeinserted_p = mallocedval;
*malloced_p = true; *malloced_p = true;
...@@ -851,7 +827,7 @@ ECPGstore_input(const struct statement * stmt, const struct variable * var, ...@@ -851,7 +827,7 @@ ECPGstore_input(const struct statement * stmt, const struct variable * var,
if (!mallocedval) if (!mallocedval)
return false; return false;
free(newcopy); ECPGfree(newcopy);
*tobeinserted_p = mallocedval; *tobeinserted_p = mallocedval;
*malloced_p = true; *malloced_p = true;
...@@ -936,11 +912,11 @@ ECPGexecute(struct statement * stmt) ...@@ -936,11 +912,11 @@ ECPGexecute(struct statement * stmt)
*/ */
if (malloced) if (malloced)
{ {
free((char *) tobeinserted); ECPGfree((char *) tobeinserted);
tobeinserted = NULL; tobeinserted = NULL;
} }
free(copiedquery); ECPGfree(copiedquery);
copiedquery = newcopy; copiedquery = newcopy;
var = var->next; var = var->next;
...@@ -968,7 +944,7 @@ ECPGexecute(struct statement * stmt) ...@@ -968,7 +944,7 @@ ECPGexecute(struct statement * stmt)
ECPGlog("ECPGexecute line %d: QUERY: %s on connection %s\n", stmt->lineno, copiedquery, stmt->connection->name); ECPGlog("ECPGexecute line %d: QUERY: %s on connection %s\n", stmt->lineno, copiedquery, stmt->connection->name);
results = PQexec(stmt->connection->connection, copiedquery); results = PQexec(stmt->connection->connection, copiedquery);
free(copiedquery); ECPGfree(copiedquery);
if (results == NULL) if (results == NULL)
{ {
...@@ -1091,7 +1067,7 @@ ECPGexecute(struct statement * stmt) ...@@ -1091,7 +1067,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);
free(notify); ECPGfree(notify);
} }
return status; return status;
...@@ -1114,15 +1090,16 @@ ECPGdo(int lineno, const char *connection_name, char *query,...) ...@@ -1114,15 +1090,16 @@ ECPGdo(int lineno, const char *connection_name, char *query,...)
if (!ECPGinit(con, connection_name, lineno)) if (!ECPGinit(con, connection_name, lineno))
{ {
setlocale(LC_NUMERIC, oldlocale); setlocale(LC_NUMERIC, oldlocale);
free(oldlocale); ECPGfree(oldlocale);
return (false); return (false);
} }
/* construct statement in our own structure */
va_start(args, query); va_start(args, query);
if (create_statement(lineno, con, &stmt, query, args) == false) if (create_statement(lineno, con, &stmt, query, args) == false)
{ {
setlocale(LC_NUMERIC, oldlocale); setlocale(LC_NUMERIC, oldlocale);
free(oldlocale); ECPGfree(oldlocale);
return (false); return (false);
} }
va_end(args); va_end(args);
...@@ -1133,16 +1110,19 @@ ECPGdo(int lineno, const char *connection_name, char *query,...) ...@@ -1133,16 +1110,19 @@ ECPGdo(int lineno, const char *connection_name, char *query,...)
free_statement(stmt); free_statement(stmt);
ECPGraise(lineno, ECPG_NOT_CONN, (con) ? con->name : "<empty>"); ECPGraise(lineno, ECPG_NOT_CONN, (con) ? con->name : "<empty>");
setlocale(LC_NUMERIC, oldlocale); setlocale(LC_NUMERIC, oldlocale);
free(oldlocale); ECPGfree(oldlocale);
return false; return false;
} }
/* initialize auto_mem struct */
ECPGclear_auto_mem();
status = ECPGexecute(stmt); status = ECPGexecute(stmt);
free_statement(stmt); free_statement(stmt);
/* and reset locale value so our application is not affected */ /* and reset locale value so our application is not affected */
setlocale(LC_NUMERIC, oldlocale); setlocale(LC_NUMERIC, oldlocale);
free(oldlocale); ECPGfree(oldlocale);
return (status); return (status);
} }
......
...@@ -6,15 +6,17 @@ ...@@ -6,15 +6,17 @@
void ECPGadd_mem(void *ptr, int lineno); void ECPGadd_mem(void *ptr, int lineno);
bool ECPGget_data(const PGresult *, int, int, int, enum ECPGttype type, bool ECPGget_data(const PGresult *, int, int, int, enum ECPGttype type,
enum ECPGttype, void *, void *, long, long, bool); enum ECPGttype, void *, void *, long, long, long, bool);
struct connection *ECPGget_connection(const char *); struct connection *ECPGget_connection(const char *);
void ECPGinit_sqlca(void); void ECPGinit_sqlca(void);
char *ECPGalloc(long, int); char *ECPGalloc(long, int);
void ECPGfree(void *);
bool ECPGinit(const struct connection *, const char *, const int); bool ECPGinit(const struct connection *, const char *, const int);
char *ECPGstrdup(const char *, int); char *ECPGstrdup(const char *, int);
const char *ECPGtype_name(enum ECPGttype); const char *ECPGtype_name(enum ECPGttype);
unsigned int ECPGDynamicType(Oid); unsigned int ECPGDynamicType(Oid);
void ECPGfree_auto_mem(void);
void ECPGclear_auto_mem(void);
/* A generic varchar type. */ /* A generic varchar type. */
struct ECPGgeneric_varchar struct ECPGgeneric_varchar
......
/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/lib/Attic/memory.c,v 1.7 2001/11/14 11:11:49 meskes Exp $ */ /* $Header: /cvsroot/pgsql/src/interfaces/ecpg/lib/Attic/memory.c,v 1.8 2001/12/23 12:17:41 meskes Exp $ */
#include "postgres_fe.h" #include "postgres_fe.h"
...@@ -7,6 +7,12 @@ ...@@ -7,6 +7,12 @@
#include "ecpgerrno.h" #include "ecpgerrno.h"
#include "extern.h" #include "extern.h"
void
ECPGfree(void *ptr)
{
free(ptr);
}
char * char *
ECPGalloc(long size, int lineno) ECPGalloc(long size, int lineno)
{ {
...@@ -35,3 +41,54 @@ ECPGstrdup(const char *string, int lineno) ...@@ -35,3 +41,54 @@ ECPGstrdup(const char *string, int lineno)
return (new); return (new);
} }
/* keep a list of memory we allocated for the user */
static struct auto_mem
{
void *pointer;
struct auto_mem *next;
} *auto_allocs = NULL;
void
ECPGadd_mem(void *ptr, int lineno)
{
struct auto_mem *am = (struct auto_mem *) ECPGalloc(sizeof(struct auto_mem), lineno);
am->pointer = ptr;
am->next = auto_allocs;
auto_allocs = am;
}
void
ECPGfree_auto_mem(void)
{
struct auto_mem *am;
/* free all memory we have allocated for the user */
for (am = auto_allocs; am;)
{
struct auto_mem *act = am;
am = am->next;
ECPGfree(act->pointer);
ECPGfree(act);
}
auto_allocs = NULL;
}
void
ECPGclear_auto_mem(void)
{
struct auto_mem *am;
/* free just our own structure */
for (am = auto_allocs; am;)
{
struct auto_mem *act = am;
am = am->next;
ECPGfree(act);
}
auto_allocs = NULL;
}
/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/lib/Attic/misc.c,v 1.10 2001/11/14 11:11:49 meskes Exp $ */ /* $Header: /cvsroot/pgsql/src/interfaces/ecpg/lib/Attic/misc.c,v 1.11 2001/12/23 12:17:41 meskes Exp $ */
#include "postgres_fe.h" #include "postgres_fe.h"
...@@ -137,6 +137,6 @@ ECPGlog(const char *format,...) ...@@ -137,6 +137,6 @@ ECPGlog(const char *format,...)
vfprintf(debugstream, f, ap); vfprintf(debugstream, f, ap);
va_end(ap); va_end(ap);
free(f); ECPGfree(f);
} }
} }
/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/lib/Attic/prepare.c,v 1.11 2001/11/14 11:11:49 meskes Exp $ */ /* $Header: /cvsroot/pgsql/src/interfaces/ecpg/lib/Attic/prepare.c,v 1.12 2001/12/23 12:17:41 meskes Exp $ */
#include "postgres_fe.h" #include "postgres_fe.h"
...@@ -76,7 +76,7 @@ ECPGprepare(int lineno, char *name, char *variable) ...@@ -76,7 +76,7 @@ ECPGprepare(int lineno, char *name, char *variable)
stmt = (struct statement *) ECPGalloc(sizeof(struct statement), lineno); stmt = (struct statement *) ECPGalloc(sizeof(struct statement), lineno);
if (!stmt) if (!stmt)
{ {
free(this); ECPGfree(this);
return false; return false;
} }
...@@ -114,15 +114,15 @@ ECPGdeallocate(int lineno, char *name) ...@@ -114,15 +114,15 @@ ECPGdeallocate(int lineno, char *name)
if (this) if (this)
{ {
/* okay, free all the resources */ /* okay, free all the resources */
free(this->name); ECPGfree(this->name);
free(this->stmt->command); ECPGfree(this->stmt->command);
free(this->stmt); ECPGfree(this->stmt);
if (prev != NULL) if (prev != NULL)
prev->next = this->next; prev->next = this->next;
else else
prep_stmts = this->next; prep_stmts = this->next;
free(this); ECPGfree(this);
return true; return true;
} }
ECPGraise(lineno, ECPG_INVALID_STMT, name); ECPGraise(lineno, ECPG_INVALID_STMT, name);
......
# $Header: /cvsroot/pgsql/src/interfaces/ecpg/preproc/Makefile,v 1.78 2001/11/16 16:32:33 petere Exp $ # $Header: /cvsroot/pgsql/src/interfaces/ecpg/preproc/Makefile,v 1.79 2001/12/23 12:17:41 meskes Exp $
subdir = src/interfaces/ecpg/preproc subdir = src/interfaces/ecpg/preproc
top_builddir = ../../../.. top_builddir = ../../../..
include $(top_builddir)/src/Makefile.global include $(top_builddir)/src/Makefile.global
CFLAGS+=-g
MAJOR_VERSION=2 MAJOR_VERSION=2
MINOR_VERSION=9 MINOR_VERSION=9
PATCHLEVEL=0 PATCHLEVEL=0
......
...@@ -45,7 +45,7 @@ ECPGnumeric_lvalue(FILE *f, char *name) ...@@ -45,7 +45,7 @@ ECPGnumeric_lvalue(FILE *f, char *name)
{ {
const struct variable *v = find_variable(name); const struct variable *v = find_variable(name);
switch (v->type->typ) switch (v->type->type)
{ {
case ECPGt_short: case ECPGt_short:
case ECPGt_int: case ECPGt_int:
...@@ -192,7 +192,7 @@ output_get_descr(char *desc_name, char *index) ...@@ -192,7 +192,7 @@ output_get_descr(char *desc_name, char *index)
break; break;
} }
fprintf(yyout, "%s,", get_dtype(results->value)); fprintf(yyout, "%s,", get_dtype(results->value));
ECPGdump_a_type(yyout, v->name, v->type, NULL, NULL, NULL, NULL); ECPGdump_a_type(yyout, v->name, v->type, NULL, NULL, NULL, NULL, 0L, NULL, NULL);
} }
drop_assignments(); drop_assignments();
fputs("ECPGd_EODT);\n", yyout); fputs("ECPGd_EODT);\n", yyout);
......
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/interfaces/ecpg/preproc/pgc.l,v 1.82 2001/12/09 15:27:49 meskes Exp $ * $Header: /cvsroot/pgsql/src/interfaces/ecpg/preproc/pgc.l,v 1.83 2001/12/23 12:17:41 meskes Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -219,9 +219,7 @@ param \${integer} ...@@ -219,9 +219,7 @@ param \${integer}
ccomment "//".*\n ccomment "//".*\n
space [ \t\r\f] space [ \t\n\r\f]
space_or_nl [ \t\r\f\n]
line_end {space}*\n
horiz_space [ \t\f] horiz_space [ \t\f]
newline [\n\r] newline [\n\r]
non_newline [^\n\r] non_newline [^\n\r]
...@@ -254,12 +252,12 @@ else [eE][lL][sS][eE] ...@@ -254,12 +252,12 @@ else [eE][lL][sS][eE]
elif [eE][lL][iI][fF] elif [eE][lL][iI][fF]
endif [eE][nN][dD][iI][fF] endif [eE][nN][dD][iI][fF]
exec_sql {exec}{space_or_nl}*{sql}{space_or_nl}* exec_sql {exec}{space}*{sql}{space}*
ipdigit ({digit}|{digit}{digit}|{digit}{digit}{digit}) ipdigit ({digit}|{digit}{digit}|{digit}{digit}{digit})
ip {ipdigit}\.{ipdigit}\.{ipdigit}\.{ipdigit} ip {ipdigit}\.{ipdigit}\.{ipdigit}\.{ipdigit}
/* Take care of cpp continuation lines */ /* Take care of cpp continuation lines */
cppline {space}*#(.*\\{line_end})*.* cppline {space}*#(.*\\{space})*.*
/* DO NOT PUT ANY COMMENTS IN THE FOLLOWING SECTION. /* DO NOT PUT ANY COMMENTS IN THE FOLLOWING SECTION.
* AT&T lex does not properly handle C-style comments in this second lex block. * AT&T lex does not properly handle C-style comments in this second lex block.
...@@ -655,7 +653,7 @@ cppline {space}*#(.*\\{line_end})*.* ...@@ -655,7 +653,7 @@ cppline {space}*#(.*\\{line_end})*.*
<C>"-" { return('-'); } <C>"-" { return('-'); }
<C>"(" { return('('); } <C>"(" { return('('); }
<C>")" { return(')'); } <C>")" { return(')'); }
<C>{space_or_nl} { ECHO; } <C>{space} { ECHO; }
<C>\{ { return('{'); } <C>\{ { return('{'); }
<C>\} { return('}'); } <C>\} { return('}'); }
<C>\[ { return('['); } <C>\[ { return('['); }
...@@ -679,13 +677,13 @@ cppline {space}*#(.*\\{line_end})*.* ...@@ -679,13 +677,13 @@ cppline {space}*#(.*\\{line_end})*.*
<C>".*" { return(S_DOTPOINT); } <C>".*" { return(S_DOTPOINT); }
<C>{other} { return S_ANYTHING; } <C>{other} { return S_ANYTHING; }
<C>{exec_sql}{define}{space_or_nl}* { BEGIN(def_ident); } <C>{exec_sql}{define}{space}* { BEGIN(def_ident); }
<C>{exec_sql}{include}{space_or_nl}* { BEGIN(incl); } <C>{exec_sql}{include}{space}* { BEGIN(incl); }
<C,xskip>{exec_sql}{ifdef}{space_or_nl}* { ifcond = TRUE; BEGIN(xcond); } <C,xskip>{exec_sql}{ifdef}{space}* { ifcond = TRUE; BEGIN(xcond); }
<C,xskip>{exec_sql}{ifndef}{space_or_nl}* { ifcond = FALSE; BEGIN(xcond); } <C,xskip>{exec_sql}{ifndef}{space}* { ifcond = FALSE; BEGIN(xcond); }
<C,xskip>{exec_sql}{elif}{space_or_nl}* { /* pop stack */ <C,xskip>{exec_sql}{elif}{space}* { /* pop stack */
if ( preproc_tos == 0 ) { if ( preproc_tos == 0 ) {
mmerror(PARSE_ERROR, ET_FATAL, "Missing matching 'EXEC SQL IFDEF / EXEC SQL IFNDEF'"); mmerror(PARSE_ERROR, ET_FATAL, "Missing matching 'EXEC SQL IFDEF / EXEC SQL IFNDEF'");
} }
...@@ -699,7 +697,7 @@ cppline {space}*#(.*\\{line_end})*.* ...@@ -699,7 +697,7 @@ cppline {space}*#(.*\\{line_end})*.*
ifcond = TRUE; BEGIN(xcond); ifcond = TRUE; BEGIN(xcond);
} }
<C,xskip>{exec_sql}{else}{space_or_nl}*";" { /* only exec sql endif pops the stack, so take care of duplicated 'else' */ <C,xskip>{exec_sql}{else}{space}*";" { /* only exec sql endif pops the stack, so take care of duplicated 'else' */
if ( stacked_if_value[preproc_tos].else_branch ) { if ( stacked_if_value[preproc_tos].else_branch ) {
mmerror(PARSE_ERROR, ET_FATAL, "Duplicated 'EXEC SQL ELSE;'"); mmerror(PARSE_ERROR, ET_FATAL, "Duplicated 'EXEC SQL ELSE;'");
} }
...@@ -717,7 +715,7 @@ cppline {space}*#(.*\\{line_end})*.* ...@@ -717,7 +715,7 @@ cppline {space}*#(.*\\{line_end})*.*
} }
} }
} }
<C,xskip>{exec_sql}{endif}{space_or_nl}*";" { <C,xskip>{exec_sql}{endif}{space}*";" {
if ( preproc_tos == 0 ) { if ( preproc_tos == 0 ) {
mmerror(PARSE_ERROR, ET_FATAL, "Unmatched 'EXEC SQL ENDIF;'"); mmerror(PARSE_ERROR, ET_FATAL, "Unmatched 'EXEC SQL ENDIF;'");
} }
...@@ -735,7 +733,7 @@ cppline {space}*#(.*\\{line_end})*.* ...@@ -735,7 +733,7 @@ cppline {space}*#(.*\\{line_end})*.*
<xskip>{other} { /* ignore */ } <xskip>{other} { /* ignore */ }
<xcond>{identifier}{space_or_nl}*";" { <xcond>{identifier}{space}*";" {
if ( preproc_tos >= MAX_NESTED_IF-1 ) { if ( preproc_tos >= MAX_NESTED_IF-1 ) {
mmerror(PARSE_ERROR, ET_FATAL, "Too many nested 'EXEC SQL IFDEF' conditions"); mmerror(PARSE_ERROR, ET_FATAL, "Too many nested 'EXEC SQL IFDEF' conditions");
} }
...@@ -773,7 +771,7 @@ cppline {space}*#(.*\\{line_end})*.* ...@@ -773,7 +771,7 @@ cppline {space}*#(.*\\{line_end})*.*
BEGIN(def); BEGIN(def);
startlit(); startlit();
} }
<def>{space_or_nl}*";" { <def>{space}*";" {
struct _defines *ptr, *this; struct _defines *ptr, *this;
for (ptr = defines; ptr != NULL; ptr = ptr->next) for (ptr = defines; ptr != NULL; ptr = ptr->next)
......
...@@ -22,10 +22,13 @@ static char *actual_startline[STRUCT_DEPTH]; ...@@ -22,10 +22,13 @@ static char *actual_startline[STRUCT_DEPTH];
/* temporarily store struct members while creating the data structure */ /* temporarily store struct members while creating the data structure */
struct ECPGstruct_member *struct_member_list[STRUCT_DEPTH] = { NULL }; struct ECPGstruct_member *struct_member_list[STRUCT_DEPTH] = { NULL };
struct ECPGtype ecpg_no_indicator = {ECPGt_NO_INDICATOR, 0L, {NULL}}; /* also store struct type so we can do a sizeof() later */
static char *ECPGstruct_sizeof = NULL;
struct ECPGtype ecpg_no_indicator = {ECPGt_NO_INDICATOR, 0L, NULL, {NULL}};
struct variable no_indicator = {"no_indicator", &ecpg_no_indicator, 0, NULL}; struct variable no_indicator = {"no_indicator", &ecpg_no_indicator, 0, NULL};
struct ECPGtype ecpg_query = {ECPGt_char_variable, 0L, {NULL}}; struct ECPGtype ecpg_query = {ECPGt_char_variable, 0L, NULL, {NULL}};
/* /*
* Handle parsing errors and warnings * Handle parsing errors and warnings
...@@ -3914,14 +3917,14 @@ connection_target: database_name opt_server opt_port ...@@ -3914,14 +3917,14 @@ connection_target: database_name opt_server opt_port
$$ = $1; $$ = $1;
else if (strcmp($1, "?") == 0) /* variable */ else if (strcmp($1, "?") == 0) /* variable */
{ {
enum ECPGttype typ = argsinsert->variable->type->typ; enum ECPGttype type = argsinsert->variable->type->type;
/* if array see what's inside */ /* if array see what's inside */
if (typ == ECPGt_array) if (type == ECPGt_array)
typ = argsinsert->variable->type->u.element->typ; type = argsinsert->variable->type->u.element->type;
/* handle varchars */ /* handle varchars */
if (typ == ECPGt_varchar) if (type == ECPGt_varchar)
$$ = make2_str(mm_strdup(argsinsert->variable->name), make_str(".arr")); $$ = make2_str(mm_strdup(argsinsert->variable->name), make_str(".arr"));
else else
$$ = mm_strdup(argsinsert->variable->name); $$ = mm_strdup(argsinsert->variable->name);
...@@ -4002,14 +4005,14 @@ user_name: UserId { ...@@ -4002,14 +4005,14 @@ user_name: UserId {
$$ = $1; $$ = $1;
else if (strcmp($1, "?") == 0) /* variable */ else if (strcmp($1, "?") == 0) /* variable */
{ {
enum ECPGttype typ = argsinsert->variable->type->typ; enum ECPGttype type = argsinsert->variable->type->type;
/* if array see what's inside */ /* if array see what's inside */
if (typ == ECPGt_array) if (type == ECPGt_array)
typ = argsinsert->variable->type->u.element->typ; type = argsinsert->variable->type->u.element->type;
/* handle varchars */ /* handle varchars */
if (typ == ECPGt_varchar) if (type == ECPGt_varchar)
$$ = make2_str(mm_strdup(argsinsert->variable->name), make_str(".arr")); $$ = make2_str(mm_strdup(argsinsert->variable->name), make_str(".arr"));
else else
$$ = mm_strdup(argsinsert->variable->name); $$ = mm_strdup(argsinsert->variable->name);
...@@ -4021,13 +4024,13 @@ user_name: UserId { ...@@ -4021,13 +4024,13 @@ user_name: UserId {
char_variable: cvariable char_variable: cvariable
{ /* check if we have a char variable */ { /* check if we have a char variable */
struct variable *p = find_variable($1); struct variable *p = find_variable($1);
enum ECPGttype typ = p->type->typ; enum ECPGttype type = p->type->type;
/* if array see what's inside */ /* if array see what's inside */
if (typ == ECPGt_array) if (type == ECPGt_array)
typ = p->type->u.element->typ; type = p->type->u.element->type;
switch (typ) switch (type)
{ {
case ECPGt_char: case ECPGt_char:
case ECPGt_unsigned_char: case ECPGt_unsigned_char:
...@@ -4267,10 +4270,10 @@ union_type: s_union '{' variable_declarations '}' ...@@ -4267,10 +4270,10 @@ union_type: s_union '{' variable_declarations '}'
s_struct: SQL_STRUCT opt_symbol s_struct: SQL_STRUCT opt_symbol
{ {
struct_member_list[struct_level++] = NULL; struct_member_list[struct_level++] = NULL;
$$ = cat2_str(make_str("struct"), $2);
ECPGstruct_sizeof = cat_str(3, make_str("sizeof("), strdup($$), make_str(")"));
if (struct_level >= STRUCT_DEPTH) if (struct_level >= STRUCT_DEPTH)
mmerror(PARSE_ERROR, ET_ERROR, "Too many levels in nested structure definition"); mmerror(PARSE_ERROR, ET_ERROR, "Too many levels in nested structure definition");
$$ = cat2_str(make_str("struct"), $2);
}; };
s_union: UNION opt_symbol s_union: UNION opt_symbol
...@@ -4360,9 +4363,9 @@ variable: opt_pointer ECPGColLabel opt_array_bounds opt_initializer ...@@ -4360,9 +4363,9 @@ variable: opt_pointer ECPGColLabel opt_array_bounds opt_initializer
case ECPGt_struct: case ECPGt_struct:
case ECPGt_union: case ECPGt_union:
if (dimension < 0) if (dimension < 0)
type = ECPGmake_struct_type(struct_member_list[struct_level], actual_type[struct_level].type_enum); type = ECPGmake_struct_type(struct_member_list[struct_level], actual_type[struct_level].type_enum, ECPGstruct_sizeof);
else else
type = ECPGmake_array_type(ECPGmake_struct_type(struct_member_list[struct_level], actual_type[struct_level].type_enum), dimension); type = ECPGmake_array_type(ECPGmake_struct_type(struct_member_list[struct_level], actual_type[struct_level].type_enum, ECPGstruct_sizeof), dimension);
$$ = cat_str(4, $1, mm_strdup($2), $3.str, $4); $$ = cat_str(4, $1, mm_strdup($2), $3.str, $4);
break; break;
...@@ -4783,9 +4786,9 @@ ECPGVar: SQL_VAR ...@@ -4783,9 +4786,9 @@ ECPGVar: SQL_VAR
case ECPGt_struct: case ECPGt_struct:
case ECPGt_union: case ECPGt_union:
if (dimension < 0) if (dimension < 0)
type = ECPGmake_struct_type(struct_member_list[struct_level], $5.type_enum); type = ECPGmake_struct_type(struct_member_list[struct_level], $5.type_enum, ECPGstruct_sizeof);
else else
type = ECPGmake_array_type(ECPGmake_struct_type(struct_member_list[struct_level], $5.type_enum), dimension); type = ECPGmake_array_type(ECPGmake_struct_type(struct_member_list[struct_level], $5.type_enum, ECPGstruct_sizeof), dimension);
break; break;
case ECPGt_varchar: case ECPGt_varchar:
if (dimension == -1) if (dimension == -1)
...@@ -5337,7 +5340,7 @@ coutputvariable: cvariable indicator ...@@ -5337,7 +5340,7 @@ coutputvariable: cvariable indicator
civarind: cvariable indicator civarind: cvariable indicator
{ {
if ($2 != NULL && (find_variable($2))->type->typ == ECPGt_array) if ($2 != NULL && (find_variable($2))->type->type == ECPGt_array)
mmerror(PARSE_ERROR, ET_ERROR, "arrays of indicators are not allowed on input"); mmerror(PARSE_ERROR, ET_ERROR, "arrays of indicators are not allowed on input");
add_variable(&argsinsert, find_variable($1), ($2 == NULL) ? &no_indicator : find_variable($2)); add_variable(&argsinsert, find_variable($1), ($2 == NULL) ? &no_indicator : find_variable($2));
......
This diff is collapsed.
...@@ -4,16 +4,17 @@ struct ECPGtype; ...@@ -4,16 +4,17 @@ struct ECPGtype;
struct ECPGstruct_member struct ECPGstruct_member
{ {
char *name; char *name;
struct ECPGtype *typ; struct ECPGtype *type;
struct ECPGstruct_member *next; struct ECPGstruct_member *next;
}; };
struct ECPGtype struct ECPGtype
{ {
enum ECPGttype typ; enum ECPGttype type;
long size; /* For array it is the number of elements. long size; /* For array it is the number of elements.
* For varchar it is the maxsize of the * For varchar it is the maxsize of the
* area. */ * area. */
char *struct_sizeof; /* For a struct this is the sizeof() type as string */
union union
{ {
struct ECPGtype *element; /* For an array this is the type struct ECPGtype *element; /* For an array this is the type
...@@ -29,7 +30,7 @@ void ECPGmake_struct_member(char *, struct ECPGtype *, struct ECPGstruct_member ...@@ -29,7 +30,7 @@ void ECPGmake_struct_member(char *, struct ECPGtype *, struct ECPGstruct_member
struct ECPGtype *ECPGmake_simple_type(enum ECPGttype, long); struct ECPGtype *ECPGmake_simple_type(enum ECPGttype, long);
struct ECPGtype *ECPGmake_varchar_type(enum ECPGttype, long); struct ECPGtype *ECPGmake_varchar_type(enum ECPGttype, long);
struct ECPGtype *ECPGmake_array_type(struct ECPGtype *, long); struct ECPGtype *ECPGmake_array_type(struct ECPGtype *, long);
struct ECPGtype *ECPGmake_struct_type(struct ECPGstruct_member *, enum ECPGttype type); struct ECPGtype *ECPGmake_struct_type(struct ECPGstruct_member *, enum ECPGttype, char *);
struct ECPGstruct_member *ECPGstruct_member_dup(struct ECPGstruct_member *); struct ECPGstruct_member *ECPGstruct_member_dup(struct ECPGstruct_member *);
/* Frees a type. */ /* Frees a type. */
...@@ -46,16 +47,16 @@ void ECPGfree_type(struct ECPGtype *); ...@@ -46,16 +47,16 @@ void ECPGfree_type(struct ECPGtype *);
size is the maxsize in case it is a varchar. Otherwise it is the size of size is the maxsize in case it is a varchar. Otherwise it is the size of
the variable (required to do array fetches of structs). the variable (required to do array fetches of structs).
*/ */
void ECPGdump_a_type(FILE *, const char *, struct ECPGtype *, const char *, struct ECPGtype *, const char *, const char *); void ECPGdump_a_type(FILE *, const char *, struct ECPGtype *, const char *, struct ECPGtype *, const char *, const char *, const long, const char *, const char *);
/* A simple struct to keep a variable and its type. */ /* A simple struct to keep a variable and its type. */
struct ECPGtemp_type struct ECPGtemp_type
{ {
struct ECPGtype *typ; struct ECPGtype *type;
const char *name; const char *name;
}; };
extern const char *ECPGtype_name(enum ECPGttype typ); extern const char *ECPGtype_name(enum ECPGttype type);
/* some stuff for whenever statements */ /* some stuff for whenever statements */
enum WHEN_TYPE enum WHEN_TYPE
......
...@@ -38,15 +38,15 @@ find_struct_member(char *name, char *str, struct ECPGstruct_member * members) ...@@ -38,15 +38,15 @@ find_struct_member(char *name, char *str, struct ECPGstruct_member * members)
if (c == '\0') if (c == '\0')
{ {
/* found the end */ /* found the end */
switch (members->typ->typ) switch (members->type->type)
{ {
case ECPGt_array: case ECPGt_array:
return (new_variable(name, ECPGmake_array_type(members->typ->u.element, members->typ->size))); return (new_variable(name, ECPGmake_array_type(members->type->u.element, members->type->size)));
case ECPGt_struct: case ECPGt_struct:
case ECPGt_union: case ECPGt_union:
return (new_variable(name, ECPGmake_struct_type(members->typ->u.members, members->typ->typ))); return (new_variable(name, ECPGmake_struct_type(members->type->u.members, members->type->type, members->type->struct_sizeof)));
default: default:
return (new_variable(name, ECPGmake_simple_type(members->typ->typ, members->typ->size))); return (new_variable(name, ECPGmake_simple_type(members->type->type, members->type->size)));
} }
} }
else else
...@@ -55,10 +55,10 @@ find_struct_member(char *name, char *str, struct ECPGstruct_member * members) ...@@ -55,10 +55,10 @@ find_struct_member(char *name, char *str, struct ECPGstruct_member * members)
if (c == '-') if (c == '-')
{ {
next++; next++;
return (find_struct_member(name, next, members->typ->u.element->u.members)); return (find_struct_member(name, next, members->type->u.element->u.members));
} }
else else
return (find_struct_member(name, next, members->typ->u.members)); return (find_struct_member(name, next, members->type->u.members));
} }
} }
} }
...@@ -78,13 +78,13 @@ find_struct(char *name, char *next) ...@@ -78,13 +78,13 @@ find_struct(char *name, char *next)
if (c == '-') if (c == '-')
{ {
if (p->type->typ != ECPGt_array) if (p->type->type != ECPGt_array)
{ {
sprintf(errortext, "variable %s is not a pointer", name); sprintf(errortext, "variable %s is not a pointer", name);
mmerror(PARSE_ERROR, ET_FATAL, errortext); mmerror(PARSE_ERROR, ET_FATAL, errortext);
} }
if (p->type->u.element->typ != ECPGt_struct && p->type->u.element->typ != ECPGt_union) if (p->type->u.element->type != ECPGt_struct && p->type->u.element->type != ECPGt_union)
{ {
sprintf(errortext, "variable %s is not a pointer to a structure or a union", name); sprintf(errortext, "variable %s is not a pointer to a structure or a union", name);
mmerror(PARSE_ERROR, ET_FATAL, errortext); mmerror(PARSE_ERROR, ET_FATAL, errortext);
...@@ -98,7 +98,7 @@ find_struct(char *name, char *next) ...@@ -98,7 +98,7 @@ find_struct(char *name, char *next)
} }
else else
{ {
if (p->type->typ != ECPGt_struct && p->type->typ != ECPGt_union) if (p->type->type != ECPGt_struct && p->type->type != ECPGt_union)
{ {
sprintf(errortext, "variable %s is neither a structure nor a union", name); sprintf(errortext, "variable %s is neither a structure nor a union", name);
mmerror(PARSE_ERROR, ET_FATAL, errortext); mmerror(PARSE_ERROR, ET_FATAL, errortext);
...@@ -242,7 +242,7 @@ dump_variables(struct arguments * list, int mode) ...@@ -242,7 +242,7 @@ dump_variables(struct arguments * list, int mode)
/* Then the current element and its indicator */ /* Then the current element and its indicator */
ECPGdump_a_type(yyout, list->variable->name, list->variable->type, ECPGdump_a_type(yyout, list->variable->name, list->variable->type,
list->indicator->name, list->indicator->type, NULL, NULL); list->indicator->name, list->indicator->type, NULL, NULL, 0, NULL, NULL);
/* Then release the list element. */ /* Then release the list element. */
if (mode != 0) if (mode != 0)
...@@ -253,7 +253,7 @@ void ...@@ -253,7 +253,7 @@ void
check_indicator(struct ECPGtype * var) check_indicator(struct ECPGtype * var)
{ {
/* make sure this is a valid indicator variable */ /* make sure this is a valid indicator variable */
switch (var->typ) switch (var->type)
{ {
struct ECPGstruct_member *p; struct ECPGstruct_member *p;
...@@ -270,7 +270,7 @@ check_indicator(struct ECPGtype * var) ...@@ -270,7 +270,7 @@ check_indicator(struct ECPGtype * var)
case ECPGt_struct: case ECPGt_struct:
case ECPGt_union: case ECPGt_union:
for (p = var->u.members; p; p = p->next) for (p = var->u.members; p; p = p->next)
check_indicator(p->typ); check_indicator(p->type);
break; break;
case ECPGt_array: case ECPGt_array:
......
# $Header: /cvsroot/pgsql/src/interfaces/ecpg/test/Makefile,v 1.32 2001/11/14 11:11:49 meskes Exp $ # $Header: /cvsroot/pgsql/src/interfaces/ecpg/test/Makefile,v 1.33 2001/12/23 12:17:41 meskes Exp $
subdir = src/interfaces/ecpg/test subdir = src/interfaces/ecpg/test
top_builddir = ../../../.. top_builddir = ../../../..
include $(top_builddir)/src/Makefile.global include $(top_builddir)/src/Makefile.global
override CPPFLAGS := -I$(srcdir)/../include $(CPPFLAGS) override CPPFLAGS := -I$(srcdir)/../include $(CPPFLAGS) -g
ECPG = ../preproc/ecpg -I$(srcdir)/../include ECPG = ../preproc/ecpg -I$(srcdir)/../include
......
#include <stdlib.h>
#include <string.h> #include <string.h>
exec sql include sqlca; exec sql include sqlca;
...@@ -34,6 +34,18 @@ exec sql begin declare section; ...@@ -34,6 +34,18 @@ exec sql begin declare section;
int increment=100; int increment=100;
char name[AMOUNT][8]; char name[AMOUNT][8];
char letter[AMOUNT][1]; char letter[AMOUNT][1];
struct name_letter_struct
{
char name[8];
int amount;
char letter;
} name_letter[AMOUNT];
struct ind_struct
{
short a;
short b;
short c;
} ind[AMOUNT];
char command[128]; char command[128];
char *connection="pm"; char *connection="pm";
exec sql end declare section; exec sql end declare section;
...@@ -113,16 +125,28 @@ exec sql end declare section; ...@@ -113,16 +125,28 @@ exec sql end declare section;
exec sql at pm insert into "Test" (name, amount, letter) values (:n, :a, :l); exec sql at pm insert into "Test" (name, amount, letter) values (:n, :a, :l);
} }
strcpy(msg, "commit");
exec sql at pm commit;
strcpy(msg, "select"); strcpy(msg, "select");
exec sql at :connection select name, amount, letter into :name, :amount, :letter from "Test"; exec sql at :connection select name, amount, letter into :name, :amount, :letter from "Test";
printf("Database: pm\n"); printf("Database: %s\n", connection);
for (i=0, j=sqlca.sqlerrd[2]; i<j; i++) for (i=0, j=sqlca.sqlerrd[2]; i<j; i++)
printf("name[%d]=%8.8s\tamount[%d]=%d\tletter[%d]=%c\n", i, name[i], i, amount[i],i, letter[i][0]); printf("name[%d]=%8.8s\tamount[%d]=%d\tletter[%d]=%c\n", i, name[i], i, amount[i],i, letter[i][0]);
strcpy(msg, "select");
exec sql at pm select name, amount, letter into :name_letter from "Test";
strcpy(msg, "commit"); strcpy(msg, "commit");
exec sql commit; exec sql commit;
exec sql at pm commit;
strcpy(msg, "select");
exec sql at pm select name, amount, letter into :name_letter:ind from "Test";
printf("Database: pm\n");
for (i=0, j=sqlca.sqlerrd[2]; i<j; i++)
printf("name[%d]=%8.8s\tamount[%d]=%d\tletter[%d]=%c\n", i, name_letter[i].name, i, name_letter[i].amount,i, name_letter[i].letter);
/* Start automatic transactioning for connection main. */ /* Start automatic transactioning for connection main. */
exec sql set autocommit to on; exec sql set autocommit to on;
......
...@@ -69,9 +69,9 @@ exec sql end declare section; ...@@ -69,9 +69,9 @@ exec sql end declare section;
strcpy(msg, "fetch"); strcpy(msg, "fetch");
exec sql fetch cur into :p:i, :married:ind_married, :children.integer:ind_children.smallint; exec sql fetch cur into :p:i, :married:ind_married, :children.integer:ind_children.smallint;
printf("%8.8s", personal.name.arr); printf("%8.8s", personal.name.arr);
if (ind_personal.ind_birth.born >= 0) if (i->ind_birth.born >= 0)
printf(", born %ld", personal.birth.born); printf(", born %ld", personal.birth.born);
if (ind_personal.ind_birth.age >= 0) if (i->ind_birth.age >= 0)
printf(", age = %d", personal.birth.age); printf(", age = %d", personal.birth.age);
if ((long)ind_married >= 0) if ((long)ind_married >= 0)
printf(", married %s", married); printf(", married %s", married);
......
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