aboutsummaryrefslogtreecommitdiff
path: root/src/backend/executor/nodeFunctionscan.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2004-04-01 21:28:47 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2004-04-01 21:28:47 +0000
commit375369acd1c621bdc683c58bc9c31d4e79d14849 (patch)
treef29974842cea4105c92da6031bac736ddf5f833a /src/backend/executor/nodeFunctionscan.c
parent8590a62b75d3dba24609eb46b34fac13ed881d9e (diff)
downloadpostgresql-375369acd1c621bdc683c58bc9c31d4e79d14849.tar.gz
postgresql-375369acd1c621bdc683c58bc9c31d4e79d14849.zip
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.
Diffstat (limited to 'src/backend/executor/nodeFunctionscan.c')
-rw-r--r--src/backend/executor/nodeFunctionscan.c39
1 files changed, 16 insertions, 23 deletions
diff --git a/src/backend/executor/nodeFunctionscan.c b/src/backend/executor/nodeFunctionscan.c
index f3fa17c8881..7847b24ffe2 100644
--- a/src/backend/executor/nodeFunctionscan.c
+++ b/src/backend/executor/nodeFunctionscan.c
@@ -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);