aboutsummaryrefslogtreecommitdiff
path: root/src/backend/executor
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/executor')
-rw-r--r--src/backend/executor/execQual.c93
-rw-r--r--src/backend/executor/functions.c82
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;
}
/*