1
0
mirror of https://github.com/postgres/postgres.git synced 2025-07-31 22:04:40 +03:00

Made sure an internal array is not treated as a user defined one.

This commit is contained in:
Michael Meskes
2003-11-08 19:46:27 +00:00
parent 449593a9fb
commit 87758314ca
4 changed files with 175 additions and 121 deletions

View File

@ -1,4 +1,4 @@
/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/ecpglib/execute.c,v 1.26 2003/10/26 09:50:47 meskes Exp $ */
/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/ecpglib/execute.c,v 1.27 2003/11/08 19:46:27 meskes Exp $ */
/*
* The aim is to get a simpler inteface to the database routines.
@ -230,29 +230,12 @@ 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
= (struct ECPGtype_information_cache *) ECPGalloc(sizeof(struct ECPGtype_information_cache), lineno);
new_entry->oid = oid;
new_entry->isarray = isarray;
new_entry->next = *cache;
*cache = new_entry;
}
static bool
static enum ARRAY_TYPE
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;
char *array_query;
enum ARRAY_TYPE isarray = ECPG_ARRAY_NOT_SET;
PGresult *query;
if ((stmt->connection->cache_head) == NULL)
{
@ -261,78 +244,119 @@ ECPGis_type_an_array(int type, const struct statement * stmt, const struct varia
* them as an array. This define reminds you to not 'correct'
* these values.
*/
#define not_an_array_in_ecpg false
/* 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, not_an_array_in_ecpg, stmt->lineno);
ECPGtypeinfocache_push(&(stmt->connection->cache_head), CHAROID, false, stmt->lineno);
ECPGtypeinfocache_push(&(stmt->connection->cache_head), NAMEOID, not_an_array_in_ecpg, 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, not_an_array_in_ecpg, 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, not_an_array_in_ecpg, 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, not_an_array_in_ecpg, 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), TIMESTAMPTZOID, 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 *) ECPGalloc(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);
ECPGfree(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)
#define not_an_array_in_ecpg ECPG_ARRAY_NONE
switch (type)
{
/*
* arrays of character strings are not yet implemented
*/
isarray = false;
case BOOLOID: isarray = ECPG_ARRAY_NONE;
break;
case BYTEAOID: isarray = ECPG_ARRAY_NONE;
break;
case CHAROID: isarray = ECPG_ARRAY_NONE;
break;
case NAMEOID: isarray = not_an_array_in_ecpg;
break;
case INT8OID: isarray = ECPG_ARRAY_NONE;
break;
case INT2OID: isarray = ECPG_ARRAY_NONE;
break;
case INT2VECTOROID: isarray = ECPG_ARRAY_VECTOR;
break;
case INT4OID: isarray = ECPG_ARRAY_NONE;
break;
case REGPROCOID: isarray = ECPG_ARRAY_NONE;
break;
case TEXTOID: isarray = ECPG_ARRAY_NONE;
break;
case OIDOID: isarray = ECPG_ARRAY_NONE;
break;
case TIDOID: isarray = ECPG_ARRAY_NONE;
break;
case XIDOID: isarray = ECPG_ARRAY_NONE;
break;
case CIDOID: isarray = ECPG_ARRAY_NONE;
break;
case OIDVECTOROID: isarray = ECPG_ARRAY_VECTOR;
break;
case POINTOID: isarray = ECPG_ARRAY_VECTOR;
break;
case LSEGOID: isarray = ECPG_ARRAY_VECTOR;
break;
case PATHOID: isarray = ECPG_ARRAY_NONE;
break;
case BOXOID: isarray = ECPG_ARRAY_VECTOR;
break;
case POLYGONOID: isarray = ECPG_ARRAY_NONE;
break;
case LINEOID: isarray = ECPG_ARRAY_VECTOR;
break;
case FLOAT4OID: isarray = ECPG_ARRAY_NONE;
break;
case FLOAT8OID: isarray = ECPG_ARRAY_NONE;
break;
case ABSTIMEOID: isarray = ECPG_ARRAY_NONE;
break;
case RELTIMEOID: isarray = ECPG_ARRAY_NONE;
break;
case TINTERVALOID: isarray = ECPG_ARRAY_NONE;
break;
case UNKNOWNOID: isarray = ECPG_ARRAY_NONE;
break;
case CIRCLEOID: isarray = ECPG_ARRAY_NONE;
break;
case CASHOID: isarray = ECPG_ARRAY_NONE;
break;
case INETOID: isarray = ECPG_ARRAY_NONE;
break;
case CIDROID: isarray = ECPG_ARRAY_NONE;
break;
case BPCHAROID: isarray = ECPG_ARRAY_NONE;
break;
case VARCHAROID: isarray = ECPG_ARRAY_NONE;
break;
case DATEOID: isarray = ECPG_ARRAY_NONE;
break;
case TIMEOID: isarray = ECPG_ARRAY_NONE;
break;
case TIMESTAMPOID: isarray = ECPG_ARRAY_NONE;
break;
case TIMESTAMPTZOID: isarray = ECPG_ARRAY_NONE;
break;
case INTERVALOID: isarray = ECPG_ARRAY_NONE;
break;
case TIMETZOID: isarray = ECPG_ARRAY_NONE;
break;
case ZPBITOID: isarray = ECPG_ARRAY_NONE;
break;
case VARBITOID: isarray = ECPG_ARRAY_NONE;
break;
case NUMERICOID: isarray = ECPG_ARRAY_NONE;
break;
default: break;
}
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);
if (isarray == ECPG_ARRAY_NOT_SET)
{
array_query = (char *) ECPGalloc(strlen("select typlen from pg_type where oid= and typelem<>0") + 11, stmt->lineno);
sprintf(array_query, "select typlen from pg_type where oid=%d and typelem<>0", type);
query = PQexec(stmt->connection->connection, array_query);
ECPGfree(array_query);
if (PQresultStatus(query) == PGRES_TUPLES_OK)
{
isarray = (atol((char *) PQgetvalue(query, 0, 0)) == -1) ? ECPG_ARRAY_ARRAY : ECPG_ARRAY_VECTOR;
if (ECPGDynamicType(type) == SQL3_CHARACTER ||
ECPGDynamicType(type) == SQL3_CHARACTER_VARYING)
{
/*
* arrays of character strings are not yet implemented
*/
isarray = ECPG_ARRAY_NONE;
}
}
PQclear(query);
}
ECPGlog("ECPGexecute line %d: TYPE database: %d C: %d array: %d\n", stmt->lineno, type, var->type, isarray);
return isarray;
}
@ -341,14 +365,14 @@ bool
ECPGstore_result(const PGresult *results, int act_field,
const struct statement * stmt, struct variable * var)
{
int isarray,
act_tuple,
enum ARRAY_TYPE isarray;
int act_tuple,
ntuples = PQntuples(results);
bool status = true;
isarray = ECPGis_type_an_array(PQftype(results, act_field), stmt, var);
if (!isarray)
if (isarray == ECPG_ARRAY_NONE)
{
/*
* if we don't have enough space, we cannot read all tuples
@ -1164,6 +1188,7 @@ ECPGexecute(struct statement * stmt)
case PGRES_TUPLES_OK:
nfields = PQnfields(results);
sqlca->sqlerrd[2] = ntuples = PQntuples(results);
ECPGlog("ECPGexecute line %d: Correctly got %d tuples with %d fields\n", stmt->lineno, ntuples, nfields);
status = true;
if (ntuples < 1)