Commit 57dd2ce7 authored by Tom Lane's avatar Tom Lane

Make SPI's column-accessing functions work for system columns as well as

user columns.  Needed for foreign keys on OID, but useful in general.
parent 3e76c9aa
...@@ -8,13 +8,14 @@ ...@@ -8,13 +8,14 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/executor/spi.c,v 1.58 2001/10/05 17:28:12 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/executor/spi.c,v 1.59 2001/10/23 17:38:25 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
#include "postgres.h" #include "postgres.h"
#include "access/printtup.h" #include "access/printtup.h"
#include "catalog/heap.h"
#include "commands/command.h" #include "commands/command.h"
#include "executor/spi_priv.h" #include "executor/spi_priv.h"
...@@ -435,28 +436,42 @@ int ...@@ -435,28 +436,42 @@ int
SPI_fnumber(TupleDesc tupdesc, char *fname) SPI_fnumber(TupleDesc tupdesc, char *fname)
{ {
int res; int res;
Form_pg_attribute sysatt;
for (res = 0; res < tupdesc->natts; res++) for (res = 0; res < tupdesc->natts; res++)
{ {
if (strcasecmp(NameStr(tupdesc->attrs[res]->attname), fname) == 0) if (namestrcmp(&tupdesc->attrs[res]->attname, fname) == 0)
return res + 1; return res + 1;
} }
sysatt = SystemAttributeByName(fname, true /* "oid" will be accepted */);
if (sysatt != NULL)
return sysatt->attnum;
/* SPI_ERROR_NOATTRIBUTE is different from all sys column numbers */
return SPI_ERROR_NOATTRIBUTE; return SPI_ERROR_NOATTRIBUTE;
} }
char * char *
SPI_fname(TupleDesc tupdesc, int fnumber) SPI_fname(TupleDesc tupdesc, int fnumber)
{ {
Form_pg_attribute att;
SPI_result = 0; SPI_result = 0;
if (tupdesc->natts < fnumber || fnumber <= 0)
if (fnumber > tupdesc->natts || fnumber == 0 ||
fnumber <= FirstLowInvalidHeapAttributeNumber)
{ {
SPI_result = SPI_ERROR_NOATTRIBUTE; SPI_result = SPI_ERROR_NOATTRIBUTE;
return NULL; return NULL;
} }
return pstrdup(NameStr(tupdesc->attrs[fnumber - 1]->attname)); if (fnumber > 0)
att = tupdesc->attrs[fnumber - 1];
else
att = SystemAttributeDefinition(fnumber, true);
return pstrdup(NameStr(att->attname));
} }
char * char *
...@@ -466,12 +481,16 @@ SPI_getvalue(HeapTuple tuple, TupleDesc tupdesc, int fnumber) ...@@ -466,12 +481,16 @@ SPI_getvalue(HeapTuple tuple, TupleDesc tupdesc, int fnumber)
val, val,
result; result;
bool isnull; bool isnull;
Oid foutoid, Oid typoid,
foutoid,
typelem; typelem;
int32 typmod;
bool typisvarlena; bool typisvarlena;
SPI_result = 0; SPI_result = 0;
if (tuple->t_data->t_natts < fnumber || fnumber <= 0)
if (fnumber > tuple->t_data->t_natts || fnumber == 0 ||
fnumber <= FirstLowInvalidHeapAttributeNumber)
{ {
SPI_result = SPI_ERROR_NOATTRIBUTE; SPI_result = SPI_ERROR_NOATTRIBUTE;
return NULL; return NULL;
...@@ -480,8 +499,19 @@ SPI_getvalue(HeapTuple tuple, TupleDesc tupdesc, int fnumber) ...@@ -480,8 +499,19 @@ SPI_getvalue(HeapTuple tuple, TupleDesc tupdesc, int fnumber)
origval = heap_getattr(tuple, fnumber, tupdesc, &isnull); origval = heap_getattr(tuple, fnumber, tupdesc, &isnull);
if (isnull) if (isnull)
return NULL; return NULL;
if (!getTypeOutputInfo(tupdesc->attrs[fnumber - 1]->atttypid,
&foutoid, &typelem, &typisvarlena)) if (fnumber > 0)
{
typoid = tupdesc->attrs[fnumber - 1]->atttypid;
typmod = tupdesc->attrs[fnumber - 1]->atttypmod;
}
else
{
typoid = (SystemAttributeDefinition(fnumber, true))->atttypid;
typmod = -1;
}
if (!getTypeOutputInfo(typoid, &foutoid, &typelem, &typisvarlena))
{ {
SPI_result = SPI_ERROR_NOOUTFUNC; SPI_result = SPI_ERROR_NOOUTFUNC;
return NULL; return NULL;
...@@ -499,7 +529,7 @@ SPI_getvalue(HeapTuple tuple, TupleDesc tupdesc, int fnumber) ...@@ -499,7 +529,7 @@ SPI_getvalue(HeapTuple tuple, TupleDesc tupdesc, int fnumber)
result = OidFunctionCall3(foutoid, result = OidFunctionCall3(foutoid,
val, val,
ObjectIdGetDatum(typelem), ObjectIdGetDatum(typelem),
Int32GetDatum(tupdesc->attrs[fnumber - 1]->atttypmod)); Int32GetDatum(typmod));
/* Clean up detoasted copy, if any */ /* Clean up detoasted copy, if any */
if (val != origval) if (val != origval)
...@@ -511,36 +541,42 @@ SPI_getvalue(HeapTuple tuple, TupleDesc tupdesc, int fnumber) ...@@ -511,36 +541,42 @@ SPI_getvalue(HeapTuple tuple, TupleDesc tupdesc, int fnumber)
Datum Datum
SPI_getbinval(HeapTuple tuple, TupleDesc tupdesc, int fnumber, bool *isnull) SPI_getbinval(HeapTuple tuple, TupleDesc tupdesc, int fnumber, bool *isnull)
{ {
Datum val;
*isnull = true;
SPI_result = 0; SPI_result = 0;
if (tuple->t_data->t_natts < fnumber || fnumber <= 0)
if (fnumber > tuple->t_data->t_natts || fnumber == 0 ||
fnumber <= FirstLowInvalidHeapAttributeNumber)
{ {
SPI_result = SPI_ERROR_NOATTRIBUTE; SPI_result = SPI_ERROR_NOATTRIBUTE;
*isnull = true;
return (Datum) NULL; return (Datum) NULL;
} }
val = heap_getattr(tuple, fnumber, tupdesc, isnull); return heap_getattr(tuple, fnumber, tupdesc, isnull);
return val;
} }
char * char *
SPI_gettype(TupleDesc tupdesc, int fnumber) SPI_gettype(TupleDesc tupdesc, int fnumber)
{ {
Oid typoid;
HeapTuple typeTuple; HeapTuple typeTuple;
char *result; char *result;
SPI_result = 0; SPI_result = 0;
if (tupdesc->natts < fnumber || fnumber <= 0)
if (fnumber > tupdesc->natts || fnumber == 0 ||
fnumber <= FirstLowInvalidHeapAttributeNumber)
{ {
SPI_result = SPI_ERROR_NOATTRIBUTE; SPI_result = SPI_ERROR_NOATTRIBUTE;
return NULL; return NULL;
} }
if (fnumber > 0)
typoid = tupdesc->attrs[fnumber - 1]->atttypid;
else
typoid = (SystemAttributeDefinition(fnumber, true))->atttypid;
typeTuple = SearchSysCache(TYPEOID, typeTuple = SearchSysCache(TYPEOID,
ObjectIdGetDatum(tupdesc->attrs[fnumber - 1]->atttypid), ObjectIdGetDatum(typoid),
0, 0, 0); 0, 0, 0);
if (!HeapTupleIsValid(typeTuple)) if (!HeapTupleIsValid(typeTuple))
...@@ -557,15 +593,19 @@ SPI_gettype(TupleDesc tupdesc, int fnumber) ...@@ -557,15 +593,19 @@ SPI_gettype(TupleDesc tupdesc, int fnumber)
Oid Oid
SPI_gettypeid(TupleDesc tupdesc, int fnumber) SPI_gettypeid(TupleDesc tupdesc, int fnumber)
{ {
SPI_result = 0; SPI_result = 0;
if (tupdesc->natts < fnumber || fnumber <= 0)
if (fnumber > tupdesc->natts || fnumber == 0 ||
fnumber <= FirstLowInvalidHeapAttributeNumber)
{ {
SPI_result = SPI_ERROR_NOATTRIBUTE; SPI_result = SPI_ERROR_NOATTRIBUTE;
return InvalidOid; return InvalidOid;
} }
return tupdesc->attrs[fnumber - 1]->atttypid; if (fnumber > 0)
return tupdesc->attrs[fnumber - 1]->atttypid;
else
return (SystemAttributeDefinition(fnumber, true))->atttypid;
} }
char * char *
......
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