16
16
#include "catalog/pg_proc.h"
17
17
#include "catalog/pg_operator.h"
18
18
#include "commands/explain.h"
19
+ #include "commands/defrem.h"
19
20
#include "funcapi.h"
20
21
21
22
#include "access/htup_details.h"
@@ -43,6 +44,8 @@ typedef struct
43
44
Oid inner_rel ;
44
45
45
46
List * joinrestrictinfo ;
47
+
48
+ float8 threshold ;
46
49
}CrossmatchJoinPath ;
47
50
48
51
typedef struct
@@ -65,6 +68,8 @@ typedef struct
65
68
HeapTuple inner_tup ;
66
69
Relation inner ;
67
70
71
+ float8 threshold ;
72
+
68
73
CrossmatchContext * ctx ;
69
74
}CrossmatchScanState ;
70
75
@@ -73,6 +78,23 @@ static CustomScanMethodscrossmatch_plan_methods;
73
78
static CustomExecMethods crossmatch_exec_methods ;
74
79
75
80
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
+
76
98
/*
77
99
* TODO: check for the predicates & decide
78
100
* whether some partial indices may suffice
@@ -174,7 +196,8 @@ create_crossmatch_path(PlannerInfo *root,
174
196
Path * inner_path ,
175
197
ParamPathInfo * param_info ,
176
198
List * restrict_clauses ,
177
- Relids required_outer )
199
+ Relids required_outer ,
200
+ float8 threshold )
178
201
{
179
202
CrossmatchJoinPath * result ;
180
203
@@ -207,6 +230,7 @@ create_crossmatch_path(PlannerInfo *root,
207
230
result -> inner_path = inner_path ;
208
231
result -> inner_idx = inner_idx ;
209
232
result -> inner_rel = inner_rel ;
233
+ result -> threshold = threshold ;
210
234
result -> joinrestrictinfo = restrict_clauses ;
211
235
212
236
/* TODO: real costs */
@@ -292,7 +316,8 @@ join_pathlist_hook(PlannerInfo *root,
292
316
& restrict_clauses );
293
317
294
318
create_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 ));
296
321
297
322
break ;
298
323
}
@@ -316,7 +341,8 @@ join_pathlist_hook(PlannerInfo *root,
316
341
& restrict_clauses );
317
342
318
343
create_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 ));
320
346
}
321
347
}
322
348
}
@@ -335,6 +361,7 @@ create_crossmatch_plan(PlannerInfo *root,
335
361
List * joinclauses ;/* NOTE: do we really need it? */
336
362
List * otherclauses ;
337
363
CustomScan * cscan ;
364
+ float8 * threshold = palloc (sizeof (float8 ));
338
365
339
366
if (IS_OUTER_JOIN (gpath -> jointype ))
340
367
{
@@ -357,10 +384,12 @@ create_crossmatch_plan(PlannerInfo *root,
357
384
cscan -> flags = best_path -> flags ;
358
385
cscan -> methods = & crossmatch_plan_methods ;
359
386
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 ;
364
393
365
394
return & cscan -> scan .plan ;
366
395
}
@@ -379,10 +408,11 @@ crossmatch_create_scan_state(CustomScan *node)
379
408
380
409
scan_state -> scan_tlist = node -> custom_scan_tlist ;
381
410
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 ));
386
416
387
417
return (Node * )scan_state ;
388
418
}
@@ -394,7 +424,8 @@ crossmatch_begin(CustomScanState *node, EState *estate, int eflags)
394
424
CrossmatchContext * ctx = (CrossmatchContext * )palloc0 (sizeof (CrossmatchContext ));
395
425
396
426
scan_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 );
398
429
399
430
scan_state -> outer = heap_open (scan_state -> outer_rel ,AccessShareLock );
400
431
scan_state -> inner = heap_open (scan_state -> inner_rel ,AccessShareLock );