diff options
Diffstat (limited to 'src/backend/executor/functions.c')
-rw-r--r-- | src/backend/executor/functions.c | 82 |
1 files changed, 36 insertions, 46 deletions
diff --git a/src/backend/executor/functions.c b/src/backend/executor/functions.c index a92811d0342..001feb267ff 100644 --- a/src/backend/executor/functions.c +++ b/src/backend/executor/functions.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/executor/functions.c,v 1.36 2000/07/12 02:37:03 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/executor/functions.c,v 1.37 2000/08/08 15:41:22 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -47,24 +47,21 @@ static void postquel_end(execution_state *es); static void postquel_sub_params(execution_state *es, FunctionCallInfo fcinfo); static Datum postquel_execute(execution_state *es, FunctionCallInfo fcinfo, - FunctionCachePtr fcache, - List *func_tlist); + FunctionCachePtr fcache); -Datum -ProjectAttribute(TupleDesc TD, - TargetEntry *tlist, - HeapTuple tup, +static Datum +ProjectAttribute(HeapTuple tup, + AttrNumber attrno, + TupleDesc TD, bool *isnullP) { Datum val; - Var *attrVar = (Var *) tlist->expr; - AttrNumber attrno = attrVar->varattno; val = heap_getattr(tup, attrno, TD, isnullP); if (*isnullP) - return (Datum) 0; + return val; return datumCopy(val, TD->attrs[attrno - 1]->attbyval, @@ -216,39 +213,29 @@ copy_function_result(FunctionCachePtr fcache, { TupleTableSlot *funcSlot; TupleDesc resultTd; + HeapTuple resultTuple; HeapTuple newTuple; - HeapTuple oldTuple; Assert(!TupIsNull(resultSlot)); - oldTuple = resultSlot->val; + resultTuple = resultSlot->val; funcSlot = (TupleTableSlot *) fcache->funcSlot; if (funcSlot == (TupleTableSlot *) NULL) return resultSlot; - resultTd = resultSlot->ttc_tupleDescriptor; - /* - * When the funcSlot is NULL we have to initialize the funcSlot's + * If first time through, we have to initialize the funcSlot's * tuple descriptor. */ if (TupIsNull(funcSlot)) { - int i = 0; - TupleDesc funcTd = funcSlot->ttc_tupleDescriptor; - - while (i < oldTuple->t_data->t_natts) - { - funcTd->attrs[i] = (Form_pg_attribute) palloc(ATTRIBUTE_TUPLE_SIZE); - memmove(funcTd->attrs[i], - resultTd->attrs[i], - ATTRIBUTE_TUPLE_SIZE); - i++; - } + resultTd = resultSlot->ttc_tupleDescriptor; + funcSlot->ttc_tupleDescriptor = CreateTupleDescCopy(resultTd); + funcSlot->ttc_descIsNew = true; } - newTuple = heap_copytuple(oldTuple); + newTuple = heap_copytuple(resultTuple); return ExecStoreTuple(newTuple, funcSlot, InvalidBuffer, true); } @@ -256,8 +243,7 @@ copy_function_result(FunctionCachePtr fcache, static Datum postquel_execute(execution_state *es, FunctionCallInfo fcinfo, - FunctionCachePtr fcache, - List *func_tlist) + FunctionCachePtr fcache) { TupleTableSlot *slot; Datum value; @@ -305,27 +291,35 @@ postquel_execute(execution_state *es, * logic and code redundancy here. */ resSlot = copy_function_result(fcache, slot); - if (func_tlist != NIL) - { - TargetEntry *tle = lfirst(func_tlist); - value = ProjectAttribute(resSlot->ttc_tupleDescriptor, - tle, - resSlot->val, - &fcinfo->isnull); - } - else + /* + * If we are supposed to return a tuple, we return the tuple slot + * pointer converted to Datum. If we are supposed to return a simple + * value, then project out the first attribute of the result tuple + * (ie, take the first result column of the final SELECT). + */ + if (fcache->returnsTuple) { - /* XXX is this right? Return whole tuple slot?? */ + /* + * XXX do we need to remove junk attrs from the result tuple? + * Probably OK to leave them, as long as they are at the end. + */ value = PointerGetDatum(resSlot); fcinfo->isnull = false; } + else + { + value = ProjectAttribute(resSlot->val, + 1, + resSlot->ttc_tupleDescriptor, + &fcinfo->isnull); + } /* * If this is a single valued function we have to end the function * execution now. */ - if (fcache->oneResult) + if (!fcache->returnsSet) { postquel_end(es); es->status = F_EXEC_DONE; @@ -346,7 +340,6 @@ postquel_execute(execution_state *es, Datum postquel_function(FunctionCallInfo fcinfo, FunctionCachePtr fcache, - List *func_tlist, bool *isDone) { MemoryContext oldcontext; @@ -388,10 +381,7 @@ postquel_function(FunctionCallInfo fcinfo, */ while (es != (execution_state *) NULL) { - result = postquel_execute(es, - fcinfo, - fcache, - func_tlist); + result = postquel_execute(es, fcinfo, fcache); if (es->status != F_EXEC_DONE) break; es = es->next; @@ -423,7 +413,7 @@ postquel_function(FunctionCallInfo fcinfo, */ *isDone = true; MemoryContextSwitchTo(oldcontext); - return (fcache->oneResult) ? result : (Datum) NULL; + return (fcache->returnsSet) ? (Datum) NULL : result; } /* |