aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2005-10-19 22:51:26 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2005-10-19 22:51:26 +0000
commitfd5efffc150233c6849bc29005291deacd7ccfee (patch)
tree7585ddc2c0ee49ac17f2527d06d5688eed3a240d /src
parent98658dd40432c3c12ace9e0fd16315b32bb478f5 (diff)
downloadpostgresql-fd5efffc150233c6849bc29005291deacd7ccfee.tar.gz
postgresql-fd5efffc150233c6849bc29005291deacd7ccfee.zip
Back-patch fix for proper labeling of whole-row Datums generated from
subquery results.
Diffstat (limited to 'src')
-rw-r--r--src/backend/access/common/heaptuple.c29
-rw-r--r--src/backend/executor/execQual.c88
2 files changed, 85 insertions, 32 deletions
diff --git a/src/backend/access/common/heaptuple.c b/src/backend/access/common/heaptuple.c
index d60cd2a214a..9a34077543c 100644
--- a/src/backend/access/common/heaptuple.c
+++ b/src/backend/access/common/heaptuple.c
@@ -9,7 +9,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/access/common/heaptuple.c,v 1.95 2004/12/31 21:59:07 pgsql Exp $
+ * $PostgreSQL: pgsql/src/backend/access/common/heaptuple.c,v 1.95.4.1 2005/10/19 22:51:26 tgl Exp $
*
* NOTES
* The old interface functions have been converted to macros
@@ -466,33 +466,6 @@ heap_getsysattr(HeapTuple tup, int attnum, TupleDesc tupleDesc, bool *isnull)
case TableOidAttributeNumber:
result = ObjectIdGetDatum(tup->t_tableOid);
break;
-
- /*
- * If the attribute number is 0, then we are supposed to
- * return the entire tuple as a row-type Datum. (Using zero
- * for this purpose is unclean since it risks confusion with
- * "invalid attr" result codes, but it's not worth changing
- * now.)
- *
- * We have to make a copy of the tuple so we can safely insert
- * the Datum overhead fields, which are not set in on-disk
- * tuples.
- */
- case InvalidAttrNumber:
- {
- HeapTupleHeader dtup;
-
- dtup = (HeapTupleHeader) palloc(tup->t_len);
- memcpy((char *) dtup, (char *) tup->t_data, tup->t_len);
-
- HeapTupleHeaderSetDatumLength(dtup, tup->t_len);
- HeapTupleHeaderSetTypeId(dtup, tupleDesc->tdtypeid);
- HeapTupleHeaderSetTypMod(dtup, tupleDesc->tdtypmod);
-
- result = PointerGetDatum(dtup);
- }
- break;
-
default:
elog(ERROR, "invalid attnum: %d", attnum);
result = 0; /* keep compiler quiet */
diff --git a/src/backend/executor/execQual.c b/src/backend/executor/execQual.c
index 0199df0f719..5ff95e10872 100644
--- a/src/backend/executor/execQual.c
+++ b/src/backend/executor/execQual.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/executor/execQual.c,v 1.171 2004/12/31 21:59:45 pgsql Exp $
+ * $PostgreSQL: pgsql/src/backend/executor/execQual.c,v 1.171.4.1 2005/10/19 22:51:26 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -63,6 +63,8 @@ static Datum ExecEvalAggref(AggrefExprState *aggref,
bool *isNull, ExprDoneCond *isDone);
static Datum ExecEvalVar(ExprState *exprstate, ExprContext *econtext,
bool *isNull, ExprDoneCond *isDone);
+static Datum ExecEvalWholeRowVar(ExprState *exprstate, ExprContext *econtext,
+ bool *isNull, ExprDoneCond *isDone);
static Datum ExecEvalConst(ExprState *exprstate, ExprContext *econtext,
bool *isNull, ExprDoneCond *isDone);
static Datum ExecEvalParam(ExprState *exprstate, ExprContext *econtext,
@@ -528,6 +530,77 @@ ExecEvalVar(ExprState *exprstate, ExprContext *econtext,
}
/* ----------------------------------------------------------------
+ * ExecEvalWholeRowVar
+ *
+ * Returns a Datum for a whole-row variable.
+ *
+ * This could be folded into ExecEvalVar, but we make it a separate
+ * routine so as not to slow down ExecEvalVar with tests for this
+ * uncommon case.
+ * ----------------------------------------------------------------
+ */
+static Datum
+ExecEvalWholeRowVar(ExprState *exprstate, ExprContext *econtext,
+ bool *isNull, ExprDoneCond *isDone)
+{
+ Var *variable = (Var *) exprstate->expr;
+ TupleTableSlot *slot;
+ HeapTuple tuple;
+ TupleDesc tupleDesc;
+ HeapTupleHeader dtuple;
+
+ if (isDone)
+ *isDone = ExprSingleResult;
+ *isNull = false;
+
+ Assert(variable->varattno == InvalidAttrNumber);
+
+ /*
+ * Whole-row Vars can only appear at the level of a relation scan,
+ * never in a join.
+ */
+ Assert(variable->varno != INNER);
+ Assert(variable->varno != OUTER);
+ slot = econtext->ecxt_scantuple;
+
+ tuple = slot->val;
+ tupleDesc = slot->ttc_tupleDescriptor;
+
+ /*
+ * We have to make a copy of the tuple so we can safely insert the
+ * Datum overhead fields, which are not set in on-disk tuples.
+ */
+ dtuple = (HeapTupleHeader) palloc(tuple->t_len);
+ memcpy((char *) dtuple, (char *) tuple->t_data, tuple->t_len);
+
+ HeapTupleHeaderSetDatumLength(dtuple, tuple->t_len);
+
+ /*
+ * If the Var identifies a named composite type, label the tuple
+ * with that type; otherwise use what is in the tupleDesc.
+ *
+ * It's likely that the slot's tupleDesc is a record type; if so,
+ * make sure it's been "blessed", so that the Datum can be interpreted
+ * later.
+ */
+ if (variable->vartype != RECORDOID)
+ {
+ HeapTupleHeaderSetTypeId(dtuple, variable->vartype);
+ HeapTupleHeaderSetTypMod(dtuple, variable->vartypmod);
+ }
+ else
+ {
+ if (tupleDesc->tdtypeid == RECORDOID &&
+ tupleDesc->tdtypmod < 0)
+ assign_record_type_typmod(tupleDesc);
+ HeapTupleHeaderSetTypeId(dtuple, tupleDesc->tdtypeid);
+ HeapTupleHeaderSetTypMod(dtuple, tupleDesc->tdtypmod);
+ }
+
+ return PointerGetDatum(dtuple);
+}
+
+/* ----------------------------------------------------------------
* ExecEvalConst
*
* Returns the value of a constant.
@@ -2830,8 +2903,15 @@ ExecInitExpr(Expr *node, PlanState *parent)
switch (nodeTag(node))
{
case T_Var:
- state = (ExprState *) makeNode(ExprState);
- state->evalfunc = ExecEvalVar;
+ {
+ Var *var = (Var *) node;
+
+ state = (ExprState *) makeNode(ExprState);
+ if (var->varattno != InvalidAttrNumber)
+ state->evalfunc = ExecEvalVar;
+ else
+ state->evalfunc = ExecEvalWholeRowVar;
+ }
break;
case T_Const:
state = (ExprState *) makeNode(ExprState);
@@ -3170,7 +3250,7 @@ ExecInitExpr(Expr *node, PlanState *parent)
{
/* generic record, use runtime type assignment */
rstate->tupdesc = ExecTypeFromExprList(rowexpr->args);
- rstate->tupdesc = BlessTupleDesc(rstate->tupdesc);
+ BlessTupleDesc(rstate->tupdesc);
}
else
{