1616#include "catalog/pg_proc.h"
1717#include "catalog/pg_operator.h"
1818#include "commands/explain.h"
19+ #include "commands/defrem.h"
1920#include "funcapi.h"
2021
2122#include "access/htup_details.h"
@@ -43,6 +44,8 @@ typedef struct
4344Oid inner_rel ;
4445
4546List * joinrestrictinfo ;
47+
48+ float8 threshold ;
4649}CrossmatchJoinPath ;
4750
4851typedef struct
@@ -65,6 +68,8 @@ typedef struct
6568HeapTuple inner_tup ;
6669Relation inner ;
6770
71+ float8 threshold ;
72+
6873CrossmatchContext * ctx ;
6974}CrossmatchScanState ;
7075
@@ -73,6 +78,23 @@ static CustomScanMethodscrossmatch_plan_methods;
7378static CustomExecMethods crossmatch_exec_methods ;
7479
7580
81+ static float8
82+ get_const_val (Const * node )
83+ {
84+ FmgrInfo finfo ;
85+ Oid cast ;
86+
87+ Assert (IsA (node ,Const ));
88+
89+ if (node -> consttype == FLOAT8OID )
90+ return DatumGetFloat8 (node -> constvalue );
91+
92+ cast = get_cast_oid (node -> consttype ,FLOAT8OID , false);
93+ fmgr_info (cast ,& finfo );
94+
95+ return DatumGetFloat8 (FunctionCall1 (& finfo ,node -> constvalue ));
96+ }
97+
7698/*
7799 * TODO: check for the predicates & decide
78100 * whether some partial indices may suffice
@@ -174,7 +196,8 @@ create_crossmatch_path(PlannerInfo *root,
174196Path * inner_path ,
175197ParamPathInfo * param_info ,
176198List * restrict_clauses ,
177- Relids required_outer )
199+ Relids required_outer ,
200+ float8 threshold )
178201{
179202CrossmatchJoinPath * result ;
180203
@@ -207,6 +230,7 @@ create_crossmatch_path(PlannerInfo *root,
207230result -> inner_path = inner_path ;
208231result -> inner_idx = inner_idx ;
209232result -> inner_rel = inner_rel ;
233+ result -> threshold = threshold ;
210234result -> joinrestrictinfo = restrict_clauses ;
211235
212236/* TODO: real costs */
@@ -292,7 +316,8 @@ join_pathlist_hook(PlannerInfo *root,
292316& restrict_clauses );
293317
294318create_crossmatch_path (root ,joinrel ,outer_path ,inner_path ,
295- param_info ,restrict_clauses ,required_outer );
319+ param_info ,restrict_clauses ,required_outer ,
320+ get_const_val ((Const * )arg2 ));
296321
297322break ;
298323}
@@ -316,7 +341,8 @@ join_pathlist_hook(PlannerInfo *root,
316341& restrict_clauses );
317342
318343create_crossmatch_path (root ,joinrel ,outer_path ,inner_path ,
319- param_info ,restrict_clauses ,required_outer );
344+ param_info ,restrict_clauses ,required_outer ,
345+ get_const_val ((Const * )arg1 ));
320346}
321347}
322348}
@@ -335,6 +361,7 @@ create_crossmatch_plan(PlannerInfo *root,
335361List * joinclauses ;/* NOTE: do we really need it? */
336362List * otherclauses ;
337363CustomScan * cscan ;
364+ float8 * threshold = palloc (sizeof (float8 ));
338365
339366if (IS_OUTER_JOIN (gpath -> jointype ))
340367{
@@ -357,10 +384,12 @@ create_crossmatch_plan(PlannerInfo *root,
357384cscan -> flags = best_path -> flags ;
358385cscan -> methods = & crossmatch_plan_methods ;
359386
360- cscan -> custom_private = list_make4_oid (gpath -> outer_idx ,
361- gpath -> outer_rel ,
362- gpath -> inner_idx ,
363- gpath -> inner_rel );
387+ cscan -> custom_private = list_make2 (list_make4_oid (gpath -> outer_idx ,
388+ gpath -> outer_rel ,
389+ gpath -> inner_idx ,
390+ gpath -> inner_rel ),
391+ list_make1 (threshold ));
392+ * threshold = gpath -> threshold ;
364393
365394return & cscan -> scan .plan ;
366395}
@@ -379,10 +408,11 @@ crossmatch_create_scan_state(CustomScan *node)
379408
380409scan_state -> scan_tlist = node -> custom_scan_tlist ;
381410
382- scan_state -> outer_idx = linitial_oid (node -> custom_private );
383- scan_state -> outer_rel = lsecond_oid (node -> custom_private );
384- scan_state -> inner_idx = lthird_oid (node -> custom_private );
385- scan_state -> inner_rel = lfourth_oid (node -> custom_private );
411+ scan_state -> outer_idx = linitial_oid (linitial (node -> custom_private ));
412+ scan_state -> outer_rel = lsecond_oid (linitial (node -> custom_private ));
413+ scan_state -> inner_idx = lthird_oid (linitial (node -> custom_private ));
414+ scan_state -> inner_rel = lfourth_oid (linitial (node -> custom_private ));
415+ scan_state -> threshold = * (float8 * )linitial (lsecond (node -> custom_private ));
386416
387417return (Node * )scan_state ;
388418}
@@ -394,7 +424,8 @@ crossmatch_begin(CustomScanState *node, EState *estate, int eflags)
394424CrossmatchContext * ctx = (CrossmatchContext * )palloc0 (sizeof (CrossmatchContext ));
395425
396426scan_state -> ctx = ctx ;
397- setupFirstcall (ctx ,scan_state -> outer_idx ,scan_state -> inner_idx ,1 );
427+ setupFirstcall (ctx ,scan_state -> outer_idx ,
428+ scan_state -> inner_idx ,scan_state -> threshold );
398429
399430scan_state -> outer = heap_open (scan_state -> outer_rel ,AccessShareLock );
400431scan_state -> inner = heap_open (scan_state -> inner_rel ,AccessShareLock );