1
0
mirror of https://github.com/postgres/postgres.git synced 2025-11-22 12:22:45 +03:00

*** empty log message ***

This commit is contained in:
Michael Meskes
2000-09-20 13:25:52 +00:00
parent 95563e7bbf
commit 339a5bbfb1
14 changed files with 575 additions and 73 deletions

View File

@@ -27,6 +27,8 @@ ecpg_finish(struct connection * act)
{
if (act != NULL)
{
struct ECPGtype_information_cache *cache, *ptr;
ECPGlog("ecpg_finish: finishing %s.\n", act->name);
PQfinish(act->connection);
@@ -45,6 +47,7 @@ ecpg_finish(struct connection * act)
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);
}
@@ -107,6 +110,120 @@ ECPGsetconn(int lineno, const char *connection_name)
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)
{
@@ -119,12 +236,14 @@ ECPGconnect(int lineno, const char *dbname, const char *user, const char *passwd
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;
@@ -147,6 +266,8 @@ ECPGconnect(int lineno, const char *dbname, const char *user, const char *passwd
this->committed = true;
this->autocommit = autocommit;
PQsetNoticeProcessor(this->connection,&ECPGnoticeProcessor,(void*)this);
return true;
}

View File

@@ -302,10 +302,10 @@ ECPGdeallocate_desc(int line, const char *name)
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;

View File

@@ -15,6 +15,8 @@
#include <stdio.h>
#include <locale.h>
#include "pg_type.h"
#include "ecpgtype.h"
#include "ecpglib.h"
#include "ecpgerrno.h"
@@ -252,13 +254,110 @@ next_insert(char *text)
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;
@@ -700,8 +799,6 @@ ECPGexecute(struct statement * stmt)
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);
@@ -709,26 +806,7 @@ ECPGexecute(struct statement * stmt)
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)
{
@@ -911,7 +989,7 @@ ECPGdo(int lineno, const char *connection_name, char *query,...)
*
* 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);

View File

@@ -21,6 +21,17 @@ struct ECPGgeneric_varchar
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
{
@@ -36,7 +47,8 @@ struct connection
{
char *name;
PGconn *connection;
bool committed;
int autocommit;
bool committed;
int autocommit;
struct ECPGtype_information_cache *cache_head;
struct connection *next;
};

View 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 */

View File

@@ -3,6 +3,7 @@
#include "ecpglib.h"
#include "extern.h"
#include "sql3types.h"
#include "pg_type.h"
/*
* This function is used to generate the correct type names.
@@ -12,7 +13,7 @@ ECPGtype_name(enum ECPGttype typ)
{
switch (typ)
{
case ECPGt_char:
case ECPGt_char:
return "char";
case ECPGt_unsigned_char:
return "unsigned char";
@@ -53,31 +54,18 @@ ECPGDynamicType(Oid type)
{
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;
}