PostgreSQL Source Code: src/backend/parser/analyze.c Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
26
57
58
59
61{
66
67
69
81 bool isTopLevel, List **targetlist);
83 Node *larg, List *nrtargetlist);
100#ifdef DEBUG_NODE_TESTS_ENABLED
101static bool test_raw_expression_coverage(Node *node, void *context);
102#endif
103
104
105
106
107
108
109
110
111
112
113
114
115
118 const Oid *paramTypes, int numParams,
120{
124
125 Assert(sourceText != NULL);
126
128
129 if (numParams > 0)
131
133
135
138
140 (*post_parse_analyze_hook) (pstate, query, jstate);
141
143
145
146 return query;
147}
148
149
150
151
152
153
154
155
158 Oid **paramTypes, int *numParams,
160{
164
165 Assert(sourceText != NULL);
166
168
170
172
174
175
177
180
182 (*post_parse_analyze_hook) (pstate, query, jstate);
183
185
187
188 return query;
189}
190
191
192
193
194
195
196
200 void *parserSetupArg,
202{
206
207 Assert(sourceText != NULL);
208
211 (*parserSetup) (pstate, parserSetupArg);
212
214
217
219 (*post_parse_analyze_hook) (pstate, query, jstate);
220
222
224
225 return query;
226}
227
228
229
230
231
232
236 bool locked_from_parent,
237 bool resolve_unknowns)
238{
241
245
247
249
250 return query;
251}
252
253
254
255
256
257
258
259
262{
264
265
267
269 result->stmt_len = parseTree->stmt_len;
270
271 return result;
272}
273
274
275
276
277
278
279
280
281
282
283
286{
288 {
290
291
295
296 if (stmt->intoClause)
297 {
299
300 ctas->query = parseTree;
301 ctas->into = stmt->intoClause;
304
305
306
307
308
309
310 stmt->intoClause = NULL;
311
312 parseTree = (Node *) ctas;
313 }
314 }
315
317}
318
319
320
321
322
325{
327
328#ifdef DEBUG_NODE_TESTS_ENABLED
329
330
331
332
333
334
335
336 if (Debug_raw_expression_coverage_test)
337 {
338 switch (nodeTag(parseTree))
339 {
340 case T_SelectStmt:
341 case T_InsertStmt:
342 case T_UpdateStmt:
343 case T_DeleteStmt:
344 case T_MergeStmt:
345 (void) test_raw_expression_coverage(parseTree, NULL);
346 break;
347 default:
348 break;
349 }
350 }
351#endif
352
353
354
355
356
357
358 switch (nodeTag(parseTree))
359 {
360
361
362
363 case T_InsertStmt:
365 break;
366
367 case T_DeleteStmt:
369 break;
370
371 case T_UpdateStmt:
373 break;
374
375 case T_MergeStmt:
377 break;
378
379 case T_SelectStmt:
380 {
382
387 else
389 }
390 break;
391
392 case T_ReturnStmt:
394 break;
395
396 case T_PLAssignStmt:
399 break;
400
401
402
403
404 case T_DeclareCursorStmt:
407 break;
408
409 case T_ExplainStmt:
412 break;
413
414 case T_CreateTableAsStmt:
417 break;
418
419 case T_CallStmt:
422 break;
423
424 default:
425
426
427
428
429
433 break;
434 }
435
436
438 result->canSetTag = true;
439
440 return result;
441}
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458bool
460{
461 bool result;
462
464 {
465
466
467
468 case T_InsertStmt:
469 case T_DeleteStmt:
470 case T_UpdateStmt:
471 case T_MergeStmt:
472 case T_SelectStmt:
473 case T_ReturnStmt:
474 case T_PLAssignStmt:
475 result = true;
476 break;
477
478
479
480
481 case T_DeclareCursorStmt:
482 case T_ExplainStmt:
483 case T_CreateTableAsStmt:
484 case T_CallStmt:
485 result = true;
486 break;
487
488 default:
489
490 result = false;
491 break;
492 }
493
494 return result;
495}
496
497
498
499
500
501
502bool
504{
505
506
507
508
509
510
511
512
513
514
515
516
517
519}
520
521
522
523
524
525
526
527
528
529
530
531bool
533{
534 bool result;
535
537 {
538
539 result = true;
540 }
541 else
542 {
543
545 {
546 case T_DeclareCursorStmt:
547 case T_ExplainStmt:
548 case T_CreateTableAsStmt:
549 case T_CallStmt:
550 result = true;
551 break;
552 default:
553 result = false;
554 break;
555 }
556 }
557 return result;
558}
559
560
561
562
563
566{
570
572
573
574 if (stmt->withClause)
575 {
576 qry->hasRecursive = stmt->withClause->recursive;
579 }
580
581
583 stmt->relation->inh,
584 true,
587
588
590
591
594
595
596
597
598
599
600
602
603
606
609
612
613
617
621 qry->hasAggs = pstate->p_hasAggs;
622
624
625
628
629 return qry;
630}
631
632
633
634
635
638{
642 bool isGeneralSelect;
643 List *sub_rtable;
644 List *sub_rteperminfos;
645 List *sub_namespace;
646 List *icolumns;
647 List *attrnos;
653 bool isOnConflictUpdate;
655
656
658
661
662
663 if (stmt->withClause)
664 {
665 qry->hasRecursive = stmt->withClause->recursive;
668 }
669
670 qry->override = stmt->override;
671
672 isOnConflictUpdate = (stmt->onConflictClause &&
674
675
676
677
678
679
680
681
682
683
684 isGeneralSelect = (selectStmt && (selectStmt->valuesLists == NIL ||
690
691
692
693
694
695
696
697
698
699
700 if (isGeneralSelect)
701 {
702 sub_rtable = pstate->p_rtable;
708 }
709 else
710 {
711 sub_rtable = NIL;
712 sub_rteperminfos = NIL;
713 sub_namespace = NIL;
714 }
715
716
717
718
719
720
721
723 if (isOnConflictUpdate)
726 false, false, targetPerms);
727
728
731
732
733
734
735 if (selectStmt == NULL)
736 {
737
738
739
740
741
742 exprList = NIL;
743 }
744 else if (isGeneralSelect)
745 {
746
747
748
749
750
751
752
754 Query *selectQuery;
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770 sub_pstate->p_rtable = sub_rtable;
772 sub_pstate->p_joinexprs = NIL;
776
778
780
781
782 if ((selectQuery, Query) ||
784 elog(ERROR, "unexpected non-SELECT command in INSERT ... SELECT");
785
786
787
788
789
791 selectQuery,
792 NULL,
793 false,
794 false);
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811 exprList = NIL;
813 {
816
817 if (tle->resjunk)
818 continue;
819 if (tle->expr &&
822 expr = tle->expr;
823 else
824 {
826
828 expr = (Expr *) var;
829 }
830 exprList = lappend(exprList, expr);
831 }
832
833
836 icolumns, attrnos,
837 false);
838 }
839 else if (list_length(selectStmt->valuesLists) > 1)
840 {
841
842
843
844
845
846
850 List *colcollations = NIL;
851 int sublist_length = -1;
852 bool lateral = false;
853
854 Assert(selectStmt->intoClause == NULL);
855
856 foreach(lc, selectStmt->valuesLists)
857 {
859
860
861
862
863
866
867
868
869
870
871
872 if (sublist_length < 0)
873 {
874
876 }
877 else if (sublist_length != list_length(sublist))
878 {
880 (errcode(ERRCODE_SYNTAX_ERROR),
881 errmsg("VALUES lists must all be the same length"),
884 }
885
886
887
888
889
890
891
892
893
894
895
898 icolumns, attrnos,
899 true);
900
901
902
903
904
905
906
907
908
909
910
911
912
914
915 exprsLists = lappend(exprsLists, sublist);
916 }
917
918
919
920
921
922
923
924
926 {
928
932 }
933
934
935
936
937
938
939
940 if (list_length(pstate->p_rtable) != 1 &&
942 lateral = true;
943
944
945
946
948 coltypes, coltypmods, colcollations,
949 NULL, lateral, true);
951
952
953
954
956
957
958
959
962 icolumns, attrnos,
963 false);
964 }
965 else
966 {
967
968
969
970
971
972
973 List *valuesLists = selectStmt->valuesLists;
974
976 Assert(selectStmt->intoClause == NULL);
977
978
979
980
981
985 true);
986
987
990 icolumns, attrnos,
991 false);
992 }
993
994
995
996
997
998 perminfo = pstate->p_target_nsitem->p_perminfo;
999 qry->targetList = NIL;
1001 forthree(lc, exprList, icols, icolumns, attnos, attrnos)
1002 {
1007
1009 attr_num,
1011 false);
1012 qry->targetList = lappend(qry->targetList, tle);
1013
1014 perminfo->insertedCols = bms_add_member(perminfo->insertedCols,
1016 }
1017
1018
1019
1020
1021
1022
1023 if (stmt->onConflictClause || stmt->returningClause)
1024 {
1025 pstate->p_namespace = NIL;
1027 false, true, true);
1028 }
1029
1030
1031 if (stmt->onConflictClause)
1033 stmt->onConflictClause);
1034
1035
1036 if (stmt->returningClause)
1039
1040
1041 qry->rtable = pstate->p_rtable;
1042 qry->rteperminfos = pstate->p_rteperminfos;
1043 qry->jointree = makeFromExpr(pstate->p_joinlist, NULL);
1044
1045 qry->hasTargetSRFs = pstate->p_hasTargetSRFs;
1046 qry->hasSubLinks = pstate->p_hasSubLinks;
1047
1049
1050 return qry;
1051}
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1065 List *stmtcols, List *icolumns, List *attrnos,
1066 bool strip_indirection)
1067{
1068 List *result;
1072
1073
1074
1075
1076
1077
1078
1079
1082 (errcode(ERRCODE_SYNTAX_ERROR),
1083 errmsg("INSERT has more expressions than target columns"),
1087 if (stmtcols != NIL &&
1089 {
1090
1091
1092
1093
1094
1095
1096
1097
1098
1100 (errcode(ERRCODE_SYNTAX_ERROR),
1101 errmsg("INSERT has more target columns than expressions"),
1105 errhint("The insertion source is a row expression containing the same number of columns expected by the INSERT. Did you accidentally use extra parentheses?") : 0),
1109 }
1110
1111
1112
1113
1114 result = NIL;
1115 forthree(lc, exprlist, icols, icolumns, attnos, attrnos)
1116 {
1120
1124 attno,
1127
1128 if (strip_indirection)
1129 {
1130
1131
1132
1133
1134
1135 while (expr)
1136 {
1137 Expr *subexpr = expr;
1138
1140 {
1142 }
1144 {
1146
1148 }
1150 {
1152
1154 break;
1155
1157 }
1158 else
1159 break;
1160 }
1161 }
1162
1163 result = lappend(result, expr);
1164 }
1165
1166 return result;
1167}
1168
1169
1170
1171
1172
1176{
1178 List *arbiterElems;
1179 Node *arbiterWhere;
1180 Oid arbiterConstraint;
1181 List *onConflictSet = NIL;
1182 Node *onConflictWhere = NULL;
1183 int exclRelIndex = 0;
1184 List *exclRelTlist = NIL;
1186
1187
1188
1189
1190
1191
1192
1194 {
1197
1199 targetrel,
1202 false, false);
1203 exclRte = exclNSItem->p_rte;
1204 exclRelIndex = exclNSItem->p_rtindex;
1205
1206
1207
1208
1209
1210
1211 exclRte->relkind = RELKIND_COMPOSITE_TYPE;
1212
1213
1215 exclRelIndex);
1216 }
1217
1218
1220 &arbiterWhere, &arbiterConstraint);
1221
1222
1224 {
1225
1226
1227
1228
1229
1231
1232
1233
1234
1235
1237
1238
1239
1240
1241 onConflictSet =
1243
1247
1248
1249
1250
1251
1252
1255 }
1256
1257
1259
1263 result->constraint = arbiterConstraint;
1268
1269 return result;
1270}
1271
1272
1273
1274
1275
1276
1277
1278
1279
1282 Index exclRelIndex)
1283{
1285 int attno;
1286 Var *var;
1288
1289
1290
1291
1292
1294 {
1297
1298 if (attr->attisdropped)
1299 {
1300
1301
1302
1303
1305 name = NULL;
1306 }
1307 else
1308 {
1309 var = makeVar(exclRelIndex, attno + 1,
1310 attr->atttypid, attr->atttypmod,
1311 attr->attcollation,
1312 0);
1314 }
1315
1317 attno + 1,
1319 false);
1320
1321 result = lappend(result, te);
1322 }
1323
1324
1325
1326
1327
1328
1329
1330
1332 targetrel->rd_rel->reltype,
1335 result = lappend(result, te);
1336
1337 return result;
1338}
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350static int
1352{
1353 if (expr == NULL)
1354 return -1;
1358 {
1361
1362 if (attnum > 0 && var->vartype == RECORDOID)
1363 {
1365
1368 {
1369
1372
1373 if (ste == NULL || ste->resjunk)
1374 return -1;
1378 }
1379 }
1380 }
1381 return -1;
1382}
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1402{
1406
1408
1409
1410 if (stmt->withClause)
1411 {
1412 qry->hasRecursive = stmt->withClause->recursive;
1415 }
1416
1417
1418 if (stmt->intoClause)
1420 (errcode(ERRCODE_SYNTAX_ERROR),
1421 errmsg("SELECT ... INTO is not allowed here"),
1424
1425
1427
1428
1430
1431
1433
1434
1437
1438
1439
1440
1441
1442
1443 if (passthru)
1445 passthru);
1446 else
1448
1449
1452
1453
1456
1457
1458
1459
1460
1461
1462
1464 stmt->sortClause,
1467 false );
1468
1470 stmt->groupClause,
1471 stmt->groupByAll,
1476 false );
1479
1480 if (stmt->distinctClause == NIL)
1481 {
1483 qry->hasDistinctOn = false;
1484 }
1485 else if (linitial(stmt->distinctClause) == NULL)
1486 {
1487
1491 false);
1492 qry->hasDistinctOn = false;
1493 }
1494 else
1495 {
1496
1498 stmt->distinctClause,
1501 qry->hasDistinctOn = true;
1502 }
1503
1504
1507 stmt->limitOption);
1510 stmt->limitOption);
1512
1513
1517
1518
1521
1525
1529 qry->hasAggs = pstate->p_hasAggs;
1530
1531 foreach(l, stmt->lockingClause)
1532 {
1535 }
1536
1538
1539
1542
1543 return qry;
1544}
1545
1546
1547
1548
1549
1550
1551
1552
1555{
1560 List *colcollations = NIL;
1561 List **colexprs = NULL;
1562 int sublist_length = -1;
1563 bool lateral = false;
1567 int i;
1568
1570
1571
1581
1582
1583 if (stmt->withClause)
1584 {
1585 qry->hasRecursive = stmt->withClause->recursive;
1588 }
1589
1590
1591
1592
1593
1594
1595
1596
1597 foreach(lc, stmt->valuesLists)
1598 {
1600
1601
1602
1603
1604
1607
1608
1609
1610
1611
1612
1613 if (sublist_length < 0)
1614 {
1615
1617
1618 colexprs = (List **) palloc0(sublist_length * sizeof(List *));
1619 }
1620 else if (sublist_length != list_length(sublist))
1621 {
1623 (errcode(ERRCODE_SYNTAX_ERROR),
1624 errmsg("VALUES lists must all be the same length"),
1627 }
1628
1629
1630 i = 0;
1631 foreach(lc2, sublist)
1632 {
1634
1635 colexprs[i] = lappend(colexprs[i], col);
1636 i++;
1637 }
1638
1639
1641
1642
1643 exprsLists = lappend(exprsLists, NIL);
1644 }
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660 for (i = 0; i < sublist_length; i++)
1661 {
1662 Oid coltype;
1663 int32 coltypmod;
1664 Oid colcoll;
1665
1667
1668 foreach(lc, colexprs[i])
1669 {
1671
1674 }
1675
1678
1679 coltypes = lappend_oid(coltypes, coltype);
1680 coltypmods = lappend_int(coltypmods, coltypmod);
1681 colcollations = lappend_oid(colcollations, colcoll);
1682 }
1683
1684
1685
1686
1687 for (i = 0; i < sublist_length; i++)
1688 {
1689 forboth(lc, colexprs[i], lc2, exprsLists)
1690 {
1693
1694 sublist = lappend(sublist, col);
1695 lfirst(lc2) = sublist;
1696 }
1698 }
1699
1700
1701
1702
1703
1704
1705
1708 lateral = true;
1709
1710
1711
1712
1714 coltypes, coltypmods, colcollations,
1715 NULL, lateral, true);
1717
1718
1719
1720
1723
1724
1725
1726
1727
1729 stmt->sortClause,
1732 false );
1733
1736 stmt->limitOption);
1739 stmt->limitOption);
1741
1742 if (stmt->lockingClause)
1744 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1745
1746
1747 errmsg("%s cannot be applied to VALUES",
1749 linitial(stmt->lockingClause))->strength))));
1750
1754
1756
1758
1759 return qry;
1760}
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1774{
1777 int leftmostRTI;
1778 Query *leftmostQuery;
1780 List *sortClause;
1781 Node *limitOffset;
1782 Node *limitCount;
1783 List *lockingClause;
1787 *lct,
1788 *lcm,
1789 *lcc,
1790 *l;
1791 List *targetvars,
1792 *targetnames,
1793 *sv_namespace;
1794 int sv_rtable_length;
1797 int sortcolindex;
1798 int tllen;
1799
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810 leftmostSelect = stmt->larg;
1811 while (leftmostSelect && leftmostSelect->op != SETOP_NONE)
1812 leftmostSelect = leftmostSelect->larg;
1814 leftmostSelect->larg == NULL);
1817 (errcode(ERRCODE_SYNTAX_ERROR),
1818 errmsg("SELECT ... INTO is not allowed here"),
1821
1822
1823
1824
1825
1826
1827 sortClause = stmt->sortClause;
1828 limitOffset = stmt->limitOffset;
1829 limitCount = stmt->limitCount;
1830 lockingClause = stmt->lockingClause;
1831 withClause = stmt->withClause;
1832
1834 stmt->limitOffset = NULL;
1835 stmt->limitCount = NULL;
1836 stmt->lockingClause = NIL;
1837 stmt->withClause = NULL;
1838
1839
1840 if (lockingClause)
1842 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1843
1844
1845 errmsg("%s is not allowed with UNION/INTERSECT/EXCEPT",
1847 linitial(lockingClause))->strength))));
1848
1849
1850 if (withClause)
1851 {
1852 qry->hasRecursive = withClause->recursive;
1855 }
1856
1857
1858
1859
1864
1865
1866
1867
1868 node = sostmt->larg;
1872 leftmostRTI = ((RangeTblRef *) node)->rtindex;
1873 leftmostQuery = rt_fetch(leftmostRTI, pstate->p_rtable)->subquery;
1874 Assert(leftmostQuery != NULL);
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1888 targetvars = NIL;
1889 targetnames = NIL;
1892 sortcolindex = 0;
1893
1894 forfour(lct, sostmt->colTypes,
1895 lcm, sostmt->colTypmods,
1896 lcc, sostmt->colCollations,
1897 left_tlist, leftmostQuery->targetList)
1898 {
1903 char *colName;
1905 Var *var;
1906
1907 Assert(!lefttle->resjunk);
1908 colName = pstrdup(lefttle->resname);
1909 var = makeVar(leftmostRTI,
1911 colType,
1912 colTypmod,
1913 colCollation,
1914 0);
1918 colName,
1919 false);
1921 targetvars = lappend(targetvars, var);
1923 sortnscolumns[sortcolindex].p_varno = leftmostRTI;
1924 sortnscolumns[sortcolindex].p_varattno = lefttle->resno;
1925 sortnscolumns[sortcolindex].p_vartype = colType;
1926 sortnscolumns[sortcolindex].p_vartypmod = colTypmod;
1927 sortnscolumns[sortcolindex].p_varcollid = colCollation;
1928 sortnscolumns[sortcolindex].p_varnosyn = leftmostRTI;
1930 sortcolindex++;
1931 }
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1944
1946 targetnames,
1947 sortnscolumns,
1949 0,
1950 targetvars,
1953 NULL,
1954 NULL,
1955 false);
1956
1959
1960
1962
1963
1964
1965
1966
1967
1968
1969
1971
1973 sortClause,
1976 false );
1977
1978
1981
1984 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1985 errmsg("invalid UNION/INTERSECT/EXCEPT ORDER BY clause"),
1986 errdetail("Only result column names can be used, not expressions or functions."),
1987 errhint("Add the expression/function to every SELECT, or move the UNION into a FROM clause."),
1990
1993 stmt->limitOption);
1996 stmt->limitOption);
1998
2002
2006 qry->hasAggs = pstate->p_hasAggs;
2007
2008 foreach(l, lockingClause)
2009 {
2012 }
2013
2015
2016
2019
2020 return qry;
2021}
2022
2023
2024
2025
2026
2027
2028
2031{
2033 Oid sortop;
2034 Oid eqop;
2035 bool hashable;
2036
2037
2039 false, true, false,
2040 &sortop, &eqop, NULL,
2041 &hashable);
2042
2043
2044
2045
2046
2047
2048
2049 if (require_hash && (rescoltype == RECORDOID || rescoltype == RECORDARRAYOID))
2050 hashable = true;
2051
2052
2054 grpcl->eqop = eqop;
2055 grpcl->sortop = sortop;
2056 grpcl->reverse_sort = false;
2057 grpcl->nulls_first = false;
2058 grpcl->hashable = hashable;
2059
2060 return grpcl;
2061}
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077static Node *
2079 bool isTopLevel, List **targetlist)
2080{
2081 bool isLeaf;
2082
2084
2085
2087
2088
2089
2090
2091 if (stmt->intoClause)
2093 (errcode(ERRCODE_SYNTAX_ERROR),
2094 errmsg("INTO is only allowed on first SELECT of UNION/INTERSECT/EXCEPT"),
2097
2098
2099 if (stmt->lockingClause)
2101 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2102
2103
2104 errmsg("%s is not allowed with UNION/INTERSECT/EXCEPT",
2106 linitial(stmt->lockingClause))->strength))));
2107
2108
2109
2110
2111
2112
2113
2115 {
2117 isLeaf = true;
2118 }
2119 else
2120 {
2122 if (stmt->sortClause || stmt->limitOffset || stmt->limitCount ||
2123 stmt->lockingClause || stmt->withClause)
2124 isLeaf = true;
2125 else
2126 isLeaf = false;
2127 }
2128
2129 if (isLeaf)
2130 {
2131
2132 Query *selectQuery;
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2152 NULL, false, false);
2153
2154
2155
2156
2157
2158
2159
2161 {
2164 (errcode(ERRCODE_INVALID_COLUMN_REFERENCE),
2165 errmsg("UNION/INTERSECT/EXCEPT member statement cannot refer to other relations of same query level"),
2168 }
2169
2170
2171
2172
2173 if (targetlist)
2174 {
2175 *targetlist = NIL;
2176 foreach(tl, selectQuery->targetList)
2177 {
2179
2180 if (!tle->resjunk)
2181 *targetlist = lappend(*targetlist, tle);
2182 }
2183 }
2184
2185
2186
2187
2189 selectQuery,
2190 NULL,
2191 false,
2192 false);
2193
2194
2195
2196
2199 return (Node *) rtr;
2200 }
2201 else
2202 {
2203
2205 List *ltargetlist;
2206 List *rtargetlist;
2209 const char *context;
2212
2215 "EXCEPT"));
2216
2219
2220
2221
2222
2224 false,
2225 <argetlist);
2226
2227
2228
2229
2230
2231
2232
2233 if (isTopLevel && recursive)
2235
2236
2237
2238
2240 false,
2241 &rtargetlist);
2242
2243
2244
2245
2246
2249 (errcode(ERRCODE_SYNTAX_ERROR),
2250 errmsg("each %s query must have the same number of columns",
2251 context),
2254
2255 if (targetlist)
2256 *targetlist = NIL;
2257 op->colTypes = NIL;
2258 op->colTypmods = NIL;
2259 op->colCollations = NIL;
2260 op->groupClauses = NIL;
2261 forboth(ltl, ltargetlist, rtl, rtargetlist)
2262 {
2269 Node *bestexpr;
2270 int bestlocation;
2271 Oid rescoltype;
2272 int32 rescoltypmod;
2273 Oid rescolcoll;
2274
2275
2278 context,
2279 &bestexpr);
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309 if (lcoltype != UNKNOWNOID)
2311 rescoltype, context);
2312 else if (IsA(lcolnode, Const) ||
2314 {
2316 rescoltype, context);
2317 ltle->expr = (Expr *) lcolnode;
2318 }
2319
2320 if (rcoltype != UNKNOWNOID)
2322 rescoltype, context);
2323 else if (IsA(rcolnode, Const) ||
2325 {
2327 rescoltype, context);
2328 rtle->expr = (Expr *) rcolnode;
2329 }
2330
2333 rescoltype);
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2347
2348
2349 op->colTypes = lappend_oid(op->colTypes, rescoltype);
2350 op->colTypmods = lappend_int(op->colTypmods, rescoltypmod);
2351 op->colCollations = lappend_oid(op->colCollations, rescolcoll);
2352
2353
2354
2355
2356
2357
2359 {
2361
2363 bestlocation);
2364
2365
2366
2367
2368
2369 op->groupClauses = lappend(op->groupClauses,
2371
2373 }
2374
2375
2376
2377
2378
2379
2380 if (targetlist)
2381 {
2384
2385 rescolnode->typeId = rescoltype;
2386 rescolnode->typeMod = rescoltypmod;
2387 rescolnode->collation = rescolcoll;
2388 rescolnode->location = bestlocation;
2390 0,
2391 NULL,
2392 false);
2393 *targetlist = lappend(*targetlist, restle);
2394 }
2395 }
2396
2397 return (Node *) op;
2398 }
2399}
2400
2401
2402
2403
2404
2405static void
2407{
2409 int leftmostRTI;
2410 Query *leftmostQuery;
2411 List *targetList;
2414 int next_resno;
2415
2416
2417
2418
2419 node = larg;
2423 leftmostRTI = ((RangeTblRef *) node)->rtindex;
2424 leftmostQuery = rt_fetch(leftmostRTI, pstate->p_rtable)->subquery;
2425 Assert(leftmostQuery != NULL);
2426
2427
2428
2429
2430
2431 targetList = NIL;
2432 next_resno = 1;
2433
2434 forboth(nrtl, nrtargetlist, left_tlist, leftmostQuery->targetList)
2435 {
2438 char *colName;
2440
2441 Assert(!lefttle->resjunk);
2442 colName = pstrdup(lefttle->resname);
2444 next_resno++,
2445 colName,
2446 false);
2447 targetList = lappend(targetList, tle);
2448 }
2449
2450
2452}
2453
2454
2455
2456
2457
2458
2461{
2463
2465 qry->isReturn = true;
2466
2468 1, NULL, false));
2469
2478 qry->hasAggs = pstate->p_hasAggs;
2479
2481
2482 return qry;
2483}
2484
2485
2486
2487
2488
2489
2492{
2496
2499
2500
2501 if (stmt->withClause)
2502 {
2503 qry->hasRecursive = stmt->withClause->recursive;
2506 }
2507
2509 stmt->relation->inh,
2510 true,
2513
2514
2517
2518
2519
2520
2521
2523
2524
2527
2530
2533
2534
2535
2536
2537
2539
2543
2546
2548
2549 return qry;
2550}
2551
2552
2553
2554
2555
2558{
2563
2566
2567
2570
2571
2574
2575 foreach(tl, tlist)
2576 {
2579 int attrno;
2580
2581 if (tle->resjunk)
2582 {
2583
2584
2585
2586
2587
2588
2590 tle->resname = NULL;
2591 continue;
2592 }
2593 if (orig_tl == NULL)
2594 elog(ERROR, "UPDATE target count mismatch --- internal error");
2596
2598 origTarget->name, true);
2601 (errcode(ERRCODE_UNDEFINED_COLUMN),
2602 errmsg("column \"%s\" of relation \"%s\" does not exist",
2603 origTarget->name,
2607 errhint("SET target columns cannot be qualified with the relation name.") : 0,
2609
2611 attrno,
2614
2615
2618
2619 orig_tl = lnext(origTlist, orig_tl);
2620 }
2621 if (orig_tl != NULL)
2622 elog(ERROR, "UPDATE target count mismatch --- internal error");
2623
2624 return tlist;
2625}
2626
2627
2628
2629
2630
2631static void
2634{
2635 List *colnames;
2636 int numattrs;
2639
2640
2643
2645
2648
2649
2650 for (int i = 0; i < numattrs; i++)
2651 nscolumns[i].p_varreturningtype = returning_type;
2652
2653
2661
2662
2664}
2665
2666
2667
2668
2669
2670void
2674{
2676 int save_next_resno;
2677
2678 if (returningClause == NULL)
2679 return;
2680
2681
2682
2683
2684
2686 {
2687 switch (option->option)
2688 {
2690 if (qry->returningOldAlias != NULL)
2692 errcode(ERRCODE_SYNTAX_ERROR),
2693
2694 errmsg("%s cannot be specified multiple times", "OLD"),
2696 qry->returningOldAlias = option->value;
2697 break;
2698
2700 if (qry->returningNewAlias != NULL)
2702 errcode(ERRCODE_SYNTAX_ERROR),
2703
2704 errmsg("%s cannot be specified multiple times", "NEW"),
2706 qry->returningNewAlias = option->value;
2707 break;
2708
2709 default:
2710 elog(ERROR, "unrecognized returning option: %d", option->option);
2711 }
2712
2715 errcode(ERRCODE_DUPLICATE_ALIAS),
2716 errmsg("table name \"%s\" specified more than once",
2719
2723 }
2724
2725
2726
2727
2728
2729 if (qry->returningOldAlias == NULL &&
2731 {
2732 qry->returningOldAlias = "old";
2734 }
2735 if (qry->returningNewAlias == NULL &&
2737 {
2738 qry->returningNewAlias = "new";
2740 }
2741
2742
2743
2744
2745
2746
2749
2750
2752 returningClause->exprs,
2753 exprKind);
2754
2755
2756
2757
2758
2759
2760
2763 (errcode(ERRCODE_SYNTAX_ERROR),
2764 errmsg("RETURNING must have at least one column"),
2767
2768
2770
2771
2774
2775
2778}
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2794{
2797 List *indirection = stmt->indirection;
2798 int nnames = stmt->nnames;
2799 Node *target;
2801 bool save_resolve_unknowns;
2802
2803
2804
2805
2806
2807
2810 if (nnames > 1)
2811 {
2812
2813 indirection = list_copy(indirection);
2814 while (--nnames > 0 && indirection != NIL)
2815 {
2817
2819 elog(ERROR, "invalid name count in PLAssignStmt");
2822 }
2823 }
2824
2825
2826
2827
2828
2829
2830
2831
2832
2835
2836
2838 passthru.target = target;
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2856
2857 return qry;
2858}
2859
2860
2861
2862
2863
2864
2865
2866
2867static List *
2870{
2874 Oid targettype;
2875 int32 targettypmod;
2876 Oid targetcollation;
2878 Oid type_id;
2879
2880 targettype = exprType(target);
2883
2884
2887 (errcode(ERRCODE_SYNTAX_ERROR),
2888 errmsg_plural("assignment source returned %d column",
2889 "assignment source returned %d columns",
2892
2894
2895
2896
2897
2898
2900
2902
2903 if (indirection)
2904 {
2907 target,
2909 false,
2910 targettype,
2911 targettypmod,
2912 targetcollation,
2913 indirection,
2918 }
2919 else if (targettype != type_id &&
2920 (targettype == RECORDOID || ISCOMPLEX(targettype)) &&
2921 (type_id == RECORDOID || ISCOMPLEX(type_id)))
2922 {
2923
2924
2925
2926
2927
2928
2929 }
2930 else
2931 {
2932
2933
2934
2935
2937
2940 orig_expr, type_id,
2941 targettype, targettypmod,
2944 -1);
2945
2946 if (tle->expr == NULL)
2948 (errcode(ERRCODE_DATATYPE_MISMATCH),
2949 errmsg("variable \"%s\" is of type %s"
2950 " but expression is of type %s",
2954 errhint("You will need to rewrite or cast the expression."),
2956 }
2957
2959
2961}
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2976{
2979
2983 (errcode(ERRCODE_INVALID_CURSOR_DEFINITION),
2984
2985 errmsg("cannot specify both %s and %s",
2986 "SCROLL", "NO SCROLL")));
2987
2991 (errcode(ERRCODE_INVALID_CURSOR_DEFINITION),
2992
2993 errmsg("cannot specify both %s and %s",
2994 "ASENSITIVE", "INSENSITIVE")));
2995
2996
2998 stmt->query = (Node *) query;
2999
3000
3003 elog(ERROR, "unexpected non-SELECT command in DECLARE CURSOR");
3004
3005
3006
3007
3008
3009
3010 if (query->hasModifyingCTE)
3012 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3013 errmsg("DECLARE CURSOR must not contain data-modifying statements in WITH")));
3014
3015
3018 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3019
3020
3021 errmsg("DECLARE CURSOR WITH HOLD ... %s is not supported",
3024 errdetail("Holdable cursors must be READ ONLY.")));
3025
3026
3029 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3030
3031
3032 errmsg("DECLARE SCROLL CURSOR ... %s is not supported",
3035 errdetail("Scrollable cursors must be READ ONLY.")));
3036
3037
3040 (errcode(ERRCODE_INVALID_CURSOR_DEFINITION),
3041
3042
3043 errmsg("DECLARE INSENSITIVE CURSOR ... %s is not valid",
3046 errdetail("Insensitive cursors must be READ ONLY.")));
3047
3048
3052
3053 return result;
3054}
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3069{
3071 bool generic_plan = false;
3072 Oid *paramTypes = NULL;
3073 int numParams = 0;
3074
3075
3076
3077
3078
3079
3081 {
3083
3084 foreach(lc, stmt->options)
3085 {
3087
3088 if (strcmp(opt->defname, "generic_plan") == 0)
3090
3091 }
3092 if (generic_plan)
3094 }
3095
3096
3098
3099
3100 if (generic_plan)
3102
3103
3107
3108 return result;
3109}
3110
3111
3112
3113
3114
3115
3116
3117
3118
3121{
3124
3125
3127 stmt->query = (Node *) query;
3128
3129
3131 {
3133
3134
3135
3136
3137
3138
3139 if (query->hasModifyingCTE)
3141 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3142 errmsg("materialized views must not use data-modifying statements in WITH")));
3143
3144
3145
3146
3147
3148
3151 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3152 errmsg("materialized views must not use temporary objects"),
3153 errdetail("This view depends on temporary %s.",
3155
3156
3157
3158
3159
3160
3163 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3164 errmsg("materialized views may not be defined using bound parameters")));
3165
3166
3167
3168
3169
3170
3171
3172
3173 if (stmt->into->rel->relpersistence == RELPERSISTENCE_UNLOGGED)
3175 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3176 errmsg("materialized views cannot be unlogged")));
3177
3178
3179
3180
3181
3182
3183
3185 }
3186
3187
3191
3192 return result;
3193}
3194
3195
3196
3197
3200{
3201 List *targs;
3206 Datum proargmodes;
3207 bool isNull;
3210
3211
3212
3213
3214
3215 targs = NIL;
3216 foreach(lc, stmt->funccall->args)
3217 {
3221 }
3222
3224 stmt->funccall->funcname,
3225 targs,
3227 stmt->funccall,
3228 true,
3229 stmt->funccall->location);
3230
3232
3234
3237 elog(ERROR, "cache lookup failed for function %u", fexpr->funcid);
3238
3239
3240
3241
3242
3243
3244
3246 true,
3247 fexpr->funcresulttype,
3248 proctup);
3249
3250
3252 Anum_pg_proc_proargmodes,
3253 &isNull);
3254 if (!isNull)
3255 {
3256
3257
3258
3259
3261 int numargs;
3262 char *argmodes;
3263 List *inargs;
3264 int i;
3265
3269 ARR_DIMS(arr)[0] != numargs ||
3272 elog(ERROR, "proargmodes is not a 1-D char array of length %d or it contains nulls",
3273 numargs);
3275
3276 inargs = NIL;
3277 i = 0;
3278 foreach(lc, fexpr->args)
3279 {
3281
3282 switch (argmodes[i])
3283 {
3284 case PROARGMODE_IN:
3285 case PROARGMODE_VARIADIC:
3286 inargs = lappend(inargs, n);
3287 break;
3288 case PROARGMODE_OUT:
3289 outargs = lappend(outargs, n);
3290 break;
3291 case PROARGMODE_INOUT:
3292 inargs = lappend(inargs, n);
3294 break;
3295 default:
3296
3297 elog(ERROR, "invalid argmode %c for procedure",
3298 argmodes[i]);
3299 break;
3300 }
3301 i++;
3302 }
3303 fexpr->args = inargs;
3304 }
3305
3306 stmt->funcexpr = fexpr;
3307 stmt->outargs = outargs;
3308
3310
3311
3315
3316 return result;
3317}
3318
3319
3320
3321
3322
3323const char *
3325{
3326 switch (strength)
3327 {
3330 break;
3332 return "FOR KEY SHARE";
3334 return "FOR SHARE";
3336 return "FOR NO KEY UPDATE";
3338 return "FOR UPDATE";
3339 }
3340 return "FOR some";
3341}
3342
3343
3344
3345
3346
3347
3348void
3350{
3351 Assert(strength != LCS_NONE);
3352
3355 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3356
3357
3358 errmsg("%s is not allowed with UNION/INTERSECT/EXCEPT",
3362 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3363
3364
3365 errmsg("%s is not allowed with DISTINCT clause",
3369 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3370
3371
3372 errmsg("%s is not allowed with GROUP BY clause",
3376 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3377
3378
3379 errmsg("%s is not allowed with HAVING clause",
3381 if (qry->hasAggs)
3383 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3384
3385
3386 errmsg("%s is not allowed with aggregate functions",
3388 if (qry->hasWindowFuncs)
3390 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3391
3392
3393 errmsg("%s is not allowed with window functions",
3395 if (qry->hasTargetSRFs)
3397 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3398
3399
3400 errmsg("%s is not allowed with set-returning functions in the target list",
3402}
3403
3404
3405
3406
3407
3408
3409
3410
3411
3412static void
3414 bool pushedDown)
3415{
3421
3423
3424
3426 allrels->lockedRels = NIL;
3429
3430 if (lockedRels == NIL)
3431 {
3432
3433
3434
3435
3436
3437
3438
3439
3440 i = 0;
3441 foreach(rt, qry->rtable)
3442 {
3444
3445 ++i;
3446 if (!rte->inFromCl)
3447 continue;
3449 {
3451 {
3453
3457 pushedDown);
3460 }
3461 break;
3464 pushedDown);
3465
3466
3467
3468
3469
3470
3471
3472
3474 allrels, true);
3475 break;
3476 default:
3477
3478 break;
3479 }
3480 }
3481 }
3482 else
3483 {
3484
3485
3486
3487
3488
3489 foreach(l, lockedRels)
3490 {
3492
3493
3496 (errcode(ERRCODE_SYNTAX_ERROR),
3497
3498
3499 errmsg("%s must specify unqualified relation names",
3502
3503 i = 0;
3504 foreach(rt, qry->rtable)
3505 {
3507 char *rtename = rte->eref->aliasname;
3508
3509 ++i;
3510 if (!rte->inFromCl)
3511 continue;
3512
3513
3514
3515
3516
3517
3518
3519
3520
3521
3522 if (rte->alias == NULL)
3523 {
3525 {
3526 if (rte->join_using_alias == NULL)
3527 continue;
3528 rtename = rte->join_using_alias->aliasname;
3529 }
3532 continue;
3533 }
3534
3535 if (strcmp(rtename, thisrel->relname) == 0)
3536 {
3538 {
3540 {
3542
3546 pushedDown);
3549 }
3550 break;
3554
3556 allrels, true);
3557 break;
3560 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3561
3562
3563 errmsg("%s cannot be applied to a join",
3566 break;
3569 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3570
3571
3572 errmsg("%s cannot be applied to a function",
3575 break;
3578 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3579
3580
3581 errmsg("%s cannot be applied to a table function",
3584 break;
3587 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3588
3589
3590 errmsg("%s cannot be applied to VALUES",
3593 break;
3596 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3597
3598
3599 errmsg("%s cannot be applied to a WITH query",
3602 break;
3605 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3606
3607
3608 errmsg("%s cannot be applied to a named tuplestore",
3611 break;
3612
3613
3614
3615 default:
3616 elog(ERROR, "unrecognized RTE type: %d",
3618 break;
3619 }
3620 break;
3621 }
3622 }
3623 if (rt == NULL)
3626
3627
3628 errmsg("relation \"%s\" in %s clause not found in FROM clause",
3632 }
3633 }
3634}
3635
3636
3637
3638
3639void
3642 bool pushedDown)
3643{
3645
3646 Assert(strength != LCS_NONE);
3647
3648
3649 if (!pushedDown)
3650 qry->hasForUpdate = true;
3651
3652
3654 {
3655
3656
3657
3658
3659
3660
3661
3662
3663
3664
3665
3666
3667
3668
3669
3670
3671
3672
3673
3677 return;
3678 }
3679
3680
3682 rc->rti = rtindex;
3687}
3688
3689#ifdef DEBUG_NODE_TESTS_ENABLED
3690
3691
3692
3693
3694
3695
3696
3697
3698static bool
3699test_raw_expression_coverage(Node *node, void *context)
3700{
3701 if (node == NULL)
3702 return false;
3704 test_raw_expression_coverage,
3705 context);
3706}
3707#endif
void(* post_parse_analyze_hook_type)(ParseState *pstate, Query *query, JumbleState *jstate)
#define DatumGetArrayTypeP(X)
#define InvalidAttrNumber
void pgstat_report_query_id(int64 query_id, bool force)
Bitmapset * bms_add_member(Bitmapset *a, int x)
List * expand_function_arguments(List *args, bool include_out_arguments, Oid result_type, HeapTuple func_tuple)
bool defGetBoolean(DefElem *def)
bool query_uses_temp_object(Query *query, ObjectAddress *temp_object)
int errmsg_plural(const char *fmt_singular, const char *fmt_plural, unsigned long n,...)
int errdetail(const char *fmt,...)
int errhint(const char *fmt,...)
int errcode(int sqlerrcode)
int errmsg(const char *fmt,...)
#define ereport(elevel,...)
#define palloc_object(type)
#define palloc_array(type, count)
char * format_type_be(Oid type_oid)
Assert(PointerIsAligned(start, uint64))
#define HeapTupleIsValid(tuple)
if(TABLE==NULL||TABLE_index==NULL)
List * lappend(List *list, void *datum)
List * list_delete_first(List *list)
List * list_copy(const List *oldlist)
List * lappend_int(List *list, int datum)
List * lappend_oid(List *list, Oid datum)
List * list_delete_last(List *list)
void list_free(List *list)
List * list_truncate(List *list, int new_size)
Alias * makeAlias(const char *aliasname, List *colnames)
Var * makeVarFromTargetEntry(int varno, TargetEntry *tle)
FromExpr * makeFromExpr(List *fromlist, Node *quals)
Var * makeVar(int varno, AttrNumber varattno, Oid vartype, int32 vartypmod, Oid varcollid, Index varlevelsup)
Const * makeNullConst(Oid consttype, int32 consttypmod, Oid constcollid)
TargetEntry * makeTargetEntry(Expr *expr, AttrNumber resno, char *resname, bool resjunk)
char * pstrdup(const char *in)
void * palloc0(Size size)
Oid exprType(const Node *expr)
int32 exprTypmod(const Node *expr)
Oid exprCollation(const Node *expr)
int exprLocation(const Node *expr)
#define raw_expression_tree_walker(n, w, c)
#define IsA(nodeptr, _type_)
#define castNode(_type_, nodeptr)
char * getObjectDescription(const ObjectAddress *object, bool missing_ok)
void(* ParserSetupHook)(ParseState *pstate, void *arg)
void parseCheckAggregates(ParseState *pstate, Query *qry)
Node * transformWhereClause(ParseState *pstate, Node *clause, ParseExprKind exprKind, const char *constructName)
List * transformGroupClause(ParseState *pstate, List *grouplist, bool groupByAll, List **groupingSets, List **targetlist, List *sortClause, ParseExprKind exprKind, bool useSQL99)
List * transformSortClause(ParseState *pstate, List *orderlist, List **targetlist, ParseExprKind exprKind, bool useSQL99)
List * transformDistinctOnClause(ParseState *pstate, List *distinctlist, List **targetlist, List *sortClause)
List * transformWindowDefinitions(ParseState *pstate, List *windowdefs, List **targetlist)
void transformFromClause(ParseState *pstate, List *frmList)
List * transformDistinctClause(ParseState *pstate, List **targetlist, List *sortClause, bool is_agg)
Node * transformLimitClause(ParseState *pstate, Node *clause, ParseExprKind exprKind, const char *constructName, LimitOption limitOption)
void transformOnConflictArbiter(ParseState *pstate, OnConflictClause *onConflictClause, List **arbiterExpr, Node **arbiterWhere, Oid *constraint)
int setTargetTable(ParseState *pstate, RangeVar *relation, bool inh, bool alsoSource, AclMode requiredPerms)
Node * coerce_to_common_type(ParseState *pstate, Node *node, Oid targetTypeId, const char *context)
int32 select_common_typmod(ParseState *pstate, List *exprs, Oid common_type)
Oid select_common_type(ParseState *pstate, List *exprs, const char *context, Node **which_expr)
Node * coerce_to_target_type(ParseState *pstate, Node *expr, Oid exprtype, Oid targettype, int32 targettypmod, CoercionContext ccontext, CoercionForm cformat, int location)
void assign_list_collations(ParseState *pstate, List *exprs)
Oid select_common_collation(ParseState *pstate, List *exprs, bool none_ok)
void assign_query_collations(ParseState *pstate, Query *query)
void assign_expr_collations(ParseState *pstate, Node *expr)
void analyzeCTETargetList(ParseState *pstate, CommonTableExpr *cte, List *tlist)
List * transformWithClause(ParseState *pstate, WithClause *withClause)
Node * transformExpr(ParseState *pstate, Node *expr, ParseExprKind exprKind)
Node * ParseFuncOrColumn(ParseState *pstate, List *funcname, List *fargs, Node *last_srf, FuncCall *fn, bool proc_call, int location)
Query * transformMergeStmt(ParseState *pstate, MergeStmt *stmt)
void cancel_parser_errposition_callback(ParseCallbackState *pcbstate)
void free_parsestate(ParseState *pstate)
int parser_errposition(ParseState *pstate, int location)
void setup_parser_errposition_callback(ParseCallbackState *pcbstate, ParseState *pstate, int location)
ParseState * make_parsestate(ParseState *parentParseState)
@ EXPR_KIND_INSERT_TARGET
@ EXPR_KIND_UPDATE_TARGET
@ EXPR_KIND_SELECT_TARGET
@ EXPR_KIND_CALL_ARGUMENT
@ EXPR_KIND_UPDATE_SOURCE
@ EXPR_KIND_VALUES_SINGLE
struct ParseNamespaceColumn ParseNamespaceColumn
void get_sort_group_operators(Oid argtype, bool needLT, bool needEQ, bool needGT, Oid *ltOpr, Oid *eqOpr, Oid *gtOpr, bool *isHashable)
void check_variable_parameters(ParseState *pstate, Query *query)
bool query_contains_extern_params(Query *query)
void setup_parse_variable_parameters(ParseState *pstate, Oid **paramTypes, int *numParams)
void setup_parse_fixed_parameters(ParseState *pstate, const Oid *paramTypes, int numParams)
ParseNamespaceItem * addRangeTableEntryForRelation(ParseState *pstate, Relation rel, int lockmode, Alias *alias, bool inh, bool inFromCl)
RTEPermissionInfo * getRTEPermissionInfo(List *rteperminfos, RangeTblEntry *rte)
RowMarkClause * get_parse_rowmark(Query *qry, Index rtindex)
TargetEntry * get_tle_by_resno(List *tlist, AttrNumber resno)
List * expandNSItemVars(ParseState *pstate, ParseNamespaceItem *nsitem, int sublevels_up, int location, List **colnames)
void addNSItemToQuery(ParseState *pstate, ParseNamespaceItem *nsitem, bool addToJoinList, bool addToRelNameSpace, bool addToVarNameSpace)
ParseNamespaceItem * addRangeTableEntryForSubquery(ParseState *pstate, Query *subquery, Alias *alias, bool lateral, bool inFromCl)
ParseNamespaceItem * addRangeTableEntryForJoin(ParseState *pstate, List *colnames, ParseNamespaceColumn *nscolumns, JoinType jointype, int nummergedcols, List *aliasvars, List *leftcols, List *rightcols, Alias *join_using_alias, Alias *alias, bool inFromCl)
List * expandNSItemAttrs(ParseState *pstate, ParseNamespaceItem *nsitem, int sublevels_up, bool require_col_privs, int location)
ParseNamespaceItem * refnameNamespaceItem(ParseState *pstate, const char *schemaname, const char *refname, int location, int *sublevels_up)
RangeTblEntry * GetRTEByRangeTablePosn(ParseState *pstate, int varno, int sublevels_up)
int attnameAttNum(Relation rd, const char *attname, bool sysColOK)
ParseNamespaceItem * addRangeTableEntryForValues(ParseState *pstate, List *exprs, List *coltypes, List *coltypmods, List *colcollations, Alias *alias, bool lateral, bool inFromCl)
Expr * transformAssignedExpr(ParseState *pstate, Expr *expr, ParseExprKind exprKind, const char *colname, int attrno, List *indirection, int location)
List * transformExpressionList(ParseState *pstate, List *exprlist, ParseExprKind exprKind, bool allowDefault)
Node * transformAssignmentIndirection(ParseState *pstate, Node *basenode, const char *targetName, bool targetIsSubscripting, Oid targetTypeId, int32 targetTypMod, Oid targetCollation, List *indirection, ListCell *indirection_cell, Node *rhs, CoercionContext ccontext, int location)
void updateTargetListEntry(ParseState *pstate, TargetEntry *tle, char *colname, int attrno, List *indirection, int location)
List * transformTargetList(ParseState *pstate, List *targetlist, ParseExprKind exprKind)
void resolveTargetListUnknowns(ParseState *pstate, List *targetlist)
void markTargetListOrigins(ParseState *pstate, List *targetlist)
List * checkInsertTargets(ParseState *pstate, List *cols, List **attrnos)
#define ISCOMPLEX(typeid)
#define CURSOR_OPT_INSENSITIVE
#define CURSOR_OPT_SCROLL
#define ACL_SELECT_FOR_UPDATE
#define CURSOR_OPT_ASENSITIVE
#define CURSOR_OPT_NO_SCROLL
static OnConflictExpr * transformOnConflictClause(ParseState *pstate, OnConflictClause *onConflictClause)
static Query * transformOptionalSelectInto(ParseState *pstate, Node *parseTree)
static void transformLockingClause(ParseState *pstate, Query *qry, LockingClause *lc, bool pushedDown)
static Query * transformDeleteStmt(ParseState *pstate, DeleteStmt *stmt)
void CheckSelectLocking(Query *qry, LockClauseStrength strength)
SortGroupClause * makeSortGroupClauseForSetOp(Oid rescoltype, bool require_hash)
static Node * transformSetOperationTree(ParseState *pstate, SelectStmt *stmt, bool isTopLevel, List **targetlist)
struct SelectStmtPassthrough SelectStmtPassthrough
Query * parse_analyze_withcb(RawStmt *parseTree, const char *sourceText, ParserSetupHook parserSetup, void *parserSetupArg, QueryEnvironment *queryEnv)
bool analyze_requires_snapshot(RawStmt *parseTree)
List * transformInsertRow(ParseState *pstate, List *exprlist, List *stmtcols, List *icolumns, List *attrnos, bool strip_indirection)
void applyLockingClause(Query *qry, Index rtindex, LockClauseStrength strength, LockWaitPolicy waitPolicy, bool pushedDown)
static void determineRecursiveColTypes(ParseState *pstate, Node *larg, List *nrtargetlist)
static Query * transformReturnStmt(ParseState *pstate, ReturnStmt *stmt)
static void addNSItemForReturning(ParseState *pstate, const char *aliasname, VarReturningType returning_type)
void transformReturningClause(ParseState *pstate, Query *qry, ReturningClause *returningClause, ParseExprKind exprKind)
static Query * transformPLAssignStmt(ParseState *pstate, PLAssignStmt *stmt)
static Query * transformCreateTableAsStmt(ParseState *pstate, CreateTableAsStmt *stmt)
post_parse_analyze_hook_type post_parse_analyze_hook
static Query * transformCallStmt(ParseState *pstate, CallStmt *stmt)
List * transformUpdateTargetList(ParseState *pstate, List *origTlist)
static Query * transformSetOperationStmt(ParseState *pstate, SelectStmt *stmt)
bool query_requires_rewrite_plan(Query *query)
static Query * transformSelectStmt(ParseState *pstate, SelectStmt *stmt, SelectStmtPassthrough *passthru)
Query * transformTopLevelStmt(ParseState *pstate, RawStmt *parseTree)
const char * LCS_asString(LockClauseStrength strength)
Query * parse_analyze_fixedparams(RawStmt *parseTree, const char *sourceText, const Oid *paramTypes, int numParams, QueryEnvironment *queryEnv)
static Query * transformUpdateStmt(ParseState *pstate, UpdateStmt *stmt)
Query * parse_sub_analyze(Node *parseTree, ParseState *parentParseState, CommonTableExpr *parentCTE, bool locked_from_parent, bool resolve_unknowns)
static Query * transformExplainStmt(ParseState *pstate, ExplainStmt *stmt)
List * BuildOnConflictExcludedTargetlist(Relation targetrel, Index exclRelIndex)
static List * transformPLAssignStmtTarget(ParseState *pstate, List *tlist, SelectStmtPassthrough *passthru)
static int count_rowexpr_columns(ParseState *pstate, Node *expr)
Query * parse_analyze_varparams(RawStmt *parseTree, const char *sourceText, Oid **paramTypes, int *numParams, QueryEnvironment *queryEnv)
bool stmt_requires_parse_analysis(RawStmt *parseTree)
static Query * transformDeclareCursorStmt(ParseState *pstate, DeclareCursorStmt *stmt)
static Query * transformInsertStmt(ParseState *pstate, InsertStmt *stmt)
static Query * transformValuesClause(ParseState *pstate, SelectStmt *stmt)
Query * transformStmt(ParseState *pstate, Node *parseTree)
#define rt_fetch(rangetable_index, rangetable)
FormData_pg_attribute * Form_pg_attribute
#define lfirst_node(type, lc)
static int list_length(const List *l)
#define linitial_node(type, l)
#define forboth(cell1, list1, cell2, list2)
#define forthree(cell1, list1, cell2, list2, cell3, list3)
static void * list_nth(const List *list, int n)
#define foreach_node(type, var, lst)
#define forfour(cell1, list1, cell2, list2, cell3, list3, cell4, list4)
static ListCell * list_head(const List *l)
static ListCell * lnext(const List *l, const ListCell *c)
#define list_make2(x1, x2)
#define ERRCODE_UNDEFINED_TABLE
static Datum ObjectIdGetDatum(Oid X)
static bool IsQueryIdEnabled(void)
JumbleState * JumbleQuery(Query *query)
#define RelationGetNumberOfAttributes(relation)
#define RelationGetRelationName(relation)
void check_stack_depth(void)
LockClauseStrength strength
LockWaitPolicy waitPolicy
ParseNamespaceColumn * p_nscolumns
RTEPermissionInfo * p_perminfo
VarReturningType p_returning_type
ParseNamespaceItem * p_target_nsitem
ParseExprKind p_expr_kind
bool p_locked_from_parent
ParseParamRefHook p_paramref_hook
QueryEnvironment * p_queryEnv
const char * p_sourcetext
Relation p_target_relation
CommonTableExpr * p_parent_cte
LockClauseStrength strength
LockWaitPolicy waitPolicy
#define FirstLowInvalidHeapAttributeNumber
void ReleaseSysCache(HeapTuple tuple)
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Datum SysCacheGetAttr(int cacheId, HeapTuple tup, AttrNumber attributeNumber, bool *isNull)
static FormData_pg_attribute * TupleDescAttr(TupleDesc tupdesc, int i)
String * makeString(char *str)
bool contain_vars_of_level(Node *node, int levelsup)
int locate_var_of_level(Node *node, int levelsup)