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

Skip to content

Commit de99e0c

Browse files
committed
refactoring, fetch_next_pair() function
1 parent d16eda9 commit de99e0c

File tree

3 files changed

+91
-80
lines changed

3 files changed

+91
-80
lines changed

crossmatch.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -128,8 +128,7 @@ indexClose(Relation r)
128128
* Do necessary initialization for first SRF call.
129129
*/
130130
void
131-
setupFirstcall(CrossmatchContext *ctx, Oid idx1, Oid idx2,
132-
float8 threshold)
131+
setupFirstcall(CrossmatchContext *ctx, Oid idx1, Oid idx2, float8 threshold)
133132
{
134133
GistNSN parentnsn = InvalidNSN;
135134

crossmatch.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,7 @@ typedef struct
3737
AttInMetadata *attinmeta;
3838
} CrossmatchContext;
3939

40-
void setupFirstcall(CrossmatchContext *ctx, Oid idx1, Oid idx2,
41-
float8 threshold);
40+
void setupFirstcall(CrossmatchContext *ctx, Oid idx1, Oid idx2, float8 threshold);
4241

4342
void endCall(CrossmatchContext *ctx);
4443

init.c

Lines changed: 89 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,6 @@ typedef struct
5353

5454
Datum *values;
5555
bool *nulls;
56-
HeapTuple stored_tuple;
5756

5857
List *scan_tlist;
5958

@@ -450,8 +449,9 @@ create_crossmatch_plan(PlannerInfo *root,
450449
cscan->scan.plan.targetlist = tlist;
451450
cscan->scan.plan.qual = joinclauses;
452451
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);
455455

456456
cscan->flags = best_path->flags;
457457
cscan->methods = &crossmatch_plan_methods;
@@ -520,100 +520,113 @@ crossmatch_begin(CustomScanState *node, EState *estate, int eflags)
520520
if (scan_state->scan_tlist == NIL)
521521
{
522522
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);
524528
}
525-
else
526-
scan_state->stored_tuple = NULL;
527529
}
528530

529-
static TupleTableSlot *
530-
crossmatch_exec(CustomScanState *node)
531+
static bool
532+
fetch_next_pair(CrossmatchScanState *scan_state)
531533
{
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;
535537

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]))
537551
{
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+
}
543554

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;
549562

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;
551570

552-
if (!ItemPointerIsValid(&p_tids[0]) || !ItemPointerIsValid(&p_tids[1]))
571+
if (var->varno == scan_state->outer_relid)
553572
{
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]);
555584
}
556585

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)
559587
{
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+
}
565594

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+
}
568599

569-
foreach(l, scan_state->scan_tlist)
570-
{
571-
TargetEntry *target = (TargetEntry *) lfirst(l);
572-
Var *var = (Var *) target->expr;
600+
col_index++;
601+
}
573602

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);
588607

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);
602609

603-
col_index++;
604-
}
610+
/* Fill scanSlot with a new tuple */
611+
ExecStoreTuple(htup, slot, InvalidBuffer, false);
612+
}
605613

606-
if (htup_outer_ready)
607-
ReleaseBuffer(buf1);
608-
if (htup_inner_ready)
609-
ReleaseBuffer(buf2);
614+
return true;
615+
}
610616

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;
613622

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;
617630
}
618631

619632
if (node->ss.ps.ps_ProjInfo)

0 commit comments

Comments
 (0)