aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/backend/executor/execQual.c33
-rw-r--r--src/test/regress/expected/subselect.out18
-rw-r--r--src/test/regress/sql/subselect.sql10
3 files changed, 47 insertions, 14 deletions
diff --git a/src/backend/executor/execQual.c b/src/backend/executor/execQual.c
index bc79e3aa00c..7cfa63f37dc 100644
--- a/src/backend/executor/execQual.c
+++ b/src/backend/executor/execQual.c
@@ -712,7 +712,6 @@ ExecEvalWholeRowVar(WholeRowVarExprState *wrvstate, ExprContext *econtext,
{
Var *variable = (Var *) wrvstate->xprstate.expr;
TupleTableSlot *slot;
- TupleDesc slot_tupdesc;
bool needslow = false;
if (isDone)
@@ -804,25 +803,14 @@ ExecEvalWholeRowVar(WholeRowVarExprState *wrvstate, ExprContext *econtext,
if (wrvstate->wrv_junkFilter != NULL)
slot = ExecFilterJunk(wrvstate->wrv_junkFilter, slot);
- slot_tupdesc = slot->tts_tupleDescriptor;
-
/*
- * If it's a RECORD Var, we'll use the slot's type ID info. It's likely
- * that the slot's type is also RECORD; if so, make sure it's been
- * "blessed", so that the Datum can be interpreted later.
- *
* If the Var identifies a named composite type, we must check that the
* actual tuple type is compatible with it.
*/
- if (variable->vartype == RECORDOID)
- {
- if (slot_tupdesc->tdtypeid == RECORDOID &&
- slot_tupdesc->tdtypmod < 0)
- assign_record_type_typmod(slot_tupdesc);
- }
- else
+ if (variable->vartype != RECORDOID)
{
TupleDesc var_tupdesc;
+ TupleDesc slot_tupdesc;
int i;
/*
@@ -839,6 +827,8 @@ ExecEvalWholeRowVar(WholeRowVarExprState *wrvstate, ExprContext *econtext,
*/
var_tupdesc = lookup_rowtype_tupdesc(variable->vartype, -1);
+ slot_tupdesc = slot->tts_tupleDescriptor;
+
if (var_tupdesc->natts != slot_tupdesc->natts)
ereport(ERROR,
(errcode(ERRCODE_DATATYPE_MISMATCH),
@@ -896,6 +886,7 @@ ExecEvalWholeRowFast(WholeRowVarExprState *wrvstate, ExprContext *econtext,
{
Var *variable = (Var *) wrvstate->xprstate.expr;
TupleTableSlot *slot;
+ TupleDesc slot_tupdesc;
HeapTupleHeader dtuple;
if (isDone)
@@ -926,6 +917,20 @@ ExecEvalWholeRowFast(WholeRowVarExprState *wrvstate, ExprContext *econtext,
slot = ExecFilterJunk(wrvstate->wrv_junkFilter, slot);
/*
+ * If it's a RECORD Var, we'll use the slot's type ID info. It's likely
+ * that the slot's type is also RECORD; if so, make sure it's been
+ * "blessed", so that the Datum can be interpreted later. (Note: we must
+ * do this here, not in ExecEvalWholeRowVar, because some plan trees may
+ * return different slots at different times. We have to be ready to
+ * bless additional slots during the run.)
+ */
+ slot_tupdesc = slot->tts_tupleDescriptor;
+ if (variable->vartype == RECORDOID &&
+ slot_tupdesc->tdtypeid == RECORDOID &&
+ slot_tupdesc->tdtypmod < 0)
+ assign_record_type_typmod(slot_tupdesc);
+
+ /*
* Copy the slot tuple and make sure any toasted fields get detoasted.
*/
dtuple = DatumGetHeapTupleHeader(ExecFetchSlotTupleDatum(slot));
diff --git a/src/test/regress/expected/subselect.out b/src/test/regress/expected/subselect.out
index d85a7170f30..01c91308f33 100644
--- a/src/test/regress/expected/subselect.out
+++ b/src/test/regress/expected/subselect.out
@@ -775,6 +775,24 @@ select * from int4_tbl o where (f1, f1) in
(1 row)
--
+-- check for over-optimization of whole-row Var referencing an Append plan
+--
+select (select q from
+ (select 1,2,3 where f1 > 0
+ union all
+ select 4,5,6.0 where f1 <= 0
+ ) q )
+from int4_tbl;
+ q
+-----------
+ (4,5,6.0)
+ (1,2,3)
+ (4,5,6.0)
+ (1,2,3)
+ (4,5,6.0)
+(5 rows)
+
+--
-- Check that volatile quals aren't pushed down past a DISTINCT:
-- nextval() should not be called more than the nominal number of times
--
diff --git a/src/test/regress/sql/subselect.sql b/src/test/regress/sql/subselect.sql
index c3b47734887..56707e26bbf 100644
--- a/src/test/regress/sql/subselect.sql
+++ b/src/test/regress/sql/subselect.sql
@@ -433,6 +433,16 @@ select * from int4_tbl o where (f1, f1) in
(select f1, generate_series(1,2) / 10 g from int4_tbl i group by f1);
--
+-- check for over-optimization of whole-row Var referencing an Append plan
+--
+select (select q from
+ (select 1,2,3 where f1 > 0
+ union all
+ select 4,5,6.0 where f1 <= 0
+ ) q )
+from int4_tbl;
+
+--
-- Check that volatile quals aren't pushed down past a DISTINCT:
-- nextval() should not be called more than the nominal number of times
--