1
0
mirror of https://github.com/postgres/postgres.git synced 2025-06-30 21:42:05 +03:00

Replace TupleTableSlot convention for whole-row variables and function

results with tuples as ordinary varlena Datums.  This commit does not
in itself do much for us, except eliminate the horrid memory leak
associated with evaluation of whole-row variables.  However, it lays the
groundwork for allowing composite types as table columns, and perhaps
some other useful features as well.  Per my proposal of a few days ago.
This commit is contained in:
Tom Lane
2004-04-01 21:28:47 +00:00
parent 8590a62b75
commit 375369acd1
60 changed files with 1779 additions and 1733 deletions

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/executor/nodeFunctionscan.c,v 1.23 2003/11/29 19:51:48 pgsql Exp $
* $PostgreSQL: pgsql/src/backend/executor/nodeFunctionscan.c,v 1.24 2004/04/01 21:28:44 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -32,6 +32,7 @@
#include "parser/parse_expr.h"
#include "parser/parse_type.h"
#include "utils/lsyscache.h"
#include "utils/typcache.h"
static TupleTableSlot *FunctionNext(FunctionScanState *node);
@ -194,25 +195,12 @@ ExecInitFunctionScan(FunctionScan *node, EState *estate)
if (functyptype == 'c')
{
/*
* Composite data type, i.e. a table's row type
*/
Oid funcrelid;
Relation rel;
funcrelid = typeidTypeRelid(funcrettype);
if (!OidIsValid(funcrelid))
elog(ERROR, "invalid typrelid for complex type %u",
funcrettype);
rel = relation_open(funcrelid, AccessShareLock);
tupdesc = CreateTupleDescCopy(RelationGetDescr(rel));
relation_close(rel, AccessShareLock);
/* Composite data type, e.g. a table's row type */
tupdesc = CreateTupleDescCopy(lookup_rowtype_tupdesc(funcrettype, -1));
}
else if (functyptype == 'b' || functyptype == 'd')
{
/*
* Must be a base data type, i.e. scalar
*/
/* Must be a base data type, i.e. scalar */
char *attname = strVal(lfirst(rte->eref->colnames));
tupdesc = CreateTemplateTupleDesc(1, false);
@ -221,14 +209,11 @@ ExecInitFunctionScan(FunctionScan *node, EState *estate)
attname,
funcrettype,
-1,
0,
false);
0);
}
else if (functyptype == 'p' && funcrettype == RECORDOID)
else if (funcrettype == RECORDOID)
{
/*
* Must be a pseudo type, i.e. record
*/
/* Must be a pseudo type, i.e. record */
tupdesc = BuildDescForRelation(rte->coldeflist);
}
else
@ -237,6 +222,14 @@ ExecInitFunctionScan(FunctionScan *node, EState *estate)
elog(ERROR, "function in FROM has unsupported return type");
}
/*
* For RECORD results, make sure a typmod has been assigned. (The
* function should do this for itself, but let's cover things in case
* it doesn't.)
*/
if (tupdesc->tdtypeid == RECORDOID && tupdesc->tdtypmod < 0)
assign_record_type_typmod(tupdesc);
scanstate->tupdesc = tupdesc;
ExecSetSlotDescriptor(scanstate->ss.ss_ScanTupleSlot,
tupdesc, false);