@@ -67,21 +67,6 @@ typedef struct
67
67
iptr2 ;
68
68
} ResultPair ;
69
69
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
-
85
70
/*
86
71
* Point information for line sweep algorithm.
87
72
*/
@@ -101,28 +86,6 @@ typedef struct
101
86
GistNSN parentlsn ;
102
87
} Box3DInfo ;
103
88
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
- }
126
89
127
90
/*
128
91
* Add pending pages pair to context.
@@ -132,10 +95,6 @@ addPendingPair(CrossmatchContext *ctx, BlockNumber blk1, BlockNumber blk2,
132
95
GistNSN parentlsn1 , GistNSN parentlsn2 )
133
96
{
134
97
PendingPair * blockNumberPair ;
135
- MemoryContext oldcontext ;
136
-
137
- /* Switch to persistent memory context */
138
- oldcontext = MemoryContextSwitchTo (ctx -> context );
139
98
140
99
/* Add pending pair */
141
100
blockNumberPair = (PendingPair * ) palloc (sizeof (PendingPair ));
@@ -144,9 +103,6 @@ addPendingPair(CrossmatchContext *ctx, BlockNumber blk1, BlockNumber blk2,
144
103
blockNumberPair -> parentlsn1 = parentlsn1 ;
145
104
blockNumberPair -> parentlsn2 = parentlsn2 ;
146
105
ctx -> pendingPairs = lcons (blockNumberPair , ctx -> pendingPairs );
147
-
148
- /* Return old memory context */
149
- MemoryContextSwitchTo (oldcontext );
150
106
}
151
107
152
108
/*
@@ -156,35 +112,13 @@ static void
156
112
addResultPair (CrossmatchContext * ctx , ItemPointer iptr1 , ItemPointer iptr2 )
157
113
{
158
114
ResultPair * itemPointerPair ;
159
- MemoryContext oldcontext ;
160
-
161
- /* Switch to persistent memory context */
162
- oldcontext = MemoryContextSwitchTo (ctx -> context );
163
115
164
116
/* Add result pair */
165
117
itemPointerPair = (ResultPair * )
166
118
palloc (sizeof (ResultPair ));
167
119
itemPointerPair -> iptr1 = * iptr1 ;
168
120
itemPointerPair -> iptr2 = * iptr2 ;
169
121
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 );
188
122
}
189
123
190
124
/*
@@ -199,69 +133,32 @@ indexClose(Relation r)
199
133
/*
200
134
* Do necessary initialization for first SRF call.
201
135
*/
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 )
205
139
{
206
- MemoryContext oldcontext ;
207
- CrossmatchContext * ctx ;
208
- TupleDesc tupdesc ;
209
140
GistNSN parentnsn = InvalidNSN ;
210
- int i ;
211
141
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 );
214
148
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 );
221
149
ctx -> pointThreshold = 2.0 * sin (0.5 * threshold );
222
150
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
- }
237
151
238
152
/*
239
153
* Add first pending pair of pages: we start scan both indexes from their
240
154
* roots.
241
155
*/
242
156
addPendingPair (ctx , GIST_ROOT_BLKNO , GIST_ROOT_BLKNO ,
243
157
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 );
254
158
}
255
159
256
- /*
257
- * Close SRF call: free occupied resources.
258
- */
259
- static void
260
- closeCall (FuncCallContext * funcctx )
160
+ void endCall (CrossmatchContext * ctx )
261
161
{
262
- CrossmatchContext * ctx = (CrossmatchContext * ) (funcctx -> user_fctx );
263
-
264
- /* Close indexes */
265
162
indexClose (ctx -> indexes [0 ]);
266
163
indexClose (ctx -> indexes [1 ]);
267
164
}
@@ -969,39 +866,9 @@ processPendingPair(CrossmatchContext *ctx, BlockNumber blk1, BlockNumber blk2,
969
866
/*
970
867
* Crossmatch SRF
971
868
*/
972
- Datum
973
- crossmatch (PG_FUNCTION_ARGS )
869
+ void
870
+ crossmatch (CrossmatchContext * ctx , ItemPointer values )
974
871
{
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
-
1005
872
/* Scan pending pairs until we have some result pairs */
1006
873
while (ctx -> resultsPairs == NIL && ctx -> pendingPairs != NIL )
1007
874
{
@@ -1018,27 +885,18 @@ crossmatch(PG_FUNCTION_ARGS)
1018
885
/* Return next result pair if any. Otherwise close SRF. */
1019
886
if (ctx -> resultsPairs != NIL )
1020
887
{
1021
- Datum datums [2 ],
1022
- result ;
1023
- bool nulls [2 ];
1024
888
ResultPair * itemPointerPair = (ResultPair * ) palloc (sizeof (ResultPair ));
1025
- HeapTuple htuple ;
1026
889
1027
890
* itemPointerPair = * ((ResultPair * ) linitial (ctx -> resultsPairs ));
1028
891
pfree (linitial (ctx -> resultsPairs ));
1029
892
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 ;
1038
896
}
1039
897
else
1040
898
{
1041
- closeCall ( funcctx );
1042
- SRF_RETURN_DONE ( funcctx );
899
+ ItemPointerSetInvalid ( & values [ 0 ] );
900
+ ItemPointerSetInvalid ( & values [ 1 ] );
1043
901
}
1044
902
}
0 commit comments