Skip to content

Commit cb6771f

Browse files
committed
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.
1 parent e991930 commit cb6771f

File tree

1 file changed

+16
-52
lines changed

1 file changed

+16
-52
lines changed

src/backend/executor/nodeIndexonlyscan.c

Lines changed: 16 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,6 @@
2626

2727
#include "access/relscan.h"
2828
#include "access/visibilitymap.h"
29-
#include "catalog/pg_opfamily.h"
30-
#include "catalog/pg_type.h"
3129
#include "executor/execdebug.h"
3230
#include "executor/nodeIndexonlyscan.h"
3331
#include "executor/nodeIndexscan.h"
@@ -162,8 +160,10 @@ StoreIndexTuple(TupleTableSlot *slot, IndexTuple itup, Relation indexRel)
162160
int i;
163161

164162
/*
165-
* Note: we must use the index relation's tupdesc in index_getattr,
166-
* not the slot's tupdesc, because of index_descriptor_hack().
163+
* Note: we must use the index relation's tupdesc in index_getattr, not
164+
* the slot's tupdesc, in case the latter has different datatypes (this
165+
* happens for btree name_ops in particular). They'd better have the same
166+
* number of columns though.
167167
*/
168168
Assert(slot->tts_tupleDescriptor->natts == nindexatts);
169169

@@ -173,45 +173,6 @@ StoreIndexTuple(TupleTableSlot *slot, IndexTuple itup, Relation indexRel)
173173
ExecStoreVirtualTuple(slot);
174174
}
175175

176-
/*
177-
* index_descriptor_hack -- ugly kluge to make index's tupdesc OK for slot
178-
*
179-
* This is necessary because, alone among btree opclasses, name_ops uses
180-
* a storage type (cstring) different from its input type. The index
181-
* tuple descriptor will show "cstring", which is correct, but we have to
182-
* expose "name" as the slot datatype or ExecEvalVar will whine. If we
183-
* ever want to have any other cases with a different storage type, we ought
184-
* to think of a cleaner solution than this.
185-
*/
186-
static TupleDesc
187-
index_descriptor_hack(Relation indexRel)
188-
{
189-
TupleDesc tupdesc = RelationGetDescr(indexRel);
190-
int i;
191-
192-
/* copy so we can scribble on it safely */
193-
tupdesc = CreateTupleDescCopy(tupdesc);
194-
195-
for (i = 0; i < tupdesc->natts; i++)
196-
{
197-
if (indexRel->rd_opfamily[i] == NAME_BTREE_FAM_OID &&
198-
tupdesc->attrs[i]->atttypid == CSTRINGOID)
199-
{
200-
tupdesc->attrs[i]->atttypid = NAMEOID;
201-
202-
/*
203-
* We set attlen to match the type OID just in case anything looks
204-
* at it. Note that this is safe only because StoreIndexTuple
205-
* will insert the data as a virtual tuple, and we don't expect
206-
* anything will try to materialize the scan tuple slot.
207-
*/
208-
tupdesc->attrs[i]->attlen = NAMEDATALEN;
209-
}
210-
}
211-
212-
return tupdesc;
213-
}
214-
215176
/*
216177
* IndexOnlyRecheck -- access method routine to recheck a tuple in EvalPlanQual
217178
*
@@ -426,9 +387,20 @@ ExecInitIndexOnlyScan(IndexOnlyScan *node, EState *estate, int eflags)
426387
indexstate->ss.ss_currentScanDesc = NULL; /* no heap scan here */
427388

428389
/*
429-
* Initialize result tuple type.
390+
* Build the scan tuple type using the indextlist generated by the
391+
* planner. We use this, rather than the index's physical tuple
392+
* descriptor, because the latter contains storage column types not the
393+
* types of the original datums. (It's the AM's responsibility to return
394+
* suitable data anyway.)
395+
*/
396+
tupDesc = ExecTypeFromTL(node->indextlist, false);
397+
ExecAssignScanType(&indexstate->ss, tupDesc);
398+
399+
/*
400+
* Initialize result tuple type and projection info.
430401
*/
431402
ExecAssignResultTypeFromTL(&indexstate->ss.ps);
403+
ExecAssignScanProjectionInfo(&indexstate->ss);
432404

433405
/*
434406
* If we are just doing EXPLAIN (ie, aren't going to run the plan), stop
@@ -449,14 +421,6 @@ ExecInitIndexOnlyScan(IndexOnlyScan *node, EState *estate, int eflags)
449421
indexstate->ioss_RelationDesc = index_open(node->indexid,
450422
relistarget ? NoLock : AccessShareLock);
451423

452-
/*
453-
* Now we can get the scan tuple's type (which is the index's rowtype,
454-
* not the heap's) and initialize result projection info.
455-
*/
456-
tupDesc = index_descriptor_hack(indexstate->ioss_RelationDesc);
457-
ExecAssignScanType(&indexstate->ss, tupDesc);
458-
ExecAssignScanProjectionInfo(&indexstate->ss);
459-
460424
/*
461425
* Initialize index-specific scan state
462426
*/

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy