Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit ea93575

Browse files
committed
experimental changes to crossmatch() function, projection is broken
1 parent 723076c commit ea93575

File tree

3 files changed

+96
-171
lines changed

3 files changed

+96
-171
lines changed

crossmatch.c

Lines changed: 17 additions & 159 deletions
Original file line numberDiff line numberDiff line change
@@ -67,21 +67,6 @@ typedef struct
6767
iptr2;
6868
} ResultPair;
6969

70-
/*
71-
* Context of crossmatch: represents data which are persistent across SRF calls.
72-
*/
73-
typedef struct
74-
{
75-
MemoryContext context;
76-
Relation indexes[2];
77-
List *pendingPairs;
78-
List *resultsPairs;
79-
float8 pointThreshold;
80-
int box3dThreshold;
81-
SBOX *box;
82-
int32 boxkey[6];
83-
} CrossmatchContext;
84-
8570
/*
8671
* Point information for line sweep algorithm.
8772
*/
@@ -101,28 +86,6 @@ typedef struct
10186
GistNSN parentlsn;
10287
} Box3DInfo;
10388

104-
PG_FUNCTION_INFO_V1(crossmatch);
105-
106-
/*
107-
* Check if relation is index and has specified am oid. Trigger error if not
108-
*/
109-
static Relation
110-
checkOpenedRelation(Relation r, Oid PgAmOid)
111-
{
112-
#if PG_VERSION_NUM >= 90600
113-
if (r->rd_amroutine == NULL)
114-
#else
115-
if (r->rd_am == NULL)
116-
#endif
117-
elog(ERROR, "Relation %s.%s is not an index",
118-
get_namespace_name(RelationGetNamespace(r)),
119-
RelationGetRelationName(r));
120-
if (r->rd_rel->relam != PgAmOid)
121-
elog(ERROR, "Index %s.%s has wrong type",
122-
get_namespace_name(RelationGetNamespace(r)),
123-
RelationGetRelationName(r));
124-
return r;
125-
}
12689

12790
/*
12891
* Add pending pages pair to context.
@@ -132,10 +95,6 @@ addPendingPair(CrossmatchContext *ctx, BlockNumber blk1, BlockNumber blk2,
13295
GistNSN parentlsn1, GistNSN parentlsn2)
13396
{
13497
PendingPair *blockNumberPair;
135-
MemoryContext oldcontext;
136-
137-
/* Switch to persistent memory context */
138-
oldcontext = MemoryContextSwitchTo(ctx->context);
13998

14099
/* Add pending pair */
141100
blockNumberPair = (PendingPair *) palloc(sizeof(PendingPair));
@@ -144,9 +103,6 @@ addPendingPair(CrossmatchContext *ctx, BlockNumber blk1, BlockNumber blk2,
144103
blockNumberPair->parentlsn1 = parentlsn1;
145104
blockNumberPair->parentlsn2 = parentlsn2;
146105
ctx->pendingPairs = lcons(blockNumberPair, ctx->pendingPairs);
147-
148-
/* Return old memory context */
149-
MemoryContextSwitchTo(oldcontext);
150106
}
151107

152108
/*
@@ -156,35 +112,13 @@ static void
156112
addResultPair(CrossmatchContext *ctx, ItemPointer iptr1, ItemPointer iptr2)
157113
{
158114
ResultPair *itemPointerPair;
159-
MemoryContext oldcontext;
160-
161-
/* Switch to persistent memory context */
162-
oldcontext = MemoryContextSwitchTo(ctx->context);
163115

164116
/* Add result pair */
165117
itemPointerPair = (ResultPair *)
166118
palloc(sizeof(ResultPair));
167119
itemPointerPair->iptr1 = *iptr1;
168120
itemPointerPair->iptr2 = *iptr2;
169121
ctx->resultsPairs = lappend(ctx->resultsPairs, itemPointerPair);
170-
171-
/* Return old memory context */
172-
MemoryContextSwitchTo(oldcontext);
173-
}
174-
175-
/*
176-
* Open index relation with AccessShareLock.
177-
*/
178-
static Relation
179-
indexOpen(RangeVar *relvar)
180-
{
181-
#if PG_VERSION_NUM < 90200
182-
Oid relOid = RangeVarGetRelid(relvar, false);
183-
#else
184-
Oid relOid = RangeVarGetRelid(relvar, NoLock, false);
185-
#endif
186-
return checkOpenedRelation(
187-
index_open(relOid, AccessShareLock), GIST_AM_OID);
188122
}
189123

