1 /*-------------------------------------------------------------------------
2  *
3  * network_selfuncs.c
4  *	  Functions for selectivity estimation of inet/cidr operators
5  *
6  * This module provides estimators for the subnet inclusion and overlap
7  * operators.  Estimates are based on null fraction, most common values,
8  * and histogram of inet/cidr columns.
9  *
10  * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group
11  * Portions Copyright (c) 1994, Regents of the University of California
12  *
13  *
14  * IDENTIFICATION
15  *	  src/backend/utils/adt/network_selfuncs.c
16  *
17  *-------------------------------------------------------------------------
18  */
19 #include "postgres.h"
20 
21 #include <math.h>
22 
23 #include "access/htup_details.h"
24 #include "catalog/pg_operator.h"
25 #include "catalog/pg_statistic.h"
26 #include "utils/builtins.h"
27 #include "utils/inet.h"
28 #include "utils/lsyscache.h"
29 #include "utils/selfuncs.h"
30 
31 
32 /* Default selectivity for the inet overlap operator */
33 #define DEFAULT_OVERLAP_SEL 0.01
34 
35 /* Default selectivity for the various inclusion operators */
36 #define DEFAULT_INCLUSION_SEL 0.005
37 
38 /* Default selectivity for specified operator */
39 #define DEFAULT_SEL(operator) \
40 	((operator) == OID_INET_OVERLAP_OP ? \
41 	 DEFAULT_OVERLAP_SEL : DEFAULT_INCLUSION_SEL)
42 
43 /* Maximum number of items to consider in join selectivity calculations */
44 #define MAX_CONSIDERED_ELEMS 1024
45 
46 static Selectivity networkjoinsel_inner(Oid operator,
47 					 VariableStatData *vardata1, VariableStatData *vardata2);
48 static Selectivity networkjoinsel_semi(Oid operator,
49 					VariableStatData *vardata1, VariableStatData *vardata2);
50 static Selectivity mcv_population(float4 *mcv_numbers, int mcv_nvalues);
51 static Selectivity inet_hist_value_sel(Datum *values, int nvalues,
52 					Datum constvalue, int opr_codenum);
53 static Selectivity inet_mcv_join_sel(Datum *mcv1_values,
54 				  float4 *mcv1_numbers, int mcv1_nvalues, Datum *mcv2_values,
55 				  float4 *mcv2_numbers, int mcv2_nvalues, Oid operator);
56 static Selectivity inet_mcv_hist_sel(Datum *mcv_values, float4 *mcv_numbers,
57 				  int mcv_nvalues, Datum *hist_values, int hist_nvalues,
58 				  int opr_codenum);
59 static Selectivity inet_hist_inclusion_join_sel(Datum *hist1_values,
60 							 int hist1_nvalues,
61 							 Datum *hist2_values, int hist2_nvalues,
62 							 int opr_codenum);
63 static Selectivity inet_semi_join_sel(Datum lhs_value,
64 				   bool mcv_exists, Datum *mcv_values, int mcv_nvalues,
65 				   bool hist_exists, Datum *hist_values, int hist_nvalues,
66 				   double hist_weight,
67 				   FmgrInfo *proc, int opr_codenum);
68 static int	inet_opr_codenum(Oid operator);
69 static int	inet_inclusion_cmp(inet *left, inet *right, int opr_codenum);
70 static int inet_masklen_inclusion_cmp(inet *left, inet *right,
71 						   int opr_codenum);
72 static int inet_hist_match_divider(inet *boundary, inet *query,
73 						int opr_codenum);
74 
75 /*
76  * Selectivity estimation for the subnet inclusion/overlap operators
77  */
78 Datum
networksel(PG_FUNCTION_ARGS)79 networksel(PG_FUNCTION_ARGS)
80 {
81 	PlannerInfo *root = (PlannerInfo *) PG_GETARG_POINTER(0);
82 	Oid			operator = PG_GETARG_OID(1);
83 	List	   *args = (List *) PG_GETARG_POINTER(2);
84 	int			varRelid = PG_GETARG_INT32(3);
85 	VariableStatData vardata;
86 	Node	   *other;
87 	bool		varonleft;
88 	Selectivity selec,
89 				mcv_selec,
90 				non_mcv_selec;
91 	Datum		constvalue;
92 	Form_pg_statistic stats;
93 	AttStatsSlot hslot;
94 	double		sumcommon,
95 				nullfrac;
96 	FmgrInfo	proc;
97 
98 	/*
99 	 * If expression is not (variable op something) or (something op
100 	 * variable), then punt and return a default estimate.
101 	 */
102 	if (!get_restriction_variable(root, args, varRelid,
103 								  &vardata, &other, &varonleft))
104 		PG_RETURN_FLOAT8(DEFAULT_SEL(operator));
105 
106 	/*
107 	 * Can't do anything useful if the something is not a constant, either.
108 	 */
109 	if (!IsA(other, Const))
110 	{
111 		ReleaseVariableStats(vardata);
112 		PG_RETURN_FLOAT8(DEFAULT_SEL(operator));
113 	}
114 
115 	/* All of the operators handled here are strict. */
116 	if (((Const *) other)->constisnull)
117 	{
118 		ReleaseVariableStats(vardata);
119 		PG_RETURN_FLOAT8(0.0);
120 	}
121 	constvalue = ((Const *) other)->constvalue;
122 
123 	/* Otherwise, we need stats in order to produce a non-default estimate. */
124 	if (!HeapTupleIsValid(vardata.statsTuple))
125 	{
126 		ReleaseVariableStats(vardata);
127 		PG_RETURN_FLOAT8(DEFAULT_SEL(operator));
128 	}
129 
130 	stats = (Form_pg_statistic) GETSTRUCT(vardata.statsTuple);
131 	nullfrac = stats->stanullfrac;
132 
133 	/*
134 	 * If we have most-common-values info, add up the fractions of the MCV
135 	 * entries that satisfy MCV OP CONST.  These fractions contribute directly
136 	 * to the result selectivity.  Also add up the total fraction represented
137 	 * by MCV entries.
138 	 */
139 	fmgr_info(get_opcode(operator), &proc);
140 	mcv_selec = mcv_selectivity(&vardata, &proc, constvalue, varonleft,
141 								&sumcommon);
142 
143 	/*
144 	 * If we have a histogram, use it to estimate the proportion of the
145 	 * non-MCV population that satisfies the clause.  If we don't, apply the
146 	 * default selectivity to that population.
147 	 */
148 	if (get_attstatsslot(&hslot, vardata.statsTuple,
149 						 STATISTIC_KIND_HISTOGRAM, InvalidOid,
150 						 ATTSTATSSLOT_VALUES))
151 	{
152 		int			opr_codenum = inet_opr_codenum(operator);
153 
154 		/* Commute if needed, so we can consider histogram to be on the left */
155 		if (!varonleft)
156 			opr_codenum = -opr_codenum;
157 		non_mcv_selec = inet_hist_value_sel(hslot.values, hslot.nvalues,
158 											constvalue, opr_codenum);
159 
160 		free_attstatsslot(&hslot);
161 	}
162 	else
163 		non_mcv_selec = DEFAULT_SEL(operator);
164 
165 	/* Combine selectivities for MCV and non-MCV populations */
166 	selec = mcv_selec + (1.0 - nullfrac - sumcommon) * non_mcv_selec;
167 
168 	/* Result should be in range, but make sure... */
169 	CLAMP_PROBABILITY(selec);
170 
171 	ReleaseVariableStats(vardata);
172 
173 	PG_RETURN_FLOAT8(selec);
174 }
175 
176 /*
177  * Join selectivity estimation for the subnet inclusion/overlap operators
178  *
179  * This function has the same structure as eqjoinsel() in selfuncs.c.
180  *
181  * Throughout networkjoinsel and its subroutines, we have a performance issue
182  * in that the amount of work to be done is O(N^2) in the length of the MCV
183  * and histogram arrays.  To keep the runtime from getting out of hand when
184  * large statistics targets have been set, we arbitrarily limit the number of
185  * values considered to 1024 (MAX_CONSIDERED_ELEMS).  For the MCV arrays, this
186  * is easy: just consider at most the first N elements.  (Since the MCVs are
187  * sorted by decreasing frequency, this correctly gets us the first N MCVs.)
188  * For the histogram arrays, we decimate; that is consider only every k'th
189  * element, where k is chosen so that no more than MAX_CONSIDERED_ELEMS
190  * elements are considered.  This should still give us a good random sample of
191  * the non-MCV population.  Decimation is done on-the-fly in the loops that
192  * iterate over the histogram arrays.
193  */
194 Datum
networkjoinsel(PG_FUNCTION_ARGS)195 networkjoinsel(PG_FUNCTION_ARGS)
196 {
197 	PlannerInfo *root = (PlannerInfo *) PG_GETARG_POINTER(0);
198 	Oid			operator = PG_GETARG_OID(1);
199 	List	   *args = (List *) PG_GETARG_POINTER(2);
200 #ifdef NOT_USED
201 	JoinType	jointype = (JoinType) PG_GETARG_INT16(3);
202 #endif
203 	SpecialJoinInfo *sjinfo = (SpecialJoinInfo *) PG_GETARG_POINTER(4);
204 	double		selec;
205 	VariableStatData vardata1;
206 	VariableStatData vardata2;
207 	bool		join_is_reversed;
208 
209 	get_join_variables(root, args, sjinfo,
210 					   &vardata1, &vardata2, &join_is_reversed);
211 
212 	switch (sjinfo->jointype)
213 	{
214 		case JOIN_INNER:
215 		case JOIN_LEFT:
216 		case JOIN_FULL:
217 
218 			/*
219 			 * Selectivity for left/full join is not exactly the same as inner
220 			 * join, but we neglect the difference, as eqjoinsel does.
221 			 */
222 			selec = networkjoinsel_inner(operator, &vardata1, &vardata2);
223 			break;
224 		case JOIN_SEMI:
225 		case JOIN_ANTI:
226 			/* Here, it's important that we pass the outer var on the left. */
227 			if (!join_is_reversed)
228 				selec = networkjoinsel_semi(operator, &vardata1, &vardata2);
229 			else
230 				selec = networkjoinsel_semi(get_commutator(operator),
231 											&vardata2, &vardata1);
232 			break;
233 		default:
234 			/* other values not expected here */
235 			elog(ERROR, "unrecognized join type: %d",
236 				 (int) sjinfo->jointype);
237 			selec = 0;			/* keep compiler quiet */
238 			break;
239 	}
240 
241 	ReleaseVariableStats(vardata1);
242 	ReleaseVariableStats(vardata2);
243 
244 	CLAMP_PROBABILITY(selec);
245 
246 	PG_RETURN_FLOAT8((float8) selec);
247 }
248 
249 /*
250  * Inner join selectivity estimation for subnet inclusion/overlap operators
251  *
252  * Calculates MCV vs MCV, MCV vs histogram and histogram vs histogram
253  * selectivity for join using the subnet inclusion operators.  Unlike the
254  * join selectivity function for the equality operator, eqjoinsel_inner(),
255  * one to one matching of the values is not enough.  Network inclusion
256  * operators are likely to match many to many, so we must check all pairs.
257  * (Note: it might be possible to exploit understanding of the histogram's
258  * btree ordering to reduce the work needed, but we don't currently try.)
259  * Also, MCV vs histogram selectivity is not neglected as in eqjoinsel_inner().
260  */
261 static Selectivity
networkjoinsel_inner(Oid operator,VariableStatData * vardata1,VariableStatData * vardata2)262 networkjoinsel_inner(Oid operator,
263 					 VariableStatData *vardata1, VariableStatData *vardata2)
264 {
265 	Form_pg_statistic stats;
266 	double		nullfrac1 = 0.0,
267 				nullfrac2 = 0.0;
268 	Selectivity selec = 0.0,
269 				sumcommon1 = 0.0,
270 				sumcommon2 = 0.0;
271 	bool		mcv1_exists = false,
272 				mcv2_exists = false,
273 				hist1_exists = false,
274 				hist2_exists = false;
275 	int			opr_codenum;
276 	int			mcv1_length = 0,
277 				mcv2_length = 0;
278 	AttStatsSlot mcv1_slot;
279 	AttStatsSlot mcv2_slot;
280 	AttStatsSlot hist1_slot;
281 	AttStatsSlot hist2_slot;
282 
283 	if (HeapTupleIsValid(vardata1->statsTuple))
284 	{
285 		stats = (Form_pg_statistic) GETSTRUCT(vardata1->statsTuple);
286 		nullfrac1 = stats->stanullfrac;
287 
288 		mcv1_exists = get_attstatsslot(&mcv1_slot, vardata1->statsTuple,
289 									   STATISTIC_KIND_MCV, InvalidOid,
290 									   ATTSTATSSLOT_VALUES | ATTSTATSSLOT_NUMBERS);
291 		hist1_exists = get_attstatsslot(&hist1_slot, vardata1->statsTuple,
292 										STATISTIC_KIND_HISTOGRAM, InvalidOid,
293 										ATTSTATSSLOT_VALUES);
294 		/* Arbitrarily limit number of MCVs considered */
295 		mcv1_length = Min(mcv1_slot.nvalues, MAX_CONSIDERED_ELEMS);
296 		if (mcv1_exists)
297 			sumcommon1 = mcv_population(mcv1_slot.numbers, mcv1_length);
298 	}
299 	else
300 	{
301 		memset(&mcv1_slot, 0, sizeof(mcv1_slot));
302 		memset(&hist1_slot, 0, sizeof(hist1_slot));
303 	}
304 
305 	if (HeapTupleIsValid(vardata2->statsTuple))
306 	{
307 		stats = (Form_pg_statistic) GETSTRUCT(vardata2->statsTuple);
308 		nullfrac2 = stats->stanullfrac;
309 
310 		mcv2_exists = get_attstatsslot(&mcv2_slot, vardata2->statsTuple,
311 									   STATISTIC_KIND_MCV, InvalidOid,
312 									   ATTSTATSSLOT_VALUES | ATTSTATSSLOT_NUMBERS);
313 		hist2_exists = get_attstatsslot(&hist2_slot, vardata2->statsTuple,
314 										STATISTIC_KIND_HISTOGRAM, InvalidOid,
315 										ATTSTATSSLOT_VALUES);
316 		/* Arbitrarily limit number of MCVs considered */
317 		mcv2_length = Min(mcv2_slot.nvalues, MAX_CONSIDERED_ELEMS);
318 		if (mcv2_exists)
319 			sumcommon2 = mcv_population(mcv2_slot.numbers, mcv2_length);
320 	}
321 	else
322 	{
323 		memset(&mcv2_slot, 0, sizeof(mcv2_slot));
324 		memset(&hist2_slot, 0, sizeof(hist2_slot));
325 	}
326 
327 	opr_codenum = inet_opr_codenum(operator);
328 
329 	/*
330 	 * Calculate selectivity for MCV vs MCV matches.
331 	 */
332 	if (mcv1_exists && mcv2_exists)
333 		selec += inet_mcv_join_sel(mcv1_slot.values, mcv1_slot.numbers,
334 								   mcv1_length,
335 								   mcv2_slot.values, mcv2_slot.numbers,
336 								   mcv2_length,
337 								   operator);
338 
339 	/*
340 	 * Add in selectivities for MCV vs histogram matches, scaling according to
341 	 * the fractions of the populations represented by the histograms. Note
342 	 * that the second case needs to commute the operator.
343 	 */
344 	if (mcv1_exists && hist2_exists)
345 		selec += (1.0 - nullfrac2 - sumcommon2) *
346 			inet_mcv_hist_sel(mcv1_slot.values, mcv1_slot.numbers, mcv1_length,
347 							  hist2_slot.values, hist2_slot.nvalues,
348 							  opr_codenum);
349 	if (mcv2_exists && hist1_exists)
350 		selec += (1.0 - nullfrac1 - sumcommon1) *
351 			inet_mcv_hist_sel(mcv2_slot.values, mcv2_slot.numbers, mcv2_length,
352 							  hist1_slot.values, hist1_slot.nvalues,
353 							  -opr_codenum);
354 
355 	/*
356 	 * Add in selectivity for histogram vs histogram matches, again scaling
357 	 * appropriately.
358 	 */
359 	if (hist1_exists && hist2_exists)
360 		selec += (1.0 - nullfrac1 - sumcommon1) *
361 			(1.0 - nullfrac2 - sumcommon2) *
362 			inet_hist_inclusion_join_sel(hist1_slot.values, hist1_slot.nvalues,
363 										 hist2_slot.values, hist2_slot.nvalues,
364 										 opr_codenum);
365 
366 	/*
367 	 * If useful statistics are not available then use the default estimate.
368 	 * We can apply null fractions if known, though.
369 	 */
370 	if ((!mcv1_exists && !hist1_exists) || (!mcv2_exists && !hist2_exists))
371 		selec = (1.0 - nullfrac1) * (1.0 - nullfrac2) * DEFAULT_SEL(operator);
372 
373 	/* Release stats. */
374 	free_attstatsslot(&mcv1_slot);
375 	free_attstatsslot(&mcv2_slot);
376 	free_attstatsslot(&hist1_slot);
377 	free_attstatsslot(&hist2_slot);
378 
379 	return selec;
380 }
381 
382 /*
383  * Semi join selectivity estimation for subnet inclusion/overlap operators
384  *
385  * Calculates MCV vs MCV, MCV vs histogram, histogram vs MCV, and histogram vs
386  * histogram selectivity for semi/anti join cases.
387  */
388 static Selectivity
networkjoinsel_semi(Oid operator,VariableStatData * vardata1,VariableStatData * vardata2)389 networkjoinsel_semi(Oid operator,
390 					VariableStatData *vardata1, VariableStatData *vardata2)
391 {
392 	Form_pg_statistic stats;
393 	Selectivity selec = 0.0,
394 				sumcommon1 = 0.0,
395 				sumcommon2 = 0.0;
396 	double		nullfrac1 = 0.0,
397 				nullfrac2 = 0.0,
398 				hist2_weight = 0.0;
399 	bool		mcv1_exists = false,
400 				mcv2_exists = false,
401 				hist1_exists = false,
402 				hist2_exists = false;
403 	int			opr_codenum;
404 	FmgrInfo	proc;
405 	int			i,
406 				mcv1_length = 0,
407 				mcv2_length = 0;
408 	AttStatsSlot mcv1_slot;
409 	AttStatsSlot mcv2_slot;
410 	AttStatsSlot hist1_slot;
411 	AttStatsSlot hist2_slot;
412 
413 	if (HeapTupleIsValid(vardata1->statsTuple))
414 	{
415 		stats = (Form_pg_statistic) GETSTRUCT(vardata1->statsTuple);
416 		nullfrac1 = stats->stanullfrac;
417 
418 		mcv1_exists = get_attstatsslot(&mcv1_slot, vardata1->statsTuple,
419 									   STATISTIC_KIND_MCV, InvalidOid,
420 									   ATTSTATSSLOT_VALUES | ATTSTATSSLOT_NUMBERS);
421 		hist1_exists = get_attstatsslot(&hist1_slot, vardata1->statsTuple,
422 										STATISTIC_KIND_HISTOGRAM, InvalidOid,
423 										ATTSTATSSLOT_VALUES);
424 		/* Arbitrarily limit number of MCVs considered */
425 		mcv1_length = Min(mcv1_slot.nvalues, MAX_CONSIDERED_ELEMS);
426 		if (mcv1_exists)
427 			sumcommon1 = mcv_population(mcv1_slot.numbers, mcv1_length);
428 	}
429 	else
430 	{
431 		memset(&mcv1_slot, 0, sizeof(mcv1_slot));
432 		memset(&hist1_slot, 0, sizeof(hist1_slot));
433 	}
434 
435 	if (HeapTupleIsValid(vardata2->statsTuple))
436 	{
437 		stats = (Form_pg_statistic) GETSTRUCT(vardata2->statsTuple);
438 		nullfrac2 = stats->stanullfrac;
439 
440 		mcv2_exists = get_attstatsslot(&mcv2_slot, vardata2->statsTuple,
441 									   STATISTIC_KIND_MCV, InvalidOid,
442 									   ATTSTATSSLOT_VALUES | ATTSTATSSLOT_NUMBERS);
443 		hist2_exists = get_attstatsslot(&hist2_slot, vardata2->statsTuple,
444 										STATISTIC_KIND_HISTOGRAM, InvalidOid,
445 										ATTSTATSSLOT_VALUES);
446 		/* Arbitrarily limit number of MCVs considered */
447 		mcv2_length = Min(mcv2_slot.nvalues, MAX_CONSIDERED_ELEMS);
448 		if (mcv2_exists)
449 			sumcommon2 = mcv_population(mcv2_slot.numbers, mcv2_length);
450 	}
451 	else
452 	{
453 		memset(&mcv2_slot, 0, sizeof(mcv2_slot));
454 		memset(&hist2_slot, 0, sizeof(hist2_slot));
455 	}
456 
457 	opr_codenum = inet_opr_codenum(operator);
458 	fmgr_info(get_opcode(operator), &proc);
459 
460 	/* Estimate number of input rows represented by RHS histogram. */
461 	if (hist2_exists && vardata2->rel)
462 		hist2_weight = (1.0 - nullfrac2 - sumcommon2) * vardata2->rel->rows;
463 
464 	/*
465 	 * Consider each element of the LHS MCV list, matching it to whatever RHS
466 	 * stats we have.  Scale according to the known frequency of the MCV.
467 	 */
468 	if (mcv1_exists && (mcv2_exists || hist2_exists))
469 	{
470 		for (i = 0; i < mcv1_length; i++)
471 		{
472 			selec += mcv1_slot.numbers[i] *
473 				inet_semi_join_sel(mcv1_slot.values[i],
474 								   mcv2_exists, mcv2_slot.values, mcv2_length,
475 								   hist2_exists,
476 								   hist2_slot.values, hist2_slot.nvalues,
477 								   hist2_weight,
478 								   &proc, opr_codenum);
479 		}
480 	}
481 
482 	/*
483 	 * Consider each element of the LHS histogram, except for the first and
484 	 * last elements, which we exclude on the grounds that they're outliers
485 	 * and thus not very representative.  Scale on the assumption that each
486 	 * such histogram element represents an equal share of the LHS histogram
487 	 * population (which is a bit bogus, because the members of its bucket may
488 	 * not all act the same with respect to the join clause, but it's hard to
489 	 * do better).
490 	 *
491 	 * If there are too many histogram elements, decimate to limit runtime.
492 	 */
493 	if (hist1_exists && hist1_slot.nvalues > 2 && (mcv2_exists || hist2_exists))
494 	{
495 		double		hist_selec_sum = 0.0;
496 		int			k,
497 					n;
498 
499 		k = (hist1_slot.nvalues - 3) / MAX_CONSIDERED_ELEMS + 1;
500 
501 		n = 0;
502 		for (i = 1; i < hist1_slot.nvalues - 1; i += k)
503 		{
504 			hist_selec_sum +=
505 				inet_semi_join_sel(hist1_slot.values[i],
506 								   mcv2_exists, mcv2_slot.values, mcv2_length,
507 								   hist2_exists,
508 								   hist2_slot.values, hist2_slot.nvalues,
509 								   hist2_weight,
510 								   &proc, opr_codenum);
511 			n++;
512 		}
513 
514 		selec += (1.0 - nullfrac1 - sumcommon1) * hist_selec_sum / n;
515 	}
516 
517 	/*
518 	 * If useful statistics are not available then use the default estimate.
519 	 * We can apply null fractions if known, though.
520 	 */
521 	if ((!mcv1_exists && !hist1_exists) || (!mcv2_exists && !hist2_exists))
522 		selec = (1.0 - nullfrac1) * (1.0 - nullfrac2) * DEFAULT_SEL(operator);
523 
524 	/* Release stats. */
525 	free_attstatsslot(&mcv1_slot);
526 	free_attstatsslot(&mcv2_slot);
527 	free_attstatsslot(&hist1_slot);
528 	free_attstatsslot(&hist2_slot);
529 
530 	return selec;
531 }
532 
533 /*
534  * Compute the fraction of a relation's population that is represented
535  * by the MCV list.
536  */
537 static Selectivity
mcv_population(float4 * mcv_numbers,int mcv_nvalues)538 mcv_population(float4 *mcv_numbers, int mcv_nvalues)
539 {
540 	Selectivity sumcommon = 0.0;
541 	int			i;
542 
543 	for (i = 0; i < mcv_nvalues; i++)
544 	{
545 		sumcommon += mcv_numbers[i];
546 	}
547 
548 	return sumcommon;
549 }
550 
551 /*
552  * Inet histogram vs single value selectivity estimation
553  *
554  * Estimate the fraction of the histogram population that satisfies
555  * "value OPR CONST".  (The result needs to be scaled to reflect the
556  * proportion of the total population represented by the histogram.)
557  *
558  * The histogram is originally for the inet btree comparison operators.
559  * Only the common bits of the network part and the length of the network part
560  * (masklen) are interesting for the subnet inclusion operators.  Fortunately,
561  * btree comparison treats the network part as the major sort key.  Even so,
562  * the length of the network part would not really be significant in the
563  * histogram.  This would lead to big mistakes for data sets with uneven
564  * masklen distribution.  To reduce this problem, comparisons with the left
565  * and the right sides of the buckets are used together.
566  *
567  * Histogram bucket matches are calculated in two forms.  If the constant
568  * matches both bucket endpoints the bucket is considered as fully matched.
569  * The second form is to match the bucket partially; we recognize this when
570  * the constant matches just one endpoint, or the two endpoints fall on
571  * opposite sides of the constant.  (Note that when the constant matches an
572  * interior histogram element, it gets credit for partial matches to the
573  * buckets on both sides, while a match to a histogram endpoint gets credit
574  * for only one partial match.  This is desirable.)
575  *
576  * The divider in the partial bucket match is imagined as the distance
577  * between the decisive bits and the common bits of the addresses.  It will
578  * be used as a power of two as it is the natural scale for the IP network
579  * inclusion.  This partial bucket match divider calculation is an empirical
580  * formula and subject to change with more experiment.
581  *
582  * For a partial match, we try to calculate dividers for both of the
583  * boundaries.  If the address family of a boundary value does not match the
584  * constant or comparison of the length of the network parts is not correct
585  * for the operator, the divider for that boundary will not be taken into
586  * account.  If both of the dividers are valid, the greater one will be used
587  * to minimize the mistake in buckets that have disparate masklens.  This
588  * calculation is unfair when dividers can be calculated for both of the
589  * boundaries but they are far from each other; but it is not a common
590  * situation as the boundaries are expected to share most of their significant
591  * bits of their masklens.  The mistake would be greater, if we would use the
592  * minimum instead of the maximum, and we don't know a sensible way to combine
593  * them.
594  *
595  * For partial match in buckets that have different address families on the
596  * left and right sides, only the boundary with the same address family is
597  * taken into consideration.  This can cause more mistakes for these buckets
598  * if the masklens of their boundaries are also disparate.  But this can only
599  * happen in one bucket, since only two address families exist.  It seems a
600  * better option than not considering these buckets at all.
601  */
602 static Selectivity
inet_hist_value_sel(Datum * values,int nvalues,Datum constvalue,int opr_codenum)603 inet_hist_value_sel(Datum *values, int nvalues, Datum constvalue,
604 					int opr_codenum)
605 {
606 	Selectivity match = 0.0;
607 	inet	   *query,
608 			   *left,
609 			   *right;
610 	int			i,
611 				k,
612 				n;
613 	int			left_order,
614 				right_order,
615 				left_divider,
616 				right_divider;
617 
618 	/* guard against zero-divide below */
619 	if (nvalues <= 1)
620 		return 0.0;
621 
622 	/* if there are too many histogram elements, decimate to limit runtime */
623 	k = (nvalues - 2) / MAX_CONSIDERED_ELEMS + 1;
624 
625 	query = DatumGetInetPP(constvalue);
626 
627 	/* "left" is the left boundary value of the current bucket ... */
628 	left = DatumGetInetPP(values[0]);
629 	left_order = inet_inclusion_cmp(left, query, opr_codenum);
630 
631 	n = 0;
632 	for (i = k; i < nvalues; i += k)
633 	{
634 		/* ... and "right" is the right boundary value */
635 		right = DatumGetInetPP(values[i]);
636 		right_order = inet_inclusion_cmp(right, query, opr_codenum);
637 
638 		if (left_order == 0 && right_order == 0)
639 		{
640 			/* The whole bucket matches, since both endpoints do. */
641 			match += 1.0;
642 		}
643 		else if ((left_order <= 0 && right_order >= 0) ||
644 				 (left_order >= 0 && right_order <= 0))
645 		{
646 			/* Partial bucket match. */
647 			left_divider = inet_hist_match_divider(left, query, opr_codenum);
648 			right_divider = inet_hist_match_divider(right, query, opr_codenum);
649 
650 			if (left_divider >= 0 || right_divider >= 0)
651 				match += 1.0 / pow(2.0, Max(left_divider, right_divider));
652 		}
653 
654 		/* Shift the variables. */
655 		left = right;
656 		left_order = right_order;
657 
658 		/* Count the number of buckets considered. */
659 		n++;
660 	}
661 
662 	return match / n;
663 }
664 
665 /*
666  * Inet MCV vs MCV join selectivity estimation
667  *
668  * We simply add up the fractions of the populations that satisfy the clause.
669  * The result is exact and does not need to be scaled further.
670  */
671 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)672 inet_mcv_join_sel(Datum *mcv1_values, float4 *mcv1_numbers, int mcv1_nvalues,
673 				  Datum *mcv2_values, float4 *mcv2_numbers, int mcv2_nvalues,
674 				  Oid operator)
675 {
676 	Selectivity selec = 0.0;
677 	FmgrInfo	proc;
678 	int			i,
679 				j;
680 
681 	fmgr_info(get_opcode(operator), &proc);
682 
683 	for (i = 0; i < mcv1_nvalues; i++)
684 	{
685 		for (j = 0; j < mcv2_nvalues; j++)
686 			if (DatumGetBool(FunctionCall2(&proc,
687 										   mcv1_values[i],
688 										   mcv2_values[j])))
689 				selec += mcv1_numbers[i] * mcv2_numbers[j];
690 	}
691 	return selec;
692 }
693 
694 /*
695  * Inet MCV vs histogram join selectivity estimation
696  *
697  * For each MCV on the lefthand side, estimate the fraction of the righthand's
698  * histogram population that satisfies the join clause, and add those up,
699  * scaling by the MCV's frequency.  The result still needs to be scaled
700  * according to the fraction of the righthand's population represented by
701  * the histogram.
702  */
703 static Selectivity
inet_mcv_hist_sel(Datum * mcv_values,float4 * mcv_numbers,int mcv_nvalues,Datum * hist_values,int hist_nvalues,int opr_codenum)704 inet_mcv_hist_sel(Datum *mcv_values, float4 *mcv_numbers, int mcv_nvalues,
705 				  Datum *hist_values, int hist_nvalues,
706 				  int opr_codenum)
707 {
708 	Selectivity selec = 0.0;
709 	int			i;
710 
711 	/*
712 	 * We'll call inet_hist_value_selec with the histogram on the left, so we
713 	 * must commute the operator.
714 	 */
715 	opr_codenum = -opr_codenum;
716 
717 	for (i = 0; i < mcv_nvalues; i++)
718 	{
719 		selec += mcv_numbers[i] *
720 			inet_hist_value_sel(hist_values, hist_nvalues, mcv_values[i],
721 								opr_codenum);
722 	}
723 	return selec;
724 }
725 
726 /*
727  * Inet histogram vs histogram join selectivity estimation
728  *
729  * Here, we take all values listed in the second histogram (except for the
730  * first and last elements, which are excluded on the grounds of possibly
731  * not being very representative) and treat them as a uniform sample of
732  * the non-MCV population for that relation.  For each one, we apply
733  * inet_hist_value_selec to see what fraction of the first histogram
734  * it matches.
735  *
736  * We could alternatively do this the other way around using the operator's
737  * commutator.  XXX would it be worthwhile to do it both ways and take the
738  * average?  That would at least avoid non-commutative estimation results.
739  */
740 static Selectivity
inet_hist_inclusion_join_sel(Datum * hist1_values,int hist1_nvalues,Datum * hist2_values,int hist2_nvalues,int opr_codenum)741 inet_hist_inclusion_join_sel(Datum *hist1_values, int hist1_nvalues,
742 							 Datum *hist2_values, int hist2_nvalues,
743 							 int opr_codenum)
744 {
745 	double		match = 0.0;
746 	int			i,
747 				k,
748 				n;
749 
750 	if (hist2_nvalues <= 2)
751 		return 0.0;				/* no interior histogram elements */
752 
753 	/* if there are too many histogram elements, decimate to limit runtime */
754 	k = (hist2_nvalues - 3) / MAX_CONSIDERED_ELEMS + 1;
755 
756 	n = 0;
757 	for (i = 1; i < hist2_nvalues - 1; i += k)
758 	{
759 		match += inet_hist_value_sel(hist1_values, hist1_nvalues,
760 									 hist2_values[i], opr_codenum);
761 		n++;
762 	}
763 
764 	return match / n;
765 }
766 
767 /*
768  * Inet semi join selectivity estimation for one value
769  *
770  * The function calculates the probability that there is at least one row
771  * in the RHS table that satisfies the "lhs_value op column" condition.
772  * It is used in semi join estimation to check a sample from the left hand
773  * side table.
774  *
775  * The MCV and histogram from the right hand side table should be provided as
776  * arguments with the lhs_value from the left hand side table for the join.
777  * hist_weight is the total number of rows represented by the histogram.
778  * For example, if the table has 1000 rows, and 10% of the rows are in the MCV
779  * list, and another 10% are NULLs, hist_weight would be 800.
780  *
781  * First, the lhs_value will be matched to the most common values.  If it
782  * matches any of them, 1.0 will be returned, because then there is surely
783  * a match.
784  *
785  * Otherwise, the histogram will be used to estimate the number of rows in
786  * the second table that match the condition.  If the estimate is greater
787  * than 1.0, 1.0 will be returned, because it means there is a greater chance
788  * that the lhs_value will match more than one row in the table.  If it is
789  * between 0.0 and 1.0, it will be returned as the probability.
790  */
791 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)792 inet_semi_join_sel(Datum lhs_value,
793 				   bool mcv_exists, Datum *mcv_values, int mcv_nvalues,
794 				   bool hist_exists, Datum *hist_values, int hist_nvalues,
795 				   double hist_weight,
796 				   FmgrInfo *proc, int opr_codenum)
797 {
798 	if (mcv_exists)
799 	{
800 		int			i;
801 
802 		for (i = 0; i < mcv_nvalues; i++)
803 		{
804 			if (DatumGetBool(FunctionCall2(proc,
805 										   lhs_value,
806 										   mcv_values[i])))
807 				return 1.0;
808 		}
809 	}
810 
811 	if (hist_exists && hist_weight > 0)
812 	{
813 		Selectivity hist_selec;
814 
815 		/* Commute operator, since we're passing lhs_value on the right */
816 		hist_selec = inet_hist_value_sel(hist_values, hist_nvalues,
817 										 lhs_value, -opr_codenum);
818 
819 		if (hist_selec > 0)
820 			return Min(1.0, hist_weight * hist_selec);
821 	}
822 
823 	return 0.0;
824 }
825 
826 /*
827  * Assign useful code numbers for the subnet inclusion/overlap operators
828  *
829  * Only inet_masklen_inclusion_cmp() and inet_hist_match_divider() depend
830  * on the exact codes assigned here; but many other places in this file
831  * know that they can negate a code to obtain the code for the commutator
832  * operator.
833  */
834 static int
inet_opr_codenum(Oid operator)835 inet_opr_codenum(Oid operator)
836 {
837 	switch (operator)
838 	{
839 		case OID_INET_SUP_OP:
840 			return -2;
841 		case OID_INET_SUPEQ_OP:
842 			return -1;
843 		case OID_INET_OVERLAP_OP:
844 			return 0;
845 		case OID_INET_SUBEQ_OP:
846 			return 1;
847 		case OID_INET_SUB_OP:
848 			return 2;
849 		default:
850 			elog(ERROR, "unrecognized operator %u for inet selectivity",
851 				 operator);
852 	}
853 	return 0;					/* unreached, but keep compiler quiet */
854 }
855 
856 /*
857  * Comparison function for the subnet inclusion/overlap operators
858  *
859  * If the comparison is okay for the specified inclusion operator, the return
860  * value will be 0.  Otherwise the return value will be less than or greater
861  * than 0 as appropriate for the operator.
862  *
863  * Comparison is compatible with the basic comparison function for the inet
864  * type.  See network_cmp_internal() in network.c for the original.  Basic
865  * comparison operators are implemented with the network_cmp_internal()
866  * function.  It is possible to implement the subnet inclusion operators with
867  * this function.
868  *
869  * Comparison is first on the common bits of the network part, then on the
870  * length of the network part (masklen) as in the network_cmp_internal()
871  * function.  Only the first part is in this function.  The second part is
872  * separated to another function for reusability.  The difference between the
873  * second part and the original network_cmp_internal() is that the inclusion
874  * operator is considered while comparing the lengths of the network parts.
875  * See the inet_masklen_inclusion_cmp() function below.
876  */
877 static int
inet_inclusion_cmp(inet * left,inet * right,int opr_codenum)878 inet_inclusion_cmp(inet *left, inet *right, int opr_codenum)
879 {
880 	if (ip_family(left) == ip_family(right))
881 	{
882 		int			order;
883 
884 		order = bitncmp(ip_addr(left), ip_addr(right),
885 						Min(ip_bits(left), ip_bits(right)));
886 		if (order != 0)
887 			return order;
888 
889 		return inet_masklen_inclusion_cmp(left, right, opr_codenum);
890 	}
891 
892 	return ip_family(left) - ip_family(right);
893 }
894 
895 /*
896  * Masklen comparison function for the subnet inclusion/overlap operators
897  *
898  * Compares the lengths of the network parts of the inputs.  If the comparison
899  * is okay for the specified inclusion operator, the return value will be 0.
900  * Otherwise the return value will be less than or greater than 0 as
901  * appropriate for the operator.
902  */
903 static int
inet_masklen_inclusion_cmp(inet * left,inet * right,int opr_codenum)904 inet_masklen_inclusion_cmp(inet *left, inet *right, int opr_codenum)
905 {
906 	int			order;
907 
908 	order = (int) ip_bits(left) - (int) ip_bits(right);
909 
910 	/*
911 	 * Return 0 if the operator would accept this combination of masklens.
912 	 * Note that opr_codenum zero (overlaps) will accept all cases.
913 	 */
914 	if ((order > 0 && opr_codenum >= 0) ||
915 		(order == 0 && opr_codenum >= -1 && opr_codenum <= 1) ||
916 		(order < 0 && opr_codenum <= 0))
917 		return 0;
918 
919 	/*
920 	 * Otherwise, return a negative value for sup/supeq (notionally, the RHS
921 	 * needs to have a larger masklen than it has, which would make it sort
922 	 * later), or a positive value for sub/subeq (vice versa).
923 	 */
924 	return opr_codenum;
925 }
926 
927 /*
928  * Inet histogram partial match divider calculation
929  *
930  * First the families and the lengths of the network parts are compared using
931  * the subnet inclusion operator.  If those are acceptable for the operator,
932  * the divider will be calculated using the masklens and the common bits of
933  * the addresses.  -1 will be returned if it cannot be calculated.
934  *
935  * See commentary for inet_hist_value_sel() for some rationale for this.
936  */
937 static int
inet_hist_match_divider(inet * boundary,inet * query,int opr_codenum)938 inet_hist_match_divider(inet *boundary, inet *query, int opr_codenum)
939 {
940 	if (ip_family(boundary) == ip_family(query) &&
941 		inet_masklen_inclusion_cmp(boundary, query, opr_codenum) == 0)
942 	{
943 		int			min_bits,
944 					decisive_bits;
945 
946 		min_bits = Min(ip_bits(boundary), ip_bits(query));
947 
948 		/*
949 		 * Set decisive_bits to the masklen of the one that should contain the
950 		 * other according to the operator.
951 		 */
952 		if (opr_codenum < 0)
953 			decisive_bits = ip_bits(boundary);
954 		else if (opr_codenum > 0)
955 			decisive_bits = ip_bits(query);
956 		else
957 			decisive_bits = min_bits;
958 
959 		/*
960 		 * Now return the number of non-common decisive bits.  (This will be
961 		 * zero if the boundary and query in fact match, else positive.)
962 		 */
963 		if (min_bits > 0)
964 			return decisive_bits - bitncommon(ip_addr(boundary),
965 											  ip_addr(query),
966 											  min_bits);
967 		return decisive_bits;
968 	}
969 
970 	return -1;
971 }
972