PostgreSQL Source Code: src/backend/utils/adt/multirangetypes_selfuncs.c Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
19
20#include <math.h>
21
26#include "utils/fmgrprotos.h"
32
40 Oid operator);
44 int hist_nvalues, bool equal);
53 int length_hist_nvalues, double value,
56 int length_hist_nvalues, double length1,
57 double length2, bool equal);
62 int hist_nvalues,
63 Datum *length_hist_values,
64 int length_hist_nvalues);
69 int hist_nvalues,
70 Datum *length_hist_values,
71 int length_hist_nvalues);
72
73
74
75
76
77static double
79{
80 switch (operator)
81 {
82 case OID_MULTIRANGE_OVERLAPS_MULTIRANGE_OP:
83 case OID_MULTIRANGE_OVERLAPS_RANGE_OP:
84 case OID_RANGE_OVERLAPS_MULTIRANGE_OP:
85 return 0.01;
86
87 case OID_RANGE_CONTAINS_MULTIRANGE_OP:
88 case OID_RANGE_MULTIRANGE_CONTAINED_OP:
89 case OID_MULTIRANGE_CONTAINS_RANGE_OP:
90 case OID_MULTIRANGE_CONTAINS_MULTIRANGE_OP:
91 case OID_MULTIRANGE_RANGE_CONTAINED_OP:
92 case OID_MULTIRANGE_MULTIRANGE_CONTAINED_OP:
93 return 0.005;
94
95 case OID_MULTIRANGE_CONTAINS_ELEM_OP:
96 case OID_MULTIRANGE_ELEM_CONTAINED_OP:
97
98
99
100
101
103
104 case OID_MULTIRANGE_LESS_OP:
105 case OID_MULTIRANGE_LESS_EQUAL_OP:
106 case OID_MULTIRANGE_GREATER_OP:
107 case OID_MULTIRANGE_GREATER_EQUAL_OP:
108 case OID_MULTIRANGE_LEFT_RANGE_OP:
109 case OID_MULTIRANGE_LEFT_MULTIRANGE_OP:
110 case OID_RANGE_LEFT_MULTIRANGE_OP:
111 case OID_MULTIRANGE_RIGHT_RANGE_OP:
112 case OID_MULTIRANGE_RIGHT_MULTIRANGE_OP:
113 case OID_RANGE_RIGHT_MULTIRANGE_OP:
114 case OID_MULTIRANGE_OVERLAPS_LEFT_RANGE_OP:
115 case OID_RANGE_OVERLAPS_LEFT_MULTIRANGE_OP:
116 case OID_MULTIRANGE_OVERLAPS_LEFT_MULTIRANGE_OP:
117 case OID_MULTIRANGE_OVERLAPS_RIGHT_RANGE_OP:
118 case OID_RANGE_OVERLAPS_RIGHT_MULTIRANGE_OP:
119 case OID_MULTIRANGE_OVERLAPS_RIGHT_MULTIRANGE_OP:
120
122
123 default:
124
125
126
127
128
129 return 0.01;
130 }
131}
132
133
134
135
138{
145 bool varonleft;
150
151
152
153
154
156 &vardata, &other, &varonleft))
158
159
160
161
163 {
166 }
167
168
169
170
171
172 if (((Const *) other)->constisnull)
173 {
176 }
177
178
179
180
181
182 if (!varonleft)
183 {
184
186 if (!operator)
187 {
188
191 }
192 }
193
194
195
196
197
198
199
200
201
202
203
204
205 if (operator == OID_MULTIRANGE_CONTAINS_ELEM_OP)
206 {
208
210 {
213
214 lower.inclusive = true;
215 lower.val = ((Const *) other)->constvalue;
216 lower.infinite = false;
217 lower.lower = true;
218 upper.inclusive = true;
219 upper.val = ((Const *) other)->constvalue;
220 upper.infinite = false;
221 upper.lower = false;
223 false, NULL);
225 1, &constrange);
226 }
227 }
228 else if (operator == OID_RANGE_MULTIRANGE_CONTAINED_OP ||
229 operator == OID_MULTIRANGE_CONTAINS_RANGE_OP ||
230 operator == OID_MULTIRANGE_OVERLAPS_RANGE_OP ||
231 operator == OID_MULTIRANGE_OVERLAPS_LEFT_RANGE_OP ||
232 operator == OID_MULTIRANGE_OVERLAPS_RIGHT_RANGE_OP ||
233 operator == OID_MULTIRANGE_LEFT_RANGE_OP ||
234 operator == OID_MULTIRANGE_RIGHT_RANGE_OP)
235 {
236
237
238
239
242 {
245 1, &constrange);
246 }
247 }
248 else if (operator == OID_RANGE_OVERLAPS_MULTIRANGE_OP ||
249 operator == OID_RANGE_OVERLAPS_LEFT_MULTIRANGE_OP ||
250 operator == OID_RANGE_OVERLAPS_RIGHT_MULTIRANGE_OP ||
251 operator == OID_RANGE_LEFT_MULTIRANGE_OP ||
252 operator == OID_RANGE_RIGHT_MULTIRANGE_OP ||
253 operator == OID_RANGE_CONTAINS_MULTIRANGE_OP ||
254 operator == OID_MULTIRANGE_ELEM_CONTAINED_OP ||
255 operator == OID_MULTIRANGE_RANGE_CONTAINED_OP)
256 {
257
258
259
260
261
262
263 }
264 else if (((Const *) other)->consttype == vardata.vartype)
265 {
266
268
270 }
271
272
273
274
275
276
277
278 if (constmultirange)
279 selec = calc_multirangesel(typcache, &vardata, constmultirange, operator);
280 else
282
284
286
288}
289
290static double
293{
294 double hist_selec;
295 double selec;
297 null_frac;
298
299
300
301
302
304 {
307
309 null_frac = stats->stanullfrac;
310
311
313 STATISTIC_KIND_RANGE_LENGTH_HISTOGRAM,
316 {
318 elog(ERROR, "invalid empty fraction statistic");
319 empty_frac = sslot.numbers[0];
321 }
322 else
323 {
324
325 empty_frac = 0.0;
326 }
327 }
328 else
329 {
330
331
332
333
334
335
336 null_frac = 0.0;
337 empty_frac = 0.0;
338 }
339
341 {
342
343
344
345
346 switch (operator)
347 {
348
349 case OID_MULTIRANGE_OVERLAPS_RANGE_OP:
350 case OID_MULTIRANGE_OVERLAPS_MULTIRANGE_OP:
351 case OID_MULTIRANGE_OVERLAPS_LEFT_RANGE_OP:
352 case OID_MULTIRANGE_OVERLAPS_LEFT_MULTIRANGE_OP:
353 case OID_MULTIRANGE_OVERLAPS_RIGHT_RANGE_OP:
354 case OID_MULTIRANGE_OVERLAPS_RIGHT_MULTIRANGE_OP:
355 case OID_MULTIRANGE_LEFT_RANGE_OP:
356 case OID_MULTIRANGE_LEFT_MULTIRANGE_OP:
357 case OID_MULTIRANGE_RIGHT_RANGE_OP:
358 case OID_MULTIRANGE_RIGHT_MULTIRANGE_OP:
359
360 case OID_MULTIRANGE_LESS_OP:
361 selec = 0.0;
362 break;
363
364
365
366
367
368 case OID_RANGE_MULTIRANGE_CONTAINED_OP:
369 case OID_MULTIRANGE_MULTIRANGE_CONTAINED_OP:
370
371 case OID_MULTIRANGE_LESS_EQUAL_OP:
372 selec = empty_frac;
373 break;
374
375
376 case OID_MULTIRANGE_CONTAINS_RANGE_OP:
377 case OID_MULTIRANGE_CONTAINS_MULTIRANGE_OP:
378
379 case OID_MULTIRANGE_GREATER_EQUAL_OP:
380 selec = 1.0;
381 break;
382
383
384 case OID_MULTIRANGE_GREATER_OP:
385 selec = 1.0 - empty_frac;
386 break;
387
388
389 case OID_MULTIRANGE_CONTAINS_ELEM_OP:
390
391
392 case OID_RANGE_OVERLAPS_MULTIRANGE_OP:
393 case OID_RANGE_OVERLAPS_LEFT_MULTIRANGE_OP:
394 case OID_RANGE_OVERLAPS_RIGHT_MULTIRANGE_OP:
395 case OID_RANGE_LEFT_MULTIRANGE_OP:
396 case OID_RANGE_RIGHT_MULTIRANGE_OP:
397 case OID_RANGE_CONTAINS_MULTIRANGE_OP:
398 case OID_MULTIRANGE_ELEM_CONTAINED_OP:
399 case OID_MULTIRANGE_RANGE_CONTAINED_OP:
400
401 default:
402 elog(ERROR, "unexpected operator %u", operator);
403 selec = 0.0;
404 break;
405 }
406 }
407 else
408 {
409
410
411
412
413
414
415
416
418 operator);
419 if (hist_selec < 0.0)
421
422
423
424
425
426
427 if (operator == OID_RANGE_MULTIRANGE_CONTAINED_OP ||
428 operator == OID_MULTIRANGE_MULTIRANGE_CONTAINED_OP)
429 {
430
431 selec = (1.0 - empty_frac) * hist_selec + empty_frac;
432 }
433 else
434 {
435
436 selec = (1.0 - empty_frac) * hist_selec;
437 }
438 }
439
440
441 selec *= (1.0 - null_frac);
442
443
445
446 return selec;
447}
448
449
450
451
452
453
454
455static double
458{
462 int nhist;
465 int i;
469 double hist_selec;
470
471
474 return -1;
478 return -1;
479
480
483 STATISTIC_KIND_BOUNDS_HISTOGRAM, InvalidOid,
485 return -1.0;
486
487
489 {
491 return -1.0;
492 }
493
494
495
496
497
501 for (i = 0; i < nhist; i++)
502 {
503 bool empty;
504
506 &hist_lower[i], &hist_upper[i], &empty);
507
508 if (empty)
509 elog(ERROR, "bounds histogram contains an empty range");
510 }
511
512
513 if (operator == OID_MULTIRANGE_CONTAINS_RANGE_OP ||
514 operator == OID_MULTIRANGE_CONTAINS_MULTIRANGE_OP ||
515 operator == OID_MULTIRANGE_RANGE_CONTAINED_OP ||
516 operator == OID_MULTIRANGE_MULTIRANGE_CONTAINED_OP)
517 {
520 STATISTIC_KIND_RANGE_LENGTH_HISTOGRAM,
523 {
525 return -1.0;
526 }
527
528
530 {
533 return -1.0;
534 }
535 }
536 else
537 memset(&lslot, 0, sizeof(lslot));
538
539
542 &const_lower, &tmp);
544 &tmp, &const_upper);
545
546
547
548
549
550 switch (operator)
551 {
552 case OID_MULTIRANGE_LESS_OP:
553
554
555
556
557
558
559
560
561
562 hist_selec =
564 hist_lower, nhist, false);
565 break;
566
567 case OID_MULTIRANGE_LESS_EQUAL_OP:
568 hist_selec =
570 hist_lower, nhist, true);
571 break;
572
573 case OID_MULTIRANGE_GREATER_OP:
574 hist_selec =
576 hist_lower, nhist, false);
577 break;
578
579 case OID_MULTIRANGE_GREATER_EQUAL_OP:
580 hist_selec =
582 hist_lower, nhist, true);
583 break;
584
585 case OID_MULTIRANGE_LEFT_RANGE_OP:
586 case OID_MULTIRANGE_LEFT_MULTIRANGE_OP:
587
588 hist_selec =
590 hist_upper, nhist, false);
591 break;
592
593 case OID_MULTIRANGE_RIGHT_RANGE_OP:
594 case OID_MULTIRANGE_RIGHT_MULTIRANGE_OP:
595
596 hist_selec =
598 hist_lower, nhist, true);
599 break;
600
601 case OID_MULTIRANGE_OVERLAPS_RIGHT_RANGE_OP:
602 case OID_MULTIRANGE_OVERLAPS_RIGHT_MULTIRANGE_OP:
603
604 hist_selec =
606 hist_lower, nhist, false);
607 break;
608
609 case OID_MULTIRANGE_OVERLAPS_LEFT_RANGE_OP:
610 case OID_MULTIRANGE_OVERLAPS_LEFT_MULTIRANGE_OP:
611
612 hist_selec =
614 hist_upper, nhist, true);
615 break;
616
617 case OID_MULTIRANGE_OVERLAPS_RANGE_OP:
618 case OID_MULTIRANGE_OVERLAPS_MULTIRANGE_OP:
619 case OID_MULTIRANGE_CONTAINS_ELEM_OP:
620
621
622
623
624
625
626
627
628
629
630
631
632
633 hist_selec =
635 &const_lower, hist_upper,
636 nhist, false);
637 hist_selec +=
639 &const_upper, hist_lower,
640 nhist, true));
641 hist_selec = 1.0 - hist_selec;
642 break;
643
644 case OID_MULTIRANGE_CONTAINS_RANGE_OP:
645 case OID_MULTIRANGE_CONTAINS_MULTIRANGE_OP:
646 hist_selec =
648 &const_upper, hist_lower, nhist,
650 break;
651
652 case OID_MULTIRANGE_MULTIRANGE_CONTAINED_OP:
653 case OID_RANGE_MULTIRANGE_CONTAINED_OP:
655 {
656
657
658
659
660 hist_selec =
662 hist_upper, nhist, true);
663 }
664 else if (const_upper.infinite)
665 {
666 hist_selec =
668 hist_lower, nhist, false);
669 }
670 else
671 {
672 hist_selec =
674 &const_upper, hist_lower, nhist,
676 }
677 break;
678
679
680 case OID_RANGE_OVERLAPS_MULTIRANGE_OP:
681 case OID_RANGE_OVERLAPS_LEFT_MULTIRANGE_OP:
682 case OID_RANGE_OVERLAPS_RIGHT_MULTIRANGE_OP:
683 case OID_RANGE_LEFT_MULTIRANGE_OP:
684 case OID_RANGE_RIGHT_MULTIRANGE_OP:
685 case OID_RANGE_CONTAINS_MULTIRANGE_OP:
686 case OID_MULTIRANGE_ELEM_CONTAINED_OP:
687 case OID_MULTIRANGE_RANGE_CONTAINED_OP:
688
689 default:
690 elog(ERROR, "unknown multirange operator %u", operator);
691 hist_selec = -1.0;
692 break;
693 }
694
697
698 return hist_selec;
699}
700
701
702
703
704
705
706static double
709{
712
713
714
715
716
719
720
721 if (index >= 0 && index < hist_nvalues - 1)
724
725 return selec;
726}
727
728
729
730
731
732
733
734
735
736
737
738static int
740 int hist_length, bool equal)
741{
743 upper = hist_length - 1,
745 middle;
746
748 {
751
754 else
755 upper = middle - 1;
756 }
758}
759
760
761
762
763
764
765
766
767static int
770{
772 upper = length_hist_nvalues - 1,
773 middle;
774
776 {
777 double middleval;
778
780
781 middleval = DatumGetFloat8(length_hist_values[middle]);
784 else
785 upper = middle - 1;
786 }
788}
789
790
791
792
796{
799
801 {
803
804
805
806
807
808
809
810 if (value->infinite)
811 return 0.5;
812
813
814 if (!has_subdiff)
815 return 0.5;
816
817
820 hist2->val,
821 hist1->val));
822 if (isnan(bin_width) || bin_width <= 0.0)
823 return 0.5;
824
828 hist1->val))
829 / bin_width;
830
831 if (isnan(position))
832 return 0.5;
833
834
835 position = Max(position, 0.0);
836 position = Min(position, 1.0);
837 return position;
838 }
840 {
841
842
843
844
845
846
847 return ((value->infinite && value->lower) ? 0.0 : 1.0);
848 }
850 {
851
852 return ((value->infinite && ->lower) ? 1.0 : 0.0);
853 }
854 else
855 {
856
857
858
859
860
861
862
863
864 return 0.5;
865 }
866}
867
868
869
870
871
872static double
874{
875 if (!isinf(hist1) && !isinf(hist2))
876 {
877
878
879
880
881
882 if (isinf(value))
883 return 0.5;
884
885 return 1.0 - (hist2 - value) / (hist2 - hist1);
886 }
887 else if (isinf(hist1) && !isinf(hist2))
888 {
889
890
891
892
893 return 1.0;
894 }
895 else if (isinf(hist1) && isinf(hist2))
896 {
897
898 return 0.0;
899 }
900 else
901 {
902
903
904
905
906
907
908
909
910 return 0.5;
911 }
912}
913
914
915
916
919{
921
923 {
924
925
926
927
928 if (has_subdiff)
929 {
931
934 bound2->val,
935 bound1->val));
936
937 if (isnan(res) || res < 0.0)
938 return 1.0;
939 else
940 return res;
941 }
942 else
943 return 1.0;
944 }
946 {
947
949 return 0.0;
950 else
952 }
953 else
954 {
955
957 }
958}
959
960
961
962
963
964
965static double
967 double length1, double length2, bool equal)
968{
969 double frac;
970 double A,
971 B,
972 PA,
973 PB;
974 double pos;
975 int i;
976 double area;
977
978 Assert(length2 >= length1);
979
980 if (length2 < 0.0)
981 return 0.0;
982
983
984 if (isinf(length2) && equal)
985 return 1.0;
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1027 if (i >= length_hist_nvalues - 1)
1028 return 1.0;
1029
1030 if (i < 0)
1031 {
1032 i = 0;
1033 pos = 0.0;
1034 }
1035 else
1036 {
1037
1041 }
1042 PB = (((double) i) + pos) / (double) (length_hist_nvalues - 1);
1043 B = length1;
1044
1045
1046
1047
1048
1049
1050 if (length2 == length1)
1051 return PB;
1052
1053
1054
1055
1056
1057
1058 area = 0.0;
1059 for (; i < length_hist_nvalues - 1; i++)
1060 {
1061 double bin_upper = DatumGetFloat8(length_hist_values[i + 1]);
1062
1063
1064 if (!(bin_upper < length2 || (equal && bin_upper <= length2)))
1065 break;
1066
1067
1068 A = B;
1069 PA = PB;
1070
1071 B = bin_upper;
1072 PB = (double) i / (double) (length_hist_nvalues - 1);
1073
1074
1075
1076
1077
1078
1079
1080 if (PA > 0 || PB > 0)
1081 area += 0.5 * (PB + PA) * (B - A);
1082 }
1083
1084
1085 A = B;
1086 PA = PB;
1087
1088 B = length2;
1089 if (i >= length_hist_nvalues - 1)
1090 pos = 0.0;
1091 else
1092 {
1094 pos = 0.0;
1095 else
1099 }
1100 PB = (((double) i) + pos) / (double) (length_hist_nvalues - 1);
1101
1102 if (PA > 0 || PB > 0)
1103 area += 0.5 * (PB + PA) * (B - A);
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113 if (isinf(area) && isinf(length2))
1114 frac = 0.5;
1115 else
1116 frac = area / (length2 - length1);
1117
1118 return frac;
1119}
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130static double
1133 const RangeBound *hist_lower, int hist_nvalues,
1134 Datum *length_hist_values, int length_hist_nvalues)
1135{
1136 int i,
1137 upper_index;
1139 double bin_width;
1140 double upper_bin_width;
1141 double sum_frac;
1142
1143
1144
1145
1146
1147
1148 upper->inclusive = ->inclusive;
1149 upper->lower = true;
1151 false);
1152
1153
1154
1155
1156
1157 if (upper_index < 0)
1158 return 0.0;
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168 upper_index = Min(upper_index, hist_nvalues - 2);
1169
1170
1171
1172
1173
1174
1176 &hist_lower[upper_index],
1177 &hist_lower[upper_index + 1]);
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188 prev_dist = 0.0;
1189 bin_width = upper_bin_width;
1190
1191 sum_frac = 0.0;
1192 for (i = upper_index; i >= 0; i--)
1193 {
1194 double dist;
1195 double length_hist_frac;
1196 bool final_bin = false;
1197
1198
1199
1200
1201
1202
1203
1205 {
1207
1208
1209
1210
1211
1213 &hist_lower[i + 1]);
1214 if (bin_width < 0.0)
1215 bin_width = 0.0;
1216 final_bin = true;
1217 }
1218 else
1220
1221
1222
1223
1224
1226 length_hist_nvalues,
1227 prev_dist, dist, true);
1228
1229
1230
1231
1232
1233 sum_frac += length_hist_frac * bin_width / (double) (hist_nvalues - 1);
1234
1235 if (final_bin)
1236 break;
1237
1238 bin_width = 1.0;
1239 prev_dist = dist;
1240 }
1241
1242 return sum_frac;
1243}
1244
1245
1246
1247
1248
1249
1250
1251static double
1254 const RangeBound *hist_lower, int hist_nvalues,
1255 Datum *length_hist_values, int length_hist_nvalues)
1256{
1257 int i,
1258 lower_index;
1259 double bin_width,
1260 lower_bin_width;
1261 double sum_frac;
1263
1264
1266 true);
1267
1268
1269
1270
1271
1272 if (lower_index < 0)
1273 return 0.0;
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283 lower_index = Min(lower_index, hist_nvalues - 2);
1284
1285
1286
1287
1288
1289
1290 lower_bin_width = get_position(typcache, lower, &hist_lower[lower_index],
1291 &hist_lower[lower_index + 1]);
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1306 sum_frac = 0.0;
1307 bin_width = lower_bin_width;
1308 for (i = lower_index; i >= 0; i--)
1309 {
1311 double length_hist_frac;
1312
1313
1314
1315
1316
1317
1319
1320
1321
1322
1323
1324 length_hist_frac =
1326 length_hist_nvalues,
1327 prev_dist, dist, false);
1328
1329 sum_frac += length_hist_frac * bin_width / (double) (hist_nvalues - 1);
1330
1331 bin_width = 1.0;
1332 prev_dist = dist;
1333 }
1334
1335 return sum_frac;
1336}
#define OidIsValid(objectId)
bool equal(const void *a, const void *b)
static float8 get_float8_infinity(void)
Datum FunctionCall2Coll(FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2)
#define PG_RETURN_FLOAT8(x)
#define PG_GETARG_POINTER(n)
#define PG_GETARG_INT32(n)
Assert(PointerIsAligned(start, uint64))
#define HeapTupleIsValid(tuple)
static void * GETSTRUCT(const HeapTupleData *tuple)
void free_attstatsslot(AttStatsSlot *sslot)
bool get_attstatsslot(AttStatsSlot *sslot, HeapTuple statstuple, int reqkind, Oid reqop, int flags)
Oid get_commutator(Oid opno)
#define ATTSTATSSLOT_NUMBERS
#define ATTSTATSSLOT_VALUES
MultirangeType * make_multirange(Oid mltrngtypoid, TypeCacheEntry *rangetyp, int32 range_count, RangeType **ranges)
void multirange_get_bounds(TypeCacheEntry *rangetyp, const MultirangeType *multirange, uint32 i, RangeBound *lower, RangeBound *upper)
TypeCacheEntry * multirange_get_typcache(FunctionCallInfo fcinfo, Oid mltrngtypid)
#define MultirangeIsEmpty(mr)
static MultirangeType * DatumGetMultirangeTypeP(Datum X)
static double calc_length_hist_frac(Datum *length_hist_values, int length_hist_nvalues, double length1, double length2, bool equal)
static double calc_hist_selectivity_contained(TypeCacheEntry *typcache, const RangeBound *lower, RangeBound *upper, const RangeBound *hist_lower, int hist_nvalues, Datum *length_hist_values, int length_hist_nvalues)
static float8 get_position(TypeCacheEntry *typcache, const RangeBound *value, const RangeBound *hist1, const RangeBound *hist2)
static double calc_hist_selectivity_scalar(TypeCacheEntry *typcache, const RangeBound *constbound, const RangeBound *hist, int hist_nvalues, bool equal)
static double calc_hist_selectivity_contains(TypeCacheEntry *typcache, const RangeBound *lower, const RangeBound *upper, const RangeBound *hist_lower, int hist_nvalues, Datum *length_hist_values, int length_hist_nvalues)
static double calc_multirangesel(TypeCacheEntry *typcache, VariableStatData *vardata, const MultirangeType *constval, Oid operator)
static int length_hist_bsearch(Datum *length_hist_values, int length_hist_nvalues, double value, bool equal)
static int rbound_bsearch(TypeCacheEntry *typcache, const RangeBound *value, const RangeBound *hist, int hist_length, bool equal)
static double calc_hist_selectivity(TypeCacheEntry *typcache, VariableStatData *vardata, const MultirangeType *constval, Oid operator)
static double default_multirange_selectivity(Oid operator)
static float8 get_len_position(double value, double hist1, double hist2)
Datum multirangesel(PG_FUNCTION_ARGS)
static float8 get_distance(TypeCacheEntry *typcache, const RangeBound *bound1, const RangeBound *bound2)
#define IsA(nodeptr, _type_)
Datum lower(PG_FUNCTION_ARGS)
Datum upper(PG_FUNCTION_ARGS)
FormData_pg_statistic * Form_pg_statistic
static float8 DatumGetFloat8(Datum X)
int range_cmp_bounds(TypeCacheEntry *typcache, const RangeBound *b1, const RangeBound *b2)
RangeType * range_serialize(TypeCacheEntry *typcache, RangeBound *lower, RangeBound *upper, bool empty, struct Node *escontext)
void range_deserialize(TypeCacheEntry *typcache, const RangeType *range, RangeBound *lower, RangeBound *upper, bool *empty)
static RangeType * DatumGetRangeTypeP(Datum X)
static int cmp(const chr *x, const chr *y, size_t len)
bool get_restriction_variable(PlannerInfo *root, List *args, int varRelid, VariableStatData *vardata, Node **other, bool *varonleft)
bool statistic_proc_security_check(VariableStatData *vardata, Oid func_oid)
#define ReleaseVariableStats(vardata)
#define CLAMP_PROBABILITY(p)
#define DEFAULT_MULTIRANGE_INEQ_SEL
FmgrInfo rng_cmp_proc_finfo
struct TypeCacheEntry * rngelemtype
struct TypeCacheEntry * rngtype
FmgrInfo rng_subdiff_finfo