190124
/*
@@ -199,69 +133,32 @@ indexClose(Relation r)
199133
/*
200134
* Do necessary initialization for first SRF call.
201135
*/
202-
static void
203-
setupFirstcall(FuncCallContext *funcctx, text *names[2],
204-
float8 threshold, SBOX *box)
136+
void
137+
setupFirstcall(CrossmatchContext *ctx, Oid idx1, Oid idx2,
138+
float8 threshold)
205139
{
206-
MemoryContext oldcontext;
207-
CrossmatchContext *ctx;
208-
TupleDesc tupdesc;
209140
GistNSN parentnsn = InvalidNSN;
210-
int i;
211141

212-
/* Switch to persistent memory context */
213-
oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
142+
ctx->box = NULL;
143+
144+
Assert(idx1 != idx2);
145+
146+
ctx->indexes[0] = index_open(idx1, AccessShareLock);
147+
ctx->indexes[1] = index_open(idx2, AccessShareLock);
214148

215-
/* Allocate crossmarch context and fill it with scan parameters */
216-
ctx = (CrossmatchContext *) palloc0(sizeof(CrossmatchContext));
217-
ctx->context = funcctx->multi_call_memory_ctx;
218-
ctx->box = box;
219-
if (box)
220-
spherebox_gen_key(ctx->boxkey, box);
221149
ctx->pointThreshold = 2.0 * sin(0.5 * threshold);
222150
ctx->box3dThreshold = MAXCVALUE * ctx->pointThreshold;
223-
funcctx->user_fctx = (void *) ctx;
224-
225-
/* Open both indexes */
226-
for (i = 0; i < 2; i++)
227-
{
228-
char *relname = text_to_cstring(names[i]);
229-
List *relname_list;
230-
RangeVar *relvar;
231-
232-
relname_list = stringToQualifiedNameList(relname);
233-
relvar = makeRangeVarFromNameList(relname_list);
234-
ctx->indexes[i] = indexOpen(relvar);
235-
pfree(relname);
236-
}
237151

238152
/*
239153
* Add first pending pair of pages: we start scan both indexes from their
240154
* roots.
241155
*/
242156
addPendingPair(ctx, GIST_ROOT_BLKNO, GIST_ROOT_BLKNO,
243157
parentnsn, parentnsn);
244-
245-
/* Describe structure of resulting tuples */
246-
tupdesc = CreateTemplateTupleDesc(2, false);
247-
TupleDescInitEntry(tupdesc, 1, "ctid1", TIDOID, -1, 0);
248-
TupleDescInitEntry(tupdesc, 2, "ctid2", TIDOID, -1, 0);
249-
funcctx->slot = TupleDescGetSlot(tupdesc);
250-
funcctx->attinmeta = TupleDescGetAttInMetadata(tupdesc);
251-
252-
/* Return old memory context */
253-
MemoryContextSwitchTo(oldcontext);
254158
}
255159

