aboutsummaryrefslogtreecommitdiff
path: root/src/backend/executor
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2000-08-08 15:43:12 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2000-08-08 15:43:12 +0000
commit62e29fe2e748933bfd8ab1429518ee7b5a8974a7 (patch)
treed9ca32ad908a811854e890c059b46b8ff13fa038 /src/backend/executor
parent8fc32374beb542380857e2fc0d67df91ad123b1d (diff)
downloadpostgresql-62e29fe2e748933bfd8ab1429518ee7b5a8974a7.tar.gz
postgresql-62e29fe2e748933bfd8ab1429518ee7b5a8974a7.zip
Remove 'func_tlist' from Func expression nodes, likewise 'param_tlist'
from Param nodes, per discussion a few days ago on pghackers. Add new expression node type FieldSelect that implements the functionality where it's actually needed. Clean up some other unused fields in Func nodes as well. NOTE: initdb forced due to change in stored expression trees for rules.
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;
}
/*