PostgreSQL Source Code: src/backend/access/gin/gininsert.c Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
16
36
37
38
39#define PARALLEL_KEY_GIN_SHARED UINT64CONST(0xB000000000000001)
40#define PARALLEL_KEY_TUPLESORT UINT64CONST(0xB000000000000002)
41#define PARALLEL_KEY_QUERY_TEXT UINT64CONST(0xB000000000000003)
42#define PARALLEL_KEY_WAL_USAGE UINT64CONST(0xB000000000000004)
43#define PARALLEL_KEY_BUFFER_USAGE UINT64CONST(0xB000000000000005)
44
45
46
47
48
50{
51
52
53
54
55
60
61
62
63
64
65
66
68
69
70
71
72
73
74
76
77
78
79
80
81
82
83
84
85
86
90
91
92
93
94
95
97
98
99
100
101
102
103
104#define ParallelTableScanFromGinBuildShared(shared) \
105 (ParallelTableScanDesc) ((char *) (shared) + BUFFERALIGN(sizeof(GinBuildShared)))
106
107
108
109
111{
112
114
115
116
117
118
119
120
122
123
124
125
126
127
128
129
130
131
138
139typedef struct
140{
149
150
151
152
153
156
157
160
161
162
163
164
165
167
168
169
170
171
172
173
176
177
178
180 bool isconcurrent, int request);
192
195
200
201
202
203
204
205
206
207
213{
219 *oldItems;
220 int oldNPosting,
221 newNPosting;
223
225
228
229
231
233 oldItems, oldNPosting,
234 &newNPosting);
235
236
237 res = NULL;
239 NULL);
241 if (compressedList)
242 {
244 (char *) compressedList,
246 newNPosting,
247 false);
248 pfree(compressedList);
249 }
250 if (!res)
251 {
252
254
255
256
257
258
259
261 oldItems,
262 oldNPosting,
263 buildStats,
264 buffer);
265
266
269 buildStats);
270
271
274 }
276
277 return res;
278}
279
280
281
282
283
284
285
286
287
293{
296
297
299 if (compressedList)
300 {
302 (char *) compressedList,
304 nitem, false);
305 pfree(compressedList);
306 }
307 if (!res)
308 {
309
311
312
313
314
315
317
318
319
320
322 buildStats, buffer);
323
324
326 }
327
328 return res;
329}
330
331
332
333
334
335
336
337
338void
343{
349
351
353 btree.isBuild = (buildStats != NULL);
354
357
358 if (btree.findItem(&btree, stack))
359 {
360
362
364 {
365
367
368
371
372
375 buildStats);
376 return;
377 }
378
381
383 items, nitem, buildStats, stack->buffer);
384
386 }
387 else
388 {
391
393 items, nitem, buildStats, stack->buffer);
394
395
396
397
398
399 if (buildStats)
401 }
402
403
404 insertdata.entry = itup;
405 ginInsertValue(&btree, stack, &insertdata, buildStats);
407}
408
409
410
411
412
413
414
415static void
419{
424
428 &nentries, &categories);
430
432 entries, categories, nentries);
433
434 buildstate->indtuples += nentries;
435
437}
438
439static void
441 bool *isnull, bool tupleIsAlive, void *state)
442{
445 int i;
446
448
452
453
455 {
461
464 &attnum, &key, &category, &nlist)) != NULL)
465 {
466
470 }
471
474 }
475
477}
478
479
480
481
482
483static void
485{
492
495 &attnum, &key, &category, &nlist)) != NULL)
496 {
497
499
500
503
504
506
508 key, attr->attlen, attr->attbyval,
509 list, nlist, &tuplen);
510
512
514 }
515
518}
519
520
521
522
523
524
525
526
527
528
529
530
531
532static void
534 bool *isnull, bool tupleIsAlive, void *state)
535{
538 int i;
539
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
561
562
563 buildstate->tid = *tid;
564
568
569
570
571
572
573
576
578}
579
582{
584 double reltuples;
588 MetaBuffer;
595
597 elog(ERROR, "index \"%s\" already contains data",
599
603
604
609
610
612
613
615
621
622
626
627
629
630
631
632
633
635 "Gin build temporary context",
637
638
639
640
641
643 "Gin build temporary context for user-defined function",
645
648
649
652
653
654
655
656
657
658
659
660
661
665
666
667
668
669
670
671
672
673
674
675 if (state->bs_leader)
676 {
678
680 coordinate->isWorker = false;
682 state->bs_leader->nparticipanttuplesorts;
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707 state->bs_sortstate =
711
712
714
716 }
717 else
718 {
719
720
721
722
725
726
730 &attnum, &key, &category, &nlist)) != NULL)
731 {
732
736 }
738 }
739
742
743
744
745
748
749
750
751
752
754 {
757 true);
758 }
759
760
761
762
764
767
768 return result;
769}
770
771
772
773
774void
776{
778 MetaBuffer;
779
780
785
786
795
796
799}
800
801
802
803
804
805static void
809{
813 nentries;
814
816 &nentries, &categories);
817
818 for (i = 0; i < nentries; i++)
820 item, 1, NULL);
821}
822
823bool
827 bool indexUnchanged,
829{
833 int i;
834
835
836 if (ginstate == NULL)
837 {
843 }
844
846 "Gin insert temporary context",
848
850
852 {
854
856
861 ht_ctid);
862
864 }
865 else
866 {
870 ht_ctid);
871 }
872
875
876 return false;
877}
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895static void
897 bool isconcurrent, int request)
898{
900 int scantuplesortstates;
902 Size estginshared;
903 Size estsort;
909 bool leaderparticipates = true;
910 int querylen;
911
912#ifdef DISABLE_LEADER_PARTICIPATION
913 leaderparticipates = false;
914#endif
915
916
917
918
922 request);
923
924 scantuplesortstates = leaderparticipates ? request + 1 : request;
925
926
927
928
929
930
931
932
933 if (!isconcurrent)
935 else
937
938
939
940
945
947
948
949
950
951
952
953
954
955
962
963
965 {
969 }
970 else
971 querylen = 0;
972
973
975
976
977 if (pcxt->seg == NULL)
978 {
983 return;
984 }
985
986
988
993
996
997
1001
1004 snapshot);
1005
1006
1007
1008
1009
1012 pcxt->seg);
1013
1016
1017
1019 {
1020 char *sharedquery;
1021
1025 }
1026
1027
1028
1029
1030
1037
1038
1040 ginleader->pcxt = pcxt;
1042 if (leaderparticipates)
1044 ginleader->ginshared = ginshared;
1046 ginleader->snapshot = snapshot;
1047 ginleader->walusage = walusage;
1049
1050
1052 {
1054 return;
1055 }
1056
1057
1058 buildstate->bs_leader = ginleader;
1059
1060
1061 if (leaderparticipates)
1063
1064
1065
1066
1067
1069}
1070
1071
1072
1073
1074static void
1076{
1077 int i;
1078
1079
1081
1082
1083
1084
1085
1088
1089
1094}
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105static double
1107{
1109 int nparticipanttuplesorts;
1110
1111 nparticipanttuplesorts = state->bs_leader->nparticipanttuplesorts;
1112 for (;;)
1113 {
1116 {
1117
1120
1122 break;
1123 }
1125
1127 WAIT_EVENT_PARALLEL_CREATE_INDEX_SCAN);
1128 }
1129
1131
1132 return state->bs_reltuples;
1133}
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1148{
1153
1154
1157
1158
1160
1161
1167
1168
1169
1170
1171
1172static void
1174{
1175#ifdef USE_ASSERT_CHECKING
1176
1179
1180 for (int i = 0; i < buffer->nitems; i++)
1181 {
1183
1184
1185 if (i == 0)
1186 continue;
1187
1189 }
1190#endif
1191}
1192
1193
1194
1195
1196
1197
1198
1199static void
1201{
1202#ifdef USE_ASSERT_CHECKING
1203
1205
1206
1207
1208
1209
1210 if (buffer->nitems == 0)
1211 return;
1212
1213
1215#endif
1216}
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1230{
1232 int i,
1233 nKeys;
1235
1236
1237
1238
1239
1240
1242
1244
1246
1247
1248
1249
1250
1251 for (i = 0; i < nKeys; i++)
1252 {
1253 Oid cmpFunc;
1256
1259
1262
1266
1268
1269
1270
1271
1272
1275 {
1277
1282 (errcode(ERRCODE_UNDEFINED_FUNCTION),
1283 errmsg("could not identify a comparison function for type %s",
1285
1287 }
1288
1290 }
1291
1292 return buffer;
1293}
1294
1295
1296static bool
1298{
1299 return (buffer->nitems == 0);
1300}
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312static bool
1314{
1315 int r;
1317
1319
1321 return false;
1322
1323
1326
1328 return false;
1329
1330
1331
1332
1333
1335 return true;
1336
1337
1338
1339
1340
1342
1344 tupkey, false,
1346
1347 return (r == 0);
1348}
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374static bool
1376{
1377
1378 if (buffer->nfrozen < 1024)
1379 return false;
1380
1381
1383 return false;
1384
1385
1386
1387
1388
1389 return true;
1390}
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415static void
1417{
1420
1422
1425
1426
1428 {
1432
1435
1438 else
1440 }
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456 if ((buffer->nitems > 0) &&
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1475 {
1476
1479 break;
1480
1482 }
1483
1484
1485 {
1486 int nnew;
1488
1489
1490
1491
1492
1493
1494 if (buffer->items == NULL)
1496 else
1499
1501 (buffer->nitems - buffer->nfrozen),
1503
1505
1506 memcpy(&buffer->items[buffer->nfrozen], new,
1508
1510
1512
1514 }
1515
1516
1518}
1519
1520
1521
1522
1523
1524static void
1526{
1528
1529
1532
1533
1534
1535
1536
1538
1544
1547}
1548
1549
1550
1551
1552
1553
1554static void
1556{
1558
1561
1564}
1565
1566
1567
1568
1569
1570static void
1572{
1573 if (buffer->items)
1575
1576
1580
1582}
1583
1584
1585
1586
1587
1588
1589
1590static bool
1592{
1593
1595 return true;
1596
1597
1599}
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612static double
1614{
1616 Size tuplen;
1617 double reltuples = 0;
1619
1620
1621 double numtuples = 0;
1622
1623
1625
1626
1629
1630
1632
1633
1634
1635
1636
1637
1638
1640
1641
1642
1643
1644
1645 {
1646 const int progress_index[] = {
1651 };
1652 const int64 progress_vals[] = {
1654 state->bs_numtuples,
1655 0, 0
1656 };
1657
1659 }
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1671 {
1673
1675
1676
1677
1678
1679
1680
1682 {
1683
1684
1685
1686
1687
1689
1691
1695
1698
1699
1701 }
1702
1703
1704
1705
1706
1707
1708
1709
1711 {
1713
1714
1715
1716
1717
1718
1720
1722
1726
1729
1730
1732 }
1733
1734
1735
1736
1737
1739
1740
1742 ++numtuples);
1743 }
1744
1745
1747 {
1749
1753
1754
1756
1757
1759 ++numtuples);
1760 }
1761
1762
1764
1766
1767 return reltuples;
1768}
1769
1770
1771
1772
1773
1776{
1777
1780}
1781
1782
1783
1784
1785static void
1787{
1789 int sortmem;
1790
1791
1792
1793
1794
1795
1797
1798
1801 sortmem, true);
1802}
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818static void
1821{
1823 Size tuplen;
1824
1826
1827
1828
1829
1830
1831
1832
1833
1835
1836
1840
1842
1843
1844 state->bs_numtuples = 0;
1845
1849
1850
1851
1852
1853
1855 {
1856
1858
1859
1860
1861
1862
1863
1865 {
1867 Size ntuplen;
1868
1869
1870
1871
1872
1873
1875
1878 buffer->items, buffer->nitems, &ntuplen);
1879
1881 state->bs_numtuples++;
1882
1884
1885
1887 }
1888
1889
1890
1891
1892
1893
1894
1895
1897 {
1899 Size ntuplen;
1900
1902
1903
1904
1905
1906
1907
1909
1913
1915
1917
1918
1920 }
1921
1922
1923
1924
1925
1927 }
1928
1929
1931 {
1933 Size ntuplen;
1934
1936
1939 buffer->items, buffer->nitems, &ntuplen);
1940
1942 state->bs_numtuples++;
1943
1945
1946
1948 }
1949
1950
1952
1954}
1955
1956
1957
1958
1959
1960
1961
1962
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
1996static void
2001{
2004 double reltuples;
2006
2007
2009 coordinate->isWorker = true;
2011 coordinate->sharedsort = sharedsort;
2012
2013
2014 state->work_mem = (sortmem / 2);
2015
2016
2018 state->work_mem,
2019 coordinate,
2021
2022
2024 state->work_mem,
2025 NULL,
2027
2028
2031
2034
2037
2038
2040
2041
2042
2043
2044
2045
2047
2048
2050
2051 state->bs_reltuples += reltuples;
2052
2053
2054
2055
2061
2062
2064
2066}
2067
2068
2069
2070
2071void
2073{
2074 char *sharedquery;
2084 int sortmem;
2085
2086
2087
2088
2089
2092
2093
2096
2097
2099
2100
2102
2103
2105 {
2108 }
2109 else
2110 {
2113 }
2114
2115
2118
2119
2124
2125
2126
2127
2128
2130 "Gin build temporary context",
2132
2133
2134
2135
2136
2138 "Gin build temporary context for user-defined function",
2140
2143
2144
2145
2148
2149
2151
2152
2153
2154
2155
2156
2158
2160 heapRel, indexRel, sortmem, false);
2161
2162
2167
2170}
2171
2172
2173
2174
2175typedef struct
2176{
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2204{
2206 char *ptr;
2207
2208 Size tuplen;
2209 int keylen;
2210
2213 int ncompressed;
2214 Size compresslen;
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2230 keylen = 0;
2231 else if (typbyval)
2232 keylen = sizeof(Datum);
2233 else if (typlen > 0)
2234 keylen = typlen;
2235 else if (typlen == -1)
2237 else if (typlen == -2)
2239 else
2240 elog(ERROR, "unexpected typlen value (%d)", typlen);
2241
2242
2243 ncompressed = 0;
2244 compresslen = 0;
2246
2247
2248 while (ncompressed < nitems)
2249 {
2250 int cnt;
2252
2254 (nitems - ncompressed),
2255 UINT16_MAX,
2256 &cnt);
2257
2258 ncompressed += cnt;
2260
2262 }
2263
2264
2265
2266
2267
2268
2270
2271 *len = tuplen;
2272
2273
2274
2275
2276
2277
2278
2279
2280 tuple = palloc0(tuplen);
2281
2282 tuple->tuplen = tuplen;
2283 tuple->attrnum = attrnum;
2285 tuple->keylen = keylen;
2287
2288
2289 tuple->typlen = typlen;
2291
2292
2293
2294
2295
2297 {
2298 if (typbyval)
2299 {
2301 }
2302 else if (typlen > 0)
2303 {
2305 }
2306 else if (typlen == -1)
2307 {
2309 }
2310 else if (typlen == -2)
2311 {
2313 }
2314 }
2315
2316
2318
2319
2321 {
2323
2325
2327
2329
2332 }
2333
2334 return tuple;
2335}
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2350{
2352
2354 return (Datum) 0;
2355
2356 if (a->typbyval)
2357 {
2358 memcpy(&key, a->data, a->keylen);
2359 return key;
2360 }
2361
2363}
2364
2365
2366
2367
2368
2371{
2372 int len;
2373 char *ptr;
2374 int ndecoded;
2376
2379
2381
2382 Assert(ndecoded == a->nitems);
2383
2385}
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401int
2403{
2404 int r;
2406 keyb;
2407
2408 if (a->attrnum < b->attrnum)
2409 return -1;
2410
2411 if (a->attrnum > b->attrnum)
2412 return 1;
2413
2414 if (a->category < b->category)
2415 return -1;
2416
2417 if (a->category > b->category)
2418 return 1;
2419
2421 {
2424
2426 keyb, false,
2427 &ssup[a->attrnum - 1]);
2428
2429
2432 }
2433
2436}
void InitializeParallelDSM(ParallelContext *pcxt)
void WaitForParallelWorkersToFinish(ParallelContext *pcxt)
void LaunchParallelWorkers(ParallelContext *pcxt)
void DestroyParallelContext(ParallelContext *pcxt)
ParallelContext * CreateParallelContext(const char *library_name, const char *function_name, int nworkers)
void WaitForParallelWorkersToAttach(ParallelContext *pcxt)
void pgstat_progress_update_param(int index, int64 val)
void pgstat_progress_update_multi_param(int nparam, const int *index, const int64 *val)
void pgstat_report_activity(BackendState state, const char *cmd_str)
static Datum values[MAXATTR]
BlockNumber BufferGetBlockNumber(Buffer buffer)
Buffer ExtendBufferedRel(BufferManagerRelation bmr, ForkNumber forkNum, BufferAccessStrategy strategy, uint32 flags)
void UnlockReleaseBuffer(Buffer buffer)
void MarkBufferDirty(Buffer buffer)
void LockBuffer(Buffer buffer, int mode)
#define RelationGetNumberOfBlocks(reln)
static Page BufferGetPage(Buffer buffer)
static Item PageGetItem(const PageData *page, const ItemIdData *itemId)
static ItemId PageGetItemId(Page page, OffsetNumber offsetNumber)
#define OidIsValid(objectId)
bool ConditionVariableCancelSleep(void)
void ConditionVariableInit(ConditionVariable *cv)
void ConditionVariableSleep(ConditionVariable *cv, uint32 wait_event_info)
void ConditionVariableSignal(ConditionVariable *cv)
Datum datumCopy(Datum value, bool typByVal, int typLen)
int errcode(int sqlerrcode)
int errmsg(const char *fmt,...)
#define ereport(elevel,...)
char * format_type_be(Oid type_oid)
#define PROGRESS_GIN_PHASE_PERFORMSORT_2
#define PROGRESS_GIN_PHASE_MERGE_1
#define PROGRESS_GIN_PHASE_PERFORMSORT_1
#define PROGRESS_GIN_PHASE_MERGE_2
#define PROGRESS_GIN_PHASE_INDEXBUILD_TABLESCAN
#define GinGetUseFastUpdate(relation)
static ItemPointer GinTupleGetFirst(GinTuple *tup)
#define GinIsPostingTree(itup)
#define SizeOfGinPostingList(plist)
#define GinGetPostingTree(itup)
signed char GinNullCategory
#define GinSetPostingTree(itup, blkno)
void freeGinBtreeStack(GinBtreeStack *stack)
void ginInsertValue(GinBtree btree, GinBtreeStack *stack, void *insertdata, GinStatsData *buildStats)
GinBtreeStack * ginFindLeafPage(GinBtree btree, bool searchMode, bool rootConflictCheck)
void ginBeginBAScan(BuildAccumulator *accum)
ItemPointerData * ginGetBAEntry(BuildAccumulator *accum, OffsetNumber *attnum, Datum *key, GinNullCategory *category, uint32 *n)
void ginInsertBAEntries(BuildAccumulator *accum, ItemPointer heapptr, OffsetNumber attnum, Datum *entries, GinNullCategory *categories, int32 nentries)
void ginInitBA(BuildAccumulator *accum)
BlockNumber createPostingTree(Relation index, ItemPointerData *items, uint32 nitems, GinStatsData *buildStats, Buffer entrybuffer)
void ginInsertItemPointers(Relation index, BlockNumber rootBlkno, ItemPointerData *items, uint32 nitem, GinStatsData *buildStats)
ItemPointer ginReadTuple(GinState *ginstate, OffsetNumber attnum, IndexTuple itup, int *nitems)
IndexTuple GinFormTuple(GinState *ginstate, OffsetNumber attnum, Datum key, GinNullCategory category, Pointer data, Size dataSize, int nipd, bool errorTooBig)
void ginPrepareEntryScan(GinBtree btree, OffsetNumber attnum, Datum key, GinNullCategory category, GinState *ginstate)
void ginHeapTupleFastCollect(GinState *ginstate, GinTupleCollector *collector, OffsetNumber attnum, Datum value, bool isNull, ItemPointer ht_ctid)
void ginHeapTupleFastInsert(GinState *ginstate, GinTupleCollector *collector)
static void ginBuildCallbackParallel(Relation index, ItemPointer tid, Datum *values, bool *isnull, bool tupleIsAlive, void *state)
#define PARALLEL_KEY_BUFFER_USAGE
static void AssertCheckItemPointers(GinBuffer *buffer)
int _gin_compare_tuples(GinTuple *a, GinTuple *b, SortSupport ssup)
struct GinBuffer GinBuffer
struct GinLeader GinLeader
static IndexTuple addItemPointersToLeafTuple(GinState *ginstate, IndexTuple old, ItemPointerData *items, uint32 nitem, GinStatsData *buildStats, Buffer buffer)
static bool GinBufferIsEmpty(GinBuffer *buffer)
#define PARALLEL_KEY_GIN_SHARED
IndexBuildResult * ginbuild(Relation heap, Relation index, IndexInfo *indexInfo)
static GinBuffer * GinBufferInit(Relation index)
static IndexTuple buildFreshLeafTuple(GinState *ginstate, OffsetNumber attnum, Datum key, GinNullCategory category, ItemPointerData *items, uint32 nitem, GinStatsData *buildStats, Buffer buffer)
static void GinBufferReset(GinBuffer *buffer)
static void ginHeapTupleBulkInsert(GinBuildState *buildstate, OffsetNumber attnum, Datum value, bool isNull, ItemPointer heapptr)
static void AssertCheckGinBuffer(GinBuffer *buffer)
static void _gin_parallel_scan_and_build(GinBuildState *state, GinBuildShared *ginshared, Sharedsort *sharedsort, Relation heap, Relation index, int sortmem, bool progress)
void ginEntryInsert(GinState *ginstate, OffsetNumber attnum, Datum key, GinNullCategory category, ItemPointerData *items, uint32 nitem, GinStatsData *buildStats)
static void GinBufferTrim(GinBuffer *buffer)
static Size _gin_parallel_estimate_shared(Relation heap, Snapshot snapshot)
static void _gin_end_parallel(GinLeader *ginleader, GinBuildState *state)
static void _gin_begin_parallel(GinBuildState *buildstate, Relation heap, Relation index, bool isconcurrent, int request)
static void ginFlushBuildState(GinBuildState *buildstate, Relation index)
struct GinBuildShared GinBuildShared
static void _gin_process_worker_data(GinBuildState *state, Tuplesortstate *worker_sort, bool progress)
static bool GinBufferKeyEquals(GinBuffer *buffer, GinTuple *tup)
static double _gin_parallel_merge(GinBuildState *state)
static void ginHeapTupleInsert(GinState *ginstate, OffsetNumber attnum, Datum value, bool isNull, ItemPointer item)
static bool GinBufferCanAddKey(GinBuffer *buffer, GinTuple *tup)
void _gin_parallel_build_main(dsm_segment *seg, shm_toc *toc)
void ginbuildempty(Relation index)
bool gininsert(Relation index, Datum *values, bool *isnull, ItemPointer ht_ctid, Relation heapRel, IndexUniqueCheck checkUnique, bool indexUnchanged, IndexInfo *indexInfo)
static void _gin_leader_participate_as_worker(GinBuildState *buildstate, Relation heap, Relation index)
static GinTuple * _gin_build_tuple(OffsetNumber attrnum, unsigned char category, Datum key, int16 typlen, bool typbyval, ItemPointerData *items, uint32 nitems, Size *len)
static Datum _gin_parse_tuple_key(GinTuple *a)
#define PARALLEL_KEY_TUPLESORT
static bool GinBufferShouldTrim(GinBuffer *buffer, GinTuple *tup)
#define PARALLEL_KEY_QUERY_TEXT
static void GinBufferFree(GinBuffer *buffer)
static ItemPointer _gin_parse_tuple_items(GinTuple *a)
#define ParallelTableScanFromGinBuildShared(shared)
#define PARALLEL_KEY_WAL_USAGE
static void GinBufferStoreTuple(GinBuffer *buffer, GinTuple *tup)
static void ginBuildCallback(Relation index, ItemPointer tid, Datum *values, bool *isnull, bool tupleIsAlive, void *state)
static double _gin_parallel_heapscan(GinBuildState *state)
ItemPointer ginPostingListDecodeAllSegments(GinPostingList *segment, int len, int *ndecoded_out)
GinPostingList * ginCompressPostingList(const ItemPointer ipd, int nipd, int maxsize, int *nwritten)
ItemPointer ginMergeItemPointers(ItemPointerData *a, uint32 na, ItemPointerData *b, uint32 nb, int *nmerged)
OffsetNumber gintuple_get_attrnum(GinState *ginstate, IndexTuple tuple)
Buffer GinNewBuffer(Relation index)
void GinInitBuffer(Buffer b, uint32 f)
Datum * ginExtractEntries(GinState *ginstate, OffsetNumber attnum, Datum value, bool isNull, int32 *nentries, GinNullCategory **categories)
Datum gintuple_get_key(GinState *ginstate, IndexTuple tuple, GinNullCategory *category)
void GinInitMetabuffer(Buffer b)
void initGinState(GinState *state, Relation index)
void ginUpdateStats(Relation index, const GinStatsData *stats, bool is_build)
Assert(PointerIsAligned(start, uint64))
static void dlist_init(dlist_head *head)
static void dlist_delete(dlist_node *node)
#define dlist_foreach_modify(iter, lhead)
static void dlist_push_tail(dlist_head *head, dlist_node *node)
#define dlist_container(type, membername, ptr)
IndexInfo * BuildIndexInfo(Relation index)
void index_close(Relation relation, LOCKMODE lockmode)
RegProcedure index_getprocid(Relation irel, AttrNumber attnum, uint16 procnum)
Relation index_open(Oid relationId, LOCKMODE lockmode)
void InstrAccumParallelQuery(BufferUsage *bufusage, WalUsage *walusage)
void InstrEndParallelQuery(BufferUsage *bufusage, WalUsage *walusage)
void InstrStartParallelQuery(void)
if(TABLE==NULL||TABLE_index==NULL)
int32 ItemPointerCompare(ItemPointer arg1, ItemPointer arg2)
static bool ItemPointerIsValid(const ItemPointerData *pointer)
IndexTupleData * IndexTuple
#define AccessExclusiveLock
#define ShareUpdateExclusiveLock
void MemoryContextReset(MemoryContext context)
void * repalloc(void *pointer, Size size)
void pfree(void *pointer)
void * palloc0(Size size)
MemoryContext CurrentMemoryContext
void MemoryContextDelete(MemoryContext context)
#define AllocSetContextCreate
#define ALLOCSET_DEFAULT_SIZES
#define START_CRIT_SECTION()
#define CHECK_FOR_INTERRUPTS()
#define END_CRIT_SECTION()
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
FormData_pg_attribute * Form_pg_attribute
const char * debug_query_string
static Datum PointerGetDatum(const void *X)
static Pointer DatumGetPointer(Datum X)
void CheckForSerializableConflictIn(Relation relation, ItemPointer tid, BlockNumber blkno)
#define PROGRESS_CREATEIDX_TUPLES_TOTAL
#define PROGRESS_SCAN_BLOCKS_DONE
#define PROGRESS_CREATEIDX_TUPLES_DONE
#define PROGRESS_CREATEIDX_SUBPHASE
#define PROGRESS_SCAN_BLOCKS_TOTAL
#define RelationGetRelid(relation)
#define RelationGetDescr(relation)
#define RelationGetRelationName(relation)
#define RelationNeedsWAL(relation)
#define IndexRelationGetNumberOfKeyAttributes(relation)
void * shm_toc_allocate(shm_toc *toc, Size nbytes)
void shm_toc_insert(shm_toc *toc, uint64 key, void *address)
void * shm_toc_lookup(shm_toc *toc, uint64 key, bool noError)
#define shm_toc_estimate_chunk(e, sz)
#define shm_toc_estimate_keys(e, cnt)
Size add_size(Size s1, Size s2)
Size mul_size(Size s1, Size s2)
Snapshot GetTransactionSnapshot(void)
void UnregisterSnapshot(Snapshot snapshot)
Snapshot RegisterSnapshot(Snapshot snapshot)
#define IsMVCCSnapshot(snapshot)
void PrepareSortSupportComparisonShim(Oid cmpFunc, SortSupport ssup)
static int ApplySortComparator(Datum datum1, bool isNull1, Datum datum2, bool isNull2, SortSupport ssup)
#define SpinLockInit(lock)
#define SpinLockRelease(lock)
#define SpinLockAcquire(lock)
bool(* findItem)(GinBtree, GinBtreeStack *)
Tuplesortstate * bs_worker_sort
Tuplesortstate * bs_sortstate
int nparticipanttuplesorts
BufferUsage * bufferusage
GinBuildShared * ginshared
char data[FLEXIBLE_ARRAY_MEMBER]
shm_toc_estimator estimator
void table_close(Relation relation, LOCKMODE lockmode)
Relation table_open(Oid relationId, LOCKMODE lockmode)
TableScanDesc table_beginscan_parallel(Relation relation, ParallelTableScanDesc pscan)
Size table_parallelscan_estimate(Relation rel, Snapshot snapshot)
void table_parallelscan_initialize(Relation rel, ParallelTableScanDesc pscan, Snapshot snapshot)
static double table_index_build_scan(Relation table_rel, Relation index_rel, struct IndexInfo *index_info, bool allow_sync, bool progress, IndexBuildCallback callback, void *callback_state, TableScanDesc scan)
static FormData_pg_attribute * TupleDescAttr(TupleDesc tupdesc, int i)
void tuplesort_performsort(Tuplesortstate *state)
void tuplesort_initialize_shared(Sharedsort *shared, int nWorkers, dsm_segment *seg)
Size tuplesort_estimate_shared(int nWorkers)
void tuplesort_end(Tuplesortstate *state)
void tuplesort_attach_shared(Sharedsort *shared, dsm_segment *seg)
struct SortCoordinateData * SortCoordinate
Tuplesortstate * tuplesort_begin_index_gin(Relation heapRel, Relation indexRel, int workMem, SortCoordinate coordinate, int sortopt)
GinTuple * tuplesort_getgintuple(Tuplesortstate *state, Size *len, bool forward)
void tuplesort_putgintuple(Tuplesortstate *state, GinTuple *tuple, Size size)
TypeCacheEntry * lookup_type_cache(Oid type_id, int flags)
#define TYPECACHE_CMP_PROC_FINFO
void ExitParallelMode(void)
void EnterParallelMode(void)
void log_newpage_range(Relation rel, ForkNumber forknum, BlockNumber startblk, BlockNumber endblk, bool page_std)
XLogRecPtr log_newpage_buffer(Buffer buffer, bool page_std)