-
Notifications
You must be signed in to change notification settings - Fork 0
/
indexonlygist2.patch
367 lines (355 loc) · 14.7 KB
/
indexonlygist2.patch
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
*** a/src/backend/access/gist/gist.c
--- b/src/backend/access/gist/gist.c
***************
*** 1379,1384 **** initGISTstate(Relation index)
--- 1379,1399 ----
else
giststate->distanceFn[i].fn_oid = InvalidOid;
+ /* opclasses are not required to provide a Fetch method */
+ if (i<1) //for Debugging. Singlecolumn index
+ {
+ //elog(NOTICE, "Debug. gist.c amsupport = %d", index->rd_am->amsupport);
+ //elog(NOTICE, "Debug. gist.c OidIsValid. fetch. rd_support(%d) = %d", GIST_FETCH_PROC, index->rd_support[GIST_FETCH_PROC-1]);
+ if (OidIsValid(index_getprocid(index, i + 1, GIST_FETCH_PROC))) {
+ fmgr_info_copy(&(giststate->fetchFn[i]),
+ index_getprocinfo(index, i + 1, GIST_FETCH_PROC),
+ scanCxt);
+ }
+ else {
+ giststate->fetchFn[i].fn_oid = InvalidOid;
+ }
+ }
+
/*
* If the index column has a specified collation, we should honor that
* while doing comparisons. However, we may have a collatable storage
***************
*** 1401,1406 **** initGISTstate(Relation index)
--- 1416,1451 ----
return giststate;
}
+ Datum
+ gistcanreturn(PG_FUNCTION_ARGS) {
+ int i;
+ Relation index = (Relation) PG_GETARG_POINTER(0);
+
+ for (i = 0; i < 1; i++) { //Singlecolumn
+
+ //elog(NOTICE, "Debug. gist.c gistcanreturn. decompress. rd_support(%d) = %d", GIST_DECOMPRESS_PROC, index->rd_support[GIST_DECOMPRESS_PROC]);
+ //elog(NOTICE, "Debug. gist.c gistcanreturn. distance. rd_support(%d) = %d", GIST_DISTANCE_PROC, index->rd_support[GIST_DISTANCE_PROC]);
+ //elog(NOTICE, "Debug. gist.c gistcanreturn. fetch. rd_support(%d) = %d", GIST_FETCH_PROC, index->rd_support[GIST_FETCH_PROC]);
+
+ //Debug. singlecolumn index ==> second argument = ???
+ //elog(NOTICE, "Debug. gist.c gistcanreturn. GIST_FETCH_PROC = %d", OidIsValid(index_getprocid(index, 0, GIST_FETCH_PROC)));
+ if (OidIsValid(index_getprocid(index, i+1, GIST_FETCH_PROC))) {
+ //elog(NOTICE, "Debug. gist.c gistcanreturn. True");
+ PG_RETURN_BOOL(true);
+ }
+ else {
+ //elog(NOTICE, "Debug. gist.c gistcanreturn. False");
+ //elog(NOTICE, " Debug. missing support function %d of index \"%s\"",
+ // GIST_FETCH_PROC,
+ //RelationGetRelationName(index));
+ PG_RETURN_BOOL(false);
+
+ }
+ }
+ //elog(NOTICE, "Debug. gist.c gistcanreturn. False. Multicolumn");
+ PG_RETURN_BOOL(false);
+ }
+
void
freeGISTstate(GISTSTATE *giststate)
{
*** a/src/backend/access/gist/gistget.c
--- b/src/backend/access/gist/gistget.c
***************
*** 240,245 **** gistScanPage(IndexScanDesc scan, GISTSearchItem *pageItem, double *myDistances,
--- 240,248 ----
GISTScanOpaque so = (GISTScanOpaque) scan->opaque;
Buffer buffer;
Page page;
+ GISTSTATE *giststate = so->giststate;
+ Relation r = scan->indexRelation;
+ bool isnull[INDEX_MAX_KEYS];
GISTPageOpaque opaque;
OffsetNumber maxoff;
OffsetNumber i;
***************
*** 334,339 **** gistScanPage(IndexScanDesc scan, GISTSearchItem *pageItem, double *myDistances,
--- 337,346 ----
*/
so->pageData[so->nPageData].heapPtr = it->t_tid;
so->pageData[so->nPageData].recheck = recheck;
+ if (scan->xs_want_itup) {
+ elog(NOTICE, "Debug. xs_want_itup => do gistFetchTuple");
+ so->pageData[so->nPageData].ftup = gistFetchTuple(giststate, r, it, isnull);
+ }
so->nPageData++;
}
else
***************
*** 357,362 **** gistScanPage(IndexScanDesc scan, GISTSearchItem *pageItem, double *myDistances,
--- 364,371 ----
item->blkno = InvalidBlockNumber;
item->data.heap.heapPtr = it->t_tid;
item->data.heap.recheck = recheck;
+ if (scan->xs_want_itup) { elog(NOTICE, "Debug. xs_want_itup => do gistFetchTuple");
+ item->data.ftup = gistFetchTuple(giststate, r, it, isnull); }
}
else
{
*** a/src/backend/access/gist/gistproc.c
--- b/src/backend/access/gist/gistproc.c
***************
*** 152,157 **** gist_box_decompress(PG_FUNCTION_ARGS)
--- 152,168 ----
}
/*
+ * GiST Fetch method for boxes
+ * do not do anything --- we just use the stored box as is.
+ */
+ Datum
+ gist_box_fetch(PG_FUNCTION_ARGS)
+ {
+ //elog(NOTICE, "Debug. gistproc.c we are in gist_box_fetch");
+ PG_RETURN_POINTER(PG_GETARG_POINTER(0));
+ }
+
+ /*
* The GiST Penalty method for boxes (also used for points)
*
* As in the R-tree paper, we use change in area as our penalty metric
*** a/src/backend/access/gist/gistscan.c
--- b/src/backend/access/gist/gistscan.c
***************
*** 198,203 **** gistrescan(PG_FUNCTION_ARGS)
--- 198,216 ----
so->curTreeItem = NULL;
so->firstCall = true;
+
+ // Check if fetchFn is defined. If gistcanreturn works correctly, this way is useless.
+ if(scan->xs_want_itup) {
+ //elog(NOTICE, "Debug. gistscan.c Check if fetchFn is defined");
+ FmgrInfo *finfo = &(so->giststate->fetchFn[0]);
+ if (!OidIsValid(finfo->fn_oid)) {
+ scan->xs_want_itup = false;
+ //elog(NOTICE, "Debug missing support function %d of index \"%s\"",
+ //GIST_FETCH_PROC,
+ //RelationGetRelationName(scan->indexRelation));
+ //elog(NOTICE, "Debug. gistscan.c fetchFn is not defined => xs_want_itup = false and indexonlysacn wouldn't work");
+ }
+ }
/* Update scan key, if a new one is given */
if (key && scan->numberOfKeys > 0)
*** a/src/backend/access/gist/gistutil.c
--- b/src/backend/access/gist/gistutil.c
***************
*** 618,623 **** gistFormTuple(GISTSTATE *giststate, Relation r,
--- 618,684 ----
return res;
}
+
+ /*
+ * initialize a GiST entry with fetched value in key field
+ */
+ void
+ gistfentryinit(GISTSTATE *giststate, int nkey,
+ GISTENTRY *e, Datum k, Relation r,
+ Page pg, OffsetNumber o, bool l, bool isNull)
+ {
+ if (!isNull)
+ {
+ GISTENTRY *fep;
+
+ gistentryinit(*e, k, r, pg, o, l);
+ fep = (GISTENTRY *)
+ DatumGetPointer(FunctionCall1Coll(&giststate->fetchFn[nkey],
+ giststate->supportCollation[nkey],
+ PointerGetDatum(e)));
+ //elog(NOTICE, "Debug. gistfentryinit()");
+ /* fecthFn returns the given pointer */
+ if (fep != e)
+ gistentryinit(*e, fep->key, fep->rel, fep->page, fep->offset,
+ fep->leafkey);
+ }
+ else
+ gistentryinit(*e, (Datum) 0, r, pg, o, l);
+ }
+
+ /*
+ * Fetch all keys in tuple --TODO
+ * Now it works only for single column indexes
+ * returns new IndexTuple that contains GISTENTRY with fetched data in key field
+ */
+ IndexTuple
+ gistFetchTuple(GISTSTATE *giststate, Relation r, IndexTuple tuple, bool isnull[])
+ {
+ GISTENTRY fentry[INDEX_MAX_KEYS];
+ Datum fetchatt[INDEX_MAX_KEYS];
+ int i;
+ IndexTuple res;
+
+ for (i = 0; i < 1; i++) { // Singlecolumn
+
+ Datum datum = index_getattr(tuple, i + 1, giststate->tupdesc, &isnull[i]);
+
+ gistfentryinit(giststate, i, &fentry[i],
+ datum, r, NULL, (OffsetNumber) 0,
+ FALSE, FALSE);
+ fetchatt[i] = fentry[i].key;
+ }
+ //elog(NOTICE, "Debug. gistFetchTuple. Before index_form_tuple");
+ res = index_form_tuple(giststate->tupdesc, fetchatt, isnull);
+
+ /*
+ * The offset number on tuples on internal pages is unused. For historical
+ * reasons, it is set 0xffff.
+ */
+ ItemPointerSetOffsetNumber(&(res->t_tid), 0xffff);
+ return res;
+ }
+
float
gistpenalty(GISTSTATE *giststate, int attno,
GISTENTRY *orig, bool isNullOrig,
*** a/src/include/access/gist.h
--- b/src/include/access/gist.h
***************
*** 33,39 ****
#define GIST_PICKSPLIT_PROC 6
#define GIST_EQUAL_PROC 7
#define GIST_DISTANCE_PROC 8
! #define GISTNProcs 8
/*
* strategy numbers for GiST opclasses that want to implement the old
--- 33,40 ----
#define GIST_PICKSPLIT_PROC 6
#define GIST_EQUAL_PROC 7
#define GIST_DISTANCE_PROC 8
! #define GIST_FETCH_PROC 9
! #define GISTNProcs 9
/*
* strategy numbers for GiST opclasses that want to implement the old
*** a/src/include/access/gist_private.h
--- b/src/include/access/gist_private.h
***************
*** 86,91 **** typedef struct GISTSTATE
--- 86,92 ----
FmgrInfo picksplitFn[INDEX_MAX_KEYS];
FmgrInfo equalFn[INDEX_MAX_KEYS];
FmgrInfo distanceFn[INDEX_MAX_KEYS];
+ FmgrInfo fetchFn[INDEX_MAX_KEYS];
/* Collations to pass to the support functions */
Oid supportCollation[INDEX_MAX_KEYS];
***************
*** 117,122 **** typedef struct GISTSearchHeapItem
--- 118,124 ----
{
ItemPointerData heapPtr;
bool recheck; /* T if quals must be rechecked */
+ IndexTuple ftup; /* Tuple contains datum fetched from key. For Index-only scans. ftup = fetched tuple*/
} GISTSearchHeapItem;
/* Unvisited item, either index page or heap tuple */
***************
*** 129,134 **** typedef struct GISTSearchItem
--- 131,137 ----
GistNSN parentlsn; /* parent page's LSN, if index page */
/* we must store parentlsn to detect whether a split occurred */
GISTSearchHeapItem heap; /* heap info, if heap tuple */
+ //IndexTuple ftup; /* Tuple contains datum fetched from key. For Index-only scans. ftup = fetched tuple*/
} data;
} GISTSearchItem;
***************
*** 423,428 **** typedef struct GiSTOptions
--- 426,432 ----
/* gist.c */
extern Datum gistbuildempty(PG_FUNCTION_ARGS);
extern Datum gistinsert(PG_FUNCTION_ARGS);
+ extern Datum gistcanreturn(PG_FUNCTION_ARGS);
extern MemoryContext createTempGistContext(void);
extern GISTSTATE *initGISTstate(Relation index);
extern void freeGISTstate(GISTSTATE *giststate);
***************
*** 522,527 **** extern bool gistKeyIsEQ(GISTSTATE *giststate, int attno, Datum a, Datum b);
--- 526,537 ----
extern void gistDeCompressAtt(GISTSTATE *giststate, Relation r, IndexTuple tuple, Page p,
OffsetNumber o, GISTENTRY *attdata, bool *isnull);
+ extern void gistfentryinit(GISTSTATE *giststate, int nkey,
+ GISTENTRY *e, Datum k, Relation r,
+ Page pg, OffsetNumber o, bool l, bool isNull);
+
+ extern IndexTuple gistFetchTuple(GISTSTATE *giststate, Relation r, IndexTuple tuple, bool *isnull);
+
extern void gistMakeUnionKey(GISTSTATE *giststate, int attno,
GISTENTRY *entry1, bool isnull1,
GISTENTRY *entry2, bool isnull2,
*** a/src/include/catalog/pg_am.h
--- b/src/include/catalog/pg_am.h
***************
*** 123,129 **** DESCR("b-tree index access method");
DATA(insert OID = 405 ( hash 1 1 f f t f f f f f f f f 23 hashinsert hashbeginscan hashgettuple hashgetbitmap hashrescan hashendscan hashmarkpos hashrestrpos hashbuild hashbuildempty hashbulkdelete hashvacuumcleanup - hashcostestimate hashoptions ));
DESCR("hash index access method");
#define HASH_AM_OID 405
! DATA(insert OID = 783 ( gist 0 8 f t f f t t f t t t f 0 gistinsert gistbeginscan gistgettuple gistgetbitmap gistrescan gistendscan gistmarkpos gistrestrpos gistbuild gistbuildempty gistbulkdelete gistvacuumcleanup - gistcostestimate gistoptions ));
DESCR("GiST index access method");
#define GIST_AM_OID 783
DATA(insert OID = 2742 ( gin 0 6 f f f f t t f f t f f 0 gininsert ginbeginscan - gingetbitmap ginrescan ginendscan ginmarkpos ginrestrpos ginbuild ginbuildempty ginbulkdelete ginvacuumcleanup - gincostestimate ginoptions ));
--- 123,129 ----
DATA(insert OID = 405 ( hash 1 1 f f t f f f f f f f f 23 hashinsert hashbeginscan hashgettuple hashgetbitmap hashrescan hashendscan hashmarkpos hashrestrpos hashbuild hashbuildempty hashbulkdelete hashvacuumcleanup - hashcostestimate hashoptions ));
DESCR("hash index access method");
#define HASH_AM_OID 405
! DATA(insert OID = 783 ( gist 0 9 f t f f t t f t t t f 0 gistinsert gistbeginscan gistgettuple gistgetbitmap gistrescan gistendscan gistmarkpos gistrestrpos gistbuild gistbuildempty gistbulkdelete gistvacuumcleanup gistcanreturn gistcostestimate gistoptions ));
DESCR("GiST index access method");
#define GIST_AM_OID 783
DATA(insert OID = 2742 ( gin 0 6 f f f f t t f f t f f 0 gininsert ginbeginscan - gingetbitmap ginrescan ginendscan ginmarkpos ginrestrpos ginbuild ginbuildempty ginbulkdelete ginvacuumcleanup - gincostestimate ginoptions ));
*** a/src/include/catalog/pg_amproc.h
--- b/src/include/catalog/pg_amproc.h
***************
*** 195,200 **** DATA(insert ( 2593 603 603 4 2580 ));
--- 195,201 ----
DATA(insert ( 2593 603 603 5 2581 ));
DATA(insert ( 2593 603 603 6 2582 ));
DATA(insert ( 2593 603 603 7 2584 ));
+ DATA(insert ( 2593 603 603 9 3252 ));
DATA(insert ( 2594 604 604 1 2585 ));
DATA(insert ( 2594 604 604 2 2583 ));
DATA(insert ( 2594 604 604 3 2586 ));
*** a/src/include/catalog/pg_proc.h
--- b/src/include/catalog/pg_proc.h
***************
*** 941,946 **** DATA(insert OID = 776 ( gistbulkdelete PGNSP PGUID 12 1 0 0 0 f f f f t f v
--- 941,949 ----
DESCR("gist(internal)");
DATA(insert OID = 2561 ( gistvacuumcleanup PGNSP PGUID 12 1 0 0 0 f f f f t f v 2 0 2281 "2281 2281" _null_ _null_ _null_ _null_ gistvacuumcleanup _null_ _null_ _null_ ));
DESCR("gist(internal)");
+ //Debug
+ DATA(insert OID = 3251 ( gistcanreturn PGNSP PGUID 12 1 0 0 0 f f f f t f s 1 0 16 "2281" _null_ _null_ _null_ _null_ gistcanreturn _null_ _null_ _null_ ));
+ DESCR("gist(internal)");
DATA(insert OID = 772 ( gistcostestimate PGNSP PGUID 12 1 0 0 0 f f f f t f v 7 0 2278 "2281 2281 2281 2281 2281 2281 2281" _null_ _null_ _null_ _null_ gistcostestimate _null_ _null_ _null_ ));
DESCR("gist(internal)");
DATA(insert OID = 2787 ( gistoptions PGNSP PGUID 12 1 0 0 0 f f f f t f s 2 0 17 "1009 16" _null_ _null_ _null_ _null_ gistoptions _null_ _null_ _null_ ));
***************
*** 3996,4001 **** DATA(insert OID = 2579 ( gist_box_compress PGNSP PGUID 12 1 0 0 0 f f f f t f
--- 3999,4007 ----
DESCR("GiST support");
DATA(insert OID = 2580 ( gist_box_decompress PGNSP PGUID 12 1 0 0 0 f f f f t f i 1 0 2281 "2281" _null_ _null_ _null_ _null_ gist_box_decompress _null_ _null_ _null_ ));
DESCR("GiST support");
+ //Debug. gist_box_fetch
+ DATA(insert OID = 3252 ( gist_box_fetch PGNSP PGUID 12 1 0 0 0 f f f f t f i 1 0 2281 "2281" _null_ _null_ _null_ _null_ gist_box_fetch _null_ _null_ _null_ ));
+ DESCR("GiST support");
DATA(insert OID = 2581 ( gist_box_penalty PGNSP PGUID 12 1 0 0 0 f f f f t f i 3 0 2281 "2281 2281 2281" _null_ _null_ _null_ _null_ gist_box_penalty _null_ _null_ _null_ ));
DESCR("GiST support");
DATA(insert OID = 2582 ( gist_box_picksplit PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 2281 "2281 2281" _null_ _null_ _null_ _null_ gist_box_picksplit _null_ _null_ _null_ ));
*** a/src/include/utils/geo_decls.h
--- b/src/include/utils/geo_decls.h
***************
*** 273,278 **** extern Datum box_out(PG_FUNCTION_ARGS);
--- 273,279 ----
extern Datum box_recv(PG_FUNCTION_ARGS);
extern Datum box_send(PG_FUNCTION_ARGS);
extern Datum box_same(PG_FUNCTION_ARGS);
+ extern Datum gist_box_fetch(PG_FUNCTION_ARGS); //Debug. gist_box_fetch
extern Datum box_overlap(PG_FUNCTION_ARGS);
extern Datum box_left(PG_FUNCTION_ARGS);
extern Datum box_overleft(PG_FUNCTION_ARGS);