aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2011-10-11 18:11:51 -0400
committerTom Lane <tgl@sss.pgh.pa.us>2011-10-11 18:12:57 -0400
commitcb6771fb32cbdb11c8d84b7d62ee940bdba38d52 (patch)
tree570b3790e334850a061f33086fe4c2b0ab9f07b5
parente991930e8a2394169d95e9a4c175a1fdf812ef04 (diff)
downloadpostgresql-cb6771fb32cbdb11c8d84b7d62ee940bdba38d52.tar.gz
postgresql-cb6771fb32cbdb11c8d84b7d62ee940bdba38d52.zip
Generate index-only scan tuple descriptor from the plan node's indextlist.
Dept. of second thoughts: as long as we've got that tlist hanging around anyway, we can apply ExecTypeFromTL to it to get a suitable descriptor for the ScanTupleSlot. This is a nicer solution than the previous one because it eliminates some hard-wired knowledge about btree name_ops, and because it avoids the somewhat shaky assumption that we needn't set up the scan tuple descriptor in EXPLAIN_ONLY mode. It doesn't change what actually happens at run-time though, and I'm still a bit nervous about that.
-rw-r--r--src/backend/executor/nodeIndexonlyscan.c68
1 files changed, 16 insertions, 52 deletions
diff --git a/src/backend/executor/nodeIndexonlyscan.c b/src/backend/executor/nodeIndexonlyscan.c
index 487373b4970..e3742cf71d0 100644
--- a/src/backend/executor/nodeIndexonlyscan.c
+++ b/src/backend/executor/nodeIndexonlyscan.c
@@ -26,8 +26,6 @@
#include "access/relscan.h"
#include "access/visibilitymap.h"
-#include "catalog/pg_opfamily.h"
-#include "catalog/pg_type.h"
#include "executor/execdebug.h"
#include "executor/nodeIndexonlyscan.h"
#include "executor/nodeIndexscan.h"
@@ -162,8 +160,10 @@ StoreIndexTuple(TupleTableSlot *slot, IndexTuple itup, Relation indexRel)
int i;
/*
- * Note: we must use the index relation's tupdesc in index_getattr,
- * not the slot's tupdesc, because of index_descriptor_hack().
+ * Note: we must use the index relation's tupdesc in index_getattr, not
+ * the slot's tupdesc, in case the latter has different datatypes (this
+ * happens for btree name_ops in particular). They'd better have the same
+ * number of columns though.
*/
Assert(slot->tts_tupleDescriptor->natts == nindexatts);
@@ -174,45 +174,6 @@ StoreIndexTuple(TupleTableSlot *slot, IndexTuple itup, Relation indexRel)
}
/*
- * index_descriptor_hack -- ugly kluge to make index's tupdesc OK for slot
- *
- * This is necessary because, alone among btree opclasses, name_ops uses
- * a storage type (cstring) different from its input type. The index
- * tuple descriptor will show "cstring", which is correct, but we have to
- * expose "name" as the slot datatype or ExecEvalVar will whine. If we
- * ever want to have any other cases with a different storage type, we ought
- * to think of a cleaner solution than this.
- */
-static TupleDesc
-index_descriptor_hack(Relation indexRel)
-{
- TupleDesc tupdesc = RelationGetDescr(indexRel);
- int i;
-
- /* copy so we can scribble on it safely */
- tupdesc = CreateTupleDescCopy(tupdesc);
-
- for (i = 0; i < tupdesc->natts; i++)
- {
- if (indexRel->rd_opfamily[i] == NAME_BTREE_FAM_OID &&
- tupdesc->attrs[i]->atttypid == CSTRINGOID)
- {
- tupdesc->attrs[i]->atttypid = NAMEOID;
-
- /*
- * We set attlen to match the type OID just in case anything looks
- * at it. Note that this is safe only because StoreIndexTuple
- * will insert the data as a virtual tuple, and we don't expect
- * anything will try to materialize the scan tuple slot.
- */
- tupdesc->attrs[i]->attlen = NAMEDATALEN;
- }
- }
-
- return tupdesc;
-}
-
-/*
* IndexOnlyRecheck -- access method routine to recheck a tuple in EvalPlanQual
*
* This can't really happen, since an index can't supply CTID which would
@@ -426,9 +387,20 @@ ExecInitIndexOnlyScan(IndexOnlyScan *node, EState *estate, int eflags)
indexstate->ss.ss_currentScanDesc = NULL; /* no heap scan here */
/*
- * Initialize result tuple type.
+ * Build the scan tuple type using the indextlist generated by the
+ * planner. We use this, rather than the index's physical tuple
+ * descriptor, because the latter contains storage column types not the
+ * types of the original datums. (It's the AM's responsibility to return
+ * suitable data anyway.)
+ */
+ tupDesc = ExecTypeFromTL(node->indextlist, false);
+ ExecAssignScanType(&indexstate->ss, tupDesc);
+
+ /*
+ * Initialize result tuple type and projection info.
*/
ExecAssignResultTypeFromTL(&indexstate->ss.ps);
+ ExecAssignScanProjectionInfo(&indexstate->ss);
/*
* If we are just doing EXPLAIN (ie, aren't going to run the plan), stop
@@ -450,14 +422,6 @@ ExecInitIndexOnlyScan(IndexOnlyScan *node, EState *estate, int eflags)
relistarget ? NoLock : AccessShareLock);
/*
- * Now we can get the scan tuple's type (which is the index's rowtype,
- * not the heap's) and initialize result projection info.
- */
- tupDesc = index_descriptor_hack(indexstate->ioss_RelationDesc);
- ExecAssignScanType(&indexstate->ss, tupDesc);
- ExecAssignScanProjectionInfo(&indexstate->ss);
-
- /*
* Initialize index-specific scan state
*/
indexstate->ioss_RuntimeKeysReady = false;