PostgreSQL Source Code: src/backend/optimizer/plan/createplan.c Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
18
19#include <math.h>
20
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70#define CP_EXACT_TLIST 0x0001
71#define CP_SMALL_TLIST 0x0002
72#define CP_LABEL_TLIST 0x0004
73#define CP_IGNORE_TLIST 0x0008
74
75
77 int flags);
79 int flags);
84 List *gating_quals);
88 int flags);
90 int flags);
95 int flags);
97 int flags);
99 int flags);
103 int flags);
110 int flags);
116 int flags);
119 int flags);
122 int flags);
124 List *tlist, List *scan_clauses);
126 List *tlist, List *scan_clauses);
128 List *tlist, List *scan_clauses, bool indexonly);
131 List *tlist, List *scan_clauses);
133 List **qual, List **indexqual, List **indexECs);
136 List *tlist, List *scan_clauses);
140 List *scan_clauses);
143 List *tlist, List *scan_clauses);
145 List *tlist, List *scan_clauses);
147 List *tlist, List *scan_clauses);
149 List *tlist, List *scan_clauses);
151 List *tlist, List *scan_clauses);
153 Path *best_path, List *tlist, List *scan_clauses);
155 List *tlist, List *scan_clauses);
157 List *tlist, List *scan_clauses);
159 List *tlist, List *scan_clauses);
162 List *tlist, List *scan_clauses);
169 List **stripped_indexquals_p,
170 List **fixed_indexquals_p);
174 Node *clause, List *indexcolnos);
181 double limit_tuples);
183 List *pathkeys, double limit_tuples);
188 Oid indexid, List *indexqual, List *indexqualorig,
189 List *indexorderby, List *indexorderbyorig,
190 List *indexorderbyops,
193 Index scanrelid, Oid indexid,
194 List *indexqual, List *recheckqual,
195 List *indexorderby,
196 List *indextlist,
199 List *indexqual,
200 List *indexqualorig);
202 List *qpqual,
203 Plan *lefttree,
204 List *bitmapqualorig,
205 Index scanrelid);
207 List *tidquals);
209 Index scanrelid, List *tidrangequals);
211 List *qpqual,
213 Plan *subplan);
217 Index scanrelid, List *values_lists);
221 Index scanrelid, int ctePlanId, int cteParam);
223 Index scanrelid, char *enrname);
225 Index scanrelid, int wtParam);
227 Plan *lefttree,
228 Plan *righttree,
229 int wtParam,
230 List *distinctList,
231 long numGroups);
235 List *joinclauses, List *otherclauses, List *nestParams,
236 Plan *lefttree, Plan *righttree,
237 JoinType jointype, bool inner_unique);
239 List *joinclauses, List *otherclauses,
240 List *hashclauses,
241 List *hashoperators, List *hashcollations,
242 List *hashkeys,
243 Plan *lefttree, Plan *righttree,
244 JoinType jointype, bool inner_unique);
246 List *hashkeys,
247 Oid skewTable,
249 bool skewInherit);
251 List *joinclauses, List *otherclauses,
252 List *mergeclauses,
253 Oid *mergefamilies,
254 Oid *mergecollations,
255 bool *mergereversals,
256 bool *mergenullsfirst,
257 Plan *lefttree, Plan *righttree,
258 JoinType jointype, bool inner_unique,
259 bool skip_mark_restore);
262 Oid *collations, bool *nullsFirst);
264 int numCols, int nPresortedCols,
266 Oid *collations, bool *nullsFirst);
270 bool adjust_tlist_in_place,
271 int *p_numsortkeys,
273 Oid **p_sortOperators,
274 Oid **p_collations,
275 bool **p_nullsFirst);
279 List *pathkeys, Relids relids, int nPresortedCols);
282 Plan *lefttree);
285 Oid *collations, List *param_exprs,
286 bool singlerow, bool binary_mode,
289 int partNumCols, AttrNumber *partColIdx, Oid *partOperators, Oid *partCollations,
290 int ordNumCols, AttrNumber *ordColIdx, Oid *ordOperators, Oid *ordCollations,
291 List *runCondition, List *qual, bool topWindow,
292 Plan *lefttree);
294 AttrNumber *grpColIdx, Oid *grpOperators, Oid *grpCollations,
295 Plan *lefttree);
298 List *pathkeys, int numCols);
300 int nworkers, int rescan_param, bool single_copy, Plan *subplan);
302 List *tlist, Plan *lefttree, Plan *righttree,
303 List *groupList, long numGroups);
308 CmdType operation, bool canSetTag,
309 Index nominalRelation, Index rootRelation,
310 bool partColsUpdated,
311 List *resultRelations,
312 List *updateColnosLists,
313 List *withCheckOptionLists, List *returningLists,
315 List *mergeActionLists, List *mergeJoinConditions,
316 int epqParam);
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
338{
340
341
343
344
345 root->curOuterRels = NULL;
346 root->curOuterParams = NIL;
347
348
350
351
352
353
354
355
356
357
360
361
362
363
364
365
366
367
369
370
371 if (root->curOuterParams != NIL)
372 elog(ERROR, "failed to assign all NestLoopParams to plan nodes");
373
374
375
376
377
379
381}
382
383
384
385
386
389{
391
392
394
396 {
397 case T_SeqScan:
398 case T_SampleScan:
399 case T_IndexScan:
400 case T_IndexOnlyScan:
401 case T_BitmapHeapScan:
402 case T_TidScan:
403 case T_TidRangeScan:
404 case T_SubqueryScan:
405 case T_FunctionScan:
406 case T_TableFuncScan:
407 case T_ValuesScan:
408 case T_CteScan:
409 case T_WorkTableScan:
410 case T_NamedTuplestoreScan:
411 case T_ForeignScan:
412 case T_CustomScan:
414 break;
415 case T_HashJoin:
416 case T_MergeJoin:
417 case T_NestLoop:
420 break;
421 case T_Append:
424 flags);
425 break;
426 case T_MergeAppend:
429 flags);
430 break;
431 case T_Result:
433 {
436 flags);
437 }
439 {
442 }
444 {
447 }
448 else
449 {
450
453 }
454 break;
455 case T_ProjectSet:
458 break;
459 case T_Material:
462 flags);
463 break;
464 case T_Memoize:
467 flags);
468 break;
469 case T_Unique:
471 {
474 flags);
475 }
476 else
477 {
481 flags);
482 }
483 break;
484 case T_Gather:
487 break;
488 case T_Sort:
491 flags);
492 break;
493 case T_IncrementalSort:
496 flags);
497 break;
498 case T_Group:
501 break;
502 case T_Agg:
506 else
507 {
511 }
512 break;
513 case T_WindowAgg:
516 break;
517 case T_SetOp:
520 flags);
521 break;
522 case T_RecursiveUnion:
525 break;
526 case T_LockRows:
529 flags);
530 break;
531 case T_ModifyTable:
534 break;
535 case T_Limit:
538 flags);
539 break;
540 case T_GatherMerge:
543 break;
544 default:
545 elog(ERROR, "unrecognized node type: %d",
546 (int) best_path->pathtype);
547 plan = NULL;
548 break;
549 }
550
552}
553
554
555
556
557
560{
562 List *scan_clauses;
563 List *gating_clauses;
566
567
568
569
570
571
572
573
574
575
576
577
578
580 {
581 case T_IndexScan:
582 case T_IndexOnlyScan:
583 scan_clauses = castNode(IndexPath, best_path)->indexinfo->indrestrictinfo;
584 break;
585 default:
587 break;
588 }
589
590
591
592
593
594
595
596 if (best_path->param_info)
598 best_path->param_info->ppi_clauses);
599
600
601
602
603
604
605
606
607
608
609
611 {
612 List *join_clauses;
613
615 best_path->pathtype == T_CustomScan);
616 if (best_path->pathtype == T_ForeignScan)
617 join_clauses = ((ForeignPath *) best_path)->fdw_restrictinfo;
618 else
619 join_clauses = ((CustomPath *) best_path)->custom_restrictinfo;
620
622 }
623 else
625 if (gating_clauses)
626 flags = 0;
627
628
629
630
631
632
633
634
635
636
637
639 {
640 tlist = NULL;
641 }
643 {
644 if (best_path->pathtype == T_IndexOnlyScan)
645 {
646
648
649
650
651
652
655 }
656 else
657 {
659 if (tlist == NIL)
660 {
661
663 }
664 else
665 {
666
669 }
670 }
671 }
672 else
673 {
675 }
676
678 {
679 case T_SeqScan:
681 best_path,
682 tlist,
683 scan_clauses);
684 break;
685
686 case T_SampleScan:
688 best_path,
689 tlist,
690 scan_clauses);
691 break;
692
693 case T_IndexScan:
696 tlist,
697 scan_clauses,
698 false);
699 break;
700
701 case T_IndexOnlyScan:
704 tlist,
705 scan_clauses,
706 true);
707 break;
708
709 case T_BitmapHeapScan:
712 tlist,
713 scan_clauses);
714 break;
715
716 case T_TidScan:
719 tlist,
720 scan_clauses);
721 break;
722
723 case T_TidRangeScan:
726 tlist,
727 scan_clauses);
728 break;
729
730 case T_SubqueryScan:
733 tlist,
734 scan_clauses);
735 break;
736
737 case T_FunctionScan:
739 best_path,
740 tlist,
741 scan_clauses);
742 break;
743
744 case T_TableFuncScan:
746 best_path,
747 tlist,
748 scan_clauses);
749 break;
750
751 case T_ValuesScan:
753 best_path,
754 tlist,
755 scan_clauses);
756 break;
757
758 case T_CteScan:
760 best_path,
761 tlist,
762 scan_clauses);
763 break;
764
765 case T_NamedTuplestoreScan:
767 best_path,
768 tlist,
769 scan_clauses);
770 break;
771
772 case T_Result:
774 best_path,
775 tlist,
776 scan_clauses);
777 break;
778
779 case T_WorkTableScan:
781 best_path,
782 tlist,
783 scan_clauses);
784 break;
785
786 case T_ForeignScan:
789 tlist,
790 scan_clauses);
791 break;
792
793 case T_CustomScan:
796 tlist,
797 scan_clauses);
798 break;
799
800 default:
801 elog(ERROR, "unrecognized node type: %d",
803 plan = NULL;
804 break;
805 }
806
807
808
809
810
811
812 if (gating_clauses)
814
816}
817
818
819
820
821
822
823
826{
828 Index *sortgrouprefs = path->pathtarget->sortgrouprefs;
829 int resno = 1;
831
832 foreach(v, path->pathtarget->exprs)
833 {
836
837
838
839
840
841
842
843 if (path->param_info)
845
847 resno,
848 NULL,
849 false);
850 if (sortgrouprefs)
852
853 tlist = lappend(tlist, tle);
854 resno++;
855 }
856 return tlist;
857}
858
859
860
861
862
863
864static bool
866{
868 int i;
870
871
872
873
875 return false;
876
877
878
879
880
887 return false;
888
889
890
891
892
893
895 return false;
896
897
898
899
900
901
902
904 return false;
905
906
907
908
909
910
912 path->pathtarget->exprs == NIL)
913 return false;
914
915
916
917
918
919
921 {
923 return false;
924 }
925
926
927
928
929
930 foreach(lc, root->placeholder_list)
931 {
933
936 return false;
937 }
938
939
940
941
942
943
944 if (path->pathtype == T_IndexOnlyScan)
945 {
947
948 for (i = 0; i < indexinfo->ncolumns; i++)
949 {
950 if (!indexinfo->canreturn[i])
951 return false;
952 }
953 }
954
955
956
957
958
959
960
961
962
963
964 if ((flags & CP_LABEL_TLIST) && path->pathtarget->sortgrouprefs)
965 {
967
968 i = 0;
969 foreach(lc, path->pathtarget->exprs)
970 {
972
973 if (path->pathtarget->sortgrouprefs[i])
974 {
975 if (expr && IsA(expr, Var))
976 {
977 int attno = ((Var *) expr)->varattno;
978
981 return false;
982 sortgroupatts = bms_add_member(sortgroupatts, attno);
983 }
984 else
985 return false;
986 }
987 i++;
988 }
989 }
990
991 return true;
992}
993
994
995
996
997
998
999
1000
1001static List *
1003{
1004
1005 if (->hasPseudoConstantQuals)
1006 return NIL;
1007
1008
1010
1011
1013}
1014
1015
1016
1017
1018
1019
1020
1021static Plan *
1023 List *gating_quals)
1024{
1025 Plan *gplan;
1026 Plan *splan;
1027
1028 Assert(gating_quals);
1029
1030
1031
1032
1033
1034
1035
1036 splan = plan;
1038 {
1040
1043 splan = NULL;
1044 }
1045
1046
1047
1048
1049
1050
1052 (Node *) gating_quals,
1053 splan);
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1068
1069
1071
1072 return gplan;
1073}
1074
1075
1076
1077
1078
1079
1080static Plan *
1082{
1084 List *gating_clauses;
1085
1086 switch (best_path->path.pathtype)
1087 {
1088 case T_MergeJoin:
1091 break;
1092 case T_HashJoin:
1095 break;
1096 case T_NestLoop:
1099 break;
1100 default:
1101 elog(ERROR, "unrecognized node type: %d",
1102 (int) best_path->path.pathtype);
1103 plan = NULL;
1104 break;
1105 }
1106
1107
1108
1109
1110
1111
1113 if (gating_clauses)
1115 gating_clauses);
1116
1117#ifdef NOT_USED
1118
1119
1120
1121
1122
1123
1124 if (get_loc_restrictinfo(best_path) != NIL)
1128#endif
1129
1130 return plan;
1131}
1132
1133
1134
1135
1136
1137
1138
1139static bool
1141{
1143 {
1144 case T_SubqueryScanPath:
1145 {
1147
1148
1149
1150
1151
1153 return false;
1154
1155
1156
1157
1158
1162 break;
1163 return false;
1164 }
1165 case T_ForeignPath:
1166 {
1167 FdwRoutine *fdwroutine = path->parent->fdwroutine;
1168
1169
1170
1171
1172
1174 return false;
1175
1176 Assert(fdwroutine != NULL);
1179 break;
1180 return false;
1181 }
1182 case T_ProjectionPath:
1183
1184
1185
1186
1187
1189 return false;
1190
1191
1192
1193
1194
1197 return true;
1198 return false;
1199 default:
1200 return false;
1201 }
1202
1203 plan->async_capable = true;
1204
1205 return true;
1206}
1207
1208
1209
1210
1211
1212
1213
1214
1215static Plan *
1217{
1220 int orig_tlist_length = list_length(tlist);
1221 bool tlist_was_changed = false;
1225 int nasyncplans = 0;
1227 int nodenumsortkeys = 0;
1229 Oid *nodeSortOperators = NULL;
1230 Oid *nodeCollations = NULL;
1231 bool *nodeNullsFirst = NULL;
1232 bool consider_async = false;
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1244 {
1245
1247
1250 false)),
1251 NULL);
1252
1254
1255 return plan;
1256 }
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1270 plan->plan.targetlist = tlist;
1272 plan->plan.lefttree = NULL;
1273 plan->plan.righttree = NULL;
1275
1276 if (pathkeys != NIL)
1277 {
1278
1279
1280
1281
1282
1283
1285 best_path->path.parent->relids,
1286 NULL,
1287 true,
1288 &nodenumsortkeys,
1289 &nodeSortColIdx,
1290 &nodeSortOperators,
1291 &nodeCollations,
1292 &nodeNullsFirst);
1293 tlist_was_changed = (orig_tlist_length != list_length(plan->plan.targetlist));
1294 }
1295
1296
1300
1301
1302 foreach(subpaths, best_path->subpaths)
1303 {
1305 Plan *subplan;
1306
1307
1309
1310
1311
1312
1313
1314 if (pathkeys != NIL)
1315 {
1316 int numsortkeys;
1318 Oid *sortOperators;
1319 Oid *collations;
1320 bool *nullsFirst;
1321
1322
1323
1324
1325
1326
1327
1329 subpath->parent->relids,
1330 nodeSortColIdx,
1331 false,
1332 &numsortkeys,
1333 &sortColIdx,
1334 &sortOperators,
1335 &collations,
1336 &nullsFirst);
1337
1338
1339
1340
1341
1342
1343
1344 Assert(numsortkeys == nodenumsortkeys);
1345 if (memcmp(sortColIdx, nodeSortColIdx,
1346 numsortkeys * sizeof(AttrNumber)) != 0)
1347 elog(ERROR, "Append child's targetlist doesn't match Append");
1348 Assert(memcmp(sortOperators, nodeSortOperators,
1349 numsortkeys * sizeof(Oid)) == 0);
1350 Assert(memcmp(collations, nodeCollations,
1351 numsortkeys * sizeof(Oid)) == 0);
1352 Assert(memcmp(nullsFirst, nodeNullsFirst,
1353 numsortkeys * sizeof(bool)) == 0);
1354
1355
1357 {
1359 sortColIdx, sortOperators,
1360 collations, nullsFirst);
1361
1364 }
1365 }
1366
1367
1369 {
1371 ++nasyncplans;
1372 }
1373
1374 subplans = lappend(subplans, subplan);
1375 }
1376
1377
1378 plan->part_prune_index = -1;
1379
1380
1381
1382
1383
1384
1386 {
1387 List *prunequal;
1388
1390
1391 if (best_path->path.param_info)
1392 {
1393 List *prmquals = best_path->path.param_info->ppi_clauses;
1394
1397 (Node *) prmquals);
1398
1399 prunequal = list_concat(prunequal, prmquals);
1400 }
1401
1402 if (prunequal != NIL)
1405 prunequal);
1406 }
1407
1408 plan->appendplans = subplans;
1409 plan->nasyncplans = nasyncplans;
1411
1413
1414
1415
1416
1417
1418
1420 {
1423 plan->plan.parallel_safe);
1424 }
1425 else
1427}
1428
1429
1430
1431
1432
1433
1434
1435
1436static Plan *
1438 int flags)
1439{
1443 int orig_tlist_length = list_length(tlist);
1444 bool tlist_was_changed;
1449
1450
1451
1452
1453
1454
1455
1457 plan->targetlist = tlist;
1459 plan->lefttree = NULL;
1460 plan->righttree = NULL;
1462
1463
1464
1465
1466
1467
1468
1470 best_path->path.parent->relids,
1471 NULL,
1472 true,
1474 &node->sortColIdx,
1475 &node->sortOperators,
1476 &node->collations,
1477 &node->nullsFirst);
1478 tlist_was_changed = (orig_tlist_length != list_length(plan->targetlist));
1479
1480
1481
1482
1483
1484
1485 foreach(subpaths, best_path->subpaths)
1486 {
1488 Plan *subplan;
1489 int numsortkeys;
1491 Oid *sortOperators;
1492 Oid *collations;
1493 bool *nullsFirst;
1494
1495
1496
1498
1499
1501 subpath->parent->relids,
1502 node->sortColIdx,
1503 false,
1504 &numsortkeys,
1505 &sortColIdx,
1506 &sortOperators,
1507 &collations,
1508 &nullsFirst);
1509
1510
1511
1512
1513
1514
1515
1517 if (memcmp(sortColIdx, node->sortColIdx,
1518 numsortkeys * sizeof(AttrNumber)) != 0)
1519 elog(ERROR, "MergeAppend child's targetlist doesn't match MergeAppend");
1520 Assert(memcmp(sortOperators, node->sortOperators,
1521 numsortkeys * sizeof(Oid)) == 0);
1522 Assert(memcmp(collations, node->collations,
1523 numsortkeys * sizeof(Oid)) == 0);
1524 Assert(memcmp(nullsFirst, node->nullsFirst,
1525 numsortkeys * sizeof(bool)) == 0);
1526
1527
1529 {
1531 sortColIdx, sortOperators,
1532 collations, nullsFirst);
1533
1536 }
1537
1538 subplans = lappend(subplans, subplan);
1539 }
1540
1541
1543
1544
1545
1546
1547
1548
1550 {
1551 List *prunequal;
1552
1554
1555
1556 Assert(best_path->path.param_info == NULL);
1557
1558 if (prunequal != NIL)
1561 prunequal);
1562 }
1563
1565
1566
1567
1568
1569
1570
1572 {
1575 }
1576 else
1577 return plan;
1578}
1579
1580
1581
1582
1583
1584
1585
1586
1589{
1591 List *tlist;
1592 List *quals;
1593
1595
1596
1598
1600
1602
1603 return plan;
1604}
1605
1606
1607
1608
1609
1610
1611
1614{
1616 Plan *subplan;
1617 List *tlist;
1618
1619
1621
1623
1625
1627
1628 return plan;
1629}
1630
1631
1632
1633
1634
1635
1636
1637
1640{
1642 Plan *subplan;
1643
1644
1645
1646
1647
1648
1651
1653
1655
1656 return plan;
1657}
1658
1659
1660
1661
1662
1663
1664
1665
1668{
1671 Plan *subplan;
1672 Oid *operators;
1673 Oid *collations;
1677 int nkeys;
1678 int i;
1679
1682
1685
1688 operators = palloc(nkeys * sizeof(Oid));
1689 collations = palloc(nkeys * sizeof(Oid));
1690
1691 i = 0;
1693 {
1696
1697 operators[i] = opno;
1699 i++;
1700 }
1701
1703
1704 plan = make_memoize(subplan, operators, collations, param_exprs,
1707
1709
1710 return plan;
1711}
1712
1713
1714
1715
1716
1717
1718
1719
1720static Plan *
1722{
1724 Plan *subplan;
1725 List *in_operators;
1726 List *uniq_exprs;
1727 List *newtlist;
1728 int nextresno;
1729 bool newitems;
1730 int numGroupCols;
1732 Oid *groupCollations;
1733 int groupColPos;
1735
1736
1738
1739
1741 return subplan;
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1761
1762
1765 newitems = false;
1766
1767 foreach(l, uniq_exprs)
1768 {
1771
1773 if (!tle)
1774 {
1776 nextresno,
1777 NULL,
1778 false);
1779 newtlist = lappend(newtlist, tle);
1780 nextresno++;
1781 newitems = true;
1782 }
1783 }
1784
1785
1789
1790
1791
1792
1793
1794
1795
1799 groupCollations = (Oid *) palloc(numGroupCols * sizeof(Oid));
1800
1801 groupColPos = 0;
1802 foreach(l, uniq_exprs)
1803 {
1806
1808 if (!tle)
1809 elog(ERROR, "failed to find unique expression in subplan tlist");
1810 groupColIdx[groupColPos] = tle->resno;
1812 groupColPos++;
1813 }
1814
1816 {
1817 Oid *groupOperators;
1818
1819
1820
1821
1822
1823
1824
1825 groupOperators = (Oid *) palloc(numGroupCols * sizeof(Oid));
1826 groupColPos = 0;
1827 foreach(l, in_operators)
1828 {
1830 Oid eq_oper;
1831
1833 elog(ERROR, "could not find compatible hash operator for operator %u",
1834 in_oper);
1835 groupOperators[groupColPos++] = eq_oper;
1836 }
1837
1838
1839
1840
1841
1842
1847 numGroupCols,
1848 groupColIdx,
1849 groupOperators,
1850 groupCollations,
1854 0,
1855 subplan);
1856 }
1857 else
1858 {
1861
1862
1863 groupColPos = 0;
1864 foreach(l, in_operators)
1865 {
1867 Oid sortop;
1868 Oid eqop;
1871
1873 if ((sortop))
1874 elog(ERROR, "could not find ordering operator for equality operator %u",
1875 in_oper);
1876
1877
1878
1879
1880
1881
1882
1884 if ((eqop))
1885 elog(ERROR, "could not find equality operator for ordering operator %u",
1886 sortop);
1887
1889 groupColIdx[groupColPos]);
1890 Assert(tle != NULL);
1891
1895 sortcl->eqop = eqop;
1896 sortcl->sortop = sortop;
1899 sortcl->hashable = false;
1900 sortList = lappend(sortList, sortcl);
1901 groupColPos++;
1902 }
1906 }
1907
1908
1910
1911 return plan;
1912}
1913
1914
1915
1916
1917
1918
1919
1922{
1923 Gather *gather_plan;
1924 Plan *subplan;
1925 List *tlist;
1926
1927
1928
1929
1930
1931
1932
1934
1936
1942 subplan);
1943
1945
1946
1947 root->glob->parallelModeNeeded = true;
1948
1949 return gather_plan;
1950}
1951
1952
1953
1954
1955
1956
1957
1960{
1962 Plan *subplan;
1965
1966
1968
1969
1974
1975
1977
1978
1980
1981
1983 best_path->subpath->parent->relids,
1984 gm_plan->sortColIdx,
1985 false,
1987 &gm_plan->sortColIdx,
1988 &gm_plan->sortOperators,
1989 &gm_plan->collations,
1990 &gm_plan->nullsFirst);
1991
1992
1993
1994
1995
1997
1998
2000
2001
2002 root->glob->parallelModeNeeded = true;
2003
2004 return gm_plan;
2005}
2006
2007
2008
2009
2010
2011
2012
2013
2014static Plan *
2016{
2018 Plan *subplan;
2019 List *tlist;
2020 bool needs_result_node = false;
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2036 {
2037
2038
2039
2040
2041
2046 best_path->path.pathtarget);
2047 }
2049 {
2050
2051
2052
2053
2054
2055
2060 }
2061 else
2062 {
2063
2064
2065
2066
2070 }
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080 if (!needs_result_node)
2081 {
2082
2083 plan = subplan;
2084 plan->targetlist = tlist;
2085
2086
2090 plan->plan_width = best_path->path.pathtarget->width;
2092
2093 }
2094 else
2095 {
2096
2098
2100 }
2101
2102 return plan;
2103}
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116static Plan *
2118{
2120
2122
2123
2124
2125
2126
2127
2128
2129
2131 plan->parallel_safe = parallel_safe;
2132
2133 return plan;
2134}
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2150{
2151
2152
2153
2154
2155
2160 tlist_parallel_safe);
2161 else
2162 {
2163
2166 }
2167 return subplan;
2168}
2169
2170
2171
2172
2173
2174
2175
2176static Sort *
2178{
2180 Plan *subplan;
2181
2182
2183
2184
2185
2186
2189
2190
2191
2192
2193
2194
2195
2198 best_path->path.parent->relids : NULL);
2199
2201
2202 return plan;
2203}
2204
2205
2206
2207
2208
2209
2212 int flags)
2213{
2215 Plan *subplan;
2216
2217
2223 best_path->spath.path.parent->relids : NULL,
2225
2227
2228 return plan;
2229}
2230
2231
2232
2233
2234
2235
2236
2239{
2241 Plan *subplan;
2242 List *tlist;
2243 List *quals;
2244
2245
2246
2247
2248
2250
2252
2254
2256 quals,
2263 subplan);
2264
2266
2267 return plan;
2268}
2269
2270
2271
2272
2273
2274
2275
2278{
2280 Plan *subplan;
2281
2282
2283
2284
2285
2288
2292
2294
2295 return plan;
2296}
2297
2298
2299
2300
2301
2302
2303
2304static Agg *
2306{
2308 Plan *subplan;
2309 List *tlist;
2310 List *quals;
2311
2312
2313
2314
2315
2317
2319
2321
2335 subplan);
2336
2338
2339 return plan;
2340}
2341
2342
2343
2344
2345
2346
2347
2348
2349
2352{
2356 int i;
2357
2358 Assert(grouping_map);
2359
2361
2362 i = 0;
2363 foreach(lc, groupClause)
2364 {
2366
2368 }
2369
2370 return new_grpColIdx;
2371}
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388static Plan *
2390{
2392 Plan *subplan;
2395 int maxref;
2396 List *chain;
2398
2399
2402
2403
2404
2405
2406
2408
2409
2410
2411
2412
2413
2414 maxref = 0;
2415 foreach(lc, root->processed_groupClause)
2416 {
2418
2421 }
2422
2424
2425
2426 foreach(lc, root->processed_groupClause)
2427 {
2430
2432 }
2433
2434
2435
2436
2437
2439 root->grouping_map = grouping_map;
2440
2441
2442
2443
2444
2445
2446
2447 chain = NIL;
2449 {
2451
2453 {
2456 Plan *sort_plan = NULL;
2457 Plan *agg_plan;
2459
2461
2462 if (!rollup->is_hashed && !is_first_sort)
2463 {
2464 sort_plan = (Plan *)
2466 new_grpColIdx,
2467 subplan);
2468 }
2469
2471 is_first_sort = false;
2472
2477 else
2479
2482 strat,
2485 new_grpColIdx,
2492 sort_plan);
2493
2494
2495
2496
2497 if (sort_plan)
2498 {
2501 }
2502
2503 chain = lappend(chain, agg_plan);
2504 }
2505 }
2506
2507
2508
2509
2510 {
2513 int numGroupCols;
2514
2516
2518
2520 best_path->qual,
2523 numGroupCols,
2524 top_grpColIdx,
2528 chain,
2531 subplan);
2532
2533
2535 }
2536
2538}
2539
2540
2541
2542
2543
2544
2545
2548{
2550 List *tlist;
2552
2553
2555 {
2560
2561
2562
2563
2564
2565
2566
2568
2573 0, NULL, NULL, NULL);
2574
2575
2579 plan->plan_rows = 1;
2580 plan->plan_width = mminfo->path->pathtarget->width;
2581 plan->parallel_aware = false;
2583
2584
2586 }
2587
2588
2590
2592
2594
2595
2596
2597
2598
2599
2600
2603
2604 return plan;
2605}
2606
2607
2608
2609
2610
2611
2612
2615{
2620 Plan *subplan;
2621 List *tlist;
2622 int partNumCols;
2624 Oid *partOperators;
2625 Oid *partCollations;
2626 int ordNumCols;
2628 Oid *ordOperators;
2629 Oid *ordCollations;
2631
2632
2633
2634
2635
2636
2637
2640
2642
2643
2644
2645
2646
2648 partOperators = (Oid *) palloc(sizeof(Oid) * numPart);
2649 partCollations = (Oid *) palloc(sizeof(Oid) * numPart);
2650
2651 partNumCols = 0;
2653 {
2656
2658 partColIdx[partNumCols] = tle->resno;
2659 partOperators[partNumCols] = sgc->eqop;
2661 partNumCols++;
2662 }
2663
2665 ordOperators = (Oid *) palloc(sizeof(Oid) * numOrder);
2666 ordCollations = (Oid *) palloc(sizeof(Oid) * numOrder);
2667
2668 ordNumCols = 0;
2670 {
2673
2675 ordColIdx[ordNumCols] = tle->resno;
2676 ordOperators[ordNumCols] = sgc->eqop;
2678 ordNumCols++;
2679 }
2680
2681
2683 wc,
2684 partNumCols,
2685 partColIdx,
2686 partOperators,
2687 partCollations,
2688 ordNumCols,
2689 ordColIdx,
2690 ordOperators,
2691 ordCollations,
2693 best_path->qual,
2695 subplan);
2696
2698
2699 return plan;
2700}
2701
2702
2703
2704
2705
2706
2707
2710{
2713 Plan *leftplan;
2714 Plan *rightplan;
2715 long numGroups;
2716
2717
2718
2719
2720
2725
2726
2728
2731 tlist,
2732 leftplan,
2733 rightplan,
2735 numGroups);
2736
2738
2739 return plan;
2740}
2741
2742
2743
2744
2745
2746
2747
2750{
2752 Plan *leftplan;
2753 Plan *rightplan;
2754 List *tlist;
2755 long numGroups;
2756
2757
2760
2762
2763
2765
2767 leftplan,
2768 rightplan,
2771 numGroups);
2772
2774
2775 return plan;
2776}
2777
2778
2779
2780
2781
2782
2783
2786 int flags)
2787{
2789 Plan *subplan;
2790
2791
2793
2795
2797
2798 return plan;
2799}
2800
2801
2802
2803
2804
2805
2806
2809{
2812 Plan *subplan;
2813
2814
2816
2817
2819
2821 subplan,
2836
2838
2839 return plan;
2840}
2841
2842
2843
2844
2845
2846
2847
2850{
2852 Plan *subplan;
2853 int numUniqkeys = 0;
2855 Oid *uniqOperators = NULL;
2856 Oid *uniqCollations = NULL;
2857
2858
2860
2861
2863 {
2866
2869 uniqOperators = (Oid *) palloc(numUniqkeys * sizeof(Oid));
2870 uniqCollations = (Oid *) palloc(numUniqkeys * sizeof(Oid));
2871
2872 numUniqkeys = 0;
2873 foreach(l, parse->sortClause)
2874 {
2877
2878 uniqColIdx[numUniqkeys] = tle->resno;
2879 uniqOperators[numUniqkeys] = sortcl->eqop;
2881 numUniqkeys++;
2882 }
2883 }
2884
2889 numUniqkeys, uniqColIdx, uniqOperators, uniqCollations);
2890
2892
2893 return plan;
2894}
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2911 List *tlist, List *scan_clauses)
2912{
2914 Index scan_relid = best_path->parent->relid;
2915
2916
2917 Assert(scan_relid > 0);
2919
2920
2922
2923
2925
2926
2927 if (best_path->param_info)
2928 {
2929 scan_clauses = (List *)
2931 }
2932
2934 scan_clauses,
2935 scan_relid);
2936
2938
2939 return scan_plan;
2940}
2941
2942
2943
2944
2945
2946
2949 List *tlist, List *scan_clauses)
2950{
2952 Index scan_relid = best_path->parent->relid;
2955
2956
2957 Assert(scan_relid > 0);
2961 Assert(tsc != NULL);
2962
2963
2965
2966
2968
2969
2970 if (best_path->param_info)
2971 {
2972 scan_clauses = (List *)
2976 }
2977
2979 scan_clauses,
2980 scan_relid,
2981 tsc);
2982
2984
2985 return scan_plan;
2986}
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998static Scan *
3001 List *tlist,
3002 List *scan_clauses,
3003 bool indexonly)
3004{
3005 Scan *scan_plan;
3008 Index baserelid = best_path->path.parent->relid;
3011 List *qpqual;
3012 List *stripped_indexquals;
3013 List *fixed_indexquals;
3014 List *fixed_indexorderbys;
3015 List *indexorderbyops = NIL;
3017
3018
3019 Assert(baserelid > 0);
3021
3024
3025
3026
3027
3028
3029
3030
3032 &stripped_indexquals,
3033 &fixed_indexquals);
3034
3035
3036
3037
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068 qpqual = NIL;
3069 foreach(l, scan_clauses)
3070 {
3072
3073 if (rinfo->pseudoconstant)
3074 continue;
3076 continue;
3079 false))
3080 continue;
3081 qpqual = lappend(qpqual, rinfo);
3082 }
3083
3084
3086
3087
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099 if (best_path->path.param_info)
3100 {
3101 stripped_indexquals = (List *)
3103 qpqual = (List *)
3105 indexorderbys = (List *)
3107 }
3108
3109
3110
3111
3112
3113 if (indexorderbys)
3114 {
3116 *exprCell;
3117
3118
3119
3120
3121
3122
3125 {
3129 Oid sortop;
3130
3131
3133 exprtype,
3134 exprtype,
3137 elog(ERROR, "missing operator %d(%u,%u) in opfamily %u",
3139 indexorderbyops = lappend_oid(indexorderbyops, sortop);
3140 }
3141 }
3142
3143
3144
3145
3146
3147
3148 if (indexonly)
3149 {
3150 int i = 0;
3151
3153 {
3155
3156 indextle->resjunk = !indexinfo->canreturn[i];
3157 i++;
3158 }
3159 }
3160
3161
3162 if (indexonly)
3164 qpqual,
3165 baserelid,
3166 indexoid,
3167 fixed_indexquals,
3168 stripped_indexquals,
3169 fixed_indexorderbys,
3172 else
3174 qpqual,
3175 baserelid,
3176 indexoid,
3177 fixed_indexquals,
3178 stripped_indexquals,
3179 fixed_indexorderbys,
3180 indexorderbys,
3181 indexorderbyops,
3183
3185
3186 return scan_plan;
3187}
3188
3189
3190
3191
3192
3193
3197 List *tlist,
3198 List *scan_clauses)
3199{
3200 Index baserelid = best_path->path.parent->relid;
3201 Plan *bitmapqualplan;
3202 List *bitmapqualorig;
3203 List *indexquals;
3204 List *indexECs;
3205 List *qpqual;
3208
3209
3210 Assert(baserelid > 0);
3212
3213
3215 &bitmapqualorig, &indexquals,
3216 &indexECs);
3217
3220
3221
3222
3223
3224
3225
3226
3227
3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247 qpqual = NIL;
3248 foreach(l, scan_clauses)
3249 {
3252
3253 if (rinfo->pseudoconstant)
3254 continue;
3256 continue;
3257 if (rinfo->parent_ec && list_member_ptr(indexECs, rinfo->parent_ec))
3258 continue;
3261 continue;
3262 qpqual = lappend(qpqual, rinfo);
3263 }
3264
3265
3267
3268
3270
3271
3272
3273
3274
3275
3276
3278
3279
3280
3281
3282
3283
3284 if (best_path->path.param_info)
3285 {
3286 qpqual = (List *)
3288 bitmapqualorig = (List *)
3290 }
3291
3292
3294 qpqual,
3295 bitmapqualplan,
3296 bitmapqualorig,
3297 baserelid);
3298
3300
3301 return scan_plan;
3302}
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
3314
3315
3316
3317
3318
3319
3320
3321
3322
3323
3324static Plan *
3326 List **qual, List **indexqual, List **indexECs)
3327{
3329
3331 {
3335 List *subindexquals = NIL;
3338
3339
3340
3341
3342
3343
3344
3345
3347 {
3348 Plan *subplan;
3349 List *subqual;
3350 List *subindexqual;
3351 List *subindexEC;
3352
3354 &subqual, &subindexqual,
3355 &subindexEC);
3356 subplans = lappend(subplans, subplan);
3359
3360 subindexECs = list_concat(subindexECs, subindexEC);
3361 }
3365 plan->plan_rows =
3367 plan->plan_width = 0;
3368 plan->parallel_aware = false;
3370 *qual = subquals;
3371 *indexqual = subindexquals;
3372 *indexECs = subindexECs;
3373 }
3375 {
3379 List *subindexquals = NIL;
3380 bool const_true_subqual = false;
3381 bool const_true_subindexqual = false;
3383
3384
3385
3386
3387
3388
3389
3390
3391
3392
3394 {
3395 Plan *subplan;
3396 List *subqual;
3397 List *subindexqual;
3398 List *subindexEC;
3399
3401 &subqual, &subindexqual,
3402 &subindexEC);
3403 subplans = lappend(subplans, subplan);
3404 if (subqual == NIL)
3405 const_true_subqual = true;
3406 else if (!const_true_subqual)
3407 subquals = lappend(subquals,
3409 if (subindexqual == NIL)
3410 const_true_subindexqual = true;
3411 else if (!const_true_subindexqual)
3412 subindexquals = lappend(subindexquals,
3414 }
3415
3416
3417
3418
3419
3421 {
3423 }
3424 else
3425 {
3429 plan->plan_rows =
3431 plan->plan_width = 0;
3432 plan->parallel_aware = false;
3434 }
3435
3436
3437
3438
3439
3440
3441 if (const_true_subqual)
3442 *qual = NIL;
3444 *qual = subquals;
3445 else
3447 if (const_true_subindexqual)
3448 *indexqual = NIL;
3449 else if (list_length(subindexquals) <= 1)
3450 *indexqual = subindexquals;
3451 else
3453 *indexECs = NIL;
3454 }
3456 {
3459 List *subquals;
3460 List *subindexquals;
3461 List *subindexECs;
3463
3464
3468
3473
3474 plan->startup_cost = 0.0;
3476 plan->plan_rows =
3478 plan->plan_width = 0;
3479 plan->parallel_aware = false;
3481
3482 subquals = NIL;
3483 subindexquals = NIL;
3484 subindexECs = NIL;
3486 {
3489
3490 Assert(!rinfo->pseudoconstant);
3492 subindexquals = list_concat(subindexquals,
3494 if (rinfo->parent_ec)
3495 subindexECs = lappend(subindexECs, rinfo->parent_ec);
3496 }
3497
3499 {
3501
3502
3503
3504
3505
3506
3507
3509 {
3510 subquals = lappend(subquals, pred);
3511 subindexquals = lappend(subindexquals, pred);
3512 }
3513 }
3514 *qual = subquals;
3515 *indexqual = subindexquals;
3516 *indexECs = subindexECs;
3517 }
3518 else
3519 {
3520 elog(ERROR, "unrecognized node type: %d", nodeTag(bitmapqual));
3521 plan = NULL;
3522 }
3523
3524 return plan;
3525}
3526
3527
3528
3529
3530
3531
3534 List *tlist, List *scan_clauses)
3535{
3537 Index scan_relid = best_path->path.parent->relid;
3539
3540
3541 Assert(scan_relid > 0);
3543
3544
3545
3546
3547
3548
3549
3550
3551
3552
3553
3554
3555
3556
3557
3558
3559
3560
3561
3562
3564 {
3567
3568 foreach(l, scan_clauses)
3569 {
3571
3572 if (rinfo->pseudoconstant)
3573 continue;
3575 continue;
3577 continue;
3578 qpqual = lappend(qpqual, rinfo);
3579 }
3580 scan_clauses = qpqual;
3581 }
3582
3583
3585
3586
3589
3590
3591
3592
3593
3594
3595
3596
3597
3598
3599
3600
3604
3605
3606 if (best_path->path.param_info)
3607 {
3608 tidquals = (List *)
3610 scan_clauses = (List *)
3612 }
3613
3615 scan_clauses,
3616 scan_relid,
3617 tidquals);
3618
3620
3621 return scan_plan;
3622}
3623
3624
3625
3626
3627
3628
3631 List *tlist, List *scan_clauses)
3632{
3634 Index scan_relid = best_path->path.parent->relid;
3636
3637
3638 Assert(scan_relid > 0);
3640
3641
3642
3643
3644
3645
3646 {
3649
3650 foreach(l, scan_clauses)
3651 {
3653
3654 if (rinfo->pseudoconstant)
3655 continue;
3657 continue;
3658 qpqual = lappend(qpqual, rinfo);
3659 }
3660 scan_clauses = qpqual;
3661 }
3662
3663
3665
3666
3669
3670
3671 if (best_path->path.param_info)
3672 {
3673 tidrangequals = (List *)
3675 scan_clauses = (List *)
3677 }
3678
3680 scan_clauses,
3681 scan_relid,
3682 tidrangequals);
3683
3685
3686 return scan_plan;
3687}
3688
3689
3690
3691
3692
3693
3696 List *tlist, List *scan_clauses)
3697{
3701 Plan *subplan;
3702
3703
3704 Assert(scan_relid > 0);
3706
3707
3708
3709
3710
3711
3713
3714
3716
3717
3719
3720
3721
3722
3723
3724
3725
3726
3727
3728
3729
3730 if (best_path->path.param_info)
3731 {
3734 scan_clauses = (List *)
3736 }
3737
3739 scan_clauses,
3740 scan_relid,
3741 subplan);
3742
3744
3745 return scan_plan;
3746}
3747
3748
3749
3750
3751
3752
3755 List *tlist, List *scan_clauses)
3756{
3758 Index scan_relid = best_path->parent->relid;
3761
3762
3763 Assert(scan_relid > 0);
3767
3768
3770
3771
3773
3774
3775 if (best_path->param_info)
3776 {
3777 scan_clauses = (List *)
3779
3781 }
3782
3785
3787
3788 return scan_plan;
3789}
3790
3791
3792
3793
3794
3795
3798 List *tlist, List *scan_clauses)
3799{
3801 Index scan_relid = best_path->parent->relid;
3804
3805
3806 Assert(scan_relid > 0);
3810
3811
3813
3814
3816
3817
3818 if (best_path->param_info)
3819 {
3820 scan_clauses = (List *)
3822
3824 }
3825
3827 tablefunc);
3828
3830
3831 return scan_plan;
3832}
3833
3834
3835
3836
3837
3838
3841 List *tlist, List *scan_clauses)
3842{
3844 Index scan_relid = best_path->parent->relid;
3846 List *values_lists;
3847
3848
3849 Assert(scan_relid > 0);
3853
3854
3856
3857
3859
3860
3861 if (best_path->param_info)
3862 {
3863 scan_clauses = (List *)
3865
3866 values_lists = (List *)
3868 }
3869
3870 scan_plan = make_valuesscan(tlist, scan_clauses, scan_relid,
3871 values_lists);
3872
3874
3875 return scan_plan;
3876}
3877
3878
3879
3880
3881
3882
3885 List *tlist, List *scan_clauses)
3886{
3888 Index scan_relid = best_path->parent->relid;
3890 SubPlan *ctesplan = NULL;
3891 int plan_id;
3892 int cte_param_id;
3895 int ndx;
3897
3898 Assert(scan_relid > 0);
3901 Assert(!rte->self_reference);
3902
3903
3904
3905
3907 cteroot = root;
3908 while (levelsup-- > 0)
3909 {
3910 cteroot = cteroot->parent_root;
3911 if (!cteroot)
3913 }
3914
3915
3916
3917
3918
3919
3920 ndx = 0;
3922 {
3924
3926 break;
3927 ndx++;
3928 }
3929 if (lc == NULL)
3932 elog(ERROR, "could not find plan for CTE \"%s\"", rte->ctename);
3934 if (plan_id <= 0)
3935 elog(ERROR, "no plan was made for CTE \"%s\"", rte->ctename);
3937 {
3939 if (ctesplan->plan_id == plan_id)
3940 break;
3941 }
3942 if (lc == NULL)
3943 elog(ERROR, "could not find plan for CTE \"%s\"", rte->ctename);
3944
3945
3946
3947
3948
3950
3951
3953
3954
3956
3957
3958 if (best_path->param_info)
3959 {
3960 scan_clauses = (List *)
3962 }
3963
3964 scan_plan = make_ctescan(tlist, scan_clauses, scan_relid,
3965 plan_id, cte_param_id);
3966
3968
3969 return scan_plan;
3970}
3971
3972
3973
3974
3975
3976
3977
3980 List *tlist, List *scan_clauses)
3981{
3983 Index scan_relid = best_path->parent->relid;
3985
3986 Assert(scan_relid > 0);
3989
3990
3992
3993
3995
3996
3997 if (best_path->param_info)
3998 {
3999 scan_clauses = (List *)
4001 }
4002
4005
4007
4008 return scan_plan;
4009}
4010
4011
4012
4013
4014
4015
4016
4019 List *tlist, List *scan_clauses)
4020{
4022 Index scan_relid = best_path->parent->relid;
4024
4025 Assert(scan_relid > 0);
4028
4029
4031
4032
4034
4035
4036 if (best_path->param_info)
4037 {
4038 scan_clauses = (List *)
4040 }
4041
4042 scan_plan = make_result(tlist, (Node *) scan_clauses, NULL);
4043
4045
4046 return scan_plan;
4047}
4048
4049
4050
4051
4052
4053
4056 List *tlist, List *scan_clauses)
4057{
4059 Index scan_relid = best_path->parent->relid;
4063
4064 Assert(scan_relid > 0);
4067 Assert(rte->self_reference);
4068
4069
4070
4071
4072
4073
4075 if (levelsup == 0)
4077 levelsup--;
4078 cteroot = root;
4079 while (levelsup-- > 0)
4080 {
4081 cteroot = cteroot->parent_root;
4082 if (!cteroot)
4084 }
4085 if (cteroot->wt_param_id < 0)
4086 elog(ERROR, "could not find param ID for CTE \"%s\"", rte->ctename);
4087
4088
4090
4091
4093
4094
4095 if (best_path->param_info)
4096 {
4097 scan_clauses = (List *)
4099 }
4100
4103
4105
4106 return scan_plan;
4107}
4108
4109
4110
4111
4112
4113
4116 List *tlist, List *scan_clauses)
4117{
4122 Plan *outer_plan = NULL;
4123
4124 Assert(rel->fdwroutine != NULL);
4125
4126
4130
4131
4132
4133
4134
4135 if (scan_relid > 0)
4136 {
4138
4142 rel_oid = rte->relid;
4143 }
4144
4145
4146
4147
4148
4150
4151
4152
4153
4154
4155
4156
4157
4158 scan_plan = rel->fdwroutine->GetForeignPlan(root, rel, rel_oid,
4159 best_path,
4160 tlist, scan_clauses,
4161 outer_plan);
4162
4163
4165
4166
4168
4169
4171
4172
4173
4174
4175
4176
4179 else
4180 scan_plan->fs_relids = best_path->path.parent->relids;
4181
4182
4183
4184
4185
4186
4188 root->outer_join_rels);
4189
4190
4191
4192
4193
4194
4196 root->glob->dependsOnRole = true;
4197
4198
4199
4200
4201
4202
4203
4204
4205
4206 if (best_path->path.param_info)
4207 {
4208 scan_plan->scan.plan.qual = (List *)
4215 }
4216
4217
4218
4219
4220
4221
4222
4223
4224
4225
4227 if (scan_relid > 0)
4228 {
4231 int i;
4232
4233
4234
4235
4236
4237
4239
4240
4242 {
4244
4246 }
4247
4248
4250 {
4252 {
4254 break;
4255 }
4256 }
4257
4259 }
4260
4261 return scan_plan;
4262}
4263
4264
4265
4266
4267
4268
4271 List *tlist, List *scan_clauses)
4272{
4275 List *custom_plans = NIL;
4277
4278
4280 {
4283
4284 custom_plans = lappend(custom_plans, plan);
4285 }
4286
4287
4288
4289
4290
4292
4293
4294
4295
4296
4299 rel,
4300 best_path,
4301 tlist,
4302 scan_clauses,
4303 custom_plans));
4304
4305
4306
4307
4308
4310
4311
4313
4314
4315
4316
4317
4318
4319
4320
4321
4322 if (best_path->path.param_info)
4323 {
4324 cplan->scan.plan.qual = (List *)
4328 }
4329
4330 return cplan;
4331}
4332
4333
4334
4335
4336
4337
4338
4339
4343{
4345 Plan *outer_plan;
4346 Plan *inner_plan;
4349 List *joinclauses;
4350 List *otherclauses;
4352 List *nestParams;
4353 Relids saveOuterRels = root->curOuterRels;
4354
4355
4356
4357
4358
4359
4364
4365
4366
4367
4368
4370
4371
4373
4374
4377
4379
4380
4382 root->curOuterRels = saveOuterRels;
4383
4384
4386
4387
4388
4390 {
4392 best_path->jpath.path.parent->relids,
4393 &joinclauses, &otherclauses);
4394 }
4395 else
4396 {
4397
4399 otherclauses = NIL;
4400 }
4401
4402
4403 if (best_path->jpath.path.param_info)
4404 {
4405 joinclauses = (List *)
4407 otherclauses = (List *)
4409 }
4410
4411
4412
4413
4414
4417
4419 joinclauses,
4420 otherclauses,
4421 nestParams,
4422 outer_plan,
4423 inner_plan,
4426
4428
4429 return join_plan;
4430}
4431
4435{
4437 Plan *outer_plan;
4438 Plan *inner_plan;
4440 List *joinclauses;
4441 List *otherclauses;
4442 List *mergeclauses;
4443 List *outerpathkeys;
4444 List *innerpathkeys;
4445 int nClauses;
4446 Oid *mergefamilies;
4447 Oid *mergecollations;
4448 bool *mergereversals;
4449 bool *mergenullsfirst;
4452 int i;
4458
4459
4460
4461
4462
4463
4464
4467
4470
4471
4472
4474
4475
4476
4478 {
4480 best_path->jpath.path.parent->relids,
4481 &joinclauses, &otherclauses);
4482 }
4483 else
4484 {
4485
4487 otherclauses = NIL;
4488 }
4489
4490
4491
4492
4493
4495 joinclauses = list_difference(joinclauses, mergeclauses);
4496
4497
4498
4499
4500
4501 if (best_path->jpath.path.param_info)
4502 {
4503 joinclauses = (List *)
4505 otherclauses = (List *)
4507 }
4508
4509
4510
4511
4512
4513
4516
4517
4518
4519
4521 {
4522 Relids outer_relids = outer_path->parent->relids;
4523 Plan *sort_plan;
4524
4525
4526
4527
4528
4529
4532
4533
4534
4535
4536
4538 {
4539 sort_plan = (Plan *)
4542 outer_relids,
4544
4548 -1.0);
4549 }
4550 else
4551 {
4552 sort_plan = (Plan *)
4555 outer_relids);
4556
4558 }
4559
4560 outer_plan = sort_plan;
4562 }
4563 else
4565
4567 {
4568
4569
4570
4571
4572
4573 Relids inner_relids = inner_path->parent->relids;
4575
4576
4577
4578
4579
4580
4583
4586 inner_relids);
4587
4591 }
4592 else
4594
4595
4596
4597
4598
4600 {
4602
4603
4604
4605
4606
4607
4610
4611 inner_plan = matplan;
4612 }
4613
4614
4615
4616
4617
4618
4619
4620
4623 mergefamilies = (Oid *) palloc(nClauses * sizeof(Oid));
4624 mergecollations = (Oid *) palloc(nClauses * sizeof(Oid));
4625 mergereversals = (bool *) palloc(nClauses * sizeof(bool));
4626 mergenullsfirst = (bool *) palloc(nClauses * sizeof(bool));
4627
4628 opathkey = NULL;
4629 opeclass = NULL;
4632 i = 0;
4634 {
4638 PathKey *ipathkey = NULL;
4640 bool first_inner_match = false;
4641
4642
4643 if (rinfo->outer_is_left)
4644 {
4645 oeclass = rinfo->left_ec;
4646 ieclass = rinfo->right_ec;
4647 }
4648 else
4649 {
4650 oeclass = rinfo->right_ec;
4651 ieclass = rinfo->left_ec;
4652 }
4653 Assert(oeclass != NULL);
4654 Assert(ieclass != NULL);
4655
4656
4657
4658
4659
4660
4661
4662
4663
4664
4665
4666
4667
4668
4669
4670
4671 if (oeclass != opeclass)
4672 {
4673
4674 if (lop == NULL)
4675 elog(ERROR, "outer pathkeys do not match mergeclauses");
4677 opeclass = opathkey->pk_eclass;
4678 lop = lnext(outerpathkeys, lop);
4679 if (oeclass != opeclass)
4680 elog(ERROR, "outer pathkeys do not match mergeclauses");
4681 }
4682
4683
4684
4685
4686
4687
4688
4689
4690
4691
4692
4693
4694
4695
4696
4697
4698 if (lip)
4699 {
4701 ipeclass = ipathkey->pk_eclass;
4702 if (ieclass == ipeclass)
4703 {
4704
4705 lip = lnext(innerpathkeys, lip);
4706 first_inner_match = true;
4707 }
4708 }
4709 if (!first_inner_match)
4710 {
4711
4713
4714 foreach(l2, innerpathkeys)
4715 {
4716 if (l2 == lip)
4717 break;
4719 ipeclass = ipathkey->pk_eclass;
4720 if (ieclass == ipeclass)
4721 break;
4722 }
4723 if (ieclass != ipeclass)
4724 elog(ERROR, "inner pathkeys do not match mergeclauses");
4725 }
4726
4727
4728
4729
4730
4731
4732
4733
4734
4735
4736
4737
4738
4739
4740
4742 opathkey->pk_eclass->ec_collation != ipathkey->pk_eclass->ec_collation)
4743 elog(ERROR, "left and right pathkeys do not match in mergejoin");
4744 if (first_inner_match &&
4747 elog(ERROR, "left and right pathkeys do not match in mergejoin");
4748
4749
4751 mergecollations[i] = opathkey->pk_eclass->ec_collation;
4754 i++;
4755 }
4756
4757
4758
4759
4760
4761
4762
4763
4764
4765
4767 joinclauses,
4768 otherclauses,
4769 mergeclauses,
4770 mergefamilies,
4771 mergecollations,
4772 mergereversals,
4773 mergenullsfirst,
4774 outer_plan,
4775 inner_plan,
4779
4780
4782
4783 return join_plan;
4784}
4785
4789{
4791 Hash *hash_plan;
4792 Plan *outer_plan;
4793 Plan *inner_plan;
4795 List *joinclauses;
4796 List *otherclauses;
4797 List *hashclauses;
4798 List *hashoperators = NIL;
4799 List *hashcollations = NIL;
4800 List *inner_hashkeys = NIL;
4801 List *outer_hashkeys = NIL;
4804 bool skewInherit = false;
4806
4807
4808
4809
4810
4811
4812
4813
4816
4819
4820
4822
4823
4824
4825
4827 {
4829 best_path->jpath.path.parent->relids,
4830 &joinclauses, &otherclauses);
4831 }
4832 else
4833 {
4834
4836 otherclauses = NIL;
4837 }
4838
4839
4840
4841
4842
4844 joinclauses = list_difference(joinclauses, hashclauses);
4845
4846
4847
4848
4849
4850 if (best_path->jpath.path.param_info)
4851 {
4852 joinclauses = (List *)
4854 otherclauses = (List *)
4856 }
4857
4858
4859
4860
4861
4864
4865
4866
4867
4868
4869
4870
4871
4872
4874 {
4877
4883 {
4886
4887 rte = root->simple_rte_array[var->varno];
4889 {
4890 skewTable = rte->relid;
4892 skewInherit = rte->inh;
4893 }
4894 }
4895 }
4896
4897
4898
4899
4900
4901
4902
4903
4904
4905 foreach(lc, hashclauses)
4906 {
4908
4909 hashoperators = lappend_oid(hashoperators, hclause->opno);
4910 hashcollations = lappend_oid(hashcollations, hclause->inputcollid);
4913 }
4914
4915
4916
4917
4918 hash_plan = make_hash(inner_plan,
4919 inner_hashkeys,
4920 skewTable,
4921 skewColumn,
4922 skewInherit);
4923
4924
4925
4926
4927
4930
4931
4932
4933
4934
4935
4936 if (best_path->jpath.path.parallel_aware)
4937 {
4940 }
4941
4943 joinclauses,
4944 otherclauses,
4945 hashclauses,
4946 hashoperators,
4947 hashcollations,
4948 outer_hashkeys,
4949 outer_plan,
4950 (Plan *) hash_plan,
4953
4955
4956 return join_plan;
4957}
4958
4959
4960
4961
4962
4963
4964
4965
4966
4967
4968
4969
4970
4971
4972
4973
4974
4975static Node *
4977{
4978
4980}
4981
4982static Node *
4984{
4985 if (node == NULL)
4986 return NULL;
4988 {
4990
4991
4993
4996 return node;
4997
4999 }
5001 {
5003
5004
5006
5007
5009 root->curOuterRels))
5010 {
5011
5012
5013
5014
5015
5016
5017
5018
5019
5020
5021
5022
5023
5024
5025
5027
5029 newphv->phexpr = (Expr *)
5032 return (Node *) newphv;
5033 }
5034
5036 }
5038}
5039
5040
5041
5042
5043
5044
5045
5046
5047
5048
5049
5050
5051
5052
5053
5054
5055
5056
5057
5058
5059
5060static void
5062 List **stripped_indexquals_p, List **fixed_indexquals_p)
5063{
5065 List *stripped_indexquals;
5066 List *fixed_indexquals;
5068
5069 stripped_indexquals = fixed_indexquals = NIL;
5070
5072 {
5074 int indexcol = iclause->indexcol;
5076
5078 {
5081
5082 stripped_indexquals = lappend(stripped_indexquals, clause);
5085 fixed_indexquals = lappend(fixed_indexquals, clause);
5086 }
5087 }
5088
5089 *stripped_indexquals_p = stripped_indexquals;
5090 *fixed_indexquals_p = fixed_indexquals;
5091}
5092
5093
5094
5095
5096
5097
5098
5099
5100
5101static List *
5103{
5105 List *fixed_indexorderbys;
5107 *lci;
5108
5109 fixed_indexorderbys = NIL;
5110
5112 {
5115
5117 fixed_indexorderbys = lappend(fixed_indexorderbys, clause);
5118 }
5119
5120 return fixed_indexorderbys;
5121}
5122
5123
5124
5125
5126
5127
5128
5129
5130static Node *
5132 Node *clause, List *indexcolnos)
5133{
5134
5135
5136
5137
5138
5139
5141
5143 {
5145
5146
5149 indexcol);
5150 }
5152 {
5155 *lcai;
5156
5157
5160 {
5164 }
5165 }
5167 {
5169
5170
5173 indexcol);
5174 }
5176 {
5178
5179
5182 indexcol);
5183 }
5184 else
5185 elog(ERROR, "unsupported indexqual type: %d",
5187
5188 return clause;
5189}
5190
5191
5192
5193
5194
5195
5196
5197
5198
5199
5200
5201static Node *
5203{
5204 Var *result;
5205 int pos;
5207
5208
5209
5210
5213
5214 Assert(indexcol >= 0 && indexcol < index->ncolumns);
5215
5216 if (index->indexkeys[indexcol] != 0)
5217 {
5218
5220 ((Var *) node)->varno == index->rel->relid &&
5221 ((Var *) node)->varattno == index->indexkeys[indexcol])
5222 {
5225 result->varattno = indexcol + 1;
5226 return (Node *) result;
5227 }
5228 else
5229 elog(ERROR, "index key does not match expected index column");
5230 }
5231
5232
5234 for (pos = 0; pos < index->ncolumns; pos++)
5235 {
5236 if (index->indexkeys[pos] == 0)
5237 {
5238 if (indexpr_item == NULL)
5239 elog(ERROR, "too few entries in indexprs list");
5240 if (pos == indexcol)
5241 {
5242 Node *indexkey;
5243
5244 indexkey = (Node *) lfirst(indexpr_item);
5247 if (equal(node, indexkey))
5248 {
5252 0);
5253 return (Node *) result;
5254 }
5255 else
5256 elog(ERROR, "index key does not match expected index column");
5257 }
5258 indexpr_item = lnext(index->indexprs, indexpr_item);
5259 }
5260 }
5261
5262
5263 elog(ERROR, "index key does not match expected index column");
5264 return NULL;
5265}
5266
5267
5268
5269
5270
5271
5272
5273
5274
5275
5276static List *
5278{
5281
5282 foreach(l, clauses)
5283 {
5286
5288 if (bms_is_subset(restrictinfo->right_relids, outerrelids))
5289 {
5290
5291
5292
5293
5294
5296
5299 temp->opresulttype = clause->opresulttype;
5300 temp->opretset = clause->opretset;
5301 temp->opcollid = clause->opcollid;
5302 temp->inputcollid = clause->inputcollid;
5305
5307 t_list = lappend(t_list, temp);
5308 restrictinfo->outer_is_left = false;
5309 }
5310 else
5311 {
5313 t_list = lappend(t_list, clause);
5314 restrictinfo->outer_is_left = true;
5315 }
5316 }
5317 return t_list;
5318}
5319
5320
5321
5322
5323
5324
5325
5326
5327
5328
5329
5330
5331
5332
5333
5334
5335
5336
5337
5338
5339
5340
5341
5342
5343
5344
5345
5346
5347
5348
5349
5350
5351
5352
5353static List *
5355{
5356 typedef struct
5357 {
5358 Node *clause;
5360 Index security_level;
5361 } QualItem;
5363 QualItem *items;
5365 int i;
5366 List *result;
5367
5368
5370 return clauses;
5371
5372
5373
5374
5375
5377 i = 0;
5378 foreach(lc, clauses)
5379 {
5382
5384 items[i].clause = clause;
5387 {
5389
5390
5391
5392
5393
5394
5395
5396
5397
5398
5399
5401 items[i].security_level = 0;
5402 else
5404 }
5405 else
5406 items[i].security_level = 0;
5407 i++;
5408 }
5409
5410
5411
5412
5413
5414
5416 {
5417 QualItem newitem = items[i];
5418 int j;
5419
5420
5422 {
5423 QualItem *olditem = &items[j - 1];
5424
5425 if (newitem.security_level > olditem->security_level ||
5426 (newitem.security_level == olditem->security_level &&
5427 newitem.cost >= olditem->cost))
5428 break;
5430 }
5432 }
5433
5434
5435 result = NIL;
5438
5439 return result;
5440}
5441
5442
5443
5444
5445
5446
5447static void
5449{
5453 dest->plan_rows = src->rows;
5454 dest->plan_width = src->pathtarget->width;
5457}
5458
5459
5460
5461
5462
5463static void
5465{
5471
5472 dest->parallel_aware = false;
5473
5475}
5476
5477
5478
5479
5480
5481
5482
5483
5484
5485
5486static void
5488{
5489 Plan *lefttree = plan->plan.lefttree;
5490 Path sort_path;
5491
5493
5495 plan->plan.disabled_nodes,
5499 0.0,
5501 limit_tuples);
5506 plan->plan.parallel_aware = false;
5508}
5509
5510
5511
5512
5513
5514static void
5516 List *pathkeys, double limit_tuples)
5517{
5518 Plan *lefttree = plan->sort.plan.lefttree;
5519 Path sort_path;
5520
5522
5524 plan->nPresortedCols,
5525 plan->sort.plan.disabled_nodes,
5530 0.0,
5532 limit_tuples);
5535 plan->sort.plan.plan_rows = lefttree->plan_rows;
5537 plan->sort.plan.parallel_aware = false;
5539}
5540
5541
5542
5543
5544
5545
5546static void
5548{
5552 {
5555 }
5558 else
5560}
5561
5562
5563
5564
5565
5566
5567
5568
5569
5570
5571
5572
5573
5574
5575
5578 List *qpqual,
5579 Index scanrelid)
5580{
5583
5584 plan->targetlist = qptlist;
5585 plan->qual = qpqual;
5586 plan->lefttree = NULL;
5587 plan->righttree = NULL;
5589
5590 return node;
5591}
5592
5595 List *qpqual,
5596 Index scanrelid,
5598{
5601
5602 plan->targetlist = qptlist;
5603 plan->qual = qpqual;
5604 plan->lefttree = NULL;
5605 plan->righttree = NULL;
5608
5609 return node;
5610}
5611
5614 List *qpqual,
5615 Index scanrelid,
5616 Oid indexid,
5617 List *indexqual,
5618 List *indexqualorig,
5619 List *indexorderby,
5620 List *indexorderbyorig,
5621 List *indexorderbyops,
5623{
5626
5627 plan->targetlist = qptlist;
5628 plan->qual = qpqual;
5629 plan->lefttree = NULL;
5630 plan->righttree = NULL;
5632 node->indexid = indexid;
5639
5640 return node;
5641}
5642
5645 List *qpqual,
5646 Index scanrelid,
5647 Oid indexid,
5648 List *indexqual,
5649 List *recheckqual,
5650 List *indexorderby,
5651 List *indextlist,
5653{
5656
5657 plan->targetlist = qptlist;
5658 plan->qual = qpqual;
5659 plan->lefttree = NULL;
5660 plan->righttree = NULL;
5662 node->indexid = indexid;
5668
5669 return node;
5670}
5671
5674 Oid indexid,
5675 List *indexqual,
5676 List *indexqualorig)
5677{
5680
5683 plan->lefttree = NULL;
5684 plan->righttree = NULL;
5686 node->indexid = indexid;
5689
5690 return node;
5691}
5692
5695 List *qpqual,
5696 Plan *lefttree,
5697 List *bitmapqualorig,
5698 Index scanrelid)
5699{
5702
5703 plan->targetlist = qptlist;
5704 plan->qual = qpqual;
5705 plan->lefttree = lefttree;
5706 plan->righttree = NULL;
5709
5710 return node;
5711}
5712
5715 List *qpqual,
5716 Index scanrelid,
5717 List *tidquals)
5718{
5721
5722 plan->targetlist = qptlist;
5723 plan->qual = qpqual;
5724 plan->lefttree = NULL;
5725 plan->righttree = NULL;
5728
5729 return node;
5730}
5731
5734 List *qpqual,
5735 Index scanrelid,
5736 List *tidrangequals)
5737{
5740
5741 plan->targetlist = qptlist;
5742 plan->qual = qpqual;
5743 plan->lefttree = NULL;
5744 plan->righttree = NULL;
5747
5748 return node;
5749}
5750
5753 List *qpqual,
5754 Index scanrelid,
5755 Plan *subplan)
5756{
5759
5760 plan->targetlist = qptlist;
5761 plan->qual = qpqual;
5762 plan->lefttree = NULL;
5763 plan->righttree = NULL;
5765 node->subplan = subplan;
5767
5768 return node;
5769}
5770
5773 List *qpqual,
5774 Index scanrelid,
5776 bool funcordinality)
5777{
5780
5781 plan->targetlist = qptlist;
5782 plan->qual = qpqual;
5783 plan->lefttree = NULL;
5784 plan->righttree = NULL;
5788
5789 return node;
5790}
5791
5794 List *qpqual,
5795 Index scanrelid,
5797{
5800
5801 plan->targetlist = qptlist;
5802 plan->qual = qpqual;
5803 plan->lefttree = NULL;
5804 plan->righttree = NULL;
5807
5808 return node;
5809}
5810
5813 List *qpqual,
5814 Index scanrelid,
5815 List *values_lists)
5816{
5819
5820 plan->targetlist = qptlist;
5821 plan->qual = qpqual;
5822 plan->lefttree = NULL;
5823 plan->righttree = NULL;
5826
5827 return node;
5828}
5829
5832 List *qpqual,
5833 Index scanrelid,
5834 int ctePlanId,
5835 int cteParam)
5836{
5839
5840 plan->targetlist = qptlist;
5841 plan->qual = qpqual;
5842 plan->lefttree = NULL;
5843 plan->righttree = NULL;
5847
5848 return node;
5849}
5850
5853 List *qpqual,
5854 Index scanrelid,
5855 char *enrname)
5856{
5859
5860
5861 plan->targetlist = qptlist;
5862 plan->qual = qpqual;
5863 plan->lefttree = NULL;
5864 plan->righttree = NULL;
5866 node->enrname = enrname;
5867
5868 return node;
5869}
5870
5873 List *qpqual,
5874 Index scanrelid,
5875 int wtParam)
5876{
5879
5880 plan->targetlist = qptlist;
5881 plan->qual = qpqual;
5882 plan->lefttree = NULL;
5883 plan->righttree = NULL;
5885 node->wtParam = wtParam;
5886
5887 return node;
5888}
5889
5892 List *qpqual,
5893 Index scanrelid,
5894 List *fdw_exprs,
5895 List *fdw_private,
5896 List *fdw_scan_tlist,
5897 List *fdw_recheck_quals,
5898 Plan *outer_plan)
5899{
5902
5903
5904 plan->targetlist = qptlist;
5905 plan->qual = qpqual;
5906 plan->lefttree = outer_plan;
5907 plan->righttree = NULL;
5909
5910
5913
5914
5921
5924
5926
5927 return node;
5928}
5929
5932 Plan *lefttree,
5933 Plan *righttree,
5934 int wtParam,
5935 List *distinctList,
5936 long numGroups)
5937{
5940 int numCols = list_length(distinctList);
5941
5942 plan->targetlist = tlist;
5944 plan->lefttree = lefttree;
5945 plan->righttree = righttree;
5946 node->wtParam = wtParam;
5947
5948
5949
5950
5951
5952 node->numCols = numCols;
5953 if (numCols > 0)
5954 {
5955 int keyno = 0;
5957 Oid *dupOperators;
5958 Oid *dupCollations;
5960
5962 dupOperators = (Oid *) palloc(sizeof(Oid) * numCols);
5963 dupCollations = (Oid *) palloc(sizeof(Oid) * numCols);
5964
5965 foreach(slitem, distinctList)
5966 {
5969 plan->targetlist);
5970
5971 dupColIdx[keyno] = tle->resno;
5972 dupOperators[keyno] = sortcl->eqop;
5975 keyno++;
5976 }
5977 node->dupColIdx = dupColIdx;
5978 node->dupOperators = dupOperators;
5979 node->dupCollations = dupCollations;
5980 }
5982
5983 return node;
5984}
5985
5988{
5991
5994 plan->lefttree = NULL;
5995 plan->righttree = NULL;
5997
5998 return node;
5999}
6000
6003{
6006
6009 plan->lefttree = NULL;
6010 plan->righttree = NULL;
6012
6013 return node;
6014}
6015
6018 List *joinclauses,
6019 List *otherclauses,
6020 List *nestParams,
6021 Plan *lefttree,
6022 Plan *righttree,
6024 bool inner_unique)
6025{
6028
6029 plan->targetlist = tlist;
6030 plan->qual = otherclauses;
6031 plan->lefttree = lefttree;
6032 plan->righttree = righttree;
6037
6038 return node;
6039}
6040
6043 List *joinclauses,
6044 List *otherclauses,
6045 List *hashclauses,
6046 List *hashoperators,
6047 List *hashcollations,
6048 List *hashkeys,
6049 Plan *lefttree,
6050 Plan *righttree,
6052 bool inner_unique)
6053{
6056
6057 plan->targetlist = tlist;
6058 plan->qual = otherclauses;
6059 plan->lefttree = lefttree;
6060 plan->righttree = righttree;
6068
6069 return node;
6070}
6071
6072static Hash *
6074 List *hashkeys,
6075 Oid skewTable,
6077 bool skewInherit)
6078{
6081
6084 plan->lefttree = lefttree;
6085 plan->righttree = NULL;
6086
6091
6092 return node;
6093}
6094
6097 List *joinclauses,
6098 List *otherclauses,
6099 List *mergeclauses,
6100 Oid *mergefamilies,
6101 Oid *mergecollations,
6102 bool *mergereversals,
6103 bool *mergenullsfirst,
6104 Plan *lefttree,
6105 Plan *righttree,
6107 bool inner_unique,
6108 bool skip_mark_restore)
6109{
6112
6113 plan->targetlist = tlist;
6114 plan->qual = otherclauses;
6115 plan->lefttree = lefttree;
6116 plan->righttree = righttree;
6119 node->mergeFamilies = mergefamilies;
6120 node->mergeCollations = mergecollations;
6121 node->mergeReversals = mergereversals;
6122 node->mergeNullsFirst = mergenullsfirst;
6126
6127 return node;
6128}
6129
6130
6131
6132
6133
6134
6135
6136static Sort *
6139 Oid *collations, bool *nullsFirst)
6140{
6143
6145
6150 plan->lefttree = lefttree;
6151 plan->righttree = NULL;
6152 node->numCols = numCols;
6153 node->sortColIdx = sortColIdx;
6154 node->sortOperators = sortOperators;
6155 node->collations = collations;
6156 node->nullsFirst = nullsFirst;
6157
6158 return node;
6159}
6160
6161
6162
6163
6164
6165
6166
6170 Oid *collations, bool *nullsFirst)
6171{
6174
6176
6180 plan->lefttree = lefttree;
6181 plan->righttree = NULL;
6184 node->sort.sortColIdx = sortColIdx;
6185 node->sort.sortOperators = sortOperators;
6186 node->sort.collations = collations;
6187 node->sort.nullsFirst = nullsFirst;
6188
6189 return node;
6190}
6191
6192
6193
6194
6195
6196
6197
6198
6199
6200
6201
6202
6203
6204
6205
6206
6207
6208
6209
6210
6211
6212
6213
6214
6215
6216
6217
6218
6219
6220
6221
6222
6223
6224
6225
6226
6227
6228
6229
6230
6231
6232
6233static Plan *
6237 bool adjust_tlist_in_place,
6238 int *p_numsortkeys,
6240 Oid **p_sortOperators,
6241 Oid **p_collations,
6242 bool **p_nullsFirst)
6243{
6246 int numsortkeys;
6248 Oid *sortOperators;
6249 Oid *collations;
6250 bool *nullsFirst;
6251
6252
6253
6254
6257 sortOperators = (Oid *) palloc(numsortkeys * sizeof(Oid));
6258 collations = (Oid *) palloc(numsortkeys * sizeof(Oid));
6259 nullsFirst = (bool *) palloc(numsortkeys * sizeof(bool));
6260
6261 numsortkeys = 0;
6262
6263 foreach(i, pathkeys)
6264 {
6270 Oid sortop;
6272
6274 {
6275
6276
6277
6278
6279
6280 if (ec->ec_sortref == 0)
6281 elog(ERROR, "volatile EquivalenceClass has no sortref");
6286 }
6287 else if (reqColIdx != NULL)
6288 {
6289
6290
6291
6292
6293
6294
6295
6296
6297
6299 if (tle)
6300 {
6302 if (em)
6303 {
6304
6306 }
6307 else
6308 tle = NULL;
6309 }
6310 }
6311 else
6312 {
6313
6314
6315
6316
6317
6318
6319
6320
6321
6322
6323
6324
6325
6326 foreach(j, tlist)
6327 {
6330 if (em)
6331 {
6332
6334 break;
6335 }
6336 tle = NULL;
6337 }
6338 }
6339
6340 if (!tle)
6341 {
6342
6343
6344
6346 if (!em)
6347 elog(ERROR, "could not find pathkey item to sort");
6349
6350
6351
6352
6353 if (!adjust_tlist_in_place &&
6355 {
6356
6360 }
6361
6362
6363 adjust_tlist_in_place = true;
6364
6365
6366
6367
6370 NULL,
6371 true);
6372 tlist = lappend(tlist, tle);
6373 lefttree->targetlist = tlist;
6374 }
6375
6376
6377
6378
6379
6381 pk_datatype,
6382 pk_datatype,
6384 if ((sortop))
6385 elog(ERROR, "missing operator %d(%u,%u) in opfamily %u",
6386 pathkey->pk_cmptype, pk_datatype, pk_datatype,
6388
6389
6390 sortColIdx[numsortkeys] = tle->resno;
6391 sortOperators[numsortkeys] = sortop;
6394 numsortkeys++;
6395 }
6396
6397
6398 *p_numsortkeys = numsortkeys;
6399 *p_sortColIdx = sortColIdx;
6400 *p_sortOperators = sortOperators;
6401 *p_collations = collations;
6402 *p_nullsFirst = nullsFirst;
6403
6404 return lefttree;
6405}
6406
6407
6408
6409
6410
6411
6412
6413
6414
6415static Sort *
6417{
6418 int numsortkeys;
6420 Oid *sortOperators;
6421 Oid *collations;
6422 bool *nullsFirst;
6423
6424
6426 relids,
6427 NULL,
6428 false,
6429 &numsortkeys,
6430 &sortColIdx,
6431 &sortOperators,
6432 &collations,
6433 &nullsFirst);
6434
6435
6436 return make_sort(lefttree, numsortkeys,
6437 sortColIdx, sortOperators,
6438 collations, nullsFirst);
6439}
6440
6441
6442
6443
6444
6445
6446
6447
6448
6449
6452 Relids relids, int nPresortedCols)
6453{
6454 int numsortkeys;
6456 Oid *sortOperators;
6457 Oid *collations;
6458 bool *nullsFirst;
6459
6460
6462 relids,
6463 NULL,
6464 false,
6465 &numsortkeys,
6466 &sortColIdx,
6467 &sortOperators,
6468 &collations,
6469 &nullsFirst);
6470
6471
6473 sortColIdx, sortOperators,
6474 collations, nullsFirst);
6475}
6476
6477
6478
6479
6480
6481
6482
6483
6486{
6489 int numsortkeys;
6491 Oid *sortOperators;
6492 Oid *collations;
6493 bool *nullsFirst;
6494
6495
6498 sortOperators = (Oid *) palloc(numsortkeys * sizeof(Oid));
6499 collations = (Oid *) palloc(numsortkeys * sizeof(Oid));
6500 nullsFirst = (bool *) palloc(numsortkeys * sizeof(bool));
6501
6502 numsortkeys = 0;
6503 foreach(l, sortcls)
6504 {
6507
6508 sortColIdx[numsortkeys] = tle->resno;
6509 sortOperators[numsortkeys] = sortcl->sortop;
6511 nullsFirst[numsortkeys] = sortcl->nulls_first;
6512 numsortkeys++;
6513 }
6514
6515 return make_sort(lefttree, numsortkeys,
6516 sortColIdx, sortOperators,
6517 collations, nullsFirst);
6518}
6519
6520
6521
6522
6523
6524
6525
6526
6527
6528
6529
6530
6531
6532
6533static Sort *
6536 Plan *lefttree)
6537{
6540 int numsortkeys;
6542 Oid *sortOperators;
6543 Oid *collations;
6544 bool *nullsFirst;
6545
6546
6549 sortOperators = (Oid *) palloc(numsortkeys * sizeof(Oid));
6550 collations = (Oid *) palloc(numsortkeys * sizeof(Oid));
6551 nullsFirst = (bool *) palloc(numsortkeys * sizeof(bool));
6552
6553 numsortkeys = 0;
6554 foreach(l, groupcls)
6555 {
6558
6559 if (!tle)
6560 elog(ERROR, "could not retrieve tle for sort-from-groupcols");
6561
6562 sortColIdx[numsortkeys] = tle->resno;
6563 sortOperators[numsortkeys] = grpcl->sortop;
6565 nullsFirst[numsortkeys] = grpcl->nulls_first;
6566 numsortkeys++;
6567 }
6568
6569 return make_sort(lefttree, numsortkeys,
6570 sortColIdx, sortOperators,
6571 collations, nullsFirst);
6572}
6573
6576{
6579
6582 plan->lefttree = lefttree;
6583 plan->righttree = NULL;
6584
6585 return node;
6586}
6587
6588
6589
6590
6591
6592
6593
6594
6595
6598{
6599 Plan *matplan;
6600 Path matpath;
6601 Cost initplan_cost;
6602 bool unsafe_initplans;
6603
6605
6606
6607
6608
6609
6610
6611
6614
6615
6617 &initplan_cost, &unsafe_initplans);
6619 subplan->total_cost -= initplan_cost;
6620
6621
6635
6636 return matplan;
6637}
6638
6641 List *param_exprs, bool singlerow, bool binary_mode,
6643{
6646
6649 plan->lefttree = lefttree;
6650 plan->righttree = NULL;
6651
6653 node->hashOperators = hashoperators;
6654 node->collations = collations;
6660
6661 return node;
6662}
6663
6667 int numGroupCols, AttrNumber *grpColIdx, Oid *grpOperators, Oid *grpCollations,
6668 List *groupingSets, List *chain, double dNumGroups,
6669 Size transitionSpace, Plan *lefttree)
6670{
6673 long numGroups;
6674
6675
6677
6680 node->numCols = numGroupCols;
6681 node->grpColIdx = grpColIdx;
6682 node->grpOperators = grpOperators;
6683 node->grpCollations = grpCollations;
6686 node->aggParams = NULL;
6688 node->chain = chain;
6689
6690 plan->qual = qual;
6691 plan->targetlist = tlist;
6692 plan->lefttree = lefttree;
6693 plan->righttree = NULL;
6694
6695 return node;
6696}
6697
6700 int partNumCols, AttrNumber *partColIdx, Oid *partOperators, Oid *partCollations,
6701 int ordNumCols, AttrNumber *ordColIdx, Oid *ordOperators, Oid *ordCollations,
6702 List *runCondition, List *qual, bool topWindow, Plan *lefttree)
6703{
6706
6707 node->winname = wc->name;
6710 node->partColIdx = partColIdx;
6711 node->partOperators = partOperators;
6712 node->partCollations = partCollations;
6714 node->ordColIdx = ordColIdx;
6715 node->ordOperators = ordOperators;
6716 node->ordCollations = ordCollations;
6721
6729
6730 plan->targetlist = tlist;
6731 plan->lefttree = lefttree;
6732 plan->righttree = NULL;
6733 plan->qual = qual;
6734
6735 return node;
6736}
6737
6741 int numGroupCols,
6743 Oid *grpOperators,
6744 Oid *grpCollations,
6745 Plan *lefttree)
6746{
6749
6750 node->numCols = numGroupCols;
6751 node->grpColIdx = grpColIdx;
6752 node->grpOperators = grpOperators;
6753 node->grpCollations = grpCollations;
6754
6755 plan->qual = qual;
6756 plan->targetlist = tlist;
6757 plan->lefttree = lefttree;
6758 plan->righttree = NULL;
6759
6760 return node;
6761}
6762
6763
6764
6765
6766
6767
6770{
6773 int numCols = list_length(distinctList);
6774 int keyno = 0;
6776 Oid *uniqOperators;
6777 Oid *uniqCollations;
6779
6782 plan->lefttree = lefttree;
6783 plan->righttree = NULL;
6784
6785
6786
6787
6788
6789 Assert(numCols > 0);
6791 uniqOperators = (Oid *) palloc(sizeof(Oid) * numCols);
6792 uniqCollations = (Oid *) palloc(sizeof(Oid) * numCols);
6793
6794 foreach(slitem, distinctList)
6795 {
6798
6799 uniqColIdx[keyno] = tle->resno;
6800 uniqOperators[keyno] = sortcl->eqop;
6803 keyno++;
6804 }
6805
6806 node->numCols = numCols;
6807 node->uniqColIdx = uniqColIdx;
6808 node->uniqOperators = uniqOperators;
6809 node->uniqCollations = uniqCollations;
6810
6811 return node;
6812}
6813
6814
6815
6816
6819{
6822 int keyno = 0;
6824 Oid *uniqOperators;
6825 Oid *uniqCollations;
6827
6830 plan->lefttree = lefttree;
6831 plan->righttree = NULL;
6832
6833
6834
6835
6836
6837
6840 uniqOperators = (Oid *) palloc(sizeof(Oid) * numCols);
6841 uniqCollations = (Oid *) palloc(sizeof(Oid) * numCols);
6842
6843 foreach(lc, pathkeys)
6844 {
6850 Oid eqop;
6852
6853
6854 if (keyno >= numCols)
6855 break;
6856
6858 {
6859
6860
6861
6862
6863
6864 if (ec->ec_sortref == 0)
6865 elog(ERROR, "volatile EquivalenceClass has no sortref");
6870 }
6871 else
6872 {
6873
6874
6875
6876
6877
6878 foreach(j, plan->targetlist)
6879 {
6882 if (em)
6883 {
6884
6886 break;
6887 }
6888 tle = NULL;
6889 }
6890 }
6891
6892 if (!tle)
6893 elog(ERROR, "could not find pathkey item to sort");
6894
6895
6896
6897
6898
6900 pk_datatype,
6901 pk_datatype,
6903 if ((eqop))
6904 elog(ERROR, "missing operator %d(%u,%u) in opfamily %u",
6905 COMPARE_EQ, pk_datatype, pk_datatype,
6907
6908 uniqColIdx[keyno] = tle->resno;
6909 uniqOperators[keyno] = eqop;
6911
6912 keyno++;
6913 }
6914
6915 node->numCols = numCols;
6916 node->uniqColIdx = uniqColIdx;
6917 node->uniqOperators = uniqOperators;
6918 node->uniqCollations = uniqCollations;
6919
6920 return node;
6921}
6922
6925 List *qpqual,
6926 int nworkers,
6927 int rescan_param,
6928 bool single_copy,
6929 Plan *subplan)
6930{
6933
6934 plan->targetlist = qptlist;
6935 plan->qual = qpqual;
6936 plan->lefttree = subplan;
6937 plan->righttree = NULL;
6943
6944 return node;
6945}
6946
6947
6948
6949
6950
6951
6954 List *tlist, Plan *lefttree, Plan *righttree,
6955 List *groupList, long numGroups)
6956{
6960 int keyno = 0;
6962 Oid *cmpOperators;
6963 Oid *cmpCollations;
6964 bool *cmpNullsFirst;
6966
6967 plan->targetlist = tlist;
6969 plan->lefttree = lefttree;
6970 plan->righttree = righttree;
6971
6972
6973
6974
6975
6977 cmpOperators = (Oid *) palloc(sizeof(Oid) * numCols);
6978 cmpCollations = (Oid *) palloc(sizeof(Oid) * numCols);
6979 cmpNullsFirst = (bool *) palloc(sizeof(bool) * numCols);
6980
6981 foreach(slitem, groupList)
6982 {
6985
6986 cmpColIdx[keyno] = tle->resno;
6988 cmpOperators[keyno] = sortcl->eqop;
6989 else
6990 cmpOperators[keyno] = sortcl->sortop;
6993 cmpNullsFirst[keyno] = sortcl->nulls_first;
6994 keyno++;
6995 }
6996
6997 node->cmd = cmd;
6999 node->numCols = numCols;
7000 node->cmpColIdx = cmpColIdx;
7001 node->cmpOperators = cmpOperators;
7002 node->cmpCollations = cmpCollations;
7003 node->cmpNullsFirst = cmpNullsFirst;
7005
7006 return node;
7007}
7008
7009
7010
7011
7012
7015{
7018
7021 plan->lefttree = lefttree;
7022 plan->righttree = NULL;
7023
7026
7027 return node;
7028}
7029
7030
7031
7032
7033
7037 Oid *uniqOperators, Oid *uniqCollations)
7038{
7041
7044 plan->lefttree = lefttree;
7045 plan->righttree = NULL;
7046
7051 node->uniqColIdx = uniqColIdx;
7052 node->uniqOperators = uniqOperators;
7053 node->uniqCollations = uniqCollations;
7054
7055 return node;
7056}
7057
7058
7059
7060
7061
7064 Node *resconstantqual,
7065 Plan *subplan)
7066{
7069
7070 plan->targetlist = tlist;
7072 plan->lefttree = subplan;
7073 plan->righttree = NULL;
7075
7076 return node;
7077}
7078
7079
7080
7081
7082
7085 Plan *subplan)
7086{
7089
7090 plan->targetlist = tlist;
7092 plan->lefttree = subplan;
7093 plan->righttree = NULL;
7094
7095 return node;
7096}
7097
7098
7099
7100
7101
7104 CmdType operation, bool canSetTag,
7105 Index nominalRelation, Index rootRelation,
7106 bool partColsUpdated,
7107 List *resultRelations,
7108 List *updateColnosLists,
7109 List *withCheckOptionLists, List *returningLists,
7111 List *mergeActionLists, List *mergeJoinConditions,
7112 int epqParam)
7113{
7115 bool returning_old_or_new = false;
7116 bool returning_old_or_new_valid = false;
7117 List *fdw_private_list;
7120 int i;
7121
7125 updateColnosLists == NIL));
7126 Assert(withCheckOptionLists == NIL ||
7130
7134
7136
7143 if (!onconflict)
7144 {
7152 }
7153 else
7154 {
7156
7157
7158
7159
7160
7161
7162
7167
7168
7169
7170
7171
7172
7173
7175
7178 }
7188
7189
7190
7191
7192
7193 fdw_private_list = NIL;
7194 direct_modify_plans = NULL;
7195 i = 0;
7196 foreach(lc, resultRelations)
7197 {
7200 List *fdw_private;
7201 bool direct_modify;
7202
7203
7204
7205
7206
7207
7208
7209
7210 if (rti < root->simple_rel_array_size &&
7211 root->simple_rel_array[rti] != NULL)
7212 {
7213 RelOptInfo *resultRel = root->simple_rel_array[rti];
7214
7215 fdwroutine = resultRel->fdwroutine;
7216 }
7217 else
7218 {
7220
7222 rte->relkind == RELKIND_FOREIGN_TABLE)
7223 {
7224
7226 {
7227
7230 (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
7231 errmsg("access to non-system foreign table is restricted")));
7232 }
7233
7235 }
7236 else
7237 fdwroutine = NULL;
7238 }
7239
7240
7241
7242
7243
7244
7245
7246
7247 if (operation == CMD_MERGE && fdwroutine != NULL)
7248 {
7250
7252 errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
7253 errmsg("cannot execute MERGE on relation \"%s\"",
7256 }
7257
7258
7259
7260
7261
7262
7263
7264
7265
7266 direct_modify = false;
7267 if (fdwroutine != NULL &&
7272 withCheckOptionLists == NIL &&
7275 {
7276
7277 if (!returning_old_or_new_valid)
7278 {
7279 returning_old_or_new =
7281 root->parse->returningList);
7282 returning_old_or_new_valid = true;
7283 }
7284 if (!returning_old_or_new)
7286 }
7287 if (direct_modify)
7288 direct_modify_plans = bms_add_member(direct_modify_plans, i);
7289
7290 if (!direct_modify &&
7291 fdwroutine != NULL &&
7294 else
7295 fdw_private = NIL;
7296 fdw_private_list = lappend(fdw_private_list, fdw_private);
7297 i++;
7298 }
7301
7302 return node;
7303}
7304
7305
7306
7307
7308
7309bool
7311{
7312
7314 {
7315 case T_Hash:
7316 case T_Material:
7317 case T_Memoize:
7318 case T_Sort:
7319 case T_IncrementalSort:
7320 case T_Unique:
7321 case T_SetOp:
7322 case T_LockRows:
7323 case T_Limit:
7324 case T_ModifyTable:
7325 case T_MergeAppend:
7326 case T_RecursiveUnion:
7327 return false;
7328 case T_CustomScan:
7330 return true;
7331 return false;
7332 case T_Append:
7333
7334
7335
7336
7337
7338
7340 case T_ProjectSet:
7341
7342
7343
7344
7345
7346
7347
7348 return false;
7349 default:
7350 break;
7351 }
7352 return true;
7353}
7354
7355
7356
7357
7358
7359bool
7361{
7362
7364 {
7365 case T_Hash:
7366 case T_Material:
7367 case T_Memoize:
7368 case T_Sort:
7369 case T_Unique:
7370 case T_SetOp:
7371 case T_LockRows:
7372 case T_Limit:
7373 case T_ModifyTable:
7374 case T_Append:
7375 case T_MergeAppend:
7376 case T_RecursiveUnion:
7377 return false;
7378 case T_CustomScan:
7380 return true;
7381 return false;
7382 case T_ProjectSet:
7383
7384
7385
7386
7387
7388
7389
7390 return false;
7391 default:
7392 break;
7393 }
7394 return true;
7395}
Datum sort(PG_FUNCTION_ARGS)
#define InvalidAttrNumber
Bitmapset * bms_difference(const Bitmapset *a, const Bitmapset *b)
bool bms_is_subset(const Bitmapset *a, const Bitmapset *b)
void bms_free(Bitmapset *a)
bool bms_is_member(int x, const Bitmapset *a)
Bitmapset * bms_add_member(Bitmapset *a, int x)
Bitmapset * bms_union(const Bitmapset *a, const Bitmapset *b)
bool bms_nonempty_difference(const Bitmapset *a, const Bitmapset *b)
#define PG_USED_FOR_ASSERTS_ONLY
#define OidIsValid(objectId)
bool contain_mutable_functions(Node *clause)
Bitmapset * pull_paramids(Expr *expr)
void CommuteOpExpr(OpExpr *clause)
void cost_material(Path *path, int input_disabled_nodes, Cost input_startup_cost, Cost input_total_cost, double tuples, int width)
void cost_sort(Path *path, PlannerInfo *root, List *pathkeys, int input_disabled_nodes, Cost input_cost, double tuples, int width, Cost comparison_cost, int sort_mem, double limit_tuples)
void cost_qual_eval_node(QualCost *cost, Node *qual, PlannerInfo *root)
void cost_incremental_sort(Path *path, PlannerInfo *root, List *pathkeys, int presorted_keys, int input_disabled_nodes, Cost input_startup_cost, Cost input_total_cost, double input_tuples, int width, Cost comparison_cost, int sort_mem, double limit_tuples)
double clamp_row_est(double nrows)
long clamp_cardinality_to_long(Cardinality x)
bool enable_partition_pruning
bool enable_incremental_sort
static Unique * make_unique_from_sortclauses(Plan *lefttree, List *distinctList)
static Plan * create_join_plan(PlannerInfo *root, JoinPath *best_path)
static bool use_physical_tlist(PlannerInfo *root, Path *path, int flags)
static SeqScan * create_seqscan_plan(PlannerInfo *root, Path *best_path, List *tlist, List *scan_clauses)
static WorkTableScan * make_worktablescan(List *qptlist, List *qpqual, Index scanrelid, int wtParam)
static Plan * create_merge_append_plan(PlannerInfo *root, MergeAppendPath *best_path, int flags)
static List * order_qual_clauses(PlannerInfo *root, List *clauses)
static MergeJoin * make_mergejoin(List *tlist, List *joinclauses, List *otherclauses, List *mergeclauses, Oid *mergefamilies, Oid *mergecollations, bool *mergereversals, bool *mergenullsfirst, Plan *lefttree, Plan *righttree, JoinType jointype, bool inner_unique, bool skip_mark_restore)
static GatherMerge * create_gather_merge_plan(PlannerInfo *root, GatherMergePath *best_path)
static ValuesScan * create_valuesscan_plan(PlannerInfo *root, Path *best_path, List *tlist, List *scan_clauses)
static SetOp * make_setop(SetOpCmd cmd, SetOpStrategy strategy, List *tlist, Plan *lefttree, Plan *righttree, List *groupList, long numGroups)
static void copy_generic_path_info(Plan *dest, Path *src)
static WindowAgg * make_windowagg(List *tlist, WindowClause *wc, int partNumCols, AttrNumber *partColIdx, Oid *partOperators, Oid *partCollations, int ordNumCols, AttrNumber *ordColIdx, Oid *ordOperators, Oid *ordCollations, List *runCondition, List *qual, bool topWindow, Plan *lefttree)
static Memoize * make_memoize(Plan *lefttree, Oid *hashoperators, Oid *collations, List *param_exprs, bool singlerow, bool binary_mode, uint32 est_entries, Bitmapset *keyparamids)
Sort * make_sort_from_sortclauses(List *sortcls, Plan *lefttree)
static BitmapOr * make_bitmap_or(List *bitmapplans)
static HashJoin * create_hashjoin_plan(PlannerInfo *root, HashPath *best_path)
static SeqScan * make_seqscan(List *qptlist, List *qpqual, Index scanrelid)
static TableFuncScan * create_tablefuncscan_plan(PlannerInfo *root, Path *best_path, List *tlist, List *scan_clauses)
static CustomScan * create_customscan_plan(PlannerInfo *root, CustomPath *best_path, List *tlist, List *scan_clauses)
static Node * fix_indexqual_operand(Node *node, IndexOptInfo *index, int indexcol)
static void fix_indexqual_references(PlannerInfo *root, IndexPath *index_path, List **stripped_indexquals_p, List **fixed_indexquals_p)
static List * fix_indexorderby_references(PlannerInfo *root, IndexPath *index_path)
static Result * make_result(List *tlist, Node *resconstantqual, Plan *subplan)
static AttrNumber * remap_groupColIdx(PlannerInfo *root, List *groupClause)
static Plan * create_append_plan(PlannerInfo *root, AppendPath *best_path, int flags)
static void bitmap_subplan_mark_shared(Plan *plan)
static TidScan * make_tidscan(List *qptlist, List *qpqual, Index scanrelid, List *tidquals)
static MergeJoin * create_mergejoin_plan(PlannerInfo *root, MergePath *best_path)
static Plan * create_plan_recurse(PlannerInfo *root, Path *best_path, int flags)
static void label_sort_with_costsize(PlannerInfo *root, Sort *plan, double limit_tuples)
static ForeignScan * create_foreignscan_plan(PlannerInfo *root, ForeignPath *best_path, List *tlist, List *scan_clauses)
static BitmapHeapScan * create_bitmap_scan_plan(PlannerInfo *root, BitmapHeapPath *best_path, List *tlist, List *scan_clauses)
static IncrementalSort * make_incrementalsort(Plan *lefttree, int numCols, int nPresortedCols, AttrNumber *sortColIdx, Oid *sortOperators, Oid *collations, bool *nullsFirst)
static Result * create_group_result_plan(PlannerInfo *root, GroupResultPath *best_path)
static Limit * create_limit_plan(PlannerInfo *root, LimitPath *best_path, int flags)
static Agg * create_agg_plan(PlannerInfo *root, AggPath *best_path)
bool is_projection_capable_path(Path *path)
static CteScan * make_ctescan(List *qptlist, List *qpqual, Index scanrelid, int ctePlanId, int cteParam)
static TidScan * create_tidscan_plan(PlannerInfo *root, TidPath *best_path, List *tlist, List *scan_clauses)
static TidRangeScan * make_tidrangescan(List *qptlist, List *qpqual, Index scanrelid, List *tidrangequals)
static Plan * create_bitmap_subplan(PlannerInfo *root, Path *bitmapqual, List **qual, List **indexqual, List **indexECs)
static Node * fix_indexqual_clause(PlannerInfo *root, IndexOptInfo *index, int indexcol, Node *clause, List *indexcolnos)
static Unique * make_unique_from_pathkeys(Plan *lefttree, List *pathkeys, int numCols)
static WorkTableScan * create_worktablescan_plan(PlannerInfo *root, Path *best_path, List *tlist, List *scan_clauses)
static Plan * create_gating_plan(PlannerInfo *root, Path *path, Plan *plan, List *gating_quals)
static FunctionScan * create_functionscan_plan(PlannerInfo *root, Path *best_path, List *tlist, List *scan_clauses)
static Result * create_resultscan_plan(PlannerInfo *root, Path *best_path, List *tlist, List *scan_clauses)
static BitmapHeapScan * make_bitmap_heapscan(List *qptlist, List *qpqual, Plan *lefttree, List *bitmapqualorig, Index scanrelid)
static Node * replace_nestloop_params_mutator(Node *node, PlannerInfo *root)
static SetOp * create_setop_plan(PlannerInfo *root, SetOpPath *best_path, int flags)
bool is_projection_capable_plan(Plan *plan)
static CteScan * create_ctescan_plan(PlannerInfo *root, Path *best_path, List *tlist, List *scan_clauses)
static Sort * create_sort_plan(PlannerInfo *root, SortPath *best_path, int flags)
static Unique * create_upper_unique_plan(PlannerInfo *root, UpperUniquePath *best_path, int flags)
static ProjectSet * make_project_set(List *tlist, Plan *subplan)
static Sort * make_sort_from_pathkeys(Plan *lefttree, List *pathkeys, Relids relids)
static HashJoin * make_hashjoin(List *tlist, List *joinclauses, List *otherclauses, List *hashclauses, List *hashoperators, List *hashcollations, List *hashkeys, Plan *lefttree, Plan *righttree, JoinType jointype, bool inner_unique)
static Gather * make_gather(List *qptlist, List *qpqual, int nworkers, int rescan_param, bool single_copy, Plan *subplan)
static Gather * create_gather_plan(PlannerInfo *root, GatherPath *best_path)
static Sort * make_sort(Plan *lefttree, int numCols, AttrNumber *sortColIdx, Oid *sortOperators, Oid *collations, bool *nullsFirst)
Limit * make_limit(Plan *lefttree, Node *limitOffset, Node *limitCount, LimitOption limitOption, int uniqNumCols, AttrNumber *uniqColIdx, Oid *uniqOperators, Oid *uniqCollations)
static ProjectSet * create_project_set_plan(PlannerInfo *root, ProjectSetPath *best_path)
static void label_incrementalsort_with_costsize(PlannerInfo *root, IncrementalSort *plan, List *pathkeys, double limit_tuples)
ForeignScan * make_foreignscan(List *qptlist, List *qpqual, Index scanrelid, List *fdw_exprs, List *fdw_private, List *fdw_scan_tlist, List *fdw_recheck_quals, Plan *outer_plan)
static Group * create_group_plan(PlannerInfo *root, GroupPath *best_path)
static ModifyTable * create_modifytable_plan(PlannerInfo *root, ModifyTablePath *best_path)
static Result * create_minmaxagg_plan(PlannerInfo *root, MinMaxAggPath *best_path)
static LockRows * create_lockrows_plan(PlannerInfo *root, LockRowsPath *best_path, int flags)
static Material * create_material_plan(PlannerInfo *root, MaterialPath *best_path, int flags)
static List * get_gating_quals(PlannerInfo *root, List *quals)
static Plan * create_scan_plan(PlannerInfo *root, Path *best_path, int flags)
static Group * make_group(List *tlist, List *qual, int numGroupCols, AttrNumber *grpColIdx, Oid *grpOperators, Oid *grpCollations, Plan *lefttree)
static LockRows * make_lockrows(Plan *lefttree, List *rowMarks, int epqParam)
static IncrementalSort * create_incrementalsort_plan(PlannerInfo *root, IncrementalSortPath *best_path, int flags)
static NamedTuplestoreScan * create_namedtuplestorescan_plan(PlannerInfo *root, Path *best_path, List *tlist, List *scan_clauses)
static Plan * create_projection_plan(PlannerInfo *root, ProjectionPath *best_path, int flags)
static RecursiveUnion * make_recursive_union(List *tlist, Plan *lefttree, Plan *righttree, int wtParam, List *distinctList, long numGroups)
static IndexOnlyScan * make_indexonlyscan(List *qptlist, List *qpqual, Index scanrelid, Oid indexid, List *indexqual, List *recheckqual, List *indexorderby, List *indextlist, ScanDirection indexscandir)
static List * build_path_tlist(PlannerInfo *root, Path *path)
static IndexScan * make_indexscan(List *qptlist, List *qpqual, Index scanrelid, Oid indexid, List *indexqual, List *indexqualorig, List *indexorderby, List *indexorderbyorig, List *indexorderbyops, ScanDirection indexscandir)
static FunctionScan * make_functionscan(List *qptlist, List *qpqual, Index scanrelid, List *functions, bool funcordinality)
static TableFuncScan * make_tablefuncscan(List *qptlist, List *qpqual, Index scanrelid, TableFunc *tablefunc)
static SubqueryScan * create_subqueryscan_plan(PlannerInfo *root, SubqueryScanPath *best_path, List *tlist, List *scan_clauses)
Agg * make_agg(List *tlist, List *qual, AggStrategy aggstrategy, AggSplit aggsplit, int numGroupCols, AttrNumber *grpColIdx, Oid *grpOperators, Oid *grpCollations, List *groupingSets, List *chain, double dNumGroups, Size transitionSpace, Plan *lefttree)
static Plan * inject_projection_plan(Plan *subplan, List *tlist, bool parallel_safe)
static TidRangeScan * create_tidrangescan_plan(PlannerInfo *root, TidRangePath *best_path, List *tlist, List *scan_clauses)
static List * get_switched_clauses(List *clauses, Relids outerrelids)
static void copy_plan_costsize(Plan *dest, Plan *src)
static ValuesScan * make_valuesscan(List *qptlist, List *qpqual, Index scanrelid, List *values_lists)
Plan * materialize_finished_plan(Plan *subplan)
static SampleScan * make_samplescan(List *qptlist, List *qpqual, Index scanrelid, TableSampleClause *tsc)
static NestLoop * create_nestloop_plan(PlannerInfo *root, NestPath *best_path)
static Memoize * create_memoize_plan(PlannerInfo *root, MemoizePath *best_path, int flags)
static NamedTuplestoreScan * make_namedtuplestorescan(List *qptlist, List *qpqual, Index scanrelid, char *enrname)
static bool mark_async_capable_plan(Plan *plan, Path *path)
static Material * make_material(Plan *lefttree)
Plan * change_plan_targetlist(Plan *subplan, List *tlist, bool tlist_parallel_safe)
static NestLoop * make_nestloop(List *tlist, List *joinclauses, List *otherclauses, List *nestParams, Plan *lefttree, Plan *righttree, JoinType jointype, bool inner_unique)
static BitmapIndexScan * make_bitmap_indexscan(Index scanrelid, Oid indexid, List *indexqual, List *indexqualorig)
static SubqueryScan * make_subqueryscan(List *qptlist, List *qpqual, Index scanrelid, Plan *subplan)
static Hash * make_hash(Plan *lefttree, List *hashkeys, Oid skewTable, AttrNumber skewColumn, bool skewInherit)
static WindowAgg * create_windowagg_plan(PlannerInfo *root, WindowAggPath *best_path)
static Node * replace_nestloop_params(PlannerInfo *root, Node *expr)
static BitmapAnd * make_bitmap_and(List *bitmapplans)
static Plan * create_groupingsets_plan(PlannerInfo *root, GroupingSetsPath *best_path)
static RecursiveUnion * create_recursiveunion_plan(PlannerInfo *root, RecursiveUnionPath *best_path)
static Sort * make_sort_from_groupcols(List *groupcls, AttrNumber *grpColIdx, Plan *lefttree)
static Scan * create_indexscan_plan(PlannerInfo *root, IndexPath *best_path, List *tlist, List *scan_clauses, bool indexonly)
static ModifyTable * make_modifytable(PlannerInfo *root, Plan *subplan, CmdType operation, bool canSetTag, Index nominalRelation, Index rootRelation, bool partColsUpdated, List *resultRelations, List *updateColnosLists, List *withCheckOptionLists, List *returningLists, List *rowMarks, OnConflictExpr *onconflict, List *mergeActionLists, List *mergeJoinConditions, int epqParam)
static Plan * prepare_sort_from_pathkeys(Plan *lefttree, List *pathkeys, Relids relids, const AttrNumber *reqColIdx, bool adjust_tlist_in_place, int *p_numsortkeys, AttrNumber **p_sortColIdx, Oid **p_sortOperators, Oid **p_collations, bool **p_nullsFirst)
static Plan * create_unique_plan(PlannerInfo *root, UniquePath *best_path, int flags)
static IncrementalSort * make_incrementalsort_from_pathkeys(Plan *lefttree, List *pathkeys, Relids relids, int nPresortedCols)
static SampleScan * create_samplescan_plan(PlannerInfo *root, Path *best_path, List *tlist, List *scan_clauses)
Plan * create_plan(PlannerInfo *root, Path *best_path)
int errcode(int sqlerrcode)
int errmsg(const char *fmt,...)
#define ereport(elevel,...)
bool equal(const void *a, const void *b)
bool is_redundant_with_indexclauses(RestrictInfo *rinfo, List *indexclauses)
EquivalenceMember * find_ec_member_matching_expr(EquivalenceClass *ec, Expr *expr, Relids relids)
EquivalenceMember * find_computable_ec_member(PlannerInfo *root, EquivalenceClass *ec, List *exprs, Relids relids, bool require_parallel_safe)
bool is_redundant_derived_clause(RestrictInfo *rinfo, List *clauselist)
#define CUSTOMPATH_SUPPORT_PROJECTION
FdwRoutine * GetFdwRoutineByRelId(Oid relid)
Assert(PointerIsAligned(start, uint64))
if(TABLE==NULL||TABLE_index==NULL)
List * list_difference(const List *list1, const List *list2)
List * lappend(List *list, void *datum)
List * list_difference_ptr(const List *list1, const List *list2)
List * list_concat(List *list1, const List *list2)
List * list_concat_copy(const List *list1, const List *list2)
List * list_copy(const List *oldlist)
List * lappend_oid(List *list, Oid datum)
bool list_member_ptr(const List *list, const void *datum)
bool list_member(const List *list, const void *datum)
List * list_copy_head(const List *oldlist, int len)
List * list_concat_unique(List *list1, const List *list2)
char * get_rel_name(Oid relid)
bool get_compatible_hash_operators(Oid opno, Oid *lhs_opno, Oid *rhs_opno)
Oid get_opfamily_member_for_cmptype(Oid opfamily, Oid lefttype, Oid righttype, CompareType cmptype)
Oid get_equality_op_for_ordering_op(Oid opno, bool *reverse)
Oid get_ordering_op_for_equality_op(Oid opno, bool use_lhs_type)
Datum lca(PG_FUNCTION_ARGS)
Datum subpath(PG_FUNCTION_ARGS)
Expr * make_orclause(List *orclauses)
Expr * make_ands_explicit(List *andclauses)
Var * makeVar(int varno, AttrNumber varattno, Oid vartype, int32 vartypmod, Oid varcollid, Index varlevelsup)
Node * makeBoolConst(bool value, bool isnull)
TargetEntry * makeTargetEntry(Expr *expr, AttrNumber resno, char *resname, bool resjunk)
void * palloc0(Size size)
Oid exprType(const Node *expr)
Oid exprCollation(const Node *expr)
#define expression_tree_mutator(n, m, c)
static bool is_opclause(const void *clause)
#define IsA(nodeptr, _type_)
#define IS_OUTER_JOIN(jointype)
#define castNode(_type_, nodeptr)
List * identify_current_nestloop_params(PlannerInfo *root, Relids leftrelids)
void process_subquery_nestloop_params(PlannerInfo *root, List *subplan_params)
Param * replace_nestloop_param_placeholdervar(PlannerInfo *root, PlaceHolderVar *phv)
int assign_special_exec_param(PlannerInfo *root)
Param * replace_nestloop_param_var(PlannerInfo *root, Var *var)
Index assignSortGroupRef(TargetEntry *tle, List *tlist)
TargetEntry * get_tle_by_resno(List *tlist, AttrNumber resno)
int make_partition_pruneinfo(PlannerInfo *root, RelOptInfo *parentrel, List *subpaths, List *prunequal)
bool pathkeys_contained_in(List *keys1, List *keys2)
Path * reparameterize_path_by_child(PlannerInfo *root, Path *path, RelOptInfo *child_rel)
#define IS_DUMMY_APPEND(p)
#define planner_rt_fetch(rti, root)
#define IS_OTHER_REL(rel)
int errdetail_relkind_not_supported(char relkind)
#define lfirst_node(type, lc)
static int list_length(const List *l)
#define forboth(cell1, list1, cell2, list2)
#define for_each_from(cell, lst, N)
static ListCell * list_head(const List *l)
static ListCell * lnext(const List *l, const ListCell *c)
static int list_nth_int(const List *list, int n)
PlaceHolderInfo * find_placeholder_info(PlannerInfo *root, PlaceHolderVar *phv)
bool has_stored_generated_columns(PlannerInfo *root, Index rti)
bool has_row_triggers(PlannerInfo *root, Index rti, CmdType event)
List * build_physical_tlist(PlannerInfo *root, RelOptInfo *rel)
List * infer_arbiter_indexes(PlannerInfo *root)
int restrict_nonsystem_relation_kind
bool predicate_implied_by(List *predicate_list, List *clause_list, bool weak)
List * extract_update_targetlist_colnos(List *tlist)
#define IS_SPECIAL_VARNO(varno)
static const struct fns functions
static struct subre * parse(struct vars *v, int stopper, int type, struct state *init, struct state *final)
List * extract_actual_clauses(List *restrictinfo_list, bool pseudoconstant)
void extract_actual_join_clauses(List *restrictinfo_list, Relids joinrelids, List **joinquals, List **otherquals)
List * get_actual_clauses(List *restrictinfo_list)
bool trivial_subqueryscan(SubqueryScan *plan)
void check_stack_depth(void)
Selectivity bitmapselectivity
Selectivity bitmapselectivity
struct Plan *(* PlanCustomPath)(PlannerInfo *root, RelOptInfo *rel, struct CustomPath *best_path, List *tlist, List *clauses, List *custom_plans)
const struct CustomPathMethods * methods
Bitmapset * custom_relids
BeginDirectModify_function BeginDirectModify
PlanForeignModify_function PlanForeignModify
PlanDirectModify_function PlanDirectModify
IterateDirectModify_function IterateDirectModify
EndDirectModify_function EndDirectModify
IsForeignPathAsyncCapable_function IsForeignPathAsyncCapable
Bitmapset * fs_base_relids
Cardinality inner_rows_total
struct RestrictInfo * rinfo
ScanDirection indexorderdir
ScanDirection indexscandir
Selectivity indexselectivity
ScanDirection indexorderdir
List * withCheckOptionLists
List * mergeJoinConditions
OnConflictExpr * onconflict
List * mergeJoinConditions
Bitmapset * fdwDirectModifyPlans
List * withCheckOptionLists
OnConflictAction onConflictAction
struct TableSampleClause * tablesample
struct PathTarget * reltarget
struct TableSampleClause * tablesample
SubqueryScanStatus scanstatus
void SS_attach_initplans(PlannerInfo *root, Plan *plan)
void SS_compute_initplan_cost(List *init_plans, Cost *initplan_cost_p, bool *unsafe_initplans_p)
void SS_make_initplan_from_plan(PlannerInfo *root, PlannerInfo *subroot, Plan *plan, Param *prm)
#define FirstLowInvalidHeapAttributeNumber
#define RESTRICT_RELKIND_FOREIGN_TABLE
Oid * extract_grouping_ops(List *groupClause)
TargetEntry * tlist_member(Expr *node, List *targetlist)
bool tlist_same_exprs(List *tlist1, List *tlist2)
void apply_tlist_labeling(List *dest_tlist, List *src_tlist)
void apply_pathtarget_labeling_to_tlist(List *tlist, PathTarget *target)
AttrNumber * extract_grouping_cols(List *groupClause, List *tlist)
TargetEntry * get_sortgroupclause_tle(SortGroupClause *sgClause, List *targetList)
TargetEntry * get_sortgroupref_tle(Index sortref, List *targetList)
Oid * extract_grouping_collations(List *groupClause, List *tlist)
#define FirstNormalObjectId
void pull_varattnos(Node *node, Index varno, Bitmapset **varattnos)
bool contain_vars_returning_old_or_new(Node *node)