@@ -281,6 +281,30 @@ eqsel_internal(PG_FUNCTION_ARGS, bool negate)
281281 return selec ;
282282}
283283
284+ /*
285+ * Call binary boolean function, converting NULL result to FALSE
286+ */
287+ static bool
288+ BoolFunctionCall2Coll (FmgrInfo * flinfo , Oid collation , Datum arg1 , Datum arg2 )
289+ {
290+ LOCAL_FCINFO (fcinfo , 2 );
291+ Datum result ;
292+
293+ InitFunctionCallInfoData (* fcinfo , flinfo , 2 , collation , NULL , NULL );
294+
295+ fcinfo -> args [0 ].value = arg1 ;
296+ fcinfo -> args [0 ].isnull = false;
297+ fcinfo -> args [1 ].value = arg2 ;
298+ fcinfo -> args [1 ].isnull = false;
299+
300+ result = FunctionCallInvoke (fcinfo );
301+
302+ if (fcinfo -> isnull )
303+ return false;
304+
305+ return DatumGetBool (result );
306+ }
307+
284308/*
285309 * var_eq_const --- eqsel for var = const case
286310 *
@@ -353,15 +377,15 @@ var_eq_const(VariableStatData *vardata, Oid operator,
353377 {
354378 /* be careful to apply operator right way 'round */
355379 if (varonleft )
356- match = DatumGetBool ( FunctionCall2Coll (& eqproc ,
357- sslot .stacoll ,
358- sslot .values [i ],
359- constval ) );
380+ match = BoolFunctionCall2Coll (& eqproc ,
381+ sslot .stacoll ,
382+ sslot .values [i ],
383+ constval );
360384 else
361- match = DatumGetBool ( FunctionCall2Coll (& eqproc ,
362- sslot .stacoll ,
363- constval ,
364- sslot .values [i ]) );
385+ match = BoolFunctionCall2Coll (& eqproc ,
386+ sslot .stacoll ,
387+ constval ,
388+ sslot .values [i ]);
365389 if (match )
366390 break ;
367391 }
@@ -726,14 +750,14 @@ mcv_selectivity(VariableStatData *vardata, FmgrInfo *opproc,
726750 for (i = 0 ; i < sslot .nvalues ; i ++ )
727751 {
728752 if (varonleft ?
729- DatumGetBool ( FunctionCall2Coll (opproc ,
730- sslot .stacoll ,
731- sslot .values [i ],
732- constval ) ) :
733- DatumGetBool ( FunctionCall2Coll (opproc ,
734- sslot .stacoll ,
735- constval ,
736- sslot .values [i ]) ))
753+ BoolFunctionCall2Coll (opproc ,
754+ sslot .stacoll ,
755+ sslot .values [i ],
756+ constval ) :
757+ BoolFunctionCall2Coll (opproc ,
758+ sslot .stacoll ,
759+ constval ,
760+ sslot .values [i ]))
737761 mcv_selec += sslot .numbers [i ];
738762 sumcommon += sslot .numbers [i ];
739763 }
@@ -804,14 +828,14 @@ histogram_selectivity(VariableStatData *vardata, FmgrInfo *opproc,
804828 for (i = n_skip ; i < sslot .nvalues - n_skip ; i ++ )
805829 {
806830 if (varonleft ?
807- DatumGetBool ( FunctionCall2Coll (opproc ,
808- sslot .stacoll ,
809- sslot .values [i ],
810- constval ) ) :
811- DatumGetBool ( FunctionCall2Coll (opproc ,
812- sslot .stacoll ,
813- constval ,
814- sslot .values [i ]) ))
831+ BoolFunctionCall2Coll (opproc ,
832+ sslot .stacoll ,
833+ sslot .values [i ],
834+ constval ) :
835+ BoolFunctionCall2Coll (opproc ,
836+ sslot .stacoll ,
837+ constval ,
838+ sslot .values [i ]))
815839 nmatch ++ ;
816840 }
817841 result = ((double ) nmatch ) / ((double ) (sslot .nvalues - 2 * n_skip ));
@@ -2329,10 +2353,10 @@ eqjoinsel_inner(Oid opfuncoid,
23292353 {
23302354 if (hasmatch2 [j ])
23312355 continue ;
2332- if (DatumGetBool ( FunctionCall2Coll (& eqproc ,
2333- sslot1 -> stacoll ,
2334- sslot1 -> values [i ],
2335- sslot2 -> values [j ]) ))
2356+ if (BoolFunctionCall2Coll (& eqproc ,
2357+ sslot1 -> stacoll ,
2358+ sslot1 -> values [i ],
2359+ sslot2 -> values [j ]))
23362360 {
23372361 hasmatch1 [i ] = hasmatch2 [j ] = true;
23382362 matchprodfreq += sslot1 -> numbers [i ] * sslot2 -> numbers [j ];
@@ -2541,10 +2565,10 @@ eqjoinsel_semi(Oid opfuncoid,
25412565 {
25422566 if (hasmatch2 [j ])
25432567 continue ;
2544- if (DatumGetBool ( FunctionCall2Coll (& eqproc ,
2545- sslot1 -> stacoll ,
2546- sslot1 -> values [i ],
2547- sslot2 -> values [j ]) ))
2568+ if (BoolFunctionCall2Coll (& eqproc ,
2569+ sslot1 -> stacoll ,
2570+ sslot1 -> values [i ],
2571+ sslot2 -> values [j ]))
25482572 {
25492573 hasmatch1 [i ] = hasmatch2 [j ] = true;
25502574 nmatches ++ ;
0 commit comments