Make SPI's column-accessing functions work for system columns as well as
authorTom Lane
Tue, 23 Oct 2001 17:38:25 +0000 (17:38 +0000)
committerTom Lane
Tue, 23 Oct 2001 17:38:25 +0000 (17:38 +0000)
user columns.  Needed for foreign keys on OID, but useful in general.

src/backend/executor/spi.c

index 29e4729351d8657f6bdf525025a291c68450bc23..73457491d6b998d5370f07d2b66a9e1e8a3acf09 100644 (file)
@@ -8,13 +8,14 @@
  *
  *
  * 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 "access/printtup.h"
+#include "catalog/heap.h"
 #include "commands/command.h"
 #include "executor/spi_priv.h"
 
@@ -435,28 +436,42 @@ int
 SPI_fnumber(TupleDesc tupdesc, char *fname)
 {
    int         res;
+   Form_pg_attribute sysatt;
 
    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;
    }
 
+   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;
 }
 
 char *
 SPI_fname(TupleDesc tupdesc, int fnumber)
 {
+   Form_pg_attribute att;
 
    SPI_result = 0;
-   if (tupdesc->natts < fnumber || fnumber <= 0)
+
+   if (fnumber > tupdesc->natts || fnumber == 0 ||
+       fnumber <= FirstLowInvalidHeapAttributeNumber)
    {
        SPI_result = SPI_ERROR_NOATTRIBUTE;
        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 *
@@ -466,12 +481,16 @@ SPI_getvalue(HeapTuple tuple, TupleDesc tupdesc, int fnumber)
                val,
                result;
    bool        isnull;
-   Oid         foutoid,
+   Oid         typoid,
+               foutoid,
                typelem;
+   int32       typmod;
    bool        typisvarlena;
 
    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;
        return NULL;
@@ -480,8 +499,19 @@ SPI_getvalue(HeapTuple tuple, TupleDesc tupdesc, int fnumber)
    origval = heap_getattr(tuple, fnumber, tupdesc, &isnull);
    if (isnull)
        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;
        return NULL;
@@ -499,7 +529,7 @@ SPI_getvalue(HeapTuple tuple, TupleDesc tupdesc, int fnumber)
    result = OidFunctionCall3(foutoid,
                              val,
                              ObjectIdGetDatum(typelem),
-                 Int32GetDatum(tupdesc->attrs[fnumber - 1]->atttypmod));
+                             Int32GetDatum(typmod));
 
    /* Clean up detoasted copy, if any */
    if (val != origval)
@@ -511,36 +541,42 @@ SPI_getvalue(HeapTuple tuple, TupleDesc tupdesc, int fnumber)
 Datum
 SPI_getbinval(HeapTuple tuple, TupleDesc tupdesc, int fnumber, bool *isnull)
 {
-   Datum       val;
-
-   *isnull = true;
    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;
+       *isnull = true;
        return (Datum) NULL;
    }
 
-   val = heap_getattr(tuple, fnumber, tupdesc, isnull);
-
-   return val;
+   return heap_getattr(tuple, fnumber, tupdesc, isnull);
 }
 
 char *
 SPI_gettype(TupleDesc tupdesc, int fnumber)
 {
+   Oid         typoid;
    HeapTuple   typeTuple;
    char       *result;
 
    SPI_result = 0;
-   if (tupdesc->natts < fnumber || fnumber <= 0)
+
+   if (fnumber > tupdesc->natts || fnumber == 0 ||
+       fnumber <= FirstLowInvalidHeapAttributeNumber)
    {
        SPI_result = SPI_ERROR_NOATTRIBUTE;
        return NULL;
    }
 
+   if (fnumber > 0)
+       typoid = tupdesc->attrs[fnumber - 1]->atttypid;
+   else
+       typoid = (SystemAttributeDefinition(fnumber, true))->atttypid;
+
    typeTuple = SearchSysCache(TYPEOID,
-                ObjectIdGetDatum(tupdesc->attrs[fnumber - 1]->atttypid),
+                              ObjectIdGetDatum(typoid),
                               0, 0, 0);
 
    if (!HeapTupleIsValid(typeTuple))
@@ -557,15 +593,19 @@ SPI_gettype(TupleDesc tupdesc, int fnumber)
 Oid
 SPI_gettypeid(TupleDesc tupdesc, int fnumber)
 {
-
    SPI_result = 0;
-   if (tupdesc->natts < fnumber || fnumber <= 0)
+
+   if (fnumber > tupdesc->natts || fnumber == 0 ||
+       fnumber <= FirstLowInvalidHeapAttributeNumber)
    {
        SPI_result = SPI_ERROR_NOATTRIBUTE;
        return InvalidOid;
    }
 
-   return tupdesc->attrs[fnumber - 1]->atttypid;
+   if (fnumber > 0)
+       return tupdesc->attrs[fnumber - 1]->atttypid;
+   else
+       return (SystemAttributeDefinition(fnumber, true))->atttypid;
 }
 
 char *