256-
/*
257-
* Close SRF call: free occupied resources.
258-
*/
259-
static void
260-
closeCall(FuncCallContext *funcctx)
160+
void endCall(CrossmatchContext *ctx)
261161
{
262-
CrossmatchContext *ctx = (CrossmatchContext *) (funcctx->user_fctx);
263-
264-
/* Close indexes */
265162
indexClose(ctx->indexes[0]);
266163
indexClose(ctx->indexes[1]);
267164
}
@@ -969,39 +866,9 @@ processPendingPair(CrossmatchContext *ctx, BlockNumber blk1, BlockNumber blk2,
969866
/*
970867
* Crossmatch SRF
971868
*/
972-
Datum
973-
crossmatch(PG_FUNCTION_ARGS)
869+
void
870+
crossmatch(CrossmatchContext *ctx, ItemPointer values)
974871
{
975-
FuncCallContext *funcctx;
976-
CrossmatchContext *ctx;
977-
978-
/*
979-
* Initialize crossmatch context if first call of SRF.
980-
*/
981-
if (SRF_IS_FIRSTCALL())
982-
{
983-
SBOX *box;
984-
text *names[2];
985-
float8 threshold = PG_GETARG_FLOAT8(2);
986-
987-
names[0] = PG_GETARG_TEXT_P(0);
988-
names[1] = PG_GETARG_TEXT_P(1);
989-
funcctx = SRF_FIRSTCALL_INIT();
990-
991-
/* Assume no restriction on first dataset if less than 3 args */
992-
if (PG_NARGS() < 4)
993-
box = NULL;
994-
else
995-
box = (SBOX *) PG_GETARG_POINTER(3);
996-
997-
setupFirstcall(funcctx, names, threshold, box);
998-
PG_FREE_IF_COPY(names[0], 0);
999-
PG_FREE_IF_COPY(names[1], 0);
1000-
}
1001-
1002-
funcctx = SRF_PERCALL_SETUP();
1003-
ctx = (CrossmatchContext *) funcctx->user_fctx;
1004-
1005872
/* Scan pending pairs until we have some result pairs */
1006873
while (ctx->resultsPairs == NIL && ctx->pendingPairs != NIL)
1007874
{
@@ -1018,27 +885,18 @@ crossmatch(PG_FUNCTION_ARGS)
1018885
/* Return next result pair if any. Otherwise close SRF. */
1019886
if (ctx->resultsPairs != NIL)
1020887
{
1021-
Datum datums[2],
1022-
result;
1023-
bool nulls[2];
1024888
ResultPair *itemPointerPair = (ResultPair *) palloc(sizeof(ResultPair));
1025-
HeapTuple htuple;
1026889

1027890
*itemPointerPair = *((ResultPair *) linitial(ctx->resultsPairs));
1028891
pfree(linitial(ctx->resultsPairs));
1029892
ctx->resultsPairs = list_delete_first(ctx->resultsPairs);
1030-
datums[0] = PointerGetDatum(&itemPointerPair->iptr1);
1031-
datums[1] = PointerGetDatum(&itemPointerPair->iptr2);
1032-
nulls[0] = false;
1033-
nulls[1] = false;
1034-
1035-
htuple = heap_formtuple(funcctx->attinmeta->tupdesc, datums, nulls);
1036-
result = TupleGetDatum(funcctx->slot, htuple);
1037-
SRF_RETURN_NEXT(funcctx, result);
893+
894+
values[0] = itemPointerPair->iptr1;
895+
values[1] = itemPointerPair->iptr2;
1038896
}
1039897
else
1040898
{
1041-
closeCall(funcctx);
1042-
SRF_RETURN_DONE(funcctx);
899+
ItemPointerSetInvalid(&values[0]);
900+
ItemPointerSetInvalid(&values[1]);
1043901
}
1044902
}

crossmatch.h

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#define __PGS_CROSSMATCH_H_
33

44
#include "types.h"
5+
#include "funcapi.h"
56

67
#if PG_VERSION_NUM >= 90300
78
#define GIST_SCAN_FOLLOW_RIGHT(parentlsn,page) \
@@ -19,7 +20,28 @@
1920
#define InvalidNSN {0, 0}
2021
#endif
2122

23+
/*
24+
* Context of crossmatch: represents data which are persistent across SRF calls.
25+
*/
26+
typedef struct
27+
{
28+
Relation indexes[2];
29+
List *pendingPairs;
30+
List *resultsPairs;
31+
float8 pointThreshold;
32+
int box3dThreshold;
33+
SBOX *box;
34+
int32 boxkey[6];
2235

23-
Datum crossmatch(PG_FUNCTION_ARGS);
36+
TupleTableSlot *slot;
37+
AttInMetadata *attinmeta;
38+
} CrossmatchContext;
39+
40+
void setupFirstcall(CrossmatchContext *ctx, Oid idx1, Oid idx2,
41+
float8 threshold);
42+
43+
void endCall(CrossmatchContext *ctx);
44+
45+
void crossmatch(CrossmatchContext *ctx, ItemPointer values);
2446

2547
#endif /* __PGS_CROSSMATCH_H_ */

0 commit comments

Comments
 (0)