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

Skip to content

Commit 6508567

Browse files
committed
refactoring (+try_crossmatch_path() function), check join quals
1 parent 725fefe commit 6508567

File tree

1 file changed

+66
-62
lines changed

1 file changed

+66
-62
lines changed

init.c

Lines changed: 66 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -263,7 +263,6 @@ create_crossmatch_path(PlannerInfo *root,
263263
Oid outer_idx;
264264
Oid inner_idx;
265265

266-
/* TODO: use actual column numbers */
267266
if ((outer_idx = pick_suitable_index(outer_rel, outer_spoint)) == InvalidOid ||
268267
(inner_idx = pick_suitable_index(inner_rel, inner_spoint)) == InvalidOid)
269268
{
@@ -297,6 +296,49 @@ create_crossmatch_path(PlannerInfo *root,
297296
add_path(joinrel, &result->cpath.path);
298297
}
299298

299+
static void
300+
try_crossmatch_path(RestrictInfo *restrInfo,
301+
FuncExpr *distFuncExpr,
302+
Const *thresholdConst,
303+
PlannerInfo *root,
304+
RelOptInfo *joinrel,
305+
RelOptInfo *outerrel,
306+
RelOptInfo *innerrel,
307+
JoinPathExtraData *extra)
308+
{
309+
AttrNumber outer_spoint,
310+
inner_spoint;
311+
List *restrict_clauses;
312+
Path *outer_path,
313+
*inner_path;
314+
Relids required_outer;
315+
ParamPathInfo *param_info;
316+
317+
/* Remove current RestrictInfo from restrict clauses */
318+
restrict_clauses = list_delete_ptr(list_copy(extra->restrictlist), restrInfo);
319+
320+
outer_path = crossmatch_find_cheapest_path(root, joinrel, outerrel);
321+
inner_path = crossmatch_find_cheapest_path(root, joinrel, innerrel);
322+
323+
required_outer = calc_nestloop_required_outer(outer_path, inner_path);
324+
325+
param_info = get_joinrel_parampathinfo(root,
326+
joinrel,
327+
outer_path,
328+
inner_path,
329+
extra->sjinfo,
330+
required_outer,
331+
&restrict_clauses);
332+
333+
get_spoint_attnums(distFuncExpr, outerrel, innerrel,
334+
&outer_spoint, &inner_spoint);
335+
336+
create_crossmatch_path(root, joinrel, outer_path, inner_path,
337+
param_info, restrict_clauses, required_outer,
338+
get_const_val(thresholdConst),
339+
outer_spoint, inner_spoint);
340+
}
341+
300342
static void
301343
join_pathlist_hook(PlannerInfo *root,
302344
RelOptInfo *joinrel,
@@ -308,7 +350,6 @@ join_pathlist_hook(PlannerInfo *root,
308350
ListCell *restr;
309351
text *dist_func_name = cstring_to_text("dist(spoint,spoint)");
310352
Oid dist_func;
311-
List *restrict_clauses = extra->restrictlist;
312353
Relids required_relids = NULL;
313354

314355
if (outerrel->reloptkind == RELOPT_BASEREL &&
@@ -357,59 +398,16 @@ join_pathlist_hook(PlannerInfo *root,
357398
if (opExpr->opno == Float8LessOperator &&
358399
IsVarSpointDist(arg1, dist_func) && IsA(arg2, Const))
359400
{
360-
AttrNumber outer_spoint,
361-
inner_spoint;
362-
363-
Path *outer_path = crossmatch_find_cheapest_path(root, joinrel, outerrel);
364-
Path *inner_path = crossmatch_find_cheapest_path(root, joinrel, innerrel);
365-
366-
Relids required_outer = calc_nestloop_required_outer(outer_path, inner_path);
367-
368-
ParamPathInfo *param_info = get_joinrel_parampathinfo(root,
369-
joinrel,
370-
outer_path,
371-
inner_path,
372-
extra->sjinfo,
373-
required_outer,
374-
&restrict_clauses);
375-
376-
get_spoint_attnums((FuncExpr *) arg1, outerrel, innerrel,
377-
&outer_spoint, &inner_spoint);
378-
379-
create_crossmatch_path(root, joinrel, outer_path, inner_path,
380-
param_info, restrict_clauses, required_outer,
381-
get_const_val((Const *) arg2),
382-
outer_spoint, inner_spoint);
383-
401+
try_crossmatch_path(restrInfo, (FuncExpr *) arg1, (Const *) arg2,
402+
root, joinrel, outerrel, innerrel, extra);
384403
break;
385404
}
386405
else if (opExpr->opno == get_commutator(Float8LessOperator) &&
387406
IsA(arg1, Const) && IsVarSpointDist(arg2, dist_func))
388407
{
389-
AttrNumber outer_spoint,
390-
inner_spoint;
391-
392-
/* TODO: merge duplicate code */
393-
Path *outer_path = crossmatch_find_cheapest_path(root, joinrel, outerrel);
394-
Path *inner_path = crossmatch_find_cheapest_path(root, joinrel, innerrel);
395-
396-
Relids required_outer = calc_nestloop_required_outer(outer_path, inner_path);
397-
398-
ParamPathInfo *param_info = get_joinrel_parampathinfo(root,
399-
joinrel,
400-
outer_path,
401-
inner_path,
402-
extra->sjinfo,
403-
required_outer,
404-
&restrict_clauses);
405-
406-
get_spoint_attnums((FuncExpr *) arg2, outerrel, innerrel,
407-
&outer_spoint, &inner_spoint);
408-
409-
create_crossmatch_path(root, joinrel, outer_path, inner_path,
410-
param_info, restrict_clauses, required_outer,
411-
get_const_val((Const *) arg1),
412-
outer_spoint, inner_spoint);
408+
try_crossmatch_path(restrInfo, (FuncExpr *) arg2, (Const *) arg1,
409+
root, joinrel, outerrel, innerrel, extra);
410+
break;
413411
}
414412
}
415413
}
@@ -433,7 +431,7 @@ create_crossmatch_plan(PlannerInfo *root,
433431

434432
cscan = makeNode(CustomScan);
435433
cscan->scan.plan.targetlist = tlist;
436-
cscan->scan.plan.qual = NIL;
434+
cscan->scan.plan.qual = joinclauses;
437435
cscan->scan.scanrelid = 0;
438436
cscan->custom_scan_tlist = tlist; /* output of this node */
439437

@@ -516,7 +514,7 @@ static TupleTableSlot *
516514
crossmatch_exec(CustomScanState *node)
517515
{
518516
CrossmatchScanState *scan_state = (CrossmatchScanState *) node;
519-
TupleTableSlot *slot = node->ss.ss_ScanTupleSlot;
517+
TupleTableSlot *scanSlot = node->ss.ss_ScanTupleSlot;
520518
HeapTuple htup = scan_state->stored_tuple;
521519

522520
for(;;)
@@ -594,37 +592,43 @@ crossmatch_exec(CustomScanState *node)
594592

595593
htup = heap_form_tuple(tupdesc, values, nulls);
596594
scan_state->stored_tuple = htup;
595+
596+
/* Fill scanSlot with a new tuple */
597+
ExecStoreTuple(htup, scanSlot, InvalidBuffer, false);
597598
}
598599
}
599600

600601
if (node->ss.ps.ps_ProjInfo)
601602
{
602603
ExprDoneCond isDone;
603-
TupleTableSlot *result;
604+
TupleTableSlot *resultSlot;
604605

605606
ResetExprContext(node->ss.ps.ps_ProjInfo->pi_exprContext);
606607

607-
/* TODO: find a better way to fill 'ecxt_scantuple' */
608-
node->ss.ps.ps_ProjInfo->pi_exprContext->ecxt_scantuple = ExecStoreTuple(htup, slot, InvalidBuffer, false);
608+
/* Check join conditions */
609+
node->ss.ps.ps_ExprContext->ecxt_scantuple = scanSlot;
610+
if (!ExecQual(node->ss.ps.qual, node->ss.ps.ps_ExprContext, false))
611+
continue;
609612

610-
result = ExecProject(node->ss.ps.ps_ProjInfo, &isDone);
613+
node->ss.ps.ps_ProjInfo->pi_exprContext->ecxt_scantuple = scanSlot;
614+
resultSlot = ExecProject(node->ss.ps.ps_ProjInfo, &isDone);
611615

612616
if (isDone != ExprEndResult)
613617
{
614618
node->ss.ps.ps_TupFromTlist = (isDone == ExprMultipleResult);
615-
return result;
619+
return resultSlot;
616620
}
617621
else
618622
node->ss.ps.ps_TupFromTlist = false;
619623
}
620624
else
621625
{
622-
TupleTableSlot *result;
623-
624-
result = ExecStoreTuple(htup, node->ss.ps.ps_ResultTupleSlot,
625-
InvalidBuffer, false);
626+
ExecStoreTuple(htup, scanSlot, InvalidBuffer, false);
626627

627-
return result;
628+
/* Check join conditions */
629+
node->ss.ps.ps_ExprContext->ecxt_scantuple = scanSlot;
630+
if (ExecQual(node->ss.ps.qual, node->ss.ps.ps_ExprContext, false))
631+
return scanSlot;
628632
}
629633
}
630634
}

0 commit comments

Comments
 (0)