mirror of
https://github.com/postgres/postgres.git
synced 2025-06-17 17:02:08 +03:00
*** empty log message ***
This commit is contained in:
@ -933,5 +933,12 @@ Mon Sep 4 14:10:38 PDT 2000
|
|||||||
Mon Sep 18 13:55:11 PDT 2000
|
Mon Sep 18 13:55:11 PDT 2000
|
||||||
|
|
||||||
- Added int8 support based on a patch by Martijn Schoemaker <martijn@osp.nl>
|
- 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 ecpg version to 2.8.0.
|
||||||
- Set library version to 3.2.0.
|
- Set library version to 3.2.0.
|
||||||
|
@ -43,4 +43,19 @@
|
|||||||
#define ECPG_TRANS -401
|
#define ECPG_TRANS -401
|
||||||
#define ECPG_CONNECT -402
|
#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 */
|
#endif /* !_ECPG_ERROR_H */
|
||||||
|
@ -22,23 +22,22 @@ extern "C"
|
|||||||
long sqlerrd[6];
|
long sqlerrd[6];
|
||||||
/* Element 0: empty */
|
/* Element 0: empty */
|
||||||
/* 1: OID of processed tuple if applicable */
|
/* 1: OID of processed tuple if applicable */
|
||||||
/* 2: number of rows processed */
|
/* 2: number of rows processed */
|
||||||
/* after an INSERT, UPDATE or */
|
/* after an INSERT, UPDATE or */
|
||||||
/* DELETE statement */
|
/* DELETE statement */
|
||||||
/* 3: empty */
|
/* 3: empty */
|
||||||
/* 4: empty */
|
/* 4: empty */
|
||||||
/* 5: empty */
|
/* 5: empty */
|
||||||
char sqlwarn[8];
|
char sqlwarn[8];
|
||||||
/* Element 0: set to 'W' if at least one other is 'W' */
|
/* Element 0: set to 'W' if at least one other is 'W' */
|
||||||
/* 1: if 'W' at least one character string */
|
/* 1: if 'W' at least one character string */
|
||||||
/* value was truncated when it was */
|
/* value was truncated when it was */
|
||||||
/* stored into a host variable. */
|
/* stored into a host variable. */
|
||||||
/* 2: empty */
|
/* 2: if 'W' a (hopefully) non-fatal notice occured */ /* 3: empty */
|
||||||
/* 3: empty */
|
/* 4: empty */
|
||||||
/* 4: empty */
|
/* 5: empty */
|
||||||
/* 5: empty */
|
/* 6: empty */
|
||||||
/* 6: empty */
|
/* 7: empty */
|
||||||
/* 7: empty */
|
|
||||||
|
|
||||||
char sqlext[8];
|
char sqlext[8];
|
||||||
};
|
};
|
||||||
|
@ -27,6 +27,8 @@ ecpg_finish(struct connection * act)
|
|||||||
{
|
{
|
||||||
if (act != NULL)
|
if (act != NULL)
|
||||||
{
|
{
|
||||||
|
struct ECPGtype_information_cache *cache, *ptr;
|
||||||
|
|
||||||
ECPGlog("ecpg_finish: finishing %s.\n", act->name);
|
ECPGlog("ecpg_finish: finishing %s.\n", act->name);
|
||||||
PQfinish(act->connection);
|
PQfinish(act->connection);
|
||||||
|
|
||||||
@ -45,6 +47,7 @@ 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));
|
||||||
free(act->name);
|
free(act->name);
|
||||||
free(act);
|
free(act);
|
||||||
}
|
}
|
||||||
@ -107,6 +110,120 @@ ECPGsetconn(int lineno, const char *connection_name)
|
|||||||
return true;
|
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
|
bool
|
||||||
ECPGconnect(int lineno, const char *dbname, const char *user, const char *passwd, const char *connection_name, int autocommit)
|
ECPGconnect(int lineno, const char *dbname, const char *user, const char *passwd, const char *connection_name, int autocommit)
|
||||||
{
|
{
|
||||||
@ -126,6 +243,8 @@ ECPGconnect(int lineno, const char *dbname, const char *user, const char *passwd
|
|||||||
else
|
else
|
||||||
this->name = ecpg_strdup(dbname, lineno);
|
this->name = ecpg_strdup(dbname, lineno);
|
||||||
|
|
||||||
|
this->cache_head = NULL;
|
||||||
|
|
||||||
if (all_connections == NULL)
|
if (all_connections == NULL)
|
||||||
this->next = NULL;
|
this->next = NULL;
|
||||||
else
|
else
|
||||||
@ -148,6 +267,8 @@ ECPGconnect(int lineno, const char *dbname, const char *user, const char *passwd
|
|||||||
this->committed = true;
|
this->committed = true;
|
||||||
this->autocommit = autocommit;
|
this->autocommit = autocommit;
|
||||||
|
|
||||||
|
PQsetNoticeProcessor(this->connection,&ECPGnoticeProcessor,(void*)this);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -302,10 +302,10 @@ ECPGdeallocate_desc(int line, const char *name)
|
|||||||
bool
|
bool
|
||||||
ECPGallocate_desc(int line, const char *name)
|
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->next = all_descriptors;
|
||||||
new->name = malloc(strlen(name) + 1);
|
new->name = ecpg_alloc(strlen(name) + 1, line);
|
||||||
new->result = PQmakeEmptyPGresult(NULL, 0);
|
new->result = PQmakeEmptyPGresult(NULL, 0);
|
||||||
strcpy(new->name, name);
|
strcpy(new->name, name);
|
||||||
all_descriptors = new;
|
all_descriptors = new;
|
||||||
|
@ -15,6 +15,8 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <locale.h>
|
#include <locale.h>
|
||||||
|
|
||||||
|
#include "pg_type.h"
|
||||||
|
|
||||||
#include "ecpgtype.h"
|
#include "ecpgtype.h"
|
||||||
#include "ecpglib.h"
|
#include "ecpglib.h"
|
||||||
#include "ecpgerrno.h"
|
#include "ecpgerrno.h"
|
||||||
@ -252,13 +254,110 @@ next_insert(char *text)
|
|||||||
return (*ptr == '\0') ? NULL : ptr;
|
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
|
static bool
|
||||||
ECPGexecute(struct statement * stmt)
|
ECPGexecute(struct statement * stmt)
|
||||||
{
|
{
|
||||||
bool status = false;
|
bool status = false;
|
||||||
char *copiedquery;
|
char *copiedquery;
|
||||||
PGresult *results,
|
PGresult *results;
|
||||||
*query;
|
|
||||||
PGnotify *notify;
|
PGnotify *notify;
|
||||||
struct variable *var;
|
struct variable *var;
|
||||||
|
|
||||||
@ -700,8 +799,6 @@ ECPGexecute(struct statement * stmt)
|
|||||||
|
|
||||||
for (act_field = 0; act_field < nfields && status; act_field++)
|
for (act_field = 0; act_field < nfields && status; act_field++)
|
||||||
{
|
{
|
||||||
char *array_query;
|
|
||||||
|
|
||||||
if (var == NULL)
|
if (var == NULL)
|
||||||
{
|
{
|
||||||
ECPGlog("ECPGexecute line %d: Too few arguments.\n", stmt->lineno);
|
ECPGlog("ECPGexecute line %d: Too few arguments.\n", stmt->lineno);
|
||||||
@ -709,26 +806,7 @@ ECPGexecute(struct statement * stmt)
|
|||||||
return (false);
|
return (false);
|
||||||
}
|
}
|
||||||
|
|
||||||
array_query = (char *) ecpg_alloc(strlen("select typelem from pg_type where oid=") + 11, stmt->lineno);
|
isarray = ECPGis_type_an_array(PQftype(results, act_field), stmt, var);
|
||||||
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);
|
|
||||||
|
|
||||||
if (!isarray)
|
if (!isarray)
|
||||||
{
|
{
|
||||||
@ -911,7 +989,7 @@ ECPGdo(int lineno, const char *connection_name, char *query,...)
|
|||||||
*
|
*
|
||||||
* Copyright (c) 2000, Christof Petig <christof.petig@wtal.de>
|
* 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);
|
PGconn *ECPG_internal_get_connection(char *name);
|
||||||
|
@ -21,6 +21,17 @@ struct ECPGgeneric_varchar
|
|||||||
char arr[1];
|
char arr[1];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* type information cache
|
||||||
|
*/
|
||||||
|
|
||||||
|
struct ECPGtype_information_cache
|
||||||
|
{
|
||||||
|
struct ECPGtype_information_cache *next;
|
||||||
|
int oid;
|
||||||
|
bool isarray;
|
||||||
|
};
|
||||||
|
|
||||||
/* structure to store one statement */
|
/* structure to store one statement */
|
||||||
struct statement
|
struct statement
|
||||||
{
|
{
|
||||||
@ -36,7 +47,8 @@ struct connection
|
|||||||
{
|
{
|
||||||
char *name;
|
char *name;
|
||||||
PGconn *connection;
|
PGconn *connection;
|
||||||
bool committed;
|
bool committed;
|
||||||
int autocommit;
|
int autocommit;
|
||||||
|
struct ECPGtype_information_cache *cache_head;
|
||||||
struct connection *next;
|
struct connection *next;
|
||||||
};
|
};
|
||||||
|
72
src/interfaces/ecpg/lib/pg_type.h
Normal file
72
src/interfaces/ecpg/lib/pg_type.h
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
/*-------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* 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 */
|
@ -3,6 +3,7 @@
|
|||||||
#include "ecpglib.h"
|
#include "ecpglib.h"
|
||||||
#include "extern.h"
|
#include "extern.h"
|
||||||
#include "sql3types.h"
|
#include "sql3types.h"
|
||||||
|
#include "pg_type.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This function is used to generate the correct type names.
|
* This function is used to generate the correct type names.
|
||||||
@ -12,7 +13,7 @@ ECPGtype_name(enum ECPGttype typ)
|
|||||||
{
|
{
|
||||||
switch (typ)
|
switch (typ)
|
||||||
{
|
{
|
||||||
case ECPGt_char:
|
case ECPGt_char:
|
||||||
return "char";
|
return "char";
|
||||||
case ECPGt_unsigned_char:
|
case ECPGt_unsigned_char:
|
||||||
return "unsigned char";
|
return "unsigned char";
|
||||||
@ -53,31 +54,18 @@ ECPGDynamicType(Oid type)
|
|||||||
{
|
{
|
||||||
switch (type)
|
switch (type)
|
||||||
{
|
{
|
||||||
case 16:return SQL3_BOOLEAN; /* bool */
|
case BOOLOID: return SQL3_BOOLEAN; /* bool */
|
||||||
case 21:
|
case INT2OID: return SQL3_SMALLINT; /* int2 */
|
||||||
return SQL3_SMALLINT; /* int2 */
|
case INT4OID: return SQL3_INTEGER;/* int4 */
|
||||||
case 23:
|
case TEXTOID: return SQL3_CHARACTER; /* text */
|
||||||
return SQL3_INTEGER;/* int4 */
|
case FLOAT4OID: return SQL3_REAL; /* float4 */
|
||||||
case 25:
|
case FLOAT8OID: return SQL3_DOUBLE_PRECISION; /* float8 */
|
||||||
return SQL3_CHARACTER; /* text */
|
case BPCHAROID: return SQL3_CHARACTER; /* bpchar */
|
||||||
case 700:
|
case VARCHAROID: return SQL3_CHARACTER_VARYING; /* varchar */
|
||||||
return SQL3_REAL; /* float4 */
|
case DATEOID: return SQL3_DATE_TIME_TIMESTAMP; /* date */
|
||||||
case 701:
|
case TIMEOID: return SQL3_DATE_TIME_TIMESTAMP; /* time */
|
||||||
return SQL3_DOUBLE_PRECISION; /* float8 */
|
case TIMESTAMPOID: return SQL3_DATE_TIME_TIMESTAMP; /* datetime */
|
||||||
case 1042:
|
case NUMERICOID: return SQL3_NUMERIC;/* numeric */
|
||||||
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 */
|
|
||||||
default:
|
default:
|
||||||
return -type;
|
return -type;
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
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=/usr/local/pgsql/bin/ecpg -I../include
|
||||||
#ECPG=../preproc/ecpg -I../include
|
ECPG=../preproc/ecpg -I../include
|
||||||
|
|
||||||
.SUFFIXES: .pgc .c
|
.SUFFIXES: .pgc .c
|
||||||
|
|
||||||
@ -14,6 +15,9 @@ test4: test4.c
|
|||||||
perftest: perftest.c
|
perftest: perftest.c
|
||||||
dyntest: dyntest.c
|
dyntest: dyntest.c
|
||||||
dyntest2: dyntest2.c
|
dyntest2: dyntest2.c
|
||||||
|
test_code100: test_code100.c
|
||||||
|
test_notice: test_notice.c
|
||||||
|
test_init: test_init.c
|
||||||
|
|
||||||
.pgc.c:
|
.pgc.c:
|
||||||
$(ECPG) $?
|
$(ECPG) $?
|
||||||
|
51
src/interfaces/ecpg/test/test_code100.pgc
Normal file
51
src/interfaces/ecpg/test/test_code100.pgc
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
// $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;
|
||||||
|
}
|
61
src/interfaces/ecpg/test/test_init.pgc
Normal file
61
src/interfaces/ecpg/test/test_init.pgc
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
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;
|
||||||
|
}
|
BIN
src/interfaces/ecpg/test/test_notice
Executable file
BIN
src/interfaces/ecpg/test/test_notice
Executable file
Binary file not shown.
94
src/interfaces/ecpg/test/test_notice.pgc
Normal file
94
src/interfaces/ecpg/test/test_notice.pgc
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
// $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;
|
||||||
|
}
|
Reference in New Issue
Block a user