PostgreSQL Source Code: src/backend/catalog/namespace.c Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
21
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
137
138
140
141
143
144
146
147
148
150
152
154
156
157
159
160
161
162
163
166
168{
172
174{
181
182
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
202
204
206
207
208
209
210
212
213
214
235 bool include_out_arguments, int pronargs,
236 int **argnumbers);
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
255{
257 int sp_len;
258
260
263
264
265
266
267
269
271}
272
273static inline bool
275{
276 return a.roleid == b.roleid &&
277 strcmp(a.searchPath, b.searchPath) == 0;
278}
279
280#define SH_PREFIX nsphash
281#define SH_ELEMENT_TYPE SearchPathCacheEntry
282#define SH_KEY_TYPE SearchPathCacheKey
283#define SH_KEY key
284#define SH_HASH_KEY(tb, key) spcachekey_hash(key)
285#define SH_EQUAL(tb, a, b) spcachekey_equal(a, b)
286#define SH_SCOPE static inline
287#define SH_DECLARE
288#define SH_DEFINE
290
291
292
293
294
295
296
297#define SPCACHE_RESET_THRESHOLD 256
298
301
302
303
304
305static void
307{
310 return;
311
314
315
316
317
318
321
323 {
324
326 "search_path processing cache",
328 }
329 else
330 {
332 }
333
334
337}
338
339
340
341
342
345{
349 {
351 }
352 else
353 {
357 .roleid = roleid
358 };
359
361 if (entry)
363 return entry;
364 }
365}
366
367
368
369
370
371
372
375{
379 {
381 }
382 else
383 {
387 .roleid = roleid
388 };
389
390
391
392
393
395
396 if (!entry)
397 {
398 bool found;
399
401 entry = nsphash_insert(SearchPathCache, cachekey, &found);
403
409
410 }
411
413 return entry;
414 }
415}
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
444{
446 Oid relId;
448 bool retry = false;
450
451
453
454
455
456
458 {
461 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
462 errmsg("cross-database references are not implemented: \"%s.%s.%s\"",
465 }
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483 for (;;)
484 {
485
486
487
488
489
491
492
493
494
495
496
497
498
499
501 {
503 relId = InvalidOid;
504 else
505 {
507 {
508 Oid namespaceId;
509
511
512
513
514
515
518 (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
519 errmsg("temporary tables cannot specify a schema name")));
520 }
521
523 }
524 }
526 {
527 Oid namespaceId;
528
529
531 if (missing_ok && (namespaceId))
533 else
535 }
536 else
537 {
538
540 }
541
542
543
544
545
546
547
548
549
550
551
553 callback(relation, relId, oldRelId, callback_arg);
554
555
556
557
558
559
560
561
562 if (lockmode == NoLock)
563 break;
564
565
566
567
568
569
570
571
572
573
574 if (retry)
575 {
576 if (relId == oldRelId)
577 break;
580 }
581
582
583
584
585
586
587
588
594 {
596
599 (errcode(ERRCODE_LOCK_NOT_AVAILABLE),
600 errmsg("could not obtain lock on relation \"%s.%s\"",
602 else
604 (errcode(ERRCODE_LOCK_NOT_AVAILABLE),
605 errmsg("could not obtain lock on relation \"%s\"",
607
609 }
610
611
612
613
615 break;
616
617
618
619
620
621
622 retry = true;
623 oldRelId = relId;
624 }
625
627 {
628 int elevel = missing_ok ? DEBUG1 : ERROR;
629
633 errmsg("relation \"%s.%s\" does not exist",
635 else
638 errmsg("relation \"%s\" does not exist",
640 }
641 return relId;
642}
643
644
645
646
647
648
649
650
651
652
655{
656 Oid namespaceId;
657
658
659
660
662 {
665 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
666 errmsg("cross-database references are not implemented: \"%s.%s.%s\"",
669 }
670
672 {
673
674 if (strcmp(newRelation->schemaname, "pg_temp") == 0)
675 {
676
679 }
680
682
683 }
684 else if (newRelation->relpersistence == RELPERSISTENCE_TEMP)
685 {
686
689 }
690 else
691 {
692
695 {
696
699 }
703 (errcode(ERRCODE_UNDEFINED_SCHEMA),
704 errmsg("no schema has been selected to create in")));
705 }
706
707
708
709 return namespaceId;
710}
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
741 Oid *existing_relation_id)
742{
744 Oid relid;
748 bool retry = false;
749
750
751
752
754 {
757 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
758 errmsg("cross-database references are not implemented: \"%s.%s.%s\"",
761 }
762
763
764
765
766
767
768
769 for (;;)
770 {
772
774
775
778 if (existing_relation_id != NULL)
780 else
782
783
784
785
786
787
789 break;
790
791
796
797 if (retry)
798 {
799
800 if (relid == oldrelid && nspid == oldnspid)
801 break;
802
803 if (nspid != oldnspid)
806
807 if (relid != oldrelid && OidIsValid(oldrelid) && lockmode != NoLock)
809 }
810
811
812 if (nspid != oldnspid)
814
815
817 {
821 if (relid != oldrelid)
823 }
824
825
827 break;
828
829
830 retry = true;
831 oldrelid = relid;
832 oldnspid = nspid;
833 }
834
836 if (existing_relation_id != NULL)
837 *existing_relation_id = relid;
839}
840
841
842
843
844
845void
847{
849 {
850 case RELPERSISTENCE_TEMP:
852 {
855 (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
856 errmsg("cannot create relations in temporary schemas of other sessions")));
857 else
859 (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
860 errmsg("cannot create temporary relation in non-temporary schema")));
861 }
862 break;
863 case RELPERSISTENCE_PERMANENT:
868 (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
869 errmsg("cannot create relations in temporary schemas of other sessions")));
870 break;
871 default:
874 (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
875 errmsg("only temporary relations may be created in temporary schemas")));
876 }
877}
878
879
880
881
882
883
886{
887 Oid relid;
889
891
893 {
895
898 return relid;
899 }
900
901
903}
904
905
906
907
908
909
910
911
912bool
914{
916}
917
918
919
920
921
922
923
924static bool
926{
929 Oid relnamespace;
930 bool visible;
931
934 {
935 if (is_missing != NULL)
936 {
937 *is_missing = true;
938 return false;
939 }
940 elog(ERROR, "cache lookup failed for relation %u", relid);
941 }
943
945
946
947
948
949
950
951 relnamespace = relform->relnamespace;
952 if (relnamespace != PG_CATALOG_NAMESPACE &&
954 visible = false;
955 else
956 {
957
958
959
960
961
964
965 visible = false;
967 {
969
970 if (namespaceId == relnamespace)
971 {
972
973 visible = true;
974 break;
975 }
977 {
978
979 break;
980 }
981 }
982 }
983
985
986 return visible;
987}
988
989
990
991
992
993
996{
998}
999
1000
1001
1002
1003
1004
1005
1006
1009{
1010 Oid typid;
1012
1014
1016 {
1018
1020 continue;
1021
1026 return typid;
1027 }
1028
1029
1031}
1032
1033
1034
1035
1036
1037
1038
1039bool
1041{
1043}
1044
1045
1046
1047
1048
1049
1050
1051static bool
1053{
1056 Oid typnamespace;
1057 bool visible;
1058
1061 {
1062 if (is_missing != NULL)
1063 {
1064 *is_missing = true;
1065 return false;
1066 }
1067 elog(ERROR, "cache lookup failed for type %u", typid);
1068 }
1070
1072
1073
1074
1075
1076
1077
1078 typnamespace = typform->typnamespace;
1079 if (typnamespace != PG_CATALOG_NAMESPACE &&
1081 visible = false;
1082 else
1083 {
1084
1085
1086
1087
1088
1091
1092 visible = false;
1094 {
1096
1097 if (namespaceId == typnamespace)
1098 {
1099
1100 visible = true;
1101 break;
1102 }
1106 {
1107
1108 break;
1109 }
1110 }
1111 }
1112
1114
1115 return visible;
1116}
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1193 bool expand_variadic, bool expand_defaults,
1194 bool include_out_arguments, bool missing_ok)
1195{
1197 bool any_special = false;
1198 char *schemaname;
1200 Oid namespaceId;
1202 int i;
1203
1204
1205 Assert(nargs >= 0 || !(expand_variadic | expand_defaults));
1206
1207
1209
1210 if (schemaname)
1211 {
1212
1215 return NULL;
1216 }
1217 else
1218 {
1219
1222 }
1223
1224
1226
1228 {
1231 Oid *proargtypes = procform->proargtypes.values;
1232 int pronargs = procform->pronargs;
1233 int effective_nargs;
1234 int pathpos = 0;
1235 bool variadic;
1236 bool use_defaults;
1237 Oid va_elem_type;
1238 int *argnumbers = NULL;
1240
1242 {
1243
1244 if (procform->pronamespace != namespaceId)
1245 continue;
1246 }
1247 else
1248 {
1249
1250
1251
1252
1254
1256 {
1257 if (procform->pronamespace == lfirst_oid(nsp) &&
1259 break;
1260 pathpos++;
1261 }
1262 if (nsp == NULL)
1263 continue;
1264 }
1265
1266
1267
1268
1269
1270
1271
1272 if (include_out_arguments)
1273 {
1274 Datum proallargtypes;
1275 bool isNull;
1276
1277 proallargtypes = SysCacheGetAttr(PROCNAMEARGSNSP, proctup,
1278 Anum_pg_proc_proallargtypes,
1279 &isNull);
1280 if (!isNull)
1281 {
1283
1289 elog(ERROR, "proallargtypes is not a 1-D Oid array or it contains nulls");
1292 }
1293 }
1294
1295 if (argnames != NIL)
1296 {
1297
1298
1299
1300
1301
1302
1303
1304 if (OidIsValid(procform->provariadic) && expand_variadic)
1305 continue;
1307 variadic = false;
1308
1309
1310
1311
1312 Assert(nargs >= 0);
1313
1314 if (pronargs > nargs && expand_defaults)
1315 {
1316
1317 if (nargs + procform->pronargdefaults < pronargs)
1318 continue;
1319 use_defaults = true;
1320 }
1321 else
1322 use_defaults = false;
1323
1324
1325 if (pronargs != nargs && !use_defaults)
1326 continue;
1327
1328
1330 include_out_arguments, pronargs,
1331 &argnumbers))
1332 continue;
1333
1334
1335 any_special = true;
1336 }
1337 else
1338 {
1339
1340
1341
1342
1343
1344
1345
1346 if (pronargs <= nargs && expand_variadic)
1347 {
1348 va_elem_type = procform->provariadic;
1349 variadic = OidIsValid(va_elem_type);
1350 any_special |= variadic;
1351 }
1352 else
1353 {
1355 variadic = false;
1356 }
1357
1358
1359
1360
1361 if (pronargs > nargs && expand_defaults)
1362 {
1363
1364 if (nargs + procform->pronargdefaults < pronargs)
1365 continue;
1366 use_defaults = true;
1367 any_special = true;
1368 }
1369 else
1370 use_defaults = false;
1371
1372
1373 if (nargs >= 0 && pronargs != nargs && !variadic && !use_defaults)
1374 continue;
1375 }
1376
1377
1378
1379
1380
1381
1382
1386 effective_nargs * sizeof(Oid));
1387 newResult->pathpos = pathpos;
1388 newResult->oid = procform->oid;
1390 newResult->nargs = effective_nargs;
1392 if (argnumbers)
1393 {
1394
1396 newResult->args[j] = proargtypes[argnumbers[j]];
1397 }
1398 else
1399 {
1400
1401 memcpy(newResult->args, proargtypes, pronargs * sizeof(Oid));
1402 }
1403 if (variadic)
1404 {
1406
1407 for (int j = pronargs - 1; j < effective_nargs; j++)
1408 newResult->args[j] = va_elem_type;
1409 }
1410 else
1411 newResult->nvargs = 0;
1412 newResult->ndargs = use_defaults ? pronargs - nargs : 0;
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422 if (resultList != NULL &&
1423 (any_special || (namespaceId)))
1424 {
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1437
1438 if (catlist->ordered && !any_special)
1439 {
1440
1441 if (effective_nargs == resultList->nargs &&
1442 memcmp(newResult->args,
1443 resultList->args,
1444 effective_nargs * sizeof(Oid)) == 0)
1445 prevResult = resultList;
1446 else
1447 prevResult = NULL;
1448 }
1449 else
1450 {
1451 int cmp_nargs = newResult->nargs - newResult->ndargs;
1452
1453 for (prevResult = resultList;
1454 prevResult;
1455 prevResult = prevResult->next)
1456 {
1457 if (cmp_nargs == prevResult->nargs - prevResult->ndargs &&
1458 memcmp(newResult->args,
1459 prevResult->args,
1460 cmp_nargs * sizeof(Oid)) == 0)
1461 break;
1462 }
1463 }
1464
1465 if (prevResult)
1466 {
1467
1468
1469
1470
1471
1472
1473
1474 int preference;
1475
1476 if (pathpos != prevResult->pathpos)
1477 {
1478
1479
1480
1481 preference = pathpos - prevResult->pathpos;
1482 }
1483 else if (variadic && prevResult->nvargs == 0)
1484 {
1485
1486
1487
1488
1489
1490
1491 preference = 1;
1492 }
1493 else if (!variadic && prevResult->nvargs > 0)
1494 {
1495 preference = -1;
1496 }
1497 else
1498 {
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508 preference = 0;
1509 }
1510
1511 if (preference > 0)
1512 {
1513
1514 pfree(newResult);
1515 continue;
1516 }
1517 else if (preference < 0)
1518 {
1519
1520 if (prevResult == resultList)
1521 resultList = prevResult->next;
1522 else
1523 {
1525
1526 for (prevPrevResult = resultList;
1527 prevPrevResult;
1528 prevPrevResult = prevPrevResult->next)
1529 {
1530 if (prevResult == prevPrevResult->next)
1531 {
1532 prevPrevResult->next = prevResult->next;
1533 break;
1534 }
1535 }
1536 Assert(prevPrevResult);
1537 }
1538 pfree(prevResult);
1539
1540 }
1541 else
1542 {
1543
1545 pfree(newResult);
1546 continue;
1547 }
1548 }
1549 }
1550
1551
1552
1553
1554 newResult->next = resultList;
1555 resultList = newResult;
1556 }
1557
1559
1560 return resultList;
1561}
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584static bool
1586 bool include_out_arguments, int pronargs,
1587 int **argnumbers)
1588{
1590 int numposargs = nargs - list_length(argnames);
1591 int pronallargs;
1592 Oid *p_argtypes;
1593 char **p_argnames;
1594 char *p_argmodes;
1596 bool isnull;
1597 int ap;
1598 int pp;
1600
1602 Assert(numposargs >= 0);
1604
1605
1606 (void) SysCacheGetAttr(PROCOID, proctup, Anum_pg_proc_proargnames,
1607 &isnull);
1608 if (isnull)
1609 return false;
1610
1611
1613 &p_argtypes, &p_argnames, &p_argmodes);
1614 Assert(p_argnames != NULL);
1615
1616 Assert(include_out_arguments ? (pronargs == pronallargs) : (pronargs <= pronallargs));
1617
1618
1619 *argnumbers = (int *) palloc(pronargs * sizeof(int));
1620 memset(arggiven, false, pronargs * sizeof(bool));
1621
1622
1623 for (ap = 0; ap < numposargs; ap++)
1624 {
1625 (*argnumbers)[ap] = ap;
1626 arggiven[ap] = true;
1627 }
1628
1629
1630 foreach(lc, argnames)
1631 {
1632 char *argname = (char *) lfirst(lc);
1633 bool found;
1634 int i;
1635
1636 pp = 0;
1637 found = false;
1638 for (i = 0; i < pronallargs; i++)
1639 {
1640
1641 if (!include_out_arguments &&
1642 p_argmodes &&
1646 continue;
1647 if (p_argnames[i] && strcmp(p_argnames[i], argname) == 0)
1648 {
1649
1650 if (arggiven[pp])
1651 return false;
1652 arggiven[pp] = true;
1653 (*argnumbers)[ap] = pp;
1654 found = true;
1655 break;
1656 }
1657
1658 pp++;
1659 }
1660
1661 if (!found)
1662 return false;
1663 ap++;
1664 }
1665
1666 Assert(ap == nargs);
1667
1668
1670 {
1671 int first_arg_with_default = pronargs - procform->pronargdefaults;
1672
1673 for (pp = numposargs; pp < pronargs; pp++)
1674 {
1675 if (arggiven[pp])
1676 continue;
1677
1678 if (pp < first_arg_with_default)
1679 return false;
1680 (*argnumbers)[ap++] = pp;
1681 }
1682 }
1683
1685
1686 return true;
1687}
1688
1689
1690
1691
1692
1693
1694
1695bool
1697{
1699}
1700
1701
1702
1703
1704
1705
1706
1707static bool
1709{
1712 Oid pronamespace;
1713 bool visible;
1714
1717 {
1718 if (is_missing != NULL)
1719 {
1720 *is_missing = true;
1721 return false;
1722 }
1723 elog(ERROR, "cache lookup failed for function %u", funcid);
1724 }
1726
1728
1729
1730
1731
1732
1733
1734 pronamespace = procform->pronamespace;
1735 if (pronamespace != PG_CATALOG_NAMESPACE &&
1737 visible = false;
1738 else
1739 {
1740
1741
1742
1743
1744
1745
1747 int nargs = procform->pronargs;
1749
1750 visible = false;
1751
1753 nargs, NIL, false, false, false, false);
1754
1755 for (; clist; clist = clist->next)
1756 {
1757 if (memcmp(clist->args, procform->proargtypes.values,
1758 nargs * sizeof(Oid)) == 0)
1759 {
1760
1761 visible = (clist->oid == funcid);
1762 break;
1763 }
1764 }
1765 }
1766
1768
1769 return visible;
1770}
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1786{
1787 char *schemaname;
1788 char *opername;
1791
1792
1794
1795 if (schemaname)
1796 {
1797
1798 Oid namespaceId;
1799
1802 {
1804
1811 {
1813 Oid result = operclass->oid;
1814
1816 return result;
1817 }
1818 }
1819
1821 }
1822
1823
1828
1830 {
1831
1834 }
1835
1836
1837
1838
1839
1840
1842
1844 {
1846 int i;
1847
1849 continue;
1850
1852 {
1855
1856 if (operform->oprnamespace == namespaceId)
1857 {
1858 Oid result = operform->oid;
1859
1861 return result;
1862 }
1863 }
1864 }
1865
1868}
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1889{
1891 char *resultSpace = NULL;
1892 int nextResult = 0;
1893 char *schemaname;
1894 char *opername;
1895 Oid namespaceId;
1897 int i;
1898
1899
1901
1902 if (schemaname)
1903 {
1904
1906 if (missing_schema_ok && (namespaceId))
1907 return NULL;
1908 }
1909 else
1910 {
1911
1914 }
1915
1916
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928#define SPACE_PER_OP MAXALIGN(offsetof(struct _FuncCandidateList, args) + \
1929 2 * sizeof(Oid))
1930
1933
1935 {
1938 int pathpos = 0;
1940
1941
1942 if (oprkind && operform->oprkind != oprkind)
1943 continue;
1944
1946 {
1947
1948 if (operform->oprnamespace != namespaceId)
1949 continue;
1950
1951 }
1952 else
1953 {
1954
1955
1956
1957
1959
1961 {
1962 if (operform->oprnamespace == lfirst_oid(nsp) &&
1964 break;
1965 pathpos++;
1966 }
1967 if (nsp == NULL)
1968 continue;
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981 if (resultList)
1982 {
1984
1986 {
1987 if (operform->oprleft == resultList->args[0] &&
1988 operform->oprright == resultList->args[1])
1989 prevResult = resultList;
1990 else
1991 prevResult = NULL;
1992 }
1993 else
1994 {
1995 for (prevResult = resultList;
1996 prevResult;
1997 prevResult = prevResult->next)
1998 {
1999 if (operform->oprleft == prevResult->args[0] &&
2000 operform->oprright == prevResult->args[1])
2001 break;
2002 }
2003 }
2004 if (prevResult)
2005 {
2006
2008 if (pathpos > prevResult->pathpos)
2009 continue;
2010
2011 prevResult->pathpos = pathpos;
2012 prevResult->oid = operform->oid;
2013 continue;
2014 }
2015 }
2016 }
2017
2018
2019
2020
2023
2024 newResult->pathpos = pathpos;
2025 newResult->oid = operform->oid;
2027 newResult->nargs = 2;
2028 newResult->nvargs = 0;
2029 newResult->ndargs = 0;
2031 newResult->args[0] = operform->oprleft;
2032 newResult->args[1] = operform->oprright;
2033 newResult->next = resultList;
2034 resultList = newResult;
2035 }
2036
2038
2039 return resultList;
2040}
2041
2042
2043
2044
2045
2046
2047
2048bool
2050{
2052}
2053
2054
2055
2056
2057
2058
2059
2060static bool
2062{
2065 Oid oprnamespace;
2066 bool visible;
2067
2070 {
2071 if (is_missing != NULL)
2072 {
2073 *is_missing = true;
2074 return false;
2075 }
2076 elog(ERROR, "cache lookup failed for operator %u", oprid);
2077 }
2079
2081
2082
2083
2084
2085
2086
2087 oprnamespace = oprform->oprnamespace;
2088 if (oprnamespace != PG_CATALOG_NAMESPACE &&
2090 visible = false;
2091 else
2092 {
2093
2094
2095
2096
2097
2098
2099 char *oprname = NameStr(oprform->oprname);
2100
2102 oprform->oprleft, oprform->oprright)
2104 }
2105
2107
2108 return visible;
2109}
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2122{
2123 Oid opcid;
2125
2127
2129 {
2131
2133 continue;
2134
2135 opcid = GetSysCacheOid3(CLAAMNAMENSP, Anum_pg_opclass_oid,
2140 return opcid;
2141 }
2142
2143
2145}
2146
2147
2148
2149
2150
2151
2152
2153bool
2155{
2157}
2158
2159
2160
2161
2162
2163
2164
2165static bool
2167{
2170 Oid opcnamespace;
2171 bool visible;
2172
2175 {
2176 if (is_missing != NULL)
2177 {
2178 *is_missing = true;
2179 return false;
2180 }
2181 elog(ERROR, "cache lookup failed for opclass %u", opcid);
2182 }
2184
2186
2187
2188
2189
2190
2191
2192 opcnamespace = opcform->opcnamespace;
2193 if (opcnamespace != PG_CATALOG_NAMESPACE &&
2195 visible = false;
2196 else
2197 {
2198
2199
2200
2201
2202
2203
2204 char *opcname = NameStr(opcform->opcname);
2205
2207 }
2208
2210
2211 return visible;
2212}
2213
2214
2215
2216
2217
2218
2219
2220
2221
2224{
2225 Oid opfid;
2227
2229
2231 {
2233
2235 continue;
2236
2237 opfid = GetSysCacheOid3(OPFAMILYAMNAMENSP, Anum_pg_opfamily_oid,
2242 return opfid;
2243 }
2244
2245
2247}
2248
2249
2250
2251
2252
2253
2254
2255bool
2257{
2259}
2260
2261
2262
2263
2264
2265
2266
2267static bool
2269{
2272 Oid opfnamespace;
2273 bool visible;
2274
2277 {
2278 if (is_missing != NULL)
2279 {
2280 *is_missing = true;
2281 return false;
2282 }
2283 elog(ERROR, "cache lookup failed for opfamily %u", opfid);
2284 }
2286
2288
2289
2290
2291
2292
2293
2294 opfnamespace = opfform->opfnamespace;
2295 if (opfnamespace != PG_CATALOG_NAMESPACE &&
2297 visible = false;
2298 else
2299 {
2300
2301
2302
2303
2304
2305
2306 char *opfname = NameStr(opfform->opfname);
2307
2309 }
2310
2312
2313 return visible;
2314}
2315
2316
2317
2318
2319
2320
2321static Oid
2323{
2327
2328
2335
2336
2337
2338
2339
2340
2341
2349 if (collform->collprovider == COLLPROVIDER_ICU)
2350 {
2352 collid = collform->oid;
2353 else
2355 }
2356 else
2357 {
2358 collid = collform->oid;
2359 }
2362}
2363
2364
2365
2366
2367
2368
2369
2370
2371
2374{
2377
2379
2381 {
2384
2386 continue;
2387
2391 }
2392
2393
2395}
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406bool
2408{
2410}
2411
2412
2413
2414
2415
2416
2417
2418static bool
2420{
2423 Oid collnamespace;
2424 bool visible;
2425
2428 {
2429 if (is_missing != NULL)
2430 {
2431 *is_missing = true;
2432 return false;
2433 }
2434 elog(ERROR, "cache lookup failed for collation %u", collid);
2435 }
2437
2439
2440
2441
2442
2443
2444
2445 collnamespace = collform->collnamespace;
2446 if (collnamespace != PG_CATALOG_NAMESPACE &&
2448 visible = false;
2449 else
2450 {
2451
2452
2453
2454
2455
2456
2457
2458 char *collname = NameStr(collform->collname);
2459
2461 }
2462
2464
2465 return visible;
2466}
2467
2468
2469
2470
2471
2472
2473
2474
2475
2478{
2479 Oid conid;
2481
2483
2485 {
2487
2489 continue;
2490
2491 conid = GetSysCacheOid2(CONNAMENSP, Anum_pg_conversion_oid,
2495 return conid;
2496 }
2497
2498
2500}
2501
2502
2503
2504
2505
2506
2507
2508bool
2510{
2512}
2513
2514
2515
2516
2517
2518
2519
2520static bool
2522{
2525 Oid connamespace;
2526 bool visible;
2527
2530 {
2531 if (is_missing != NULL)
2532 {
2533 *is_missing = true;
2534 return false;
2535 }
2536 elog(ERROR, "cache lookup failed for conversion %u", conid);
2537 }
2539
2541
2542
2543
2544
2545
2546
2547 connamespace = conform->connamespace;
2548 if (connamespace != PG_CATALOG_NAMESPACE &&
2550 visible = false;
2551 else
2552 {
2553
2554
2555
2556
2557
2558
2559 char *conname = NameStr(conform->conname);
2560
2562 }
2563
2565
2566 return visible;
2567}
2568
2569
2570
2571
2572
2573
2576{
2577 char *schemaname;
2578 char *stats_name;
2579 Oid namespaceId;
2582
2583
2585
2586 if (schemaname)
2587 {
2588
2590 if (missing_ok && (namespaceId))
2592 else
2593 stats_oid = GetSysCacheOid2(STATEXTNAMENSP, Anum_pg_statistic_ext_oid,
2596 }
2597 else
2598 {
2599
2601
2603 {
2605
2607 continue;
2608 stats_oid = GetSysCacheOid2(STATEXTNAMENSP, Anum_pg_statistic_ext_oid,
2612 break;
2613 }
2614 }
2615
2616 if ((stats_oid) && !missing_ok)
2618 (errcode(ERRCODE_UNDEFINED_OBJECT),
2619 errmsg("statistics object \"%s\" does not exist",
2621
2622 return stats_oid;
2623}
2624
2625
2626
2627
2628
2629
2630
2631bool
2633{
2635}
2636
2637
2638
2639
2640
2641
2642
2643static bool
2645{
2648 Oid stxnamespace;
2649 bool visible;
2650
2653 {
2654 if (is_missing != NULL)
2655 {
2656 *is_missing = true;
2657 return false;
2658 }
2659 elog(ERROR, "cache lookup failed for statistics object %u", stxid);
2660 }
2662
2664
2665
2666
2667
2668
2669
2670 stxnamespace = stxform->stxnamespace;
2671 if (stxnamespace != PG_CATALOG_NAMESPACE &&
2673 visible = false;
2674 else
2675 {
2676
2677
2678
2679
2680
2681 char *stxname = NameStr(stxform->stxname);
2683
2684 visible = false;
2686 {
2688
2689 if (namespaceId == stxnamespace)
2690 {
2691
2692 visible = true;
2693 break;
2694 }
2698 {
2699
2700 break;
2701 }
2702 }
2703 }
2704
2706
2707 return visible;
2708}
2709
2710
2711
2712
2713
2714
2717{
2718 char *schemaname;
2719 char *parser_name;
2720 Oid namespaceId;
2723
2724
2726
2727 if (schemaname)
2728 {
2729
2731 if (missing_ok && (namespaceId))
2733 else
2734 prsoid = GetSysCacheOid2(TSPARSERNAMENSP, Anum_pg_ts_parser_oid,
2737 }
2738 else
2739 {
2740
2742
2744 {
2746
2748 continue;
2749
2750 prsoid = GetSysCacheOid2(TSPARSERNAMENSP, Anum_pg_ts_parser_oid,
2754 break;
2755 }
2756 }
2757
2758 if ((prsoid) && !missing_ok)
2760 (errcode(ERRCODE_UNDEFINED_OBJECT),
2761 errmsg("text search parser \"%s\" does not exist",
2763
2764 return prsoid;
2765}
2766
2767
2768
2769
2770
2771
2772
2773bool
2775{
2777}
2778
2779
2780
2781
2782
2783
2784
2785static bool
2787{
2790 Oid namespace;
2791 bool visible;
2792
2795 {
2796 if (is_missing != NULL)
2797 {
2798 *is_missing = true;
2799 return false;
2800 }
2801 elog(ERROR, "cache lookup failed for text search parser %u", prsId);
2802 }
2804
2806
2807
2808
2809
2810
2811
2812 namespace = form->prsnamespace;
2813 if (namespace != PG_CATALOG_NAMESPACE &&
2815 visible = false;
2816 else
2817 {
2818
2819
2820
2821
2822
2825
2826 visible = false;
2828 {
2830
2832 continue;
2833
2834 if (namespaceId == namespace)
2835 {
2836
2837 visible = true;
2838 break;
2839 }
2843 {
2844
2845 break;
2846 }
2847 }
2848 }
2849
2851
2852 return visible;
2853}
2854
2855
2856
2857
2858
2859
2862{
2863 char *schemaname;
2864 char *dict_name;
2865 Oid namespaceId;
2868
2869
2871
2872 if (schemaname)
2873 {
2874
2876 if (missing_ok && (namespaceId))
2878 else
2879 dictoid = GetSysCacheOid2(TSDICTNAMENSP, Anum_pg_ts_dict_oid,
2882 }
2883 else
2884 {
2885
2887
2889 {
2891
2893 continue;
2894
2895 dictoid = GetSysCacheOid2(TSDICTNAMENSP, Anum_pg_ts_dict_oid,
2899 break;
2900 }
2901 }
2902
2903 if ((dictoid) && !missing_ok)
2905 (errcode(ERRCODE_UNDEFINED_OBJECT),
2906 errmsg("text search dictionary \"%s\" does not exist",
2908
2909 return dictoid;
2910}
2911
2912
2913
2914
2915
2916
2917
2918bool
2920{
2922}
2923
2924
2925
2926
2927
2928
2929
2930static bool
2932{
2935 Oid namespace;
2936 bool visible;
2937
2940 {
2941 if (is_missing != NULL)
2942 {
2943 *is_missing = true;
2944 return false;
2945 }
2946 elog(ERROR, "cache lookup failed for text search dictionary %u",
2947 dictId);
2948 }
2950
2952
2953
2954
2955
2956
2957
2958 namespace = form->dictnamespace;
2959 if (namespace != PG_CATALOG_NAMESPACE &&
2961 visible = false;
2962 else
2963 {
2964
2965
2966
2967
2968
2971
2972 visible = false;
2974 {
2976
2978 continue;
2979
2980 if (namespaceId == namespace)
2981 {
2982
2983 visible = true;
2984 break;
2985 }
2989 {
2990
2991 break;
2992 }
2993 }
2994 }
2995
2997
2998 return visible;
2999}
3000
3001
3002
3003
3004
3005
3008{
3009 char *schemaname;
3010 char *template_name;
3011 Oid namespaceId;
3014
3015
3017
3018 if (schemaname)
3019 {
3020
3022 if (missing_ok && (namespaceId))
3024 else
3025 tmploid = GetSysCacheOid2(TSTEMPLATENAMENSP, Anum_pg_ts_template_oid,
3028 }
3029 else
3030 {
3031
3033
3035 {
3037
3039 continue;
3040
3041 tmploid = GetSysCacheOid2(TSTEMPLATENAMENSP, Anum_pg_ts_template_oid,
3045 break;
3046 }
3047 }
3048
3049 if ((tmploid) && !missing_ok)
3051 (errcode(ERRCODE_UNDEFINED_OBJECT),
3052 errmsg("text search template \"%s\" does not exist",
3054
3055 return tmploid;
3056}
3057
3058
3059
3060
3061
3062
3063
3064bool
3066{
3068}
3069
3070
3071
3072
3073
3074
3075
3076static bool
3078{
3081 Oid namespace;
3082 bool visible;
3083
3086 {
3087 if (is_missing != NULL)
3088 {
3089 *is_missing = true;
3090 return false;
3091 }
3092 elog(ERROR, "cache lookup failed for text search template %u", tmplId);
3093 }
3095
3097
3098
3099
3100
3101
3102
3103 namespace = form->tmplnamespace;
3104 if (namespace != PG_CATALOG_NAMESPACE &&
3106 visible = false;
3107 else
3108 {
3109
3110
3111
3112
3113
3116
3117 visible = false;
3119 {
3121
3123 continue;
3124
3125 if (namespaceId == namespace)
3126 {
3127
3128 visible = true;
3129 break;
3130 }
3134 {
3135
3136 break;
3137 }
3138 }
3139 }
3140
3142
3143 return visible;
3144}
3145
3146
3147
3148
3149
3150
3153{
3154 char *schemaname;
3155 char *config_name;
3156 Oid namespaceId;
3159
3160
3162
3163 if (schemaname)
3164 {
3165
3167 if (missing_ok && (namespaceId))
3169 else
3170 cfgoid = GetSysCacheOid2(TSCONFIGNAMENSP, Anum_pg_ts_config_oid,
3173 }
3174 else
3175 {
3176
3178
3180 {
3182
3184 continue;
3185
3186 cfgoid = GetSysCacheOid2(TSCONFIGNAMENSP, Anum_pg_ts_config_oid,
3190 break;
3191 }
3192 }
3193
3194 if ((cfgoid) && !missing_ok)
3196 (errcode(ERRCODE_UNDEFINED_OBJECT),
3197 errmsg("text search configuration \"%s\" does not exist",
3199
3200 return cfgoid;
3201}
3202
3203
3204
3205
3206
3207
3208
3209bool
3211{
3213}
3214
3215
3216
3217
3218
3219
3220
3221static bool
3223{
3226 Oid namespace;
3227 bool visible;
3228
3231 {
3232 if (is_missing != NULL)
3233 {
3234 *is_missing = true;
3235 return false;
3236 }
3237 elog(ERROR, "cache lookup failed for text search configuration %u",
3238 cfgid);
3239 }
3241
3243
3244
3245
3246
3247
3248
3249 namespace = form->cfgnamespace;
3250 if (namespace != PG_CATALOG_NAMESPACE &&
3252 visible = false;
3253 else
3254 {
3255
3256
3257
3258
3259
3262
3263 visible = false;
3265 {
3267
3269 continue;
3270
3271 if (namespaceId == namespace)
3272 {
3273
3274 visible = true;
3275 break;
3276 }
3280 {
3281
3282 break;
3283 }
3284 }
3285 }
3286
3288
3289 return visible;
3290}
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300void
3302 char **nspname_p,
3303 char **objname_p)
3304{
3305 char *catalogname;
3306 char *schemaname = NULL;
3307 char *objname = NULL;
3308
3310 {
3311 case 1:
3313 break;
3314 case 2:
3317 break;
3318 case 3:
3322
3323
3324
3325
3328 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3329 errmsg("cross-database references are not implemented: %s",
3331 break;
3332 default:
3334 (errcode(ERRCODE_SYNTAX_ERROR),
3335 errmsg("improper qualified name (too many dotted names): %s",
3337 break;
3338 }
3339
3340 *nspname_p = schemaname;
3341 *objname_p = objname;
3342}
3343
3344
3345
3346
3347
3348
3349
3350
3351
3352
3353
3356{
3357
3358 if (strcmp(nspname, "pg_temp") == 0)
3359 {
3361 {
3364 }
3365
3366
3367
3368
3369
3370
3372 }
3373
3375}
3376
3377
3378
3379
3380
3381
3382
3383
3386{
3387 Oid namespaceId;
3389
3390
3391 if (strcmp(nspname, "pg_temp") == 0)
3392 {
3395
3396
3397
3398
3399
3400
3401 }
3402
3404 if (missing_ok && (namespaceId))
3406
3410 nspname);
3411
3413
3414 return namespaceId;
3415}
3416
3417
3418
3419
3420
3421
3422
3423
3424
3425
3426
3429{
3430 Oid namespaceId;
3432
3433
3434 if (strcmp(nspname, "pg_temp") == 0)
3435 {
3436
3439 }
3440
3442
3446 nspname);
3447
3448 return namespaceId;
3449}
3450
3451
3452
3453
3454
3455
3456
3457
3458void
3460{
3461
3464 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3465 errmsg("cannot move objects into or out of temporary schemas")));
3466
3467
3468 if (nspOid == PG_TOAST_NAMESPACE || oldNspOid == PG_TOAST_NAMESPACE)
3470 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3471 errmsg("cannot move objects into or out of TOAST schema")));
3472}
3473
3474
3475
3476
3477
3478
3479
3480
3481
3482
3483
3484
3485
3488{
3489 char *schemaname;
3490 Oid namespaceId;
3491
3492
3494
3495 if (schemaname)
3496 {
3497
3498 if (strcmp(schemaname, "pg_temp") == 0)
3499 {
3500
3503 }
3504
3506
3507 }
3508 else
3509 {
3510
3513 {
3514
3517 }
3521 (errcode(ERRCODE_UNDEFINED_SCHEMA),
3522 errmsg("no schema has been selected to create in")));
3523 }
3524
3525 return namespaceId;
3526}
3527
3528
3529
3530
3531
3532
3533
3536{
3537 Oid oid;
3538
3539 oid = GetSysCacheOid1(NAMESPACENAME, Anum_pg_namespace_oid,
3541 if ((oid) && !missing_ok)
3543 (errcode(ERRCODE_UNDEFINED_SCHEMA),
3544 errmsg("schema \"%s\" does not exist", nspname)));
3545
3546 return oid;
3547}
3548
3549
3550
3551
3552
3555{
3557
3559 {
3560 case 1:
3562 break;
3563 case 2:
3566 break;
3567 case 3:
3571 break;
3572 default:
3574 (errcode(ERRCODE_SYNTAX_ERROR),
3575 errmsg("improper relation name (too many dotted names): %s",
3577 break;
3578 }
3579
3580 return rel;
3581}
3582
3583
3584
3585
3586
3587
3588
3589
3590
3591
3592
3593char *
3595{
3598
3600
3601 foreach(l, names)
3602 {
3604
3607
3612 else
3613 elog(ERROR, "unexpected node type in name list: %d",
3615 }
3616
3617 return string.data;
3618}
3619
3620
3621
3622
3623
3624
3625
3626
3627char *
3629{
3632
3634
3635 foreach(l, names)
3636 {
3640 }
3641
3642 return string.data;
3643}
3644
3645
3646
3647
3648bool
3650{
3652 return true;
3653 return false;
3654}
3655
3656
3657
3658
3659
3660bool
3662{
3664 return true;
3665 return false;
3666}
3667
3668
3669
3670
3671
3672bool
3674{
3677 return true;
3678 return false;
3679}
3680
3681
3682
3683
3684
3685
3686bool
3688{
3689 bool result;
3690 char *nspname;
3691
3692
3694 if (!nspname)
3695 return false;
3696 result = (strncmp(nspname, "pg_temp_", 8) == 0) ||
3697 (strncmp(nspname, "pg_toast_temp_", 14) == 0);
3699 return result;
3700}
3701
3702
3703
3704
3705
3706
3707
3708
3709bool
3711{
3712
3714 return false;
3715
3717}
3718
3719
3720
3721
3722
3723
3724
3725
3726
3727
3730{
3733
3735
3737
3738
3741
3742
3744 if (proc == NULL)
3746
3747
3750
3751
3754
3755
3757}
3758
3759
3760
3761
3762
3763
3764
3767{
3768 int result;
3769 char *nspname;
3770
3771
3773 if (!nspname)
3775 if (strncmp(nspname, "pg_temp_", 8) == 0)
3776 result = atoi(nspname + 8);
3777 else if (strncmp(nspname, "pg_toast_temp_", 14) == 0)
3778 result = atoi(nspname + 14);
3779 else
3782 return result;
3783}
3784
3785
3786
3787
3788
3789
3792{
3795}
3796
3797
3798
3799
3800
3801
3802
3803
3804void
3806{
3807
3810}
3811
3812
3813
3814
3815
3816
3817
3818
3819
3820void
3822{
3823
3827
3828
3831
3832
3833
3834
3835
3836
3837
3838
3841}
3842
3843
3844
3845
3846
3847
3848
3849
3850
3853{
3855 List *schemas;
3857
3859
3861
3865 {
3868 else
3869 {
3872 }
3874 }
3875 result->schemas = schemas;
3877
3879
3880 return result;
3881}
3882
3883
3884
3885
3886
3887
3890{
3892
3898
3899 return result;
3900}
3901
3902
3903
3904
3905
3906
3907
3908
3909
3910bool
3912{
3914 *lcp;
3915
3917
3918
3920 return true;
3921
3922
3924
3925
3927 {
3930 else
3931 return false;
3932 }
3933
3935 {
3936 if (lc && lfirst_oid(lc) == PG_CATALOG_NAMESPACE)
3938 else
3939 return false;
3940 }
3941
3943 return false;
3944
3945 foreach(lcp, path->schemas)
3946 {
3949 else
3950 return false;
3951 }
3952 if (lc)
3953 return false;
3954
3955
3956
3957
3958
3960
3961 return true;
3962}
3963
3964
3965
3966
3967
3968
3969
3972{
3973 char *schemaname;
3974 char *collation_name;
3976 Oid namespaceId;
3977 Oid colloid;
3979
3980
3982
3983 if (schemaname)
3984 {
3985
3987 if (missing_ok && (namespaceId))
3989
3990 colloid = lookup_collation(collation_name, namespaceId, dbencoding);
3992 return colloid;
3993 }
3994 else
3995 {
3996
3998
4000 {
4002
4004 continue;
4005
4006 colloid = lookup_collation(collation_name, namespaceId, dbencoding);
4008 return colloid;
4009 }
4010 }
4011
4012
4013 if (!missing_ok)
4015 (errcode(ERRCODE_UNDEFINED_OBJECT),
4016 errmsg("collation \"%s\" for encoding \"%s\" does not exist",
4019}
4020
4021
4022
4023
4026{
4027 char *schemaname;
4028 char *conversion_name;
4029 Oid namespaceId;
4032
4033
4035
4036 if (schemaname)
4037 {
4038
4040 if (missing_ok && (namespaceId))
4042 else
4043 conoid = GetSysCacheOid2(CONNAMENSP, Anum_pg_conversion_oid,
4046 }
4047 else
4048 {
4049
4051
4053 {
4055
4057 continue;
4058
4059 conoid = GetSysCacheOid2(CONNAMENSP, Anum_pg_conversion_oid,
4063 return conoid;
4064 }
4065 }
4066
4067
4068 if ((conoid) && !missing_ok)
4070 (errcode(ERRCODE_UNDEFINED_OBJECT),
4071 errmsg("conversion \"%s\" does not exist",
4073 return conoid;
4074}
4075
4076
4077
4078
4081{
4082 Oid proc;
4084
4086
4088 {
4090
4092 continue;
4093
4096 return proc;
4097 }
4098
4099
4101}
4102
4103
4104
4105
4106static List *
4108 bool *temp_missing)
4109{
4110 char *rawname;
4111 List *namelist;
4112 List *oidlist;
4114
4115
4116 rawname = pstrdup(searchPath);
4117
4118
4120 {
4121
4122
4123 elog(ERROR, "invalid list syntax");
4124 }
4125
4126
4127
4128
4129
4130
4131
4132 oidlist = NIL;
4133 *temp_missing = false;
4134 foreach(l, namelist)
4135 {
4136 char *curname = (char *) lfirst(l);
4137 Oid namespaceId;
4138
4139 if (strcmp(curname, "$user") == 0)
4140 {
4141
4143
4146 {
4147 char *rname;
4148
4153 object_aclcheck(NamespaceRelationId, namespaceId, roleid,
4155 oidlist = lappend_oid(oidlist, namespaceId);
4156 }
4157 }
4158 else if (strcmp(curname, "pg_temp") == 0)
4159 {
4160
4163 else
4164 {
4165
4166 if (oidlist == NIL)
4167 *temp_missing = true;
4168 }
4169 }
4170 else
4171 {
4172
4175 object_aclcheck(NamespaceRelationId, namespaceId, roleid,
4177 oidlist = lappend_oid(oidlist, namespaceId);
4178 }
4179 }
4180
4183
4184 return oidlist;
4185}
4186
4187
4188
4189
4190
4191
4192
4193
4194
4195
4196
4197static List *
4199{
4202
4203 foreach(lc, oidlist)
4204 {
4206
4208 {
4210 finalPath = lappend_oid(finalPath, namespaceId);
4211 }
4212 }
4213
4214
4215
4216
4217
4218
4219 if (finalPath == NIL)
4221 else
4223
4224
4225
4226
4227
4228
4230 finalPath = lcons_oid(PG_CATALOG_NAMESPACE, finalPath);
4231
4235
4236 return finalPath;
4237}
4238
4239
4240
4241
4242
4245{
4248
4250
4252
4253
4254
4255
4256
4257
4259 {
4264 }
4265
4266
4267
4268
4269
4270
4271
4274 {
4277
4282
4283
4284
4285
4286
4287
4288
4290 }
4291
4292 return entry;
4293}
4294
4295
4296
4297
4298static void
4300{
4302 bool pathChanged;
4304
4305
4307 return;
4308
4310
4314 {
4315 pathChanged = false;
4316 }
4317 else
4318 {
4320 List *newpath;
4321
4322 pathChanged = true;
4323
4324
4328
4329
4334 }
4335
4336
4339
4340
4344
4345
4346
4347
4348
4349 if (pathChanged)
4351}
4352
4353
4354
4355
4356
4357
4358
4359
4360
4361static void
4363{
4364
4365
4366
4367
4369
4370
4371
4372
4373
4374
4376 return;
4377
4378
4379
4380
4381
4383}
4384
4385
4386
4387
4388
4389static void
4391{
4393 Oid namespaceId;
4394 Oid toastspaceId;
4395
4397
4398
4399
4400
4401
4402
4403
4404
4405
4406
4407
4411 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
4412 errmsg("permission denied to create temporary tables in database \"%s\"",
4414
4415
4416
4417
4418
4419
4420
4421
4422
4423
4424
4427 (errcode(ERRCODE_READ_ONLY_SQL_TRANSACTION),
4428 errmsg("cannot create temporary tables during recovery")));
4429
4430
4433 (errcode(ERRCODE_READ_ONLY_SQL_TRANSACTION),
4434 errmsg("cannot create temporary tables during a parallel operation")));
4435
4437
4440 {
4441
4442
4443
4444
4445
4446
4447
4448
4449 namespaceId = NamespaceCreate(namespaceName, BOOTSTRAP_SUPERUSERID,
4450 true);
4451
4453 }
4454 else
4455 {
4456
4457
4458
4459
4461 }
4462
4463
4464
4465
4466
4467
4468 snprintf(namespaceName, sizeof(namespaceName), "pg_toast_temp_%d",
4470
4473 {
4474 toastspaceId = NamespaceCreate(namespaceName, BOOTSTRAP_SUPERUSERID,
4475 true);
4476
4478 }
4479
4480
4481
4482
4483
4484
4487
4488
4489
4490
4491
4492
4493
4494
4495
4496
4497
4499
4500
4503
4506}
4507
4508
4509
4510
4511void
4513{
4514
4515
4516
4517
4518
4519
4520
4521
4523 {
4524 if (isCommit)
4526 else
4527 {
4532
4533
4534
4535
4536
4537
4538
4539
4540
4541
4543 }
4545 }
4546
4547}
4548
4549
4550
4551
4552
4553
4554
4555
4556
4557void
4560{
4561
4563 {
4564 if (isCommit)
4566 else
4567 {
4569
4574
4575
4576
4577
4578
4579
4580
4581
4582
4583
4585 }
4586 }
4587}
4588
4589
4590
4591
4592
4593
4594
4595
4596
4597static void
4599{
4601
4602
4603
4604
4605
4606
4607
4608
4609 object.classId = NamespaceRelationId;
4610 object.objectId = tempNamespaceId;
4611 object.objectSubId = 0;
4612
4618}
4619
4620
4621
4622
4623static void
4625{
4627 {
4628
4632
4634
4637 }
4638}
4639
4640
4641
4642
4643void
4645{
4648}
4649
4650
4651
4652
4653
4654
4655
4656bool
4658{
4660 const char *searchPath = *newval;
4661 char *rawname;
4662 List *namelist;
4664
4665
4666
4667
4668
4669
4670
4671
4672
4673
4674
4675
4676 if (use_cache)
4677 {
4679
4681
4683 return true;
4684 }
4685
4686
4687
4688
4689
4690 rawname = pstrdup(searchPath);
4691
4692
4694 {
4695
4699 return false;
4700 }
4703
4704
4705 if (use_cache)
4707
4708 return true;
4709}
4710
4711
4712void
4714{
4715
4717
4718
4719
4720
4721
4722
4723
4724
4725
4726
4728}
4729
4730
4731
4732
4733
4734
4735void
4737{
4739 {
4740
4741
4742
4743
4745
4757 }
4758 else
4759 {
4760
4761
4762
4763
4764
4765
4769
4770
4774
4775
4779
4780
4784
4785
4788 }
4789}
4790
4791
4792
4793
4794
4795static void
4797{
4798
4799
4800
4801
4802
4805}
4806
4807
4808
4809
4810
4811
4812
4813
4814
4815
4816
4817
4820{
4821 List *result;
4822
4824
4825
4826
4827
4828
4829
4830
4831
4833 {
4836 }
4837
4839 if (!includeImplicit)
4840 {
4843 }
4844
4845 return result;
4846}
4847
4848
4849
4850
4851
4852
4853
4854
4855
4856
4857
4858int
4860{
4861 int count = 0;
4863
4865
4867 {
4869
4871 continue;
4872
4873 if (count < sarray_len)
4874 sarray[count] = namespaceId;
4875 count++;
4876 }
4877
4878 return count;
4879}
4880
4881
4882
4883
4884
4885
4886
4887
4888
4889
4890
4891
4892
4895{
4897 bool result;
4898 bool is_missing = false;
4899
4901
4902 if (is_missing)
4905}
4906
4909{
4911 bool result;
4912 bool is_missing = false;
4913
4915
4916 if (is_missing)
4919}
4920
4923{
4925 bool result;
4926 bool is_missing = false;
4927
4929
4930 if (is_missing)
4933}
4934
4937{
4939 bool result;
4940 bool is_missing = false;
4941
4943
4944 if (is_missing)
4947}
4948
4951{
4953 bool result;
4954 bool is_missing = false;
4955
4957
4958 if (is_missing)
4961}
4962
4965{
4967 bool result;
4968 bool is_missing = false;
4969
4971
4972 if (is_missing)
4975}
4976
4979{
4981 bool result;
4982 bool is_missing = false;
4983
4985
4986 if (is_missing)
4989}
4990
4993{
4995 bool result;
4996 bool is_missing = false;
4997
4999
5000 if (is_missing)
5003}
5004
5007{
5009 bool result;
5010 bool is_missing = false;
5011
5013
5014 if (is_missing)
5017}
5018
5021{
5023 bool result;
5024 bool is_missing = false;
5025
5027
5028 if (is_missing)
5031}
5032
5035{
5037 bool result;
5038 bool is_missing = false;
5039
5041
5042 if (is_missing)
5045}
5046
5049{
5051 bool result;
5052 bool is_missing = false;
5053
5055
5056 if (is_missing)
5059}
5060
5063{
5065 bool result;
5066 bool is_missing = false;
5067
5069
5070 if (is_missing)
5073}
5074
5077{
5079}
5080
5083{
5085
5087}
void aclcheck_error(AclResult aclerr, ObjectType objtype, const char *objectname)
AclResult object_aclcheck(Oid classid, Oid objectid, Oid roleid, AclMode mode)
bool object_ownercheck(Oid classid, Oid objectid, Oid roleid)
#define DatumGetArrayTypeP(X)
#define InvalidSubTransactionId
#define OidIsValid(objectId)
char * get_database_name(Oid dbid)
void performDeletion(const ObjectAddress *object, DropBehavior behavior, int flags)
#define PERFORM_DELETION_SKIP_EXTENSIONS
#define PERFORM_DELETION_QUIETLY
#define PERFORM_DELETION_SKIP_ORIGINAL
#define PERFORM_DELETION_INTERNAL
int errcode(int sqlerrcode)
int errmsg(const char *fmt,...)
#define ereport(elevel,...)
bool is_encoding_supported_by_icu(int encoding)
bool equal(const void *a, const void *b)
#define PG_RETURN_BOOL(x)
int get_func_arg_info(HeapTuple procTup, Oid **p_argtypes, char ***p_argnames, char **p_argmodes)
#define GUC_check_errdetail
Assert(PointerIsAligned(start, uint64))
static size_t fasthash_accum_cstring(fasthash_state *hs, const char *str)
static uint32 fasthash_final32(fasthash_state *hs, uint64 tweak)
static void fasthash_combine(fasthash_state *hs)
static void fasthash_init(fasthash_state *hs, uint64 seed)
#define HeapTupleIsValid(tuple)
static void * GETSTRUCT(const HeapTupleData *tuple)
#define IsParallelWorker()
void AcceptInvalidationMessages(void)
void CacheRegisterSyscacheCallback(int cacheid, SyscacheCallbackFunction func, Datum arg)
void before_shmem_exit(pg_on_exit_callback function, Datum arg)
List * lcons_oid(Oid datum, List *list)
List * list_delete_first(List *list)
List * list_copy(const List *oldlist)
List * lappend_oid(List *list, Oid datum)
void list_free(List *list)
bool list_member_oid(const List *list, Oid datum)
bool ConditionalLockRelationOid(Oid relid, LOCKMODE lockmode)
void UnlockRelationOid(Oid relid, LOCKMODE lockmode)
void LockDatabaseObject(Oid classid, Oid objid, uint16 objsubid, LOCKMODE lockmode)
void LockRelationOid(Oid relid, LOCKMODE lockmode)
void UnlockDatabaseObject(Oid classid, Oid objid, uint16 objsubid, LOCKMODE lockmode)
char get_rel_relkind(Oid relid)
char * get_namespace_name(Oid nspid)
Oid get_relname_relid(const char *relname, Oid relnamespace)
RangeVar * makeRangeVar(char *schemaname, char *relname, int location)
int GetDatabaseEncoding(void)
const char * GetDatabaseEncodingName(void)
char * MemoryContextStrdup(MemoryContext context, const char *string)
void MemoryContextReset(MemoryContext context)
char * pstrdup(const char *in)
void pfree(void *pointer)
void * palloc0(Size size)
MemoryContext TopMemoryContext
#define AllocSetContextCreate
#define ALLOCSET_DEFAULT_SIZES
#define IsBootstrapProcessingMode()
static const SearchPathCacheEntry * cachedNamespacePath(const char *searchPath, Oid roleid)
Oid RangeVarGetAndCheckCreationNamespace(RangeVar *relation, LOCKMODE lockmode, Oid *existing_relation_id)
Oid OpclassnameGetOpcid(Oid amid, const char *opcname)
static bool CollationIsVisibleExt(Oid collid, bool *is_missing)
bool isTempOrTempToastNamespace(Oid namespaceId)
void ResetTempTableNamespace(void)
static bool baseTempCreationPending
Oid FindDefaultConversionProc(int32 for_encoding, int32 to_encoding)
Oid OpernameGetOprid(List *names, Oid oprleft, Oid oprright)
char * NameListToString(const List *names)
Oid LookupExplicitNamespace(const char *nspname, bool missing_ok)
static SearchPathCacheEntry * spcache_lookup(const char *searchPath, Oid roleid)
Datum pg_is_other_temp_schema(PG_FUNCTION_ARGS)
bool TSTemplateIsVisible(Oid tmplId)
Oid QualifiedNameGetCreationNamespace(const List *names, char **objname_p)
bool OpfamilyIsVisible(Oid opfid)
bool CollationIsVisible(Oid collid)
static Oid baseCreationNamespace
bool TypeIsVisible(Oid typid)
bool isOtherTempNamespace(Oid namespaceId)
static MemoryContext SearchPathCacheContext
static bool searchPathCacheValid
static Oid lookup_collation(const char *collname, Oid collnamespace, int32 encoding)
Oid CollationGetCollid(const char *collname)
void assign_search_path(const char *newval, void *extra)
static Oid activeCreationNamespace
bool isTempNamespace(Oid namespaceId)
bool isAnyTempNamespace(Oid namespaceId)
Datum pg_operator_is_visible(PG_FUNCTION_ARGS)
static List * activeSearchPath
bool ConversionIsVisible(Oid conid)
static bool baseSearchPathValid
static SubTransactionId myTempNamespaceSubID
Oid get_statistics_object_oid(List *names, bool missing_ok)
Oid LookupCreationNamespace(const char *nspname)
void RangeVarAdjustRelationPersistence(RangeVar *newRelation, Oid nspid)
static Oid myTempToastNamespace
Datum pg_collation_is_visible(PG_FUNCTION_ARGS)
Oid get_collation_oid(List *collname, bool missing_ok)
void DeconstructQualifiedName(const List *names, char **nspname_p, char **objname_p)
Datum pg_function_is_visible(PG_FUNCTION_ARGS)
Datum pg_type_is_visible(PG_FUNCTION_ARGS)
static bool OpclassIsVisibleExt(Oid opcid, bool *is_missing)
static bool RelationIsVisibleExt(Oid relid, bool *is_missing)
List * fetch_search_path(bool includeImplicit)
static bool FunctionIsVisibleExt(Oid funcid, bool *is_missing)
FuncCandidateList FuncnameGetCandidates(List *names, int nargs, List *argnames, bool expand_variadic, bool expand_defaults, bool include_out_arguments, bool missing_ok)
Datum pg_opclass_is_visible(PG_FUNCTION_ARGS)
Oid get_namespace_oid(const char *nspname, bool missing_ok)
static SearchPathCacheEntry * spcache_insert(const char *searchPath, Oid roleid)
SearchPathMatcher * GetSearchPathMatcher(MemoryContext context)
Oid TypenameGetTypidExtended(const char *typname, bool temp_ok)
static bool TSDictionaryIsVisibleExt(Oid dictId, bool *is_missing)
char * NameListToQuotedString(const List *names)
Oid RangeVarGetCreationNamespace(const RangeVar *newRelation)
bool RelationIsVisible(Oid relid)
static List * preprocessNamespacePath(const char *searchPath, Oid roleid, bool *temp_missing)
Datum pg_ts_config_is_visible(PG_FUNCTION_ARGS)
static void spcache_init(void)
Datum pg_opfamily_is_visible(PG_FUNCTION_ARGS)
bool OpclassIsVisible(Oid opcid)
Oid ConversionGetConid(const char *conname)
void AtEOSubXact_Namespace(bool isCommit, SubTransactionId mySubid, SubTransactionId parentSubid)
static List * finalNamespacePath(List *oidlist, Oid *firstNS)
TempNamespaceStatus checkTempNamespaceStatus(Oid namespaceId)
Datum pg_conversion_is_visible(PG_FUNCTION_ARGS)
void CheckSetNamespace(Oid oldNspOid, Oid nspOid)
static SearchPathCacheEntry * LastSearchPathCacheEntry
void GetTempNamespaceState(Oid *tempNamespaceId, Oid *tempToastNamespaceId)
void InitializeSearchPath(void)
static bool TSParserIsVisibleExt(Oid prsId, bool *is_missing)
static bool StatisticsObjIsVisibleExt(Oid stxid, bool *is_missing)
bool OperatorIsVisible(Oid oprid)
static bool TSTemplateIsVisibleExt(Oid tmplId, bool *is_missing)
char * namespace_search_path
bool TSParserIsVisible(Oid prsId)
static void RemoveTempRelations(Oid tempNamespaceId)
static void recomputeNamespacePath(void)
static Oid myTempNamespace
#define SPCACHE_RESET_THRESHOLD
bool SearchPathMatchesCurrentEnvironment(SearchPathMatcher *path)
Datum pg_statistics_obj_is_visible(PG_FUNCTION_ARGS)
static nsphash_hash * SearchPathCache
static bool MatchNamedCall(HeapTuple proctup, int nargs, List *argnames, bool include_out_arguments, int pronargs, int **argnumbers)
static bool ConversionIsVisibleExt(Oid conid, bool *is_missing)
static bool activeTempCreationPending
Oid get_conversion_oid(List *conname, bool missing_ok)
static void InitTempTableNamespace(void)
bool FunctionIsVisible(Oid funcid)
Oid get_ts_dict_oid(List *names, bool missing_ok)
static bool OperatorIsVisibleExt(Oid oprid, bool *is_missing)
Oid get_ts_parser_oid(List *names, bool missing_ok)
Datum pg_ts_template_is_visible(PG_FUNCTION_ARGS)
static bool TSConfigIsVisibleExt(Oid cfgid, bool *is_missing)
static bool TypeIsVisibleExt(Oid typid, bool *is_missing)
SearchPathMatcher * CopySearchPathMatcher(SearchPathMatcher *path)
static void AccessTempTableNamespace(bool force)
void SetTempNamespaceState(Oid tempNamespaceId, Oid tempToastNamespaceId)
static void InvalidationCallback(Datum arg, int cacheid, uint32 hashvalue)
Oid GetTempToastNamespace(void)
static bool OpfamilyIsVisibleExt(Oid opfid, bool *is_missing)
Oid OpfamilynameGetOpfid(Oid amid, const char *opfname)
RangeVar * makeRangeVarFromNameList(const List *names)
void AtEOXact_Namespace(bool isCommit, bool parallel)
Oid get_ts_config_oid(List *names, bool missing_ok)
static bool spcachekey_equal(SearchPathCacheKey a, SearchPathCacheKey b)
FuncCandidateList OpernameGetCandidates(List *names, char oprkind, bool missing_schema_ok)
bool check_search_path(char **newval, void **extra, GucSource source)
Oid LookupNamespaceNoError(const char *nspname)
struct SearchPathCacheKey SearchPathCacheKey
ProcNumber GetTempNamespaceProcNumber(Oid namespaceId)
static void RemoveTempRelationsCallback(int code, Datum arg)
Oid TypenameGetTypid(const char *typname)
int fetch_search_path_array(Oid *sarray, int sarray_len)
Oid RangeVarGetRelidExtended(const RangeVar *relation, LOCKMODE lockmode, uint32 flags, RangeVarGetRelidCallback callback, void *callback_arg)
struct SearchPathCacheEntry SearchPathCacheEntry
static uint32 spcachekey_hash(SearchPathCacheKey key)
static uint64 activePathGeneration
bool TSConfigIsVisible(Oid cfgid)
bool StatisticsObjIsVisible(Oid stxid)
Datum pg_ts_dict_is_visible(PG_FUNCTION_ARGS)
Oid RelnameGetRelid(const char *relname)
static List * baseSearchPath
Datum pg_my_temp_schema(PG_FUNCTION_ARGS)
Datum pg_ts_parser_is_visible(PG_FUNCTION_ARGS)
bool TSDictionaryIsVisible(Oid dictId)
Datum pg_table_is_visible(PG_FUNCTION_ARGS)
bool isTempToastNamespace(Oid namespaceId)
Oid get_ts_template_oid(List *names, bool missing_ok)
void(* RangeVarGetRelidCallback)(const RangeVar *relation, Oid relId, Oid oldRelId, void *callback_arg)
@ TEMP_NAMESPACE_NOT_TEMP
struct _FuncCandidateList * FuncCandidateList
#define IsA(nodeptr, _type_)
object_access_hook_type object_access_hook
#define InvokeNamespaceSearchHook(objectId, ereport_on_violation)
ObjectType get_relkind_objtype(char relkind)
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
FormData_pg_authid * Form_pg_authid
FormData_pg_class * Form_pg_class
FormData_pg_collation * Form_pg_collation
Oid FindDefaultConversion(Oid name_space, int32 for_encoding, int32 to_encoding)
FormData_pg_conversion * Form_pg_conversion
static int list_length(const List *l)
#define list_make1_oid(x1)
static ListCell * list_head(const List *l)
static ListCell * lnext(const List *l, const ListCell *c)
Oid NamespaceCreate(const char *nspName, Oid ownerId, bool isTemp)
FormData_pg_opclass * Form_pg_opclass
FormData_pg_operator * Form_pg_operator
FormData_pg_opfamily * Form_pg_opfamily
FormData_pg_proc * Form_pg_proc
static rewind_source * source
FormData_pg_statistic_ext * Form_pg_statistic_ext
FormData_pg_ts_config * Form_pg_ts_config
FormData_pg_ts_dict * Form_pg_ts_dict
FormData_pg_ts_parser * Form_pg_ts_parser
FormData_pg_ts_template * Form_pg_ts_template
FormData_pg_type * Form_pg_type
#define ERRCODE_UNDEFINED_TABLE
static Datum PointerGetDatum(const void *X)
static Datum ObjectIdGetDatum(Oid X)
static Datum CStringGetDatum(const char *X)
static Datum Int32GetDatum(int32 X)
PGPROC * ProcNumberGetProc(ProcNumber procNumber)
#define INVALID_PROC_NUMBER
const char * quote_identifier(const char *ident)
uint64 SharedInvalidMessageCounter
Snapshot GetTransactionSnapshot(void)
void PushActiveSnapshot(Snapshot snapshot)
void PopActiveSnapshot(void)
void appendStringInfoString(StringInfo str, const char *s)
void appendStringInfoChar(StringInfo str, char ch)
void initStringInfo(StringInfo str)
struct _FuncCandidateList * next
Oid args[FLEXIBLE_ARRAY_MEMBER]
CatCTup * members[FLEXIBLE_ARRAY_MEMBER]
void ReleaseSysCache(HeapTuple tuple)
HeapTuple SearchSysCache1(int cacheId, Datum key1)
HeapTuple SearchSysCache3(int cacheId, Datum key1, Datum key2, Datum key3)
Datum SysCacheGetAttr(int cacheId, HeapTuple tup, AttrNumber attributeNumber, bool *isNull)
HeapTuple SearchSysCache4(int cacheId, Datum key1, Datum key2, Datum key3, Datum key4)
#define SearchSysCacheList3(cacheId, key1, key2, key3)
#define ReleaseSysCacheList(x)
#define SearchSysCacheExists2(cacheId, key1, key2)
#define SearchSysCacheList1(cacheId, key1)
#define GetSysCacheOid3(cacheId, oidcol, key1, key2, key3)
#define GetSysCacheOid1(cacheId, oidcol, key1)
#define GetSysCacheOid2(cacheId, oidcol, key1, key2)
static void callback(struct sockaddr *addr, struct sockaddr *mask, void *unused)
String * makeString(char *str)
bool SplitIdentifierString(char *rawstring, char separator, List **namelist)
SubTransactionId GetCurrentSubTransactionId(void)
void CommandCounterIncrement(void)
void StartTransactionCommand(void)
void CommitTransactionCommand(void)
void AbortOutOfAnyTransaction(void)
#define XACT_FLAGS_ACCESSEDTEMPNAMESPACE
bool RecoveryInProgress(void)