Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 57dd2ce

Browse files
committed
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.
1 parent 3e76c9a commit 57dd2ce

File tree

1 file changed

+61
-21
lines changed
  • src/backend/executor

1 file changed

+61
-21
lines changed

src/backend/executor/spi.c

Lines changed: 61 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,14 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/executor/spi.c,v 1.58 2001/10/05 17:28:12 tgl Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/executor/spi.c,v 1.59 2001/10/23 17:38:25 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
1515
#include "postgres.h"
1616

1717
#include "access/printtup.h"
18+
#include "catalog/heap.h"
1819
#include "commands/command.h"
1920
#include "executor/spi_priv.h"
2021

@@ -435,28 +436,42 @@ int
435436
SPI_fnumber(TupleDesc tupdesc, char *fname)
436437
{
437438
int res;
439+
Form_pg_attribute sysatt;
438440

439441
for (res = 0; res < tupdesc->natts; res++)
440442
{
441-
if (strcasecmp(NameStr(tupdesc->attrs[res]->attname), fname) == 0)
443+
if (namestrcmp(&tupdesc->attrs[res]->attname, fname) == 0)
442444
return res + 1;
443445
}
444446

447+
sysatt = SystemAttributeByName(fname, true /* "oid" will be accepted */);
448+
if (sysatt != NULL)
449+
return sysatt->attnum;
450+
451+
/* SPI_ERROR_NOATTRIBUTE is different from all sys column numbers */
445452
return SPI_ERROR_NOATTRIBUTE;
446453
}
447454

448455
char *
449456
SPI_fname(TupleDesc tupdesc, int fnumber)
450457
{
458+
Form_pg_attribute att;
451459

452460
SPI_result = 0;
453-
if (tupdesc->natts < fnumber || fnumber <= 0)
461+
462+
if (fnumber > tupdesc->natts || fnumber == 0 ||
463+
fnumber <= FirstLowInvalidHeapAttributeNumber)
454464
{
455465
SPI_result = SPI_ERROR_NOATTRIBUTE;
456466
return NULL;
457467
}
458468

459-
return pstrdup(NameStr(tupdesc->attrs[fnumber - 1]->attname));
469+
if (fnumber > 0)
470+
att = tupdesc->attrs[fnumber - 1];
471+
else
472+
att = SystemAttributeDefinition(fnumber, true);
473+
474+
return pstrdup(NameStr(att->attname));
460475
}
461476

462477
char *
@@ -466,12 +481,16 @@ SPI_getvalue(HeapTuple tuple, TupleDesc tupdesc, int fnumber)
466481
val,
467482
result;
468483
bool isnull;
469-
Oid foutoid,
484+
Oid typoid,
485+
foutoid,
470486
typelem;
487+
int32 typmod;
471488
bool typisvarlena;
472489

