Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit336c1d7

Browse files
committed
Avoid assuming that index-only scan data matches the index's rowtype.
In general the data returned by an index-only scan should have thedatatypes originally computed by FormIndexDatum. If the index opclassesuse "storage" datatypes different from their input datatypes, the scantuple will not have the same rowtype attributed to the index; but we hada hard-wired assumption that that was true in nodeIndexonlyscan.c. We'dalready hacked around the issue for the one case where the types aredifferent in btree indexes (btree name_ops), but this would definitelycome back to bite us if we ever implement index-only scans in GiST.To fix, require the index AM to explicitly provide the tupdesc for thetuple it is returning. btree can just pass back the index's tupdesc, butGiST will have to work harder when and if it supports index-only scans.I had previously proposed fixing this by allowing the index AM to fill thescan tuple slot directly; but on reflection that seemed like a modulelayering violation, since TupleTableSlots are creatures of the executor.At least in the btree case, it would also be less efficient, since thetuple deconstruction work would occur even for rows later found to beinvisible to the scan's snapshot.
1 parente661c3d commit336c1d7

File tree

5 files changed

+17
-10
lines changed

5 files changed

+17
-10
lines changed

‎doc/src/sgml/indexam.sgml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -396,7 +396,8 @@ amgettuple (IndexScanDesc scan,
396396
row), then on success it must also check
397397
<literal>scan-&gt;xs_want_itup</>, and if that is true it must return
398398
the original indexed data for the index entry, in the form of an
399-
<structname>IndexTuple</> pointer stored at <literal>scan-&gt;xs_itup</>.
399+
<structname>IndexTuple</> pointer stored at <literal>scan-&gt;xs_itup</>,
400+
with tuple descriptor <literal>scan-&gt;xs_itupdesc</>.
400401
(Management of the data referenced by the pointer is the access method's
401402
responsibility. The data must remain good at least until the next
402403
<function>amgettuple</>, <function>amrescan</>, or <function>amendscan</>

‎src/backend/access/index/genam.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,7 @@ RelationGetIndexScan(Relation indexRelation, int nkeys, int norderbys)
112112
scan->opaque=NULL;
113113

114114
scan->xs_itup=NULL;
115+
scan->xs_itupdesc=NULL;
115116

116117
ItemPointerSetInvalid(&scan->xs_ctup.t_self);
117118
scan->xs_ctup.t_data=NULL;

‎src/backend/access/nbtree/nbtree.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -433,12 +433,15 @@ btbeginscan(PG_FUNCTION_ARGS)
433433

434434
/*
435435
* We don't know yet whether the scan will be index-only, so we do not
436-
* allocate the tuple workspace arrays until btrescan.
436+
* allocate the tuple workspace arrays until btrescan. However, we set up
437+
* scan->xs_itupdesc whether we'll need it or not, since that's so cheap.
437438
*/
438439
so->currTuples=so->markTuples=NULL;
439440
so->currPos.nextTupleOffset=0;
440441
so->markPos.nextTupleOffset=0;
441442

443+
scan->xs_itupdesc=RelationGetDescr(rel);
444+
442445
scan->opaque=so;
443446

444447
PG_RETURN_POINTER(scan);

‎src/backend/executor/nodeIndexonlyscan.c

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@
3636

3737
staticTupleTableSlot*IndexOnlyNext(IndexOnlyScanState*node);
3838
staticvoidStoreIndexTuple(TupleTableSlot*slot,IndexTupleitup,
39-
RelationindexRel);
39+
TupleDescitupdesc);
4040

4141

4242
/* ----------------------------------------------------------------
@@ -114,7 +114,7 @@ IndexOnlyNext(IndexOnlyScanState *node)
114114
/*
115115
* Fill the scan tuple slot with data from the index.
116116
*/
117-
StoreIndexTuple(slot,scandesc->xs_itup,scandesc->indexRelation);
117+
StoreIndexTuple(slot,scandesc->xs_itup,scandesc->xs_itupdesc);
118118

119119
/*
120120
* If the index was lossy, we have to recheck the index quals.
@@ -151,25 +151,25 @@ IndexOnlyNext(IndexOnlyScanState *node)
151151
* right now we don't need it elsewhere.
152152
*/
153153
staticvoid
154-
StoreIndexTuple(TupleTableSlot*slot,IndexTupleitup,RelationindexRel)
154+
StoreIndexTuple(TupleTableSlot*slot,IndexTupleitup,TupleDescitupdesc)
155155
{
156-
TupleDescindexDesc=RelationGetDescr(indexRel);
157-
intnindexatts=indexDesc->natts;
156+
intnindexatts=itupdesc->natts;
158157
Datum*values=slot->tts_values;
159158
bool*isnull=slot->tts_isnull;
160159
inti;
161160

162161
/*
163-
* Note: we must use theindex relation's tupdesc in index_getattr, not
162+
* Note: we must use thetupdesc supplied by the AM in index_getattr, not
164163
* the slot's tupdesc, in case the latter has different datatypes (this
165164
* happens for btree name_ops in particular). They'd better have the same
166-
* number of columns though.
165+
* number of columns though, as well as being datatype-compatible which
166+
* is something we can't so easily check.
167167
*/
168168
Assert(slot->tts_tupleDescriptor->natts==nindexatts);
169169

170170
ExecClearTuple(slot);
171171
for (i=0;i<nindexatts;i++)
172-
values[i]=index_getattr(itup,i+1,indexDesc,&isnull[i]);
172+
values[i]=index_getattr(itup,i+1,itupdesc,&isnull[i]);
173173
ExecStoreVirtualTuple(slot);
174174
}
175175

‎src/include/access/relscan.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include"access/genam.h"
1818
#include"access/heapam.h"
1919
#include"access/itup.h"
20+
#include"access/tupdesc.h"
2021

2122

2223
typedefstructHeapScanDescData
@@ -80,6 +81,7 @@ typedef struct IndexScanDescData
8081

8182
/* in an index-only scan, this is valid after a successful amgettuple */
8283
IndexTuplexs_itup;/* index tuple returned by AM */
84+
TupleDescxs_itupdesc;/* rowtype descriptor of xs_itup */
8385

8486
/* xs_ctup/xs_cbuf/xs_recheck are valid after a successful index_getnext */
8587
HeapTupleDataxs_ctup;/* current heap tuple, if any */

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp