26#include "utils/fmgrprotos.h"
33#define DEFAULT_OVERLAP_SEL 0.01
36#define DEFAULT_INCLUSION_SEL 0.005
39#define DEFAULT_SEL(operator) \
40 ((operator) == OID_INET_OVERLAP_OP ? \
41 DEFAULT_OVERLAP_SEL : DEFAULT_INCLUSION_SEL)
44#define MAX_CONSIDERED_ELEMS 1024
52 Datum constvalue,
int opr_codenum);
54 float4 *mcv1_numbers,
int mcv1_nvalues,
Datum *mcv2_values,
55 float4 *mcv2_numbers,
int mcv2_nvalues,
Oid operator);
57 int mcv_nvalues,
Datum *hist_values,
int hist_nvalues,
61 Datum *hist2_values,
int hist2_nvalues,
64 bool mcv_exists,
Datum *mcv_values,
int mcv_nvalues,
65 bool hist_exists,
Datum *hist_values,
int hist_nvalues,
103 &vardata, &other, &varonleft))
116 if (((
Const *) other)->constisnull)
121 constvalue = ((
Const *) other)->constvalue;
131 nullfrac = stats->stanullfrac;
141 constvalue, varonleft,
157 opr_codenum = -opr_codenum;
159 constvalue, opr_codenum);
167 selec = mcv_selec + (1.0 - nullfrac - sumcommon) * non_mcv_selec;
208 bool join_is_reversed;
211 &vardata1, &vardata2, &join_is_reversed);
228 if (!join_is_reversed)
232 &vardata2, &vardata1);
236 elog(
ERROR,
"unrecognized join type: %d",
267 double nullfrac1 = 0.0,
272 bool mcv1_exists =
false,
274 hist1_exists =
false,
275 hist2_exists =
false;
287 nullfrac1 = stats->stanullfrac;
302 memset(&mcv1_slot, 0,
sizeof(mcv1_slot));
303 memset(&hist1_slot, 0,
sizeof(hist1_slot));
309 nullfrac2 = stats->stanullfrac;
324 memset(&mcv2_slot, 0,
sizeof(mcv2_slot));
325 memset(&hist2_slot, 0,
sizeof(hist2_slot));
333 if (mcv1_exists && mcv2_exists)
345 if (mcv1_exists && hist2_exists)
346 selec += (1.0 - nullfrac2 - sumcommon2) *
350 if (mcv2_exists && hist1_exists)
351 selec += (1.0 - nullfrac1 - sumcommon1) *
360 if (hist1_exists && hist2_exists)
361 selec += (1.0 - nullfrac1 - sumcommon1) *
362 (1.0 - nullfrac2 - sumcommon2) *
371 if ((!mcv1_exists && !hist1_exists) || (!mcv2_exists && !hist2_exists))
372 selec = (1.0 - nullfrac1) * (1.0 - nullfrac2) *
DEFAULT_SEL(
operator);
397 double nullfrac1 = 0.0,
400 bool mcv1_exists =
false,
402 hist1_exists =
false,
403 hist2_exists =
false;
417 nullfrac1 = stats->stanullfrac;
432 memset(&mcv1_slot, 0,
sizeof(mcv1_slot));
433 memset(&hist1_slot, 0,
sizeof(hist1_slot));
439 nullfrac2 = stats->stanullfrac;
454 memset(&mcv2_slot, 0,
sizeof(mcv2_slot));
455 memset(&hist2_slot, 0,
sizeof(hist2_slot));
462 if (hist2_exists && vardata2->
rel)
463 hist2_weight = (1.0 - nullfrac2 - sumcommon2) * vardata2->
rel->
rows;
469 if (mcv1_exists && (mcv2_exists || hist2_exists))
471 for (
i = 0;
i < mcv1_length;
i++)
475 mcv2_exists, mcv2_slot.
values, mcv2_length,
494 if (hist1_exists && hist1_slot.
nvalues > 2 && (mcv2_exists || hist2_exists))
496 double hist_selec_sum = 0.0;
503 for (
i = 1;
i < hist1_slot.
nvalues - 1;
i += k)
507 mcv2_exists, mcv2_slot.
values, mcv2_length,
515 selec += (1.0 - nullfrac1 - sumcommon1) * hist_selec_sum / n;
522 if ((!mcv1_exists && !hist1_exists) || (!mcv2_exists && !hist2_exists))
523 selec = (1.0 - nullfrac1) * (1.0 - nullfrac2) *
DEFAULT_SEL(
operator);
544 for (
i = 0;
i < mcv_nvalues;
i++)
546 sumcommon += mcv_numbers[
i];
633 for (
i = k;
i < nvalues;
i += k)
639 if (left_order == 0 && right_order == 0)
644 else if ((left_order <= 0 && right_order >= 0) ||
645 (left_order >= 0 && right_order <= 0))
651 if (left_divider >= 0 || right_divider >= 0)
652 match += 1.0 / pow(2.0,
Max(left_divider, right_divider));
657 left_order = right_order;
674 Datum *mcv2_values,
float4 *mcv2_numbers,
int mcv2_nvalues,
684 for (
i = 0;
i < mcv1_nvalues;
i++)
686 for (
j = 0;
j < mcv2_nvalues;
j++)
690 selec += mcv1_numbers[
i] * mcv2_numbers[
j];
706 Datum *hist_values,
int hist_nvalues,
716 opr_codenum = -opr_codenum;
718 for (
i = 0;
i < mcv_nvalues;
i++)
720 selec += mcv_numbers[
i] *
743 Datum *hist2_values,
int hist2_nvalues,
751 if (hist2_nvalues <= 2)
758 for (
i = 1;
i < hist2_nvalues - 1;
i += k)
761 hist2_values[
i], opr_codenum);
794 bool mcv_exists,
Datum *mcv_values,
int mcv_nvalues,
795 bool hist_exists,
Datum *hist_values,
int hist_nvalues,
803 for (
i = 0;
i < mcv_nvalues;
i++)
812 if (hist_exists && hist_weight > 0)
818 lhs_value, -opr_codenum);
821 return Min(1.0, hist_weight * hist_selec);
840 case OID_INET_SUP_OP:
842 case OID_INET_SUPEQ_OP:
844 case OID_INET_OVERLAP_OP:
846 case OID_INET_SUBEQ_OP:
848 case OID_INET_SUB_OP:
851 elog(
ERROR,
"unrecognized operator %u for inet selectivity",
915 if ((order > 0 && opr_codenum >= 0) ||
916 (order == 0 && opr_codenum >= -1 && opr_codenum <= 1) ||
917 (order < 0 && opr_codenum <= 0))
954 decisive_bits =
ip_bits(boundary);
955 else if (opr_codenum > 0)
956 decisive_bits =
ip_bits(query);
958 decisive_bits = min_bits;
968 return decisive_bits;
static Datum values[MAXATTR]
void fmgr_info(Oid functionId, FmgrInfo *finfo)
#define PG_RETURN_FLOAT8(x)
#define PG_GETARG_POINTER(n)
#define FunctionCall2(flinfo, arg1, arg2)
#define PG_GETARG_INT32(n)
#define PG_GETARG_INT16(n)
#define HeapTupleIsValid(tuple)
if(TABLE==NULL||TABLE_index==NULL)
void free_attstatsslot(AttStatsSlot *sslot)
RegProcedure get_opcode(Oid opno)
bool get_attstatsslot(AttStatsSlot *sslot, HeapTuple statstuple, int reqkind, Oid reqop, int flags)
Oid get_commutator(Oid opno)
#define ATTSTATSSLOT_NUMBERS
#define ATTSTATSSLOT_VALUES
int bitncommon(const unsigned char *l, const unsigned char *r, int n)
int bitncmp(const unsigned char *l, const unsigned char *r, int n)
static int inet_inclusion_cmp(inet *left, inet *right, int opr_codenum)
static int inet_opr_codenum(Oid operator)
static Selectivity networkjoinsel_semi(Oid operator, VariableStatData *vardata1, VariableStatData *vardata2)
static Selectivity inet_semi_join_sel(Datum lhs_value, bool mcv_exists, Datum *mcv_values, int mcv_nvalues, bool hist_exists, Datum *hist_values, int hist_nvalues, double hist_weight, FmgrInfo *proc, int opr_codenum)
static int inet_masklen_inclusion_cmp(inet *left, inet *right, int opr_codenum)
Datum networksel(PG_FUNCTION_ARGS)
static Selectivity mcv_population(float4 *mcv_numbers, int mcv_nvalues)
static Selectivity inet_mcv_join_sel(Datum *mcv1_values, float4 *mcv1_numbers, int mcv1_nvalues, Datum *mcv2_values, float4 *mcv2_numbers, int mcv2_nvalues, Oid operator)
Datum networkjoinsel(PG_FUNCTION_ARGS)
static Selectivity inet_hist_value_sel(Datum *values, int nvalues, Datum constvalue, int opr_codenum)
static Selectivity inet_mcv_hist_sel(Datum *mcv_values, float4 *mcv_numbers, int mcv_nvalues, Datum *hist_values, int hist_nvalues, int opr_codenum)
#define MAX_CONSIDERED_ELEMS
static int inet_hist_match_divider(inet *boundary, inet *query, int opr_codenum)
static Selectivity networkjoinsel_inner(Oid operator, VariableStatData *vardata1, VariableStatData *vardata2)
#define DEFAULT_SEL(operator)
static Selectivity inet_hist_inclusion_join_sel(Datum *hist1_values, int hist1_nvalues, Datum *hist2_values, int hist2_nvalues, int opr_codenum)
#define IsA(nodeptr, _type_)
FormData_pg_statistic * Form_pg_statistic
static bool DatumGetBool(Datum X)
bool get_restriction_variable(PlannerInfo *root, List *args, int varRelid, VariableStatData *vardata, Node **other, bool *varonleft)
double mcv_selectivity(VariableStatData *vardata, FmgrInfo *opproc, Oid collation, Datum constval, bool varonleft, double *sumcommonp)
void get_join_variables(PlannerInfo *root, List *args, SpecialJoinInfo *sjinfo, VariableStatData *vardata1, VariableStatData *vardata2, bool *join_is_reversed)
#define ReleaseVariableStats(vardata)
#define CLAMP_PROBABILITY(p)
static inet * DatumGetInetPP(Datum X)
#define ip_family(inetptr)