Mon Sep 18 13:55:11 PDT 2000
- Added int8 support based on a patch by Martijn Schoemaker <martijn@osp.nl>
+
+Mit Sep 20 12:40:27 PDT 2000
+
+ - Added patch by Christof Petig <christof.petig@wtal.de> to process
+ backend NOTICEs.
+ - Added patch by Christof Petig <christof.petig@wtal.de> to cache
+ type information.
- Set ecpg version to 2.8.0.
- Set library version to 3.2.0.
#define ECPG_TRANS -401
#define ECPG_CONNECT -402
+/* backend notices, starting at 600 */
+#define ECPG_NOTICE_UNRECOGNIZED -600
+ /* NOTICE: (transaction aborted): queries ignored until END */
+ /* NOTICE: current transaction is aborted, queries ignored until end of transaction block */
+#define ECPG_NOTICE_QUERY_IGNORED -601
+ /* NOTICE: PerformPortalClose: portal "*" not found */
+#define ECPG_NOTICE_UNKNOWN_PORTAL -602
+ /* NOTICE: BEGIN: already a transaction in progress */
+#define ECPG_NOTICE_IN_TRANSACTION -603
+ /* NOTICE: AbortTransaction and not in in-progress state */
+ /* NOTICE: COMMIT: no transaction in progress */
+#define ECPG_NOTICE_NO_TRANSACTION -604
+ /* NOTICE: BlankPortalAssignName: portal * already exists */
+#define ECPG_NOTICE_PORTAL_EXISTS -605
+
#endif /* !_ECPG_ERROR_H */
long sqlerrd[6];
/* Element 0: empty */
/* 1: OID of processed tuple if applicable */
- /* 2: number of rows processed */
- /* after an INSERT, UPDATE or */
- /* DELETE statement */
+ /* 2: number of rows processed */
+ /* after an INSERT, UPDATE or */
+ /* DELETE statement */
/* 3: empty */
/* 4: empty */
/* 5: empty */
char sqlwarn[8];
- /* Element 0: set to 'W' if at least one other is 'W' */
- /* 1: if 'W' at least one character string */
- /* value was truncated when it was */
- /* stored into a host variable. */
- /* 2: empty */
- /* 3: empty */
- /* 4: empty */
- /* 5: empty */
- /* 6: empty */
- /* 7: empty */
+ /* Element 0: set to 'W' if at least one other is 'W' */
+ /* 1: if 'W' at least one character string */
+ /* value was truncated when it was */
+ /* stored into a host variable. */
+ /* 2: if 'W' a (hopefully) non-fatal notice occured */ /* 3: empty */
+ /* 4: empty */
+ /* 5: empty */
+ /* 6: empty */
+ /* 7: empty */
char sqlext[8];
};
{
if (act != NULL)
{
+ struct ECPGtype_information_cache *cache, *ptr;
+
ECPGlog("ecpg_finish: finishing %s.\n", act->name);
PQfinish(act->connection);
if (actual_connection == act)
actual_connection = all_connections;
+ for (cache = act->cache_head; cache; ptr = cache, cache = cache->next, free(ptr));
free(act->name);
free(act);
}
return true;
}
+static void
+ECPGnoticeProcessor_raise(int code, const char *message)
+{
+ sqlca.sqlcode = code;
+ strncpy(sqlca.sqlerrm.sqlerrmc, message, sizeof(sqlca.sqlerrm.sqlerrmc));
+ sqlca.sqlerrm.sqlerrmc[sizeof(sqlca.sqlerrm.sqlerrmc)-1]=0;
+ sqlca.sqlerrm.sqlerrml = strlen(sqlca.sqlerrm.sqlerrmc);
+
+ // remove trailing newline
+ if (sqlca.sqlerrm.sqlerrml
+ && sqlca.sqlerrm.sqlerrmc[sqlca.sqlerrm.sqlerrml-1]=='\n')
+ {
+ sqlca.sqlerrm.sqlerrmc[sqlca.sqlerrm.sqlerrml-1]=0;
+ sqlca.sqlerrm.sqlerrml--;
+ }
+
+ ECPGlog("raising sqlcode %d\n",code);
+}
+
+/*
+ * I know this is a mess, but we can't redesign the backend
+ */
+
+static void
+ECPGnoticeProcessor(void *arg, const char *message)
+{
+ /* these notices raise an error */
+ if (strncmp(message,"NOTICE: ",8))
+ {
+ ECPGlog("ECPGnoticeProcessor: strange notice '%s'\n", message);
+ ECPGnoticeProcessor_raise(ECPG_NOTICE_UNRECOGNIZED, message);
+ return;
+ }
+
+ message+=8;
+ while (*message==' ') message++;
+ ECPGlog("NOTICE: %s", message);
+
+ /* NOTICE: (transaction aborted): queries ignored until END */
+ /* NOTICE: current transaction is aborted, queries ignored until end of transaction block */
+ if (strstr(message,"queries ignored") && strstr(message,"transaction")
+ && strstr(message,"aborted"))
+ {
+ ECPGnoticeProcessor_raise(ECPG_NOTICE_QUERY_IGNORED, message);
+ return;
+ }
+
+ /* NOTICE: PerformPortalClose: portal "*" not found */
+ if (!strncmp(message,"PerformPortalClose: portal",26)
+ && strstr(message+26,"not found"))
+ {
+ ECPGnoticeProcessor_raise(ECPG_NOTICE_UNKNOWN_PORTAL, message);
+ return;
+ }
+
+ /* NOTICE: BEGIN: already a transaction in progress */
+ if (!strncmp(message,"BEGIN: already a transaction in progress",40))
+ {
+ ECPGnoticeProcessor_raise(ECPG_NOTICE_IN_TRANSACTION, message);
+ return;
+ }
+
+ /* NOTICE: AbortTransaction and not in in-progress state */
+ /* NOTICE: COMMIT: no transaction in progress */
+ /* NOTICE: ROLLBACK: no transaction in progress */
+ if (!strncmp(message,"AbortTransaction and not in in-progress state",45)
+ || !strncmp(message,"COMMIT: no transaction in progress",34)
+ || !strncmp(message,"ROLLBACK: no transaction in progress",36))
+ {
+ ECPGnoticeProcessor_raise(ECPG_NOTICE_NO_TRANSACTION, message);
+ return;
+ }
+
+ /* NOTICE: BlankPortalAssignName: portal * already exists */
+ if (!strncmp(message,"BlankPortalAssignName: portal",29)
+ && strstr(message+29,"already exists"))
+ {
+ ECPGnoticeProcessor_raise(ECPG_NOTICE_PORTAL_EXISTS, message);
+ return;
+ }
+
+ /* these are harmless - do nothing */
+ /* NOTICE: CREATE TABLE/PRIMARY KEY will create implicit index '*' for table '*' */
+ /* NOTICE: ALTER TABLE ... ADD CONSTRAINT will create implicit trigger(s) for FOREIGN KEY check(s) */
+ /* NOTICE: CREATE TABLE will create implicit sequence '*' for SERIAL column '*.*' */
+ /* NOTICE: CREATE TABLE will create implicit trigger(s) for FOREIGN KEY check(s) */
+ if ((!strncmp(message,"CREATE TABLE",12) || !strncmp(message,"ALTER TABLE",11))
+ && strstr(message+11,"will create implicit"))
+ return;
+
+ /* NOTICE: QUERY PLAN: */
+ if (!strncmp(message,"QUERY PLAN:",11)) // do we really see these?
+ return;
+
+ /* NOTICE: DROP TABLE implicitly drops referential integrity trigger from table "*" */
+ if (!strncmp(message,"DROP TABLE implicitly drops",27))
+ return;
+
+ /* NOTICE: Caution: DROP INDEX cannot be rolled back, so don't abort now */
+ if (strstr(message,"cannot be rolled back"))
+ return;
+
+ /* these and other unmentioned should set sqlca.sqlwarn[2] */
+ /* NOTICE: The ':' operator is deprecated. Use exp(x) instead. */
+ /* NOTICE: Rel *: Uninitialized page 0 - fixing */
+ /* NOTICE: PortalHeapMemoryFree: * not in alloc set! */
+ /* NOTICE: Too old parent tuple found - can't continue vc_repair_frag */
+ /* NOTICE: identifier "*" will be truncated to "*" */
+ /* NOTICE: InvalidateSharedInvalid: cache state reset */
+ /* NOTICE: RegisterSharedInvalid: SI buffer overflow */
+ sqlca.sqlwarn[2]='W';
+ sqlca.sqlwarn[0]='W';
+}
+
bool
ECPGconnect(int lineno, const char *dbname, const char *user, const char *passwd, const char *connection_name, int autocommit)
{
if (dbname == NULL && connection_name == NULL)
connection_name = "DEFAULT";
-
+
/* add connection to our list */
if (connection_name != NULL)
this->name = ecpg_strdup(connection_name, lineno);
else
this->name = ecpg_strdup(dbname, lineno);
+
+ this->cache_head = NULL;
if (all_connections == NULL)
this->next = NULL;
this->committed = true;
this->autocommit = autocommit;
+
+ PQsetNoticeProcessor(this->connection,&ECPGnoticeProcessor,(void*)this);
return true;
}
bool
ECPGallocate_desc(int line, const char *name)
{
- struct descriptor *new = (struct descriptor *) malloc(sizeof(struct descriptor));
+ struct descriptor *new = (struct descriptor *) ecpg_alloc(sizeof(struct descriptor), line);
new->next = all_descriptors;
- new->name = malloc(strlen(name) + 1);
+ new->name = ecpg_alloc(strlen(name) + 1, line);
new->result = PQmakeEmptyPGresult(NULL, 0);
strcpy(new->name, name);
all_descriptors = new;
#include <stdio.h>
#include <locale.h>
+#include "pg_type.h"
+
#include "ecpgtype.h"
#include "ecpglib.h"
#include "ecpgerrno.h"
return (*ptr == '\0') ? NULL : ptr;
}
+/*
+ * push a value on the cache
+ */
+
+static void
+ECPGtypeinfocache_push(struct ECPGtype_information_cache **cache, int oid, bool isarray, int lineno)
+{
+ struct ECPGtype_information_cache *new_entry
+ = ecpg_alloc(sizeof(struct ECPGtype_information_cache), lineno);
+ new_entry->oid = oid;
+ new_entry->isarray = isarray;
+ new_entry->next = *cache;
+ *cache = new_entry;
+}
+
+static bool
+ECPGis_type_an_array(int type,const struct statement * stmt,const struct variable *var)
+{
+ char *array_query;
+ int isarray = 0;
+ PGresult *query;
+ struct ECPGtype_information_cache *cache_entry;
+
+ if ((stmt->connection->cache_head)==NULL)
+ {
+ /* populate cache with well known types to speed things up */
+ ECPGtypeinfocache_push(&(stmt->connection->cache_head), BOOLOID, false, stmt->lineno);
+ ECPGtypeinfocache_push(&(stmt->connection->cache_head), BYTEAOID, true, stmt->lineno);
+ ECPGtypeinfocache_push(&(stmt->connection->cache_head), CHAROID, false, stmt->lineno);
+ ECPGtypeinfocache_push(&(stmt->connection->cache_head), NAMEOID, true, stmt->lineno);
+ ECPGtypeinfocache_push(&(stmt->connection->cache_head), INT8OID, false, stmt->lineno);
+ ECPGtypeinfocache_push(&(stmt->connection->cache_head), INT2OID, false, stmt->lineno);
+ ECPGtypeinfocache_push(&(stmt->connection->cache_head), INT2VECTOROID, true, stmt->lineno);
+ ECPGtypeinfocache_push(&(stmt->connection->cache_head), INT4OID, false, stmt->lineno);
+ ECPGtypeinfocache_push(&(stmt->connection->cache_head), REGPROCOID, false, stmt->lineno);
+ ECPGtypeinfocache_push(&(stmt->connection->cache_head), TEXTOID, true, stmt->lineno);
+ ECPGtypeinfocache_push(&(stmt->connection->cache_head), OIDOID, false, stmt->lineno);
+ ECPGtypeinfocache_push(&(stmt->connection->cache_head), TIDOID, false, stmt->lineno);
+ ECPGtypeinfocache_push(&(stmt->connection->cache_head), XIDOID, false, stmt->lineno);
+ ECPGtypeinfocache_push(&(stmt->connection->cache_head), CIDOID, false, stmt->lineno);
+ ECPGtypeinfocache_push(&(stmt->connection->cache_head), OIDVECTOROID, true, stmt->lineno);
+ ECPGtypeinfocache_push(&(stmt->connection->cache_head), POINTOID, true, stmt->lineno);
+ ECPGtypeinfocache_push(&(stmt->connection->cache_head), LSEGOID, true, stmt->lineno);
+ ECPGtypeinfocache_push(&(stmt->connection->cache_head), PATHOID, true, stmt->lineno);
+ ECPGtypeinfocache_push(&(stmt->connection->cache_head), BOXOID, true, stmt->lineno);
+ ECPGtypeinfocache_push(&(stmt->connection->cache_head), POLYGONOID, false, stmt->lineno);
+ ECPGtypeinfocache_push(&(stmt->connection->cache_head), LINEOID, true, stmt->lineno);
+ ECPGtypeinfocache_push(&(stmt->connection->cache_head), FLOAT4OID, false, stmt->lineno);
+ ECPGtypeinfocache_push(&(stmt->connection->cache_head), FLOAT8OID, false, stmt->lineno);
+ ECPGtypeinfocache_push(&(stmt->connection->cache_head), ABSTIMEOID, false, stmt->lineno);
+ ECPGtypeinfocache_push(&(stmt->connection->cache_head), RELTIMEOID, false, stmt->lineno);
+ ECPGtypeinfocache_push(&(stmt->connection->cache_head), TINTERVALOID, false, stmt->lineno);
+ ECPGtypeinfocache_push(&(stmt->connection->cache_head), UNKNOWNOID, true, stmt->lineno);
+ ECPGtypeinfocache_push(&(stmt->connection->cache_head), CIRCLEOID, false, stmt->lineno);
+ ECPGtypeinfocache_push(&(stmt->connection->cache_head), CASHOID, false, stmt->lineno);
+ ECPGtypeinfocache_push(&(stmt->connection->cache_head), INETOID, false, stmt->lineno);
+ ECPGtypeinfocache_push(&(stmt->connection->cache_head), CIDROID, false, stmt->lineno);
+ ECPGtypeinfocache_push(&(stmt->connection->cache_head), BPCHAROID, false, stmt->lineno);
+ ECPGtypeinfocache_push(&(stmt->connection->cache_head), VARCHAROID, false, stmt->lineno);
+ ECPGtypeinfocache_push(&(stmt->connection->cache_head), DATEOID, false, stmt->lineno);
+ ECPGtypeinfocache_push(&(stmt->connection->cache_head), TIMEOID, false, stmt->lineno);
+ ECPGtypeinfocache_push(&(stmt->connection->cache_head), TIMESTAMPOID, false, stmt->lineno);
+ ECPGtypeinfocache_push(&(stmt->connection->cache_head), INTERVALOID, false, stmt->lineno);
+ ECPGtypeinfocache_push(&(stmt->connection->cache_head), TIMETZOID, false, stmt->lineno);
+ ECPGtypeinfocache_push(&(stmt->connection->cache_head), ZPBITOID, false, stmt->lineno);
+ ECPGtypeinfocache_push(&(stmt->connection->cache_head), VARBITOID, false, stmt->lineno);
+ ECPGtypeinfocache_push(&(stmt->connection->cache_head), NUMERICOID, false, stmt->lineno);
+ }
+
+ for (cache_entry = (stmt->connection->cache_head);cache_entry != NULL;cache_entry=cache_entry->next)
+ {
+ if (cache_entry->oid==type)
+ return cache_entry->isarray;
+ }
+
+ array_query = (char *) ecpg_alloc(strlen("select typelem from pg_type where oid=") + 11, stmt->lineno);
+ sprintf(array_query, "select typelem from pg_type where oid=%d", type);
+ query = PQexec(stmt->connection->connection, array_query);
+ if (PQresultStatus(query) == PGRES_TUPLES_OK)
+ {
+ isarray = atol((char *) PQgetvalue(query, 0, 0));
+ if (ECPGDynamicType(type) == SQL3_CHARACTER ||
+ ECPGDynamicType(type) == SQL3_CHARACTER_VARYING)
+ {
+
+ /*
+ * arrays of character strings are not yet
+ * implemented
+ */
+ isarray = false;
+ }
+ ECPGlog("ECPGexecute line %d: TYPE database: %d C: %d array: %s\n", stmt->lineno, type, var->type, isarray ? "yes" : "no");
+ ECPGtypeinfocache_push(&(stmt->connection->cache_head), type, isarray, stmt->lineno);
+ }
+ PQclear(query);
+ return isarray;
+}
+
static bool
ECPGexecute(struct statement * stmt)
{
bool status = false;
char *copiedquery;
- PGresult *results,
- *query;
+ PGresult *results;
PGnotify *notify;
struct variable *var;
for (act_field = 0; act_field < nfields && status; act_field++)
{
- char *array_query;
-
if (var == NULL)
{
ECPGlog("ECPGexecute line %d: Too few arguments.\n", stmt->lineno);
return (false);
}
- array_query = (char *) ecpg_alloc(strlen("select typelem from pg_type where oid=") + 11, stmt->lineno);
- sprintf(array_query, "select typelem from pg_type where oid=%d", PQftype(results, act_field));
- query = PQexec(stmt->connection->connection, array_query);
- isarray = 0;
- if (PQresultStatus(query) == PGRES_TUPLES_OK)
- {
- isarray = atol((char *) PQgetvalue(query, 0, 0));
- if (ECPGDynamicType(PQftype(results, act_field)) == SQL3_CHARACTER ||
- ECPGDynamicType(PQftype(results, act_field)) == SQL3_CHARACTER_VARYING)
- {
-
- /*
- * arrays of character strings are not yet
- * implemented
- */
- isarray = false;
- }
- ECPGlog("ECPGexecute line %d: TYPE database: %d C: %d array: %s\n", stmt->lineno, PQftype(results, act_field), var->type, isarray ? "yes" : "no");
- }
- PQclear(query);
+ isarray = ECPGis_type_an_array(PQftype(results, act_field), stmt, var);
if (!isarray)
{
*
* Copyright (c) 2000, Christof Petig <christof.petig@wtal.de>
*
- * $Header: /cvsroot/pgsql/src/interfaces/ecpg/lib/Attic/execute.c,v 1.8 2000/09/19 11:47:13 meskes Exp $
+ * $Header: /cvsroot/pgsql/src/interfaces/ecpg/lib/Attic/execute.c,v 1.9 2000/09/20 13:25:51 meskes Exp $
*/
PGconn *ECPG_internal_get_connection(char *name);
char arr[1];
};
+/*
+ * type information cache
+ */
+
+struct ECPGtype_information_cache
+{
+ struct ECPGtype_information_cache *next;
+ int oid;
+ bool isarray;
+};
+
/* structure to store one statement */
struct statement
{
{
char *name;
PGconn *connection;
- bool committed;
- int autocommit;
+ bool committed;
+ int autocommit;
+ struct ECPGtype_information_cache *cache_head;
struct connection *next;
};
--- /dev/null
+/*-------------------------------------------------------------------------
+ *
+ * pg_type.h
+ * definition of the system "type" relation (pg_type)
+ * along with the relation's initial contents.
+ *
+ *
+ * Portions Copyright (c) 1996-2000, PostgreSQL, Inc
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ * $Id: pg_type.h,v 1.1 2000/09/20 13:25:51 meskes Exp $
+ *
+ * NOTES
+ * the genbki.sh script reads this file and generates .bki
+ * information from the DATA() statements.
+ *
+ *-------------------------------------------------------------------------
+ */
+#ifndef PG_TYPE_H
+#define PG_TYPE_H
+
+/* ----------------
+ * initial contents of pg_type
+ * ----------------
+ */
+
+/* keep the following ordered by OID so that later changes can be made easier*/
+
+/* OIDS 1 - 99 */
+#define BOOLOID 16
+#define BYTEAOID 17
+#define CHAROID 18
+#define NAMEOID 19
+#define INT8OID 20
+#define INT2OID 21
+#define INT2VECTOROID 22
+#define INT4OID 23
+#define REGPROCOID 24
+#define TEXTOID 25
+#define OIDOID 26
+#define TIDOID 27
+#define XIDOID 28
+#define CIDOID 29
+#define OIDVECTOROID 30
+#define POINTOID 600
+#define LSEGOID 601
+#define PATHOID 602
+#define BOXOID 603
+#define POLYGONOID 604
+#define LINEOID 628
+#define FLOAT4OID 700
+#define FLOAT8OID 701
+#define ABSTIMEOID 702
+#define RELTIMEOID 703
+#define TINTERVALOID 704
+#define UNKNOWNOID 705
+#define CIRCLEOID 718
+#define CASHOID 790
+#define INETOID 869
+#define CIDROID 650
+#define BPCHAROID 1042
+#define VARCHAROID 1043
+#define DATEOID 1082
+#define TIMEOID 1083
+#define TIMESTAMPOID 1184
+#define INTERVALOID 1186
+#define TIMETZOID 1266
+#define ZPBITOID 1560
+#define VARBITOID 1562
+#define NUMERICOID 1700
+
+#endif /* PG_TYPE_H */
#include "ecpglib.h"
#include "extern.h"
#include "sql3types.h"
+#include "pg_type.h"
/*
* This function is used to generate the correct type names.
{
switch (typ)
{
- case ECPGt_char:
+ case ECPGt_char:
return "char";
case ECPGt_unsigned_char:
return "unsigned char";
{
switch (type)
{
- case 16:return SQL3_BOOLEAN; /* bool */
- case 21:
- return SQL3_SMALLINT; /* int2 */
- case 23:
- return SQL3_INTEGER;/* int4 */
- case 25:
- return SQL3_CHARACTER; /* text */
- case 700:
- return SQL3_REAL; /* float4 */
- case 701:
- return SQL3_DOUBLE_PRECISION; /* float8 */
- case 1042:
- return SQL3_CHARACTER; /* bpchar */
- case 1043:
- return SQL3_CHARACTER_VARYING; /* varchar */
- case 1082:
- return SQL3_DATE_TIME_TIMESTAMP; /* date */
- case 1083:
- return SQL3_DATE_TIME_TIMESTAMP; /* time */
- case 1184:
- return SQL3_DATE_TIME_TIMESTAMP; /* datetime */
- case 1296:
- return SQL3_DATE_TIME_TIMESTAMP; /* timestamp */
- case 1700:
- return SQL3_NUMERIC;/* numeric */
+ case BOOLOID: return SQL3_BOOLEAN; /* bool */
+ case INT2OID: return SQL3_SMALLINT; /* int2 */
+ case INT4OID: return SQL3_INTEGER;/* int4 */
+ case TEXTOID: return SQL3_CHARACTER; /* text */
+ case FLOAT4OID: return SQL3_REAL; /* float4 */
+ case FLOAT8OID: return SQL3_DOUBLE_PRECISION; /* float8 */
+ case BPCHAROID: return SQL3_CHARACTER; /* bpchar */
+ case VARCHAROID: return SQL3_CHARACTER_VARYING; /* varchar */
+ case DATEOID: return SQL3_DATE_TIME_TIMESTAMP; /* date */
+ case TIMEOID: return SQL3_DATE_TIME_TIMESTAMP; /* time */
+ case TIMESTAMPOID: return SQL3_DATE_TIME_TIMESTAMP; /* datetime */
+ case NUMERICOID: return SQL3_NUMERIC;/* numeric */
default:
return -type;
}
-all: test1 test2 test3 test4 perftest dyntest dyntest2
+all: test1 test2 test3 test4 perftest dyntest dyntest2 test_notice
-LDFLAGS=-g -I /usr/local/pgsql/include -L/usr/local/pgsql/lib -lecpg -lpq
+#LDFLAGS=-g -I /usr/local/pgsql/include -L/usr/local/pgsql/lib -lecpg -lpq
+LDFLAGS=-g -I ../include -I /usr/include/postgresql -L /usr/lib -lecpg -lpq
-ECPG=/usr/local/pgsql/bin/ecpg -I../include
-#ECPG=../preproc/ecpg -I../include
+#ECPG=/usr/local/pgsql/bin/ecpg -I../include
+ECPG=../preproc/ecpg -I../include
.SUFFIXES: .pgc .c
perftest: perftest.c
dyntest: dyntest.c
dyntest2: dyntest2.c
+test_code100: test_code100.c
+test_notice: test_notice.c
+test_init: test_init.c
.pgc.c:
$(ECPG) $?
--- /dev/null
+// $Id: test_code100.pgc,v 1.1 2000/09/20 13:25:52 meskes Exp $
+
+exec sql include sqlca;
+#include <stdio.h>
+
+int main(int argc, char **argv)
+{ exec sql begin declare section;
+ int index;
+ exec sql end declare section;
+
+
+ // ECPGdebug(1,stdout);
+
+ exec sql connect to test;
+ if (sqlca.sqlcode) printf("%ld:%s\n",sqlca.sqlcode,sqlca.sqlerrm.sqlerrmc);
+
+ exec sql create table test (
+ "index" numeric(3) primary key,
+ "payload" int4 NOT NULL);
+ if (sqlca.sqlcode) printf("%ld:%s\n",sqlca.sqlcode,sqlca.sqlerrm.sqlerrmc);
+ exec sql commit work;
+ if (sqlca.sqlcode) printf("%ld:%s\n",sqlca.sqlcode,sqlca.sqlerrm.sqlerrmc);
+
+ for (index=0;index<10;++index)
+ { exec sql insert into test
+ (payload, index)
+ values (0, :index);
+ if (sqlca.sqlcode) printf("%ld:%s\n",sqlca.sqlcode,sqlca.sqlerrm.sqlerrmc);
+ }
+ exec sql commit work;
+ if (sqlca.sqlcode) printf("%ld:%s\n",sqlca.sqlcode,sqlca.sqlerrm.sqlerrmc);
+
+ exec sql update test
+ set payload=payload+1 where index=-1;
+ if (sqlca.sqlcode!=100) printf("%ld:%s\n",sqlca.sqlcode,sqlca.sqlerrm.sqlerrmc);
+
+ exec sql delete from test where index=-1;
+ if (sqlca.sqlcode!=100) printf("%ld:%s\n",sqlca.sqlcode,sqlca.sqlerrm.sqlerrmc);
+
+ exec sql insert into test (select * from test where index=-1);
+ if (sqlca.sqlcode!=100) printf("%ld:%s\n",sqlca.sqlcode,sqlca.sqlerrm.sqlerrmc);
+
+ exec sql drop table test;
+ if (sqlca.sqlcode) printf("%ld:%s\n",sqlca.sqlcode,sqlca.sqlerrm.sqlerrmc);
+ exec sql commit work;
+ if (sqlca.sqlcode) printf("%ld:%s\n",sqlca.sqlcode,sqlca.sqlerrm.sqlerrmc);
+
+ exec sql disconnect;
+ if (sqlca.sqlcode) printf("%ld:%s\n",sqlca.sqlcode,sqlca.sqlerrm.sqlerrmc);
+ return 0;
+}
--- /dev/null
+exec sql include sqlca;
+
+int fa() { return 2; }
+int fb(int x) { return x; }
+int fc(const char *x) { return *x; }
+int fd(const char *x,int i) { return (*x)*i; }
+enum e { ENUM0, ENUM1 };
+int fe(enum e x) { return (int)x; }
+struct sa { int member; };
+
+void sqlmeldung(char *meldung, short trans)
+{
+}
+
+#define NO 0
+#define YES 1
+
+#ifdef _cplusplus
+namespace N
+{ static const int i=2;
+};
+#endif
+
+int main()
+{ struct sa x,*y;
+exec sql begin declare section;
+int a=2;
+int b=2+2;
+int d=x.member;
+int g=fb(2);
+int i=3^1;
+int j=1?1:2;
+
+/*int e=y->member; /* compile error */
+/*int c=10>>2; /* compile error */
+/*bool h=2||1; /* compile error */
+exec sql end declare section;
+
+/* not working */
+int f=fa();
+
+#ifdef _cplusplus
+exec sql begin declare section;
+int k=N::i; /* compile error */
+exec sql end declare section;
+#endif
+
+exec sql whenever sqlerror do fa();
+exec sql select now();
+exec sql whenever sqlerror do fb(20);
+exec sql select now();
+exec sql whenever sqlerror do fc("50");
+exec sql select now();
+exec sql whenever sqlerror do fd("50",1);
+exec sql select now();
+exec sql whenever sqlerror do fe(ENUM0);
+exec sql select now();
+/* ex ec sql whenever sqlerror do sqlmeldung(NULL,NO); */
+exec sql select now();
+return 0;
+}
--- /dev/null
+// $Id: test_notice.pgc,v 1.1 2000/09/20 13:25:52 meskes Exp $
+
+exec sql include sqlca;
+
+#include <stdio.h>
+
+void printwarning(void)
+{
+ if (sqlca.sqlwarn[0]) printf("sqlca.sqlwarn: %c",sqlca.sqlwarn[0]);
+ else return;
+
+ if (sqlca.sqlwarn[1]) putchar('1');
+ if (sqlca.sqlwarn[2]) putchar('2');
+
+ putchar('\n');
+}
+
+int main(int argc, char **argv)
+{
+ exec sql begin declare section;
+ int index,payload;
+ exec sql end declare section;
+ FILE *dbgs;
+
+ /* actually this will print 'sql error' if a warning occurs */
+ exec sql whenever sqlwarning do printwarning();
+
+ if ((dbgs = fopen("log", "w")) != NULL)
+ ECPGdebug(1, dbgs);
+
+ exec sql connect to mm;
+ if (sqlca.sqlcode) printf("%d %ld:%s\n",__LINE__,sqlca.sqlcode,sqlca.sqlerrm.sqlerrmc);
+
+ exec sql create table test (
+ "index" numeric(3) primary key,
+ "payload" int4 NOT NULL);
+ if (sqlca.sqlcode) printf("%d %ld:%s\n",__LINE__,sqlca.sqlcode,sqlca.sqlerrm.sqlerrmc);
+
+ exec sql commit work;
+ if (sqlca.sqlcode) printf("%d %ld:%s\n",__LINE__,sqlca.sqlcode,sqlca.sqlerrm.sqlerrmc);
+
+ exec sql begin work;
+ if (sqlca.sqlcode) printf("%d %ld:%s\n",__LINE__,sqlca.sqlcode,sqlca.sqlerrm.sqlerrmc);
+
+ exec sql begin work;
+ if (sqlca.sqlcode!=ECPG_NOTICE_IN_TRANSACTION) printf("%d %ld:%s\n",__LINE__,sqlca.sqlcode,sqlca.sqlerrm.sqlerrmc);
+
+ exec sql commit;
+ if (sqlca.sqlcode) printf("%d %ld:%s\n",__LINE__,sqlca.sqlcode,sqlca.sqlerrm.sqlerrmc);
+
+ exec sql commit;
+ if (sqlca.sqlcode!=ECPG_NOTICE_NO_TRANSACTION) printf("%d %ld:%s\n",__LINE__,sqlca.sqlcode,sqlca.sqlerrm.sqlerrmc);
+
+ exec sql rollback;
+ if (sqlca.sqlcode!=ECPG_NOTICE_NO_TRANSACTION) printf("%d %ld:%s\n",__LINE__,sqlca.sqlcode,sqlca.sqlerrm.sqlerrmc);
+
+ sqlca.sqlcode=0;
+ exec sql declare x cursor for select * from test;
+ if (sqlca.sqlcode) printf("%d %ld:%s\n",__LINE__,sqlca.sqlcode,sqlca.sqlerrm.sqlerrmc);
+
+ exec sql open x;
+ if (sqlca.sqlcode) printf("%d %ld:%s\n",__LINE__,sqlca.sqlcode,sqlca.sqlerrm.sqlerrmc);
+
+ exec sql open x;
+ if (sqlca.sqlcode!=ECPG_NOTICE_PORTAL_EXISTS) printf("%d %ld:%s\n",__LINE__,sqlca.sqlcode,sqlca.sqlerrm.sqlerrmc);
+
+ exec sql close x;
+ if (sqlca.sqlcode) printf("%d %ld:%s\n",__LINE__,sqlca.sqlcode,sqlca.sqlerrm.sqlerrmc);
+
+ exec sql close x;
+ if (sqlca.sqlcode!=ECPG_NOTICE_UNKNOWN_PORTAL) printf("%d %ld:%s\n",__LINE__,sqlca.sqlcode,sqlca.sqlerrm.sqlerrmc);
+
+ exec sql update test set nonexistent=2;
+ if (sqlca.sqlcode!=ECPG_PGSQL) printf("%d %ld:%s\n",__LINE__,sqlca.sqlcode,sqlca.sqlerrm.sqlerrmc);
+
+ exec sql select payload into :payload from test where index=1;
+ if (sqlca.sqlcode!=ECPG_NOTICE_QUERY_IGNORED) printf("%d %ld:%s\n",__LINE__,sqlca.sqlcode,sqlca.sqlerrm.sqlerrmc);
+
+ exec sql rollback;
+ if (sqlca.sqlcode) printf("%d %ld:%s\n",__LINE__,sqlca.sqlcode,sqlca.sqlerrm.sqlerrmc);
+
+ // this will raise a warning
+ exec sql drop table test;
+ if (sqlca.sqlcode) printf("%d %ld:%s\n",__LINE__,sqlca.sqlcode,sqlca.sqlerrm.sqlerrmc);
+ exec sql commit work;
+ if (sqlca.sqlcode) printf("%d %ld:%s\n",__LINE__,sqlca.sqlcode,sqlca.sqlerrm.sqlerrmc);
+
+ exec sql disconnect;
+ if (sqlca.sqlcode) printf("%d %ld:%s\n",__LINE__,sqlca.sqlcode,sqlca.sqlerrm.sqlerrmc);
+
+ if (dbgs != NULL)
+ fclose(dbgs);
+ return 0;
+}