86 : ((
value) && (match)))
87
88
89
90
91
92
93
94
95
96
97#define RESULT_IS_FINAL(value, is_or) ((is_or) ? (value) : (!(value)))
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144static double
146{
147 double n = samplerows;
151
153 denom = N - n + 0.04 * n * (N - 1);
154
155
157 return 0.0;
158
160}
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
178{
181 numrows,
189
190
192
193
196
199
200
202 numrows =
data->numrows;
203
204
206
207
208
209
210
211
212
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
235
236
237
238
239
240
242 {
244 {
246 break;
247 }
248 }
249
250
251
252
253
254
256 {
260
261
264
265
268
269
272
273
274
275
278
283
284
287
288
290 {
291
293
296
297
300
301
303
304
306
307
310 {
312
313
316
317
320
324
326 }
327 }
328
331 }
332
335
337}
338
339
340
341
342
345{
348
349
351
352
354 {
357
360 elog(
ERROR,
"cache lookup failed for ordering operator for type %u",
362
364 }
365
367}
368
369
370
371
372
373
374
375static int
377{
379 int ndistinct;
380
381 ndistinct = 1;
382 for (
i = 1;
i < numrows;
i++)
383 {
384
386
388 ndistinct += 1;
389 }
390
391 return ndistinct;
392}
393
394
395
396
397
398
399static int
401{
404
405 if (
ia->count ==
ib->count)
406 return 0;
407 else if (
ia->count >
ib->count)
408 return -1;
409
410 return 1;
411}
412
413
414
415
416
417
418
419
422 int *ndistinct)
423{
427
429
433
434 for (
i = 1;
i < numrows;
i++)
435 {
436
438
439
441 {
444 }
445
447 }
448
449
451
452
455
458}
459
460
461static int
463{
467
469 ib->values[0],
ib->isnull[0],
470 ssup);
471}
472
473
474
475
476
477
478
479
480
481
482
483
484
485
489{
491 dim;
493 char *ptr;
494
497
498
501
502
505
506 for (dim = 0; dim <
mss->ndims; dim++)
507 {
509
510
513
514
516 {
517
521 }
522
523
526
527
528
529
530
531
534 {
536 {
538 continue;
539 }
540
542
544 }
545 }
546
548}
549
550
551
552
553
556{
558 bool isnull;
562
564 elog(
ERROR,
"cache lookup failed for statistics object %u",
mvoid);
565
568
569 if (isnull)
571 "requested statistics kind \"%c\" is not yet built for statistics object %u",
573
575
577
579}
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
619{
620 int dim;
621 int ndims =
mcvlist->ndimensions;
622
625
627
628
630 char *ptr;
632
633
636
637
638
639
640
641
642
643
644
646
647
649
650
651 for (dim = 0; dim < ndims; dim++)
652 {
653 int ndistinct;
655
656
657
658
659
661
662
665
666
668
670 {
671
673 continue;
674
675
677 counts[dim] += 1;
678 }
679
680
681 if (counts[dim] == 0)
682 continue;
683
684
688
690
693
694
695
696
697
698
699
700 ndistinct = 1;
701 for (
int i = 1;
i < counts[dim];
i++)
702 {
703
705
706
708 continue;
709
711 ndistinct += 1;
712 }
713
714
716
717
718
719
720
721
722
724
725 if (info[dim].typbyval)
726 {
728
729
730
731
732
734 }
735 else if (info[dim].typlen > 0)
736 {
737
738
739
740
741
742
743
744
745
748 }
749 else if (info[dim].typlen == -1)
750 {
754 {
756
757
758
759
760
761
762
764
765
769
770
771
772
773
775 }
776 }
777 else if (info[dim].typlen == -2)
778 {
782 {
784
785
786
787
788
789
790
791
792
796
797
799 }
800 }
801
802
803 Assert(info[dim].nbytes > 0);
804 }
805
806
807
808
809
810
813 + (ndims *
sizeof(
Oid));
814
815
817
818
819 for (
int i = 0;
i < ndims;
i++)
821
822
823
824
825
827
828
829
830
831
834
837
838
841
844
847
850
852 ptr += (
sizeof(
Oid) * ndims);
853
854
857
858
859 for (dim = 0; dim < ndims; dim++)
860 {
861
863
865 {
867
868 if (info[dim].typbyval)
869 {
871
872
873
874
875
876
877
878
879
880
882
883 memcpy(ptr, &tmp, info[dim].typlen);
885 }
886 else if (info[dim].typlen > 0)
887 {
888
891 }
892 else if (info[dim].typlen == -1)
893 {
895
896
899
900
903 }
904 else if (info[dim].typlen == -2)
905 {
907
908
911
912
915 }
916
917
919 }
920
921
923 }
924
925
927 {
929
930
932
933
935 ptr +=
sizeof(
bool) * ndims;
936
939
942
943
944 for (dim = 0; dim < ndims; dim++)
945 {
948
949
951 {
953 info[dim].nvalues,
sizeof(
Datum),
955
957
958
959
961
962
964 }
965
966
969 }
970
971
973 }
974
975
977
980
982}
983
984
985
986
987
988
989
990
993{
994 int dim,
999 char *ptr;
1001
1002 int ndims,
1005
1006
1008
1009
1011
1012
1014 char *dataptr;
1016 char *isnullptr;
1017
1020
1021
1022
1023
1024
1025
1027 elog(
ERROR,
"invalid MCV size %zu (expected at least %zu)",
1029
1030
1032
1033
1037
1038
1041
1044
1047
1050
1052 elog(
ERROR,
"invalid MCV magic %u (expected %u)",
1054
1056 elog(
ERROR,
"invalid MCV type %u (expected %u)",
1058
1059 if (
mcvlist->ndimensions == 0)
1060 elog(
ERROR,
"invalid zero-length dimension array in MCVList");
1063 elog(
ERROR,
"invalid length (%d) dimension array in MCVList",
1065
1067 elog(
ERROR,
"invalid zero-length item array in MCVList");
1069 elog(
ERROR,
"invalid length (%u) item array in MCVList",
1071
1074
1075
1076
1077
1078
1079
1081
1082
1083
1084
1085
1086
1088 elog(
ERROR,
"invalid MCV size %zu (expected %zu)",
1090
1091
1093 ptr += (
sizeof(
Oid) * ndims);
1094
1095
1097
1100
1101
1102 for (dim = 0; dim < ndims; dim++)
1103 {
1104
1105
1106
1107
1108 Assert(info[dim].nvalues >= 0);
1109 Assert(info[dim].nbytes >= 0);
1110
1112 }
1113
1114
1115
1116
1117
1118
1120 elog(
ERROR,
"invalid MCV size %zu (expected %zu)",
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132 datalen = 0;
1134
1135 for (dim = 0; dim < ndims; dim++)
1136 {
1138
1139
1141 }
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1154
1155
1158
1159
1161
1162
1164
1165
1168
1170
1172
1173
1174
1175
1176
1177 for (dim = 0; dim < ndims; dim++)
1178 {
1179
1181
1182 if (info[dim].typbyval)
1183 {
1184
1186 {
1188
1189 memcpy(&v, ptr, info[dim].typlen);
1191
1192 map[dim][
i] =
fetch_att(&v,
true, info[dim].typlen);
1193
1194
1196 }
1197 }
1198 else
1199 {
1200
1201
1202
1203 if (info[dim].typlen > 0)
1204 {
1206 {
1207 memcpy(dataptr, ptr, info[dim].typlen);
1209
1210
1212 dataptr +=
MAXALIGN(info[dim].typlen);
1213 }
1214 }
1215 else if (info[dim].typlen == -1)
1216 {
1217
1219 {
1221
1222
1225
1226
1230
1231
1233
1234
1236 }
1237 }
1238 else if (info[dim].typlen == -2)
1239 {
1240
1242 {
1244
1247
1250
1251
1254 }
1255 }
1256
1257
1259
1260
1262 }
1263
1264
1266 }
1267
1268
1270
1271
1273 {
1275
1278
1279 item->
isnull = (
bool *) isnullptr;
1280 isnullptr +=
MAXALIGN(
sizeof(
bool) * ndims);
1281
1283 ptr +=
sizeof(
bool) * ndims;
1284
1287
1290
1291
1292 for (dim = 0; dim < ndims; dim++)
1293 {
1295
1298
1300 continue;
1301
1303 }
1304
1305
1307 }
1308
1309
1311
1312
1313 for (dim = 0; dim < ndims; dim++)
1315
1317
1319}
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1335{
1337
1338
1340 {
1344
1345
1347
1348
1350
1352
1354
1355
1359
1360
1364 errmsg(
"function returning record called in context "
1365 "that cannot accept type record")));
1367
1368
1369
1370
1371
1373
1375 }
1376
1377
1379
1381
1382 {
1384 bool nulls[5];
1389
1393
1395
1397
1399
1401 {
1402
1405 false,
1408
1410 {
1416
1417
1420
1423
1426 false,
1429 }
1430 else
1433 true,
1436 }
1437
1443
1444
1445 memset(nulls, 0,
sizeof(nulls));
1446
1447
1449
1450
1452
1454 }
1455 else
1456 {
1458 }
1459}
1460
1461
1462
1463
1464
1465
1466
1469{
1470
1471
1472
1473
1476 errmsg(
"cannot accept a value of type %s",
"pg_mcv_list")));
1477
1479}
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1495{
1497}
1498
1499
1500
1501
1504{
1507 errmsg(
"cannot accept a value of type %s",
"pg_mcv_list")));
1508
1510}
1511
1512
1513
1514
1515
1516
1517
1520{
1522}
1523
1524
1525
1526
1527
1528
1529
1530static int
1532{
1534
1536 {
1537
1539
1541 *
collid = var->varcollid;
1542
1544
1546 elog(
ERROR,
"variable not found in statistics object");
1547 }
1548 else
1549 {
1550
1552
1555
1556
1559 {
1561
1563 break;
1564
1566 }
1567
1569 elog(
ERROR,
"expression not found in statistics object");
1570 }
1571
1573}
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594static bool *
1598{
1601
1602
1607
1610
1611
1612
1613
1614
1615 foreach(l, clauses)
1616 {
1618
1619
1622
1623
1624
1625
1626
1628 {
1631
1632
1638
1640
1641
1644
1645
1647
1648
1649
1650
1651
1652
1654 {
1655 bool match = true;
1657
1659
1660
1661
1662
1663
1664
1666 {
1668 continue;
1669 }
1670
1671
1672
1673
1674
1675
1677 continue;
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1696 else
1701
1702
1704 }
1705 }
1707 {
1710
1711
1717
1718
1721 bool elmbyval;
1723 int num_elems;
1725 bool *elem_nulls;
1726
1728
1729
1732
1733
1736
1737
1738
1739
1740
1741 if (!
cst->constisnull)
1742 {
1749 &elem_values, &elem_nulls, &num_elems);
1750 }
1751
1752
1754
1755
1756
1757
1758
1759
1761 {
1763 bool match = !expr->
useOr;
1765
1766
1767
1768
1769
1770
1772 {
1774 continue;
1775 }
1776
1777
1778
1779
1780
1781
1783 continue;
1784
1785 for (
j = 0;
j < num_elems;
j++)
1786 {
1790
1791
1793 {
1795 continue;
1796 }
1797
1798
1799
1800
1801
1802
1804 break;
1805
1810
1812 }
1813
1814
1816 }
1817 }
1819 {
1822
1823
1825
1826
1827
1828
1829
1830
1832 {
1833 bool match = false;
1835
1836
1838 {
1840 match = (item->
isnull[
idx]) ?
true : match;
1841 break;
1842
1844 match = (!item->
isnull[
idx]) ?
true : match;
1845 break;
1846 }
1847
1848
1850 }
1851 }
1853 {
1854
1855
1858
1859
1861
1864
1865
1868
1869
1870
1871
1872
1873
1876
1878 }
1880 {
1881
1882
1885
1886
1888
1891
1892
1895
1896
1897
1898
1899
1900
1903
1905 }
1906 else if (
IsA(clause,
Var))
1907 {
1908
1909
1910 Var *var = (
Var *) (clause);
1911
1912
1914
1916
1917
1918
1919
1920
1921
1923 {
1925 bool match = false;
1926
1927
1929 match = true;
1930
1931
1933 }
1934 }
1935 else
1936 {
1937
1939
1940
1942
1943
1944
1945
1946
1947
1949 {
1950 bool match;
1952
1953
1955
1956
1958 }
1959 }
1960 }
1961
1963}
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
2004{
2007
2008
2011
2012
2015
2016
2019
2021}
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2043 List *clauses,
int varRelid,
2047{
2051
2052
2054
2055
2057
2058
2060 mcv, false);
2061
2062
2065 for (
uint32 i = 0;
i < mcv->nitems;
i++)
2066 {
2068
2070 {
2071 *
basesel += mcv->items[
i].base_frequency;
2072 s += mcv->items[
i].frequency;
2073 }
2074 }
2075
2076 return s;
2077}
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2123{
2126
2127
2130
2131
2133 stat->exprs, mcv,
false);
2134
2135
2136
2137
2138
2139
2144 for (
uint32 i = 0;
i < mcv->nitems;
i++)
2145 {
2147
2149 {
2150 s += mcv->items[
i].frequency;
2151 *
basesel += mcv->items[
i].base_frequency;
2152
2154 {
2157 }
2158 }
2159
2160
2162 }
2163
2165
2166 return s;
2167}
2168
2169
2170
2171
2172void
2174{
2176 {
2178
2181 }
2183}
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2202{
2206
2207
2208
2209
2212
2217
2218
2220 {
2222
2227 }
2228
2229
2230
2231
2232
2233
2234
2236 {
2241
2244
2245
2247
2249 {
2251
2253 {
2254
2257 }
2258 else
2259 {
2262
2265 {
2268 errmsg(
"could not parse MCV element \"%s\": incorrect value", s)));
2271 }
2272
2274 }
2275
2277 }
2278 }
2279
2280
2281
2282
2283
2284
2286
2288 {
2291
2293
2295 elog(
ERROR,
"cache lookup failed for type %u", typid);
2296
2298
2302 }
2303
2305
2307 {
2309 }
2311
2314
2316 {
2319 errmsg(
"could not import MCV list")));
2321 }
2322
2324
2328}
Datum idx(PG_FUNCTION_ARGS)
#define DatumGetArrayTypeP(X)
ArrayBuildState * accumArrayResult(ArrayBuildState *astate, Datum dvalue, bool disnull, Oid element_type, MemoryContext rcontext)
Datum makeArrayResult(ArrayBuildState *astate, MemoryContext rcontext)
void deconstruct_array(const ArrayType *array, Oid elmtype, int elmlen, bool elmbyval, char elmalign, Datum **elemsp, bool **nullsp, int *nelemsp)
int bms_num_members(const Bitmapset *a)
int bms_member_index(Bitmapset *a, int x)
static Datum values[MAXATTR]
#define TextDatumGetCString(d)
Datum byteaout(PG_FUNCTION_ARGS)
Datum byteasend(PG_FUNCTION_ARGS)
#define PG_USED_FOR_ASSERTS_ONLY
#define Assert(condition)
memcpy(sums, checksumBaseOffsets, sizeof(checksumBaseOffsets))
int errcode(int sqlerrcode)
#define ereport(elevel,...)
bool equal(const void *a, const void *b)
TupleDesc BlessTupleDesc(TupleDesc tupdesc)
AttInMetadata * TupleDescGetAttInMetadata(TupleDesc tupdesc)
struct SortSupportData * SortSupport
int compare_scalars_simple(const void *a, const void *b, void *arg)
int compare_datums_simple(Datum a, Datum b, SortSupport ssup)
SortItem * build_sorted_items(StatsBuildData *data, int *nitems, MultiSortSupport mss, int numattrs, AttrNumber *attnums)
int multi_sort_compare(const void *a, const void *b, void *arg)
MultiSortSupport multi_sort_init(int ndims)
void multi_sort_add_dimension(MultiSortSupport mss, int sortdim, Oid oper, Oid collation)
bool examine_opclause_args(List *args, Node **exprp, Const **cstp, bool *expronleftp)
MultiSortSupportData * MultiSortSupport
#define palloc_array(type, count)
#define palloc0_array(type, count)
#define palloc0_object(type)
Datum FunctionCall2Coll(FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2)
void fmgr_info(Oid functionId, FmgrInfo *finfo)
bool InputFunctionCallSafe(FmgrInfo *flinfo, char *str, Oid typioparam, int32 typmod, Node *escontext, Datum *result)
#define PG_DETOAST_DATUM(datum)
#define FunctionCall1(flinfo, arg1)
#define PG_GETARG_BYTEA_P(n)
#define DatumGetByteaP(X)
TypeFuncClass get_call_result_type(FunctionCallInfo fcinfo, Oid *resultTypeId, TupleDesc *resultTupleDesc)
#define SRF_IS_FIRSTCALL()
#define SRF_PERCALL_SETUP()
#define SRF_RETURN_NEXT(_funcctx, _result)
#define SRF_FIRSTCALL_INIT()
static Datum HeapTupleGetDatum(const HeapTupleData *tuple)
#define SRF_RETURN_DONE(_funcctx)
HeapTuple heap_form_tuple(TupleDesc tupleDescriptor, const Datum *values, const bool *isnull)
#define HeapTupleIsValid(tuple)
static void * GETSTRUCT(const HeapTupleData *tuple)
void getTypeOutputInfo(Oid type, Oid *typOutput, bool *typIsVarlena)
void get_typlenbyvalalign(Oid typid, int16 *typlen, bool *typbyval, char *typalign)
RegProcedure get_opcode(Oid opno)
void getTypeInputInfo(Oid type, Oid *typInput, Oid *typIOParam)
void statext_mcv_free(MCVList *mcvlist)
Datum pg_stats_ext_mcvlist_items(PG_FUNCTION_ARGS)
Datum pg_mcv_list_in(PG_FUNCTION_ARGS)
MCVList * statext_mcv_deserialize(bytea *data)
Selectivity mcv_clauselist_selectivity(PlannerInfo *root, StatisticExtInfo *stat, List *clauses, int varRelid, JoinType jointype, SpecialJoinInfo *sjinfo, RelOptInfo *rel, Selectivity *basesel, Selectivity *totalsel)
static MultiSortSupport build_mss(StatsBuildData *data)
static int compare_sort_item_count(const void *a, const void *b, void *arg)
MCVList * statext_mcv_load(Oid mvoid, bool inh)
Datum pg_mcv_list_out(PG_FUNCTION_ARGS)
static int count_distinct_groups(int numrows, SortItem *items, MultiSortSupport mss)
Datum statext_mcv_import(int elevel, int numattrs, Oid *atttypids, int32 *atttypmods, Oid *atttypcolls, int nitems, Datum *mcv_elems, bool *mcv_nulls, float8 *freqs, float8 *base_freqs)
Datum pg_mcv_list_send(PG_FUNCTION_ARGS)
#define SizeOfMCVList(ndims, nitems)
static bool * mcv_get_match_bitmap(PlannerInfo *root, List *clauses, Bitmapset *keys, List *exprs, MCVList *mcvlist, bool is_or)
#define RESULT_MERGE(value, is_or, match)
static double get_mincount_for_mcv_list(int samplerows, double totalrows)
Selectivity mcv_combine_selectivities(Selectivity simple_sel, Selectivity mcv_sel, Selectivity mcv_basesel, Selectivity mcv_totalsel)
Selectivity mcv_clause_selectivity_or(PlannerInfo *root, StatisticExtInfo *stat, MCVList *mcv, Node *clause, bool **or_matches, Selectivity *basesel, Selectivity *overlap_mcvsel, Selectivity *overlap_basesel, Selectivity *totalsel)
#define RESULT_IS_FINAL(value, is_or)
static int mcv_match_expression(Node *expr, Bitmapset *keys, List *exprs, Oid *collid)
MCVList * statext_mcv_build(StatsBuildData *data, double totalrows, int stattarget)
Datum pg_mcv_list_recv(PG_FUNCTION_ARGS)
static int sort_item_compare(const void *a, const void *b, void *arg)
static SortItem ** build_column_frequencies(SortItem *groups, int ngroups, MultiSortSupport mss, int *ncounts)
bytea * statext_mcv_serialize(MCVList *mcvlist, VacAttrStats **stats)
static SortItem * build_distinct_groups(int numrows, SortItem *items, MultiSortSupport mss, int *ndistinct)
void * repalloc(void *pointer, Size size)
void pfree(void *pointer)
void * palloc0(Size size)
MemoryContext CurrentMemoryContext
Oid exprCollation(const Node *expr)
static bool is_andclause(const void *clause)
static bool is_orclause(const void *clause)
static bool is_opclause(const void *clause)
static bool is_notclause(const void *clause)
#define IsA(nodeptr, _type_)
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
static int list_length(const List *l)
END_CATALOG_STRUCT typedef FormData_pg_type * Form_pg_type
void * bsearch_arg(const void *key, const void *base0, size_t nmemb, size_t size, int(*compar)(const void *, const void *, void *), void *arg)
void qsort_interruptible(void *base, size_t nel, size_t elsize, qsort_arg_comparator cmp, void *arg)
static bool DatumGetBool(Datum X)
static Datum BoolGetDatum(bool X)
static Datum ObjectIdGetDatum(Oid X)
static char * DatumGetCString(Datum X)
static Pointer DatumGetPointer(Datum X)
static Datum Float8GetDatum(float8 X)
static Datum Int32GetDatum(int32 X)
#define PointerGetDatum(X)
#define CLAMP_PROBABILITY(p)
void PrepareSortSupportFromOrderingOp(Oid orderingOp, SortSupport ssup)
static int ApplySortComparator(Datum datum1, bool isNull1, Datum datum2, bool isNull2, SortSupport ssup)
#define STATS_MCV_TYPE_BASIC
#define STATS_MCVLIST_MAX_ITEMS
#define STATS_MAX_DIMENSIONS
SortSupportData ssup[FLEXIBLE_ARRAY_MEMBER]
NullTestType nulltesttype
void ReleaseSysCache(HeapTuple tuple)
HeapTuple SearchSysCache2(SysCacheIdentifier cacheId, Datum key1, Datum key2)
Datum SysCacheGetAttr(SysCacheIdentifier cacheId, HeapTuple tup, AttrNumber attributeNumber, bool *isNull)
#define SearchSysCacheCopy1(cacheId, key1)
static Datum fetch_att(const void *T, bool attbyval, int attlen)
static void store_att_byval(void *T, Datum newdatum, int attlen)
TypeCacheEntry * lookup_type_cache(Oid type_id, int flags)
static Size VARSIZE_ANY(const void *PTR)
static Size VARSIZE_ANY_EXHDR(const void *PTR)
static char * VARDATA(const void *PTR)
static char * VARDATA_ANY(const void *PTR)
static void SET_VARSIZE(void *PTR, Size len)
text * cstring_to_text(const char *s)