5
5
#include "utils/builtins.h"
6
6
#include "utils/elog.h"
7
7
#include "utils/lsyscache.h"
8
+
8
9
#include "nodes/print.h"
10
+
9
11
#include "catalog/pg_proc.h"
10
12
#include "catalog/pg_operator.h"
11
13
#include "commands/explain.h"
@@ -37,12 +39,15 @@ typedef struct
37
39
{
38
40
CustomScanState css ;
39
41
40
- HeapTupleData scan_tuple ; /* buffer to fetch tuple */
41
- List * dev_tlist ; /* tlist to be returned from the device */
42
- List * dev_quals ; /* quals to be run on the device */
42
+ List * scan_tlist ;
43
+
44
+ Relation outer_rel ;
45
+ ItemPointer outer_ptr ;
46
+ HeapTuple outer_tup ;
43
47
44
- Relation left ;
45
- Relation right ;
48
+ Relation inner_rel ;
49
+ ItemPointer inner_ptr ;
50
+ HeapTuple inner_tup ;
46
51
} CrossmatchScanState ;
47
52
48
53
static CustomPathMethods crossmatch_path_methods ;
@@ -232,6 +237,12 @@ create_crossmatch_plan(PlannerInfo *root,
232
237
List * otherclauses ;
233
238
CustomScan * cscan ;
234
239
240
+ Index lrel = gpath -> outer_path -> parent -> relid ;
241
+ Index rrel = gpath -> inner_path -> parent -> relid ;
242
+
243
+ /* relids should not be 0 */
244
+ Assert (lrel != 0 && rrel != 0 );
245
+
235
246
if (IS_OUTER_JOIN (gpath -> jointype ))
236
247
{
237
248
extract_actual_join_clauses (joinrestrictclauses ,
@@ -246,17 +257,16 @@ create_crossmatch_plan(PlannerInfo *root,
246
257
247
258
cscan = makeNode (CustomScan );
248
259
cscan -> scan .plan .targetlist = tlist ;
260
+ cscan -> custom_scan_tlist = tlist ; /* output of this node */
249
261
cscan -> scan .plan .qual = NIL ;
250
262
cscan -> scan .scanrelid = 0 ;
251
263
252
- cscan -> custom_scan_tlist = tlist ; /* TODO: recheck target list */
253
-
254
- elog (LOG , "tlist:" );
255
- pprint (tlist );
256
-
257
264
cscan -> flags = best_path -> flags ;
258
265
cscan -> methods = & crossmatch_plan_methods ;
259
266
267
+ cscan -> custom_private = list_make2_oid (root -> simple_rte_array [lrel ]-> relid ,
268
+ root -> simple_rte_array [rrel ]-> relid );
269
+
260
270
return & cscan -> scan .plan ;
261
271
}
262
272
@@ -271,6 +281,12 @@ crossmatch_create_scan_state(CustomScan *node)
271
281
272
282
scan_state -> css .ss .ps .ps_TupFromTlist = false;
273
283
284
+ scan_state -> scan_tlist = node -> custom_scan_tlist ;
285
+ scan_state -> outer_rel = heap_open (linitial_oid (node -> custom_private ),
286
+ AccessShareLock );
287
+ scan_state -> inner_rel = heap_open (lsecond_oid (node -> custom_private ),
288
+ AccessShareLock );
289
+
274
290
return (Node * ) scan_state ;
275
291
}
276
292
@@ -283,49 +299,53 @@ crossmatch_begin(CustomScanState *node, EState *estate, int eflags)
283
299
static TupleTableSlot *
284
300
crossmatch_exec (CustomScanState * node )
285
301
{
286
- TupleTableSlot * slot = node -> ss .ps .ps_ResultTupleSlot ;
287
- TupleDesc tupdesc = node -> ss .ps .ps_ResultTupleSlot -> tts_tupleDescriptor ;
288
- ExprContext * econtext = node -> ss .ps .ps_ProjInfo -> pi_exprContext ;
302
+ TupleTableSlot * slot = node -> ss .ss_ScanTupleSlot ;
303
+ TupleDesc tupdesc = node -> ss .ss_ScanTupleSlot -> tts_tupleDescriptor ;
289
304
HeapTuple htup ;
290
-
291
- HeapTupleData fetched_tup ;
292
-
293
- ResetExprContext (econtext );
305
+ TupleTableSlot * result ;
294
306
295
307
/* TODO: fill with real data from joined tables */
296
- Datum values [4 ] = { DirectFunctionCall1 (spherepoint_in , CStringGetDatum ("(0d, 0d)" )),
308
+ Datum values [2 ] = { DirectFunctionCall1 (spherepoint_in , CStringGetDatum ("(0d, 0d)" )),
297
309
DirectFunctionCall1 (spherepoint_in , CStringGetDatum ("(0d, 0d)" )) };
298
- bool nulls [4 ] = {0 ,1 , 1 , 1 };
310
+ bool nulls [2 ] = {0 ,0 };
299
311
300
312
elog (LOG , "slot.natts: %d" , tupdesc -> natts );
301
313
302
314
htup = heap_form_tuple (tupdesc , values , nulls );
303
315
304
- if (node -> ss .ps .ps_ProjInfo -> pi_itemIsDone != ExprEndResult )
316
+ if (node -> ss .ps .ps_ProjInfo )
305
317
{
306
- TupleTableSlot * result ;
307
- ExprDoneCond isDone ;
318
+ if (* (node -> ss .ps .ps_ProjInfo -> pi_itemIsDone ) != ExprEndResult )
319
+ {
320
+ ExprDoneCond isDone ;
308
321
309
- econtext -> ecxt_scantuple = ExecStoreTuple (htup , slot , InvalidBuffer , false);
322
+ node -> ss . ps . ps_ProjInfo -> pi_exprContext -> ecxt_scantuple = ExecStoreTuple (htup , slot , InvalidBuffer , false);
310
323
311
- result = ExecProject (node -> ss .ps .ps_ProjInfo , & isDone );
324
+ result = ExecProject (node -> ss .ps .ps_ProjInfo , & isDone );
312
325
313
- if (isDone != ExprEndResult )
314
- {
315
- node -> ss .ps .ps_TupFromTlist = (isDone == ExprMultipleResult );
316
- return result ;
326
+ if (isDone != ExprEndResult )
327
+ {
328
+ node -> ss .ps .ps_TupFromTlist = (isDone == ExprMultipleResult );
329
+ }
317
330
}
331
+ else
332
+ result = ExecClearTuple (node -> ss .ps .ps_ResultTupleSlot );
318
333
}
319
334
else
320
- ExecClearTuple (slot );
335
+ {
336
+ result = ExecClearTuple (node -> ss .ps .ps_ResultTupleSlot );
337
+ }
321
338
322
- return slot ;
339
+ return result ;
323
340
}
324
341
325
342
static void
326
343
crossmatch_end (CustomScanState * node )
327
344
{
345
+ CrossmatchScanState * scan_state = (CrossmatchScanState * ) node ;
328
346
347
+ heap_close (scan_state -> outer_rel , AccessShareLock );
348
+ heap_close (scan_state -> inner_rel , AccessShareLock );
329
349
}
330
350
331
351
static void
0 commit comments