diff options
Diffstat (limited to 'src/backend/executor')
-rw-r--r-- | src/backend/executor/execQual.c | 93 | ||||
-rw-r--r-- | src/backend/executor/functions.c | 82 |
2 files changed, 73 insertions, 102 deletions
diff --git a/src/backend/executor/execQual.c b/src/backend/executor/execQual.c index a445a57d9cf..6e934a17725 100644 --- a/src/backend/executor/execQual.c +++ b/src/backend/executor/execQual.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/executor/execQual.c,v 1.76 2000/07/23 01:35:58 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/executor/execQual.c,v 1.77 2000/08/08 15:41:22 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -294,8 +294,6 @@ ExecEvalVar(Var *variable, ExprContext *econtext, bool *isNull) AttrNumber attnum; HeapTuple heapTuple; TupleDesc tuple_type; - bool byval; - int16 len; /* * get the slot we want @@ -363,36 +361,6 @@ ExecEvalVar(Var *variable, ExprContext *econtext, bool *isNull) tuple_type, /* tuple descriptor of tuple */ isNull); /* return: is attribute null? */ - /* - * return null if att is null - */ - if (*isNull) - return (Datum) 0; - - /* - * get length and type information.. ??? what should we do about - * variable length attributes - variable length attributes have their - * length stored in the first 4 bytes of the memory pointed to by the - * returned value.. If we can determine that the type is a variable - * length type, we can do the right thing. -cim 9/15/89 - */ - if (attnum < 0) - { - - /* - * If this is a pseudo-att, we get the type and fake the length. - * There ought to be a routine to return the real lengths, so - * we'll mark this one ... XXX -mao - */ - len = heap_sysattrlen(attnum); /* XXX see -mao above */ - byval = heap_sysattrbyval(attnum); /* XXX see -mao above */ - } - else - { - len = tuple_type->attrs[attnum - 1]->attlen; - byval = tuple_type->attrs[attnum - 1]->attbyval ? true : false; - } - return result; } @@ -519,25 +487,7 @@ ExecEvalParam(Param *expression, ExprContext *econtext, bool *isNull) /* * return the value. */ - if (paramList->isnull) - { - *isNull = true; - return (Datum) 0; - } - - if (expression->param_tlist != NIL) - { - HeapTuple tup; - Datum value; - List *tlist = expression->param_tlist; - TargetEntry *tle = (TargetEntry *) lfirst(tlist); - TupleTableSlot *slot = (TupleTableSlot *) paramList->value; - - tup = slot->val; - value = ProjectAttribute(slot->ttc_tupleDescriptor, - tle, tup, isNull); - return value; - } + *isNull = paramList->isnull; return paramList->value; } @@ -686,7 +636,6 @@ ExecMakeFunctionResult(Node *node, { FunctionCallInfoData fcinfo; FunctionCachePtr fcache; - List *ftlist; bool funcisset; Datum result; bool argDone; @@ -702,13 +651,11 @@ ExecMakeFunctionResult(Node *node, if (IsA(node, Func)) { fcache = ((Func *) node)->func_fcache; - ftlist = ((Func *) node)->func_tlist; funcisset = (((Func *) node)->funcid == F_SETEVAL); } else { fcache = ((Oper *) node)->op_fcache; - ftlist = NIL; funcisset = false; } @@ -822,7 +769,7 @@ ExecMakeFunctionResult(Node *node, if (callit) { - result = postquel_function(&fcinfo, fcache, ftlist, isDone); + result = postquel_function(&fcinfo, fcache, isDone); *isNull = fcinfo.isnull; } else @@ -1215,6 +1162,34 @@ ExecEvalCase(CaseExpr *caseExpr, ExprContext *econtext, bool *isNull) } /* ---------------------------------------------------------------- + * ExecEvalFieldSelect + * + * Evaluate a FieldSelect node. + * ---------------------------------------------------------------- + */ +static Datum +ExecEvalFieldSelect(FieldSelect *fselect, + ExprContext *econtext, + bool *isNull, + bool *isDone) +{ + Datum result; + TupleTableSlot *resSlot; + + result = ExecEvalExpr(fselect->arg, econtext, isNull, isDone); + if (*isNull) + return result; + /* XXX what about isDone? */ + resSlot = (TupleTableSlot *) DatumGetPointer(result); + Assert(resSlot != NULL && IsA(resSlot, TupleTableSlot)); + result = heap_getattr(resSlot->val, + fselect->fieldnum, + resSlot->ttc_tupleDescriptor, + isNull); + return result; +} + +/* ---------------------------------------------------------------- * ExecEvalExpr * * Recursively evaluate a targetlist or qualification expression. @@ -1319,6 +1294,12 @@ ExecEvalExpr(Node *expression, } break; } + case T_FieldSelect: + retDatum = ExecEvalFieldSelect((FieldSelect *) expression, + econtext, + isNull, + isDone); + break; case T_RelabelType: retDatum = ExecEvalExpr(((RelabelType *) expression)->arg, econtext, 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; } /* |