@@ -53,7 +53,6 @@ typedef struct
53
53
54
54
Datum * values ;
55
55
bool * nulls ;
56
- HeapTuple stored_tuple ;
57
56
58
57
List * scan_tlist ;
59
58
@@ -450,8 +449,9 @@ create_crossmatch_plan(PlannerInfo *root,
450
449
cscan -> scan .plan .targetlist = tlist ;
451
450
cscan -> scan .plan .qual = joinclauses ;
452
451
cscan -> scan .scanrelid = 0 ;
453
- cscan -> custom_scan_tlist = make_tlist_from_pathtarget (& rel -> reltarget ); /* tlist of the 'virtual' join rel
454
- we'll have to build and scan */
452
+
453
+ /* tlist of the 'virtual' join rel we'll have to build and scan */
454
+ cscan -> custom_scan_tlist = make_tlist_from_pathtarget (& rel -> reltarget );
455
455
456
456
cscan -> flags = best_path -> flags ;
457
457
cscan -> methods = & crossmatch_plan_methods ;
@@ -520,100 +520,113 @@ crossmatch_begin(CustomScanState *node, EState *estate, int eflags)
520
520
if (scan_state -> scan_tlist == NIL )
521
521
{
522
522
TupleDesc tupdesc = node -> ss .ss_ScanTupleSlot -> tts_tupleDescriptor ;
523
- scan_state -> stored_tuple = heap_form_tuple (tupdesc , NULL , NULL );
523
+
524
+ ExecStoreTuple (heap_form_tuple (tupdesc , NULL , NULL ),
525
+ node -> ss .ss_ScanTupleSlot ,
526
+ InvalidBuffer ,
527
+ false);
524
528
}
525
- else
526
- scan_state -> stored_tuple = NULL ;
527
529
}
528
530
529
- static TupleTableSlot *
530
- crossmatch_exec ( CustomScanState * node )
531
+ static bool
532
+ fetch_next_pair ( CrossmatchScanState * scan_state )
531
533
{
532
- CrossmatchScanState * scan_state = ( CrossmatchScanState * ) node ;
533
- TupleTableSlot * scanSlot = node -> ss . ss_ScanTupleSlot ;
534
- HeapTuple htup = scan_state -> stored_tuple ;
534
+ ScanState * ss = & scan_state -> css . ss ;
535
+ TupleTableSlot * slot = ss -> ss_ScanTupleSlot ;
536
+ TupleDesc tupdesc = ss -> ss_ScanTupleSlot -> tts_tupleDescriptor ;
535
537
536
- for (;;)
538
+ HeapTuple htup ;
539
+ Datum * values = scan_state -> values ;
540
+ bool * nulls = scan_state -> nulls ;
541
+
542
+ ItemPointerData p_tids [2 ] = { 0 };
543
+ HeapTupleData htup_outer ;
544
+ HeapTupleData htup_inner ;
545
+ Buffer buf1 ;
546
+ Buffer buf2 ;
547
+
548
+ crossmatch (scan_state -> ctx , p_tids );
549
+
550
+ if (!ItemPointerIsValid (& p_tids [0 ]) || !ItemPointerIsValid (& p_tids [1 ]))
537
551
{
538
- /* Fetch next tid pair */
539
- if (!node -> ss .ps .ps_TupFromTlist )
540
- {
541
- Datum * values = scan_state -> values ;
542
- bool * nulls = scan_state -> nulls ;
552
+ return false;
553
+ }
543
554
544
- ItemPointerData p_tids [2 ] = { 0 };
545
- HeapTupleData htup_outer ;
546
- HeapTupleData htup_inner ;
547
- Buffer buf1 ;
548
- Buffer buf2 ;
555
+ /* We don't have to fetch tuples if scan tlist is empty */
556
+ if (scan_state -> scan_tlist != NIL )
557
+ {
558
+ bool htup_outer_ready = false;
559
+ bool htup_inner_ready = false;
560
+ int col_index = 0 ;
561
+ ListCell * l ;
549
562
550
- crossmatch (scan_state -> ctx , p_tids );
563
+ htup_outer .t_self = p_tids [0 ];
564
+ htup_inner .t_self = p_tids [1 ];
565
+
566
+ foreach (l , scan_state -> scan_tlist )
567
+ {
568
+ TargetEntry * target = (TargetEntry * ) lfirst (l );
569
+ Var * var = (Var * ) target -> expr ;
551
570
552
- if (! ItemPointerIsValid ( & p_tids [ 0 ]) || ! ItemPointerIsValid ( & p_tids [ 1 ]) )
571
+ if (var -> varno == scan_state -> outer_relid )
553
572
{
554
- return ExecClearTuple (node -> ss .ps .ps_ResultTupleSlot );
573
+ if (!htup_outer_ready )
574
+ {
575
+ htup_outer_ready = true;
576
+ /* TODO: check result */
577
+ heap_fetch (scan_state -> outer , SnapshotSelf ,
578
+ & htup_outer , & buf1 , false, NULL );
579
+ }
580
+
581
+ values [col_index ] = heap_getattr (& htup_outer , var -> varattno ,
582
+ scan_state -> outer -> rd_att ,
583
+ & nulls [col_index ]);
555
584
}
556
585
557
- /* We don't have to fetch tuples if scan tlist is empty */
558
- if (scan_state -> scan_tlist != NIL )
586
+ if (var -> varno == scan_state -> inner_relid )
559
587
{
560
- TupleDesc tupdesc = node -> ss .ss_ScanTupleSlot -> tts_tupleDescriptor ;
561
- bool htup_outer_ready = false;
562
- bool htup_inner_ready = false;
563
- int col_index = 0 ;
564
- ListCell * l ;
588
+ if (!htup_inner_ready )
589
+ {
590
+ htup_inner_ready = true;
591
+ heap_fetch (scan_state -> inner , SnapshotSelf ,
592
+ & htup_inner , & buf2 , false, NULL );
593
+ }
565
594
566
- htup_outer .t_self = p_tids [0 ];
567
- htup_inner .t_self = p_tids [1 ];
595
+ values [col_index ] = heap_getattr (& htup_inner , var -> varattno ,
596
+ scan_state -> outer -> rd_att ,
597
+ & nulls [col_index ]);
598
+ }
568
599
569
- foreach (l , scan_state -> scan_tlist )
570
- {
571
- TargetEntry * target = (TargetEntry * ) lfirst (l );
572
- Var * var = (Var * ) target -> expr ;
600
+ col_index ++ ;
601
+ }
573
602
574
- if (var -> varno == scan_state -> outer_relid )
575
- {
576
- if (!htup_outer_ready )
577
- {
578
- htup_outer_ready = true;
579
- /* TODO: check result */
580
- heap_fetch (scan_state -> outer , SnapshotSelf ,
581
- & htup_outer , & buf1 , false, NULL );
582
- }
583
-
584
- values [col_index ] = heap_getattr (& htup_outer , var -> varattno ,
585
- scan_state -> outer -> rd_att ,
586
- & nulls [col_index ]);
587
- }
603
+ if (htup_outer_ready )
604
+ ReleaseBuffer (buf1 );
605
+ if (htup_inner_ready )
606
+ ReleaseBuffer (buf2 );
588
607
589
- if (var -> varno == scan_state -> inner_relid )
590
- {
591
- if (!htup_inner_ready )
592
- {
593
- htup_inner_ready = true;
594
- heap_fetch (scan_state -> inner , SnapshotSelf ,
595
- & htup_inner , & buf2 , false, NULL );
596
- }
597
-
598
- values [col_index ] = heap_getattr (& htup_inner , var -> varattno ,
599
- scan_state -> outer -> rd_att ,
600
- & nulls [col_index ]);
601
- }
608
+ htup = heap_form_tuple (tupdesc , values , nulls );
602
609
603
- col_index ++ ;
604
- }
610
+ /* Fill scanSlot with a new tuple */
611
+ ExecStoreTuple (htup , slot , InvalidBuffer , false);
612
+ }
605
613
606
- if (htup_outer_ready )
607
- ReleaseBuffer (buf1 );
608
- if (htup_inner_ready )
609
- ReleaseBuffer (buf2 );
614
+ return true;
615
+ }
610
616
611
- htup = heap_form_tuple (tupdesc , values , nulls );
612
- scan_state -> stored_tuple = htup ;
617
+ static TupleTableSlot *
618
+ crossmatch_exec (CustomScanState * node )
619
+ {
620
+ CrossmatchScanState * scan_state = (CrossmatchScanState * ) node ;
621
+ TupleTableSlot * scanSlot = node -> ss .ss_ScanTupleSlot ;
613
622
614
- /* Fill scanSlot with a new tuple */
615
- ExecStoreTuple (htup , scanSlot , InvalidBuffer , false);
616
- }
623
+ for (;;)
624
+ {
625
+ if (!node -> ss .ps .ps_TupFromTlist )
626
+ {
627
+ /* Fetch next tid pair if we're done with the SRF function */
628
+ if (!fetch_next_pair (scan_state ))
629
+ return NULL ;
617
630
}
618
631
619
632
if (node -> ss .ps .ps_ProjInfo )
0 commit comments