diff --git a/doc/src/sgml/spi.sgml b/doc/src/sgml/spi.sgml new file mode 100644 index 6869366..4acf824 *** a/doc/src/sgml/spi.sgml --- b/doc/src/sgml/spi.sgml *************** Oid SPI_gettypeid(TupleDesc r *** 3186,3191 **** --- 3186,3257 ---- + + + SPI_gettypmod + 3 + + + + SPI_gettypmod + return the type-specific data of the specified column + + + SPI_gettypmod + + + + int4 SPI_gettypmod(TupleDesc rowdesc, int colnumber) + + + + + Description + + + SPI_gettypmod returns the type-specific data supplied + at table creation time. For example: the max length of a varchar field. + + + + + Arguments + + + + TupleDesc rowdesc + + + input row description + + + + + + int colnumber + + + column number (count starts at 1) + + + + + + + + Return Value + + + The type-specific data supplied at table creation time of the specified + column or InvalidOid on error. On error, + SPI_result is set to + SPI_ERROR_NOATTRIBUTE. + + + + + + SPI_getrelname diff --git a/src/backend/executor/spi.c b/src/backend/executor/spi.c new file mode 100644 index de8d59a..86c1cee *** a/src/backend/executor/spi.c --- b/src/backend/executor/spi.c *************** SPI_gettypeid(TupleDesc tupdesc, int fnu *** 958,963 **** --- 958,981 ---- return (SystemAttributeDefinition(fnumber, true))->atttypid; } + int32 + SPI_gettypmod(TupleDesc tupdesc, int fnumber) + { + SPI_result = 0; + + if (fnumber > tupdesc->natts || fnumber == 0 || + fnumber <= FirstLowInvalidHeapAttributeNumber) + { + SPI_result = SPI_ERROR_NOATTRIBUTE; + return -1; + } + + if (fnumber > 0) + return tupdesc->attrs[fnumber - 1]->atttypmod; + else + return (SystemAttributeDefinition(fnumber, true))->atttypmod; + } + char * SPI_getrelname(Relation rel) { diff --git a/src/include/executor/spi.h b/src/include/executor/spi.h new file mode 100644 index d4f1272..cfd95fe *** a/src/include/executor/spi.h --- b/src/include/executor/spi.h *************** extern char *SPI_getvalue(HeapTuple tupl *** 116,121 **** --- 116,122 ---- extern Datum SPI_getbinval(HeapTuple tuple, TupleDesc tupdesc, int fnumber, bool *isnull); extern char *SPI_gettype(TupleDesc tupdesc, int fnumber); extern Oid SPI_gettypeid(TupleDesc tupdesc, int fnumber); + extern int32 SPI_gettypmod(TupleDesc tupdesc, int fnumber); extern char *SPI_getrelname(Relation rel); extern char *SPI_getnspname(Relation rel); extern void *SPI_palloc(Size size); diff --git a/src/pl/plpgsql/src/pl_exec.c b/src/pl/plpgsql/src/pl_exec.c new file mode 100644 index 591a432..73ab354 *** a/src/pl/plpgsql/src/pl_exec.c --- b/src/pl/plpgsql/src/pl_exec.c *************** exec_eval_datum(PLpgSQL_execstate *estat *** 4386,4396 **** errmsg("record \"%s\" has no field \"%s\"", rec->refname, recfield->fieldname))); *typeid = SPI_gettypeid(rec->tupdesc, fno); ! /* XXX there's no SPI_gettypmod, for some reason */ ! if (fno > 0) ! *typetypmod = rec->tupdesc->attrs[fno - 1]->atttypmod; ! else ! *typetypmod = -1; *value = SPI_getbinval(rec->tup, rec->tupdesc, fno, isnull); break; } --- 4386,4392 ---- errmsg("record \"%s\" has no field \"%s\"", rec->refname, recfield->fieldname))); *typeid = SPI_gettypeid(rec->tupdesc, fno); ! *typetypmod = SPI_gettypeid(rec->tupdesc, fno); *value = SPI_getbinval(rec->tup, rec->tupdesc, fno, isnull); break; } *************** exec_get_datum_type_info(PLpgSQL_execsta *** 4563,4573 **** errmsg("record \"%s\" has no field \"%s\"", rec->refname, recfield->fieldname))); *typeid = SPI_gettypeid(rec->tupdesc, fno); ! /* XXX there's no SPI_gettypmod, for some reason */ ! if (fno > 0) ! *typmod = rec->tupdesc->attrs[fno - 1]->atttypmod; ! else ! *typmod = -1; /* XXX there's no SPI_getcollation either */ if (fno > 0) *collation = rec->tupdesc->attrs[fno - 1]->attcollation; --- 4559,4565 ---- errmsg("record \"%s\" has no field \"%s\"", rec->refname, recfield->fieldname))); *typeid = SPI_gettypeid(rec->tupdesc, fno); ! *typmod = SPI_gettypmod(rec->tupdesc, fno); /* XXX there's no SPI_getcollation either */ if (fno > 0) *collation = rec->tupdesc->attrs[fno - 1]->attcollation;