473490
SPI_result = 0;
474-
if (tuple->t_data->t_natts < fnumber || fnumber <= 0)
491+
492+
if (fnumber > tuple->t_data->t_natts || fnumber == 0 ||
493+
fnumber <= FirstLowInvalidHeapAttributeNumber)
475494
{
476495
SPI_result = SPI_ERROR_NOATTRIBUTE;
477496
return NULL;
@@ -480,8 +499,19 @@ SPI_getvalue(HeapTuple tuple, TupleDesc tupdesc, int fnumber)
480499
origval = heap_getattr(tuple, fnumber, tupdesc, &isnull);
481500
if (isnull)
482501
return NULL;
483-
if (!getTypeOutputInfo(tupdesc->attrs[fnumber - 1]->atttypid,
484-
&foutoid, &typelem, &typisvarlena))
502+
503+
if (fnumber > 0)
504+
{
505+
typoid = tupdesc->attrs[fnumber - 1]->atttypid;
506+
typmod = tupdesc->attrs[fnumber - 1]->atttypmod;
507+
}
508+
else
509+
{
510+
typoid = (SystemAttributeDefinition(fnumber, true))->atttypid;
511+
typmod = -1;
512+
}
513+
514+
if (!getTypeOutputInfo(typoid, &foutoid, &typelem, &typisvarlena))
485515
{
486516
SPI_result = SPI_ERROR_NOOUTFUNC;
487517
return NULL;
@@ -499,7 +529,7 @@ SPI_getvalue(HeapTuple tuple, TupleDesc tupdesc, int fnumber)
499529
result = OidFunctionCall3(foutoid,
500530
val,
501531
ObjectIdGetDatum(typelem),
502-
Int32GetDatum(tupdesc->attrs[fnumber - 1]->atttypmod));
532+
Int32GetDatum(typmod));
503533

504534
/* Clean up detoasted copy, if any */
505535
if (val != origval)
@@ -511,36 +541,42 @@ SPI_getvalue(HeapTuple tuple, TupleDesc tupdesc, int fnumber)
511541
Datum
512542
SPI_getbinval(HeapTuple tuple, TupleDesc tupdesc, int fnumber, bool *isnull)
513543
{
514-
Datum val;
515-
516-
*isnull = true;
517544
SPI_result = 0;
518-
if (tuple->t_data->t_natts < fnumber || fnumber <= 0)
545+
546+
if (fnumber > tuple->t_data->t_natts || fnumber == 0 ||
547+
fnumber <= FirstLowInvalidHeapAttributeNumber)
519548
{
520549
SPI_result = SPI_ERROR_NOATTRIBUTE;
550+
*isnull = true;
521551
return (Datum) NULL;
522552
}
523553

524-
val = heap_getattr(tuple, fnumber, tupdesc, isnull);
525-
526-
return val;
554+
return heap_getattr(tuple, fnumber, tupdesc, isnull);
527555
}
528556

529557
char *
530558
SPI_gettype(TupleDesc tupdesc, int fnumber)
531559
{
560+
Oid typoid;
532561
HeapTuple typeTuple;
533562
char *result;
534563

535564
SPI_result = 0;
536-
if (tupdesc->natts < fnumber || fnumber <= 0)
565+
566+
if (fnumber > tupdesc->natts || fnumber == 0 ||
567+
fnumber <= FirstLowInvalidHeapAttributeNumber)
537568
{
538569
SPI_result = SPI_ERROR_NOATTRIBUTE;
539570
return NULL;
540571
}
541572

573+
if (fnumber > 0)
574+
typoid = tupdesc->attrs[fnumber - 1]->atttypid;
575+
else
576+
typoid = (SystemAttributeDefinition(fnumber, true))->atttypid;
577+
542578
typeTuple = SearchSysCache(TYPEOID,
543-
ObjectIdGetDatum(tupdesc->attrs[fnumber - 1]->atttypid),
579+
ObjectIdGetDatum(typoid),
544580
0, 0, 0);
545581

546582
if (!HeapTupleIsValid(typeTuple))
@@ -557,15 +593,19 @@ SPI_gettype(TupleDesc tupdesc, int fnumber)
557593
Oid
558594
SPI_gettypeid(TupleDesc tupdesc, int fnumber)
559595
{
560-
561596
SPI_result = 0;
562-
if (tupdesc->natts < fnumber || fnumber <= 0)
597+
598+
if (fnumber > tupdesc->natts || fnumber == 0 ||
599+
fnumber <= FirstLowInvalidHeapAttributeNumber)
563600
{
564601
SPI_result = SPI_ERROR_NOATTRIBUTE;
565602
return InvalidOid;
566603
}
567604

568-
return tupdesc->attrs[fnumber - 1]->atttypid;
605+
if (fnumber > 0)
606+
return tupdesc->attrs[fnumber - 1]->atttypid;
607+
else
608+
return (SystemAttributeDefinition(fnumber, true))->atttypid;
569609
}
570610

571611
char *

0 commit comments

Comments
 (0)