@@ -56,16 +56,14 @@ typedef struct
56
56
57
57
List * scan_tlist ;
58
58
59
+ Index outer_relid ;
59
60
Oid outer_idx ;
60
61
Oid outer_rel ;
61
- ItemPointer outer_ptr ;
62
- HeapTuple outer_tup ;
63
62
Relation outer ;
64
63
64
+ Index inner_relid ;
65
65
Oid inner_idx ;
66
66
Oid inner_rel ;
67
- ItemPointer inner_ptr ;
68
- HeapTuple inner_tup ;
69
67
Relation inner ;
70
68
71
69
float8 threshold ;
@@ -446,9 +444,17 @@ create_crossmatch_plan(PlannerInfo *root,
446
444
gpath -> outer_rel ,
447
445
gpath -> inner_idx ,
448
446
gpath -> inner_rel ));
447
+
448
+ /* store threshold as cstring */
449
449
cscan -> custom_private = lappend (cscan -> custom_private ,
450
450
makeString (float8_to_cstring (gpath -> threshold )));
451
451
452
+ cscan -> custom_private = lappend (cscan -> custom_private ,
453
+ makeInteger (gpath -> outer_path -> parent -> relid ));
454
+
455
+ cscan -> custom_private = lappend (cscan -> custom_private ,
456
+ makeInteger (gpath -> inner_path -> parent -> relid ));
457
+
452
458
return & cscan -> scan .plan ;
453
459
}
454
460
@@ -470,8 +476,12 @@ crossmatch_create_scan_state(CustomScan *node)
470
476
scan_state -> outer_rel = lsecond_oid (linitial (node -> custom_private ));
471
477
scan_state -> inner_idx = lthird_oid (linitial (node -> custom_private ));
472
478
scan_state -> inner_rel = lfourth_oid (linitial (node -> custom_private ));
479
+
473
480
scan_state -> threshold = cstring_to_float8 (strVal (lsecond (node -> custom_private )));
474
481
482
+ scan_state -> outer_relid = intVal (lthird (node -> custom_private ));
483
+ scan_state -> inner_relid = intVal (lfourth (node -> custom_private ));
484
+
475
485
return (Node * )scan_state ;
476
486
}
477
487
@@ -480,9 +490,7 @@ crossmatch_begin(CustomScanState *node, EState *estate, int eflags)
480
490
{
481
491
CrossmatchScanState * scan_state = (CrossmatchScanState * )node ;
482
492
CrossmatchContext * ctx = (CrossmatchContext * )palloc0 (sizeof (CrossmatchContext ));
483
-
484
- /* TODO: fix this kludge */
485
- int nlist = list_length (scan_state -> scan_tlist )+ 2 ;
493
+ int nlist = list_length (scan_state -> scan_tlist );
486
494
487
495
scan_state -> ctx = ctx ;
488
496
setupFirstcall (ctx ,scan_state -> outer_idx ,
@@ -519,8 +527,8 @@ crossmatch_exec(CustomScanState *node)
519
527
bool * nulls = scan_state -> nulls ;
520
528
521
529
ItemPointerData p_tids [2 ]= {0 };
522
- HeapTupleData htup1 ;
523
- HeapTupleData htup2 ;
530
+ HeapTupleData htup_outer ;
531
+ HeapTupleData htup_inner ;
524
532
Buffer buf1 ;
525
533
Buffer buf2 ;
526
534
@@ -534,22 +542,55 @@ crossmatch_exec(CustomScanState *node)
534
542
/* We don't have to fetch tuples if scan tlist is empty */
535
543
if (scan_state -> scan_tlist != NIL )
536
544
{
537
- TupleDesc tupdesc = node -> ss .ss_ScanTupleSlot -> tts_tupleDescriptor ;
538
-
539
- htup1 .t_self = p_tids [0 ];
540
- heap_fetch (scan_state -> outer ,SnapshotSelf ,
541
- & htup1 ,& buf1 , false,NULL );
542
- values [0 ]= heap_getattr (& htup1 ,1 ,scan_state -> outer -> rd_att ,
543
- & nulls [0 ]);
544
-
545
- htup2 .t_self = p_tids [1 ];
546
- heap_fetch (scan_state -> inner ,SnapshotSelf ,
547
- & htup2 ,& buf2 , false,NULL );
548
- values [1 ]= heap_getattr (& htup2 ,1 ,scan_state -> inner -> rd_att ,
549
- & nulls [1 ]);
550
-
551
- ReleaseBuffer (buf1 );
552
- ReleaseBuffer (buf2 );
545
+ TupleDesc tupdesc = node -> ss .ss_ScanTupleSlot -> tts_tupleDescriptor ;
546
+ int col_index = 0 ;
547
+ bool htup_outer_ready = false;
548
+ bool htup_inner_ready = false;
549
+ ListCell * l ;
550
+
551
+ htup_outer .t_self = p_tids [0 ];
552
+ htup_inner .t_self = p_tids [1 ];
553
+
554
+ foreach (l ,scan_state -> scan_tlist )
555
+ {
556
+ TargetEntry * target = (TargetEntry * )lfirst (l );
557
+ Var * var = (Var * )target -> expr ;
558
+
559
+ if (var -> varno == scan_state -> outer_relid )
560
+ {
561
+ if (!htup_outer_ready )
562
+ {
563
+ htup_outer_ready = true;
564
+ heap_fetch (scan_state -> outer ,SnapshotSelf ,
565
+ & htup_outer ,& buf1 , false,NULL );
566
+ }
567
+
568
+ values [col_index ]= heap_getattr (& htup_outer ,var -> varattno ,
569
+ scan_state -> outer -> rd_att ,
570
+ & nulls [col_index ]);
571
+ }
572
+
573
+ if (var -> varno == scan_state -> inner_relid )
574
+ {
575
+ if (!htup_inner_ready )
576
+ {
577
+ htup_inner_ready = true;
578
+ heap_fetch (scan_state -> inner ,SnapshotSelf ,
579
+ & htup_inner ,& buf2 , false,NULL );
580
+ }
581
+
582
+ values [col_index ]= heap_getattr (& htup_inner ,var -> varattno ,
583
+ scan_state -> outer -> rd_att ,
584
+ & nulls [col_index ]);
585
+ }
586
+
587
+ col_index ++ ;
588
+ }
589
+
590
+ if (htup_outer_ready )
591
+ ReleaseBuffer (buf1 );
592
+ if (htup_inner_ready )
593
+ ReleaseBuffer (buf2 );
553
594
554
595
htup = heap_form_tuple (tupdesc ,values ,nulls );
555
596
scan_state -> stored_tuple = htup ;