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
62
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
136
137
139
140
142
143
145
146
147
149
151
153
155
156
158
159
160
161
162
165
167{
171
173{
180
181
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
201
203
205
206
207
208
209
211
212
213
234 bool include_out_arguments, int pronargs,
235 int **argnumbers, int *fgc_flags);
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
254{
256 int sp_len;
257
259
262
263
264
265
266
268
270}
271
272static inline bool
274{
275 return a.roleid == b.roleid &&
276 strcmp(a.searchPath, b.searchPath) == 0;
277}
278
279#define SH_PREFIX nsphash
280#define SH_ELEMENT_TYPE SearchPathCacheEntry
281#define SH_KEY_TYPE SearchPathCacheKey
282#define SH_KEY key
283#define SH_HASH_KEY(tb, key) spcachekey_hash(key)
284#define SH_EQUAL(tb, a, b) spcachekey_equal(a, b)
285#define SH_SCOPE static inline
286#define SH_DECLARE
287#define SH_DEFINE
289
290
291
292
293
294
295
296#define SPCACHE_RESET_THRESHOLD 256
297
300
301
302
303
304static void
306{
309 return;
310
313
314
315
316
317
320
322 {
323
325 "search_path processing cache",
327 }
328 else
329 {
331 }
332
333
336}
337
338
339
340
341
344{
348 {
350 }
351 else
352 {
356 .roleid = roleid
357 };
358
360 if (entry)
362 return entry;
363 }
364}
365
366
367
368
369
370
371
374{
378 {
380 }
381 else
382 {
386 .roleid = roleid
387 };
388
389
390
391
392
394
395 if (!entry)
396 {
397 bool found;
398
400 entry = nsphash_insert(SearchPathCache, cachekey, &found);
402
408
409 }
410
412 return entry;
413 }
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
443{
445 Oid relId;
447 bool retry = false;
449
450
452
453
454
455
457 {
460 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
461 errmsg("cross-database references are not implemented: \"%s.%s.%s\"",
464 }
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482 for (;;)
483 {
484
485
486
487
488
490
491
492
493
494
495
496
497
498
500 {
502 relId = InvalidOid;
503 else
504 {
506 {
507 Oid namespaceId;
508
510
511
512
513
514
517 (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
518 errmsg("temporary tables cannot specify a schema name")));
519 }
520
522 }
523 }
525 {
526 Oid namespaceId;
527
528
530 if (missing_ok && (namespaceId))
532 else
534 }
535 else
536 {
537
539 }
540
541
542
543
544
545
546
547
548
549
550
552 callback(relation, relId, oldRelId, callback_arg);
553
554
555
556
557
558
559
560
561 if (lockmode == NoLock)
562 break;
563
564
565
566
567
568
569
570
571
572
573 if (retry)
574 {
575 if (relId == oldRelId)
576 break;
579 }
580
581
582
583
584
585
586
587
593 {
595
598 (errcode(ERRCODE_LOCK_NOT_AVAILABLE),
599 errmsg("could not obtain lock on relation \"%s.%s\"",
601 else
603 (errcode(ERRCODE_LOCK_NOT_AVAILABLE),
604 errmsg("could not obtain lock on relation \"%s\"",
606
608 }
609
610
611
612
614 break;
615
616
617
618
619
620
621 retry = true;
622 oldRelId = relId;
623 }
624
626 {
627 int elevel = missing_ok ? DEBUG1 : ERROR;
628
632 errmsg("relation \"%s.%s\" does not exist",
634 else
637 errmsg("relation \"%s\" does not exist",
639 }
640 return relId;
641}
642
643
644
645
646
647
648
649
650
651
654{
655 Oid namespaceId;
656
657
658
659
661 {
664 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
665 errmsg("cross-database references are not implemented: \"%s.%s.%s\"",
668 }
669
671 {
672
673 if (strcmp(newRelation->schemaname, "pg_temp") == 0)
674 {
675
678 }
679
681
682 }
683 else if (newRelation->relpersistence == RELPERSISTENCE_TEMP)
684 {
685
688 }
689 else
690 {
691
694 {
695
698 }
702 (errcode(ERRCODE_UNDEFINED_SCHEMA),
703 errmsg("no schema has been selected to create in")));
704 }
705
706
707
708 return namespaceId;
709}
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
740 Oid *existing_relation_id)
741{
743 Oid relid;
747 bool retry = false;
748
749
750
751
753 {
756 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
757 errmsg("cross-database references are not implemented: \"%s.%s.%s\"",
760 }
761
762
763
764
765
766
767
768 for (;;)
769 {
771
773
774
777 if (existing_relation_id != NULL)
779 else
781
782
783
784
785
786
788 break;
789
790
795
796 if (retry)
797 {
798
799 if (relid == oldrelid && nspid == oldnspid)
800 break;
801
802 if (nspid != oldnspid)
805
806 if (relid != oldrelid && OidIsValid(oldrelid) && lockmode != NoLock)
808 }
809
810
811 if (nspid != oldnspid)
813
814
816 {
820 if (relid != oldrelid)
822 }
823
824
826 break;
827
828
829 retry = true;
830 oldrelid = relid;
831 oldnspid = nspid;
832 }
833
835 if (existing_relation_id != NULL)
836 *existing_relation_id = relid;
838}
839
840
841
842
843
844void
846{
848 {
849 case RELPERSISTENCE_TEMP:
851 {
854 (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
855 errmsg("cannot create relations in temporary schemas of other sessions")));
856 else
858 (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
859 errmsg("cannot create temporary relation in non-temporary schema")));
860 }
861 break;
862 case RELPERSISTENCE_PERMANENT:
867 (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
868 errmsg("cannot create relations in temporary schemas of other sessions")));
869 break;
870 default:
873 (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
874 errmsg("only temporary relations may be created in temporary schemas")));
875 }
876}
877
878
879
880
881
882
885{
886 Oid relid;
888
890
892 {
894
897 return relid;
898 }
899
900
902}
903
904
905
906
907
908
909
910
911bool
913{
915}
916
917
918
919
920
921
922
923static bool
925{
928 Oid relnamespace;
929 bool visible;
930
933 {
934 if (is_missing != NULL)
935 {
936 *is_missing = true;
937 return false;
938 }
939 elog(ERROR, "cache lookup failed for relation %u", relid);
940 }
942
944
945
946
947
948
949
950 relnamespace = relform->relnamespace;
951 if (relnamespace != PG_CATALOG_NAMESPACE &&
953 visible = false;
954 else
955 {
956
957
958
959
960
963
964 visible = false;
966 {
968
969 if (namespaceId == relnamespace)
970 {
971
972 visible = true;
973 break;
974 }
976 {
977
978 break;
979 }
980 }
981 }
982
984
985 return visible;
986}
987
988
989
990
991
992
995{
997}
998
999
1000
1001
1002
1003
1004
1005
1008{
1009 Oid typid;
1011
1013
1015 {
1017
1019 continue;
1020
1025 return typid;
1026 }
1027
1028
1030}
1031
1032
1033
1034
1035
1036
1037
1038bool
1040{
1042}
1043
1044
1045
1046
1047
1048
1049
1050static bool
1052{
1055 Oid typnamespace;
1056 bool visible;
1057
1060 {
1061 if (is_missing != NULL)
1062 {
1063 *is_missing = true;
1064 return false;
1065 }
1066 elog(ERROR, "cache lookup failed for type %u", typid);
1067 }
1069
1071
1072
1073
1074
1075
1076
1077 typnamespace = typform->typnamespace;
1078 if (typnamespace != PG_CATALOG_NAMESPACE &&
1080 visible = false;
1081 else
1082 {
1083
1084
1085
1086
1087
1090
1091 visible = false;
1093 {
1095
1096 if (namespaceId == typnamespace)
1097 {
1098
1099 visible = true;
1100 break;
1101 }
1105 {
1106
1107 break;
1108 }
1109 }
1110 }
1111
1113
1114 return visible;
1115}
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
1191
1192
1193
1194
1195
1198 bool expand_variadic, bool expand_defaults,
1199 bool include_out_arguments, bool missing_ok,
1200 int *fgc_flags)
1201{
1203 bool any_special = false;
1204 char *schemaname;
1206 Oid namespaceId;
1208 int i;
1209
1210
1211 Assert(nargs >= 0 || !(expand_variadic | expand_defaults));
1212
1213
1214 *fgc_flags = 0;
1215
1216
1218
1219 if (schemaname)
1220 {
1221
1222 *fgc_flags |= FGC_SCHEMA_GIVEN;
1225 return NULL;
1226 *fgc_flags |= FGC_SCHEMA_EXISTS;
1227 }
1228 else
1229 {
1230
1233 }
1234
1235
1237
1239 {
1242 Oid *proargtypes = procform->proargtypes.values;
1243 int pronargs = procform->pronargs;
1244 int effective_nargs;
1245 int pathpos = 0;
1246 bool variadic;
1247 bool use_defaults;
1248 Oid va_elem_type;
1249 int *argnumbers = NULL;
1251
1252 *fgc_flags |= FGC_NAME_EXISTS;
1253
1255 {
1256
1257 if (procform->pronamespace != namespaceId)
1258 continue;
1259 }
1260 else
1261 {
1262
1263
1264
1265
1267
1269 {
1270 if (procform->pronamespace == lfirst_oid(nsp) &&
1272 break;
1273 pathpos++;
1274 }
1275 if (nsp == NULL)
1276 continue;
1277 }
1278
1279 *fgc_flags |= FGC_NAME_VISIBLE;
1280
1281
1282
1283
1284
1285
1286
1287 if (include_out_arguments)
1288 {
1289 Datum proallargtypes;
1290 bool isNull;
1291
1292 proallargtypes = SysCacheGetAttr(PROCNAMEARGSNSP, proctup,
1293 Anum_pg_proc_proallargtypes,
1294 &isNull);
1295 if (!isNull)
1296 {
1298
1304 elog(ERROR, "proallargtypes is not a 1-D Oid array or it contains nulls");
1307 }
1308 }
1309
1310 if (argnames != NIL)
1311 {
1312
1313
1314
1315
1316
1317 Assert(nargs >= 0);
1318
1319 if (pronargs > nargs && expand_defaults)
1320 {
1321
1322 if (nargs + procform->pronargdefaults < pronargs)
1323 continue;
1324 use_defaults = true;
1325 }
1326 else
1327 use_defaults = false;
1328
1329
1330 if (pronargs != nargs && !use_defaults)
1331 continue;
1332
1333
1335
1336
1338 include_out_arguments, pronargs,
1339 &argnumbers, fgc_flags))
1340 continue;
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352 if (OidIsValid(procform->provariadic) && expand_variadic)
1353 continue;
1355 variadic = false;
1356
1357
1359
1360
1361 any_special = true;
1362 }
1363 else
1364 {
1365
1366
1367
1368
1369
1370
1371
1372 if (pronargs <= nargs && expand_variadic)
1373 {
1374 va_elem_type = procform->provariadic;
1375 variadic = OidIsValid(va_elem_type);
1376 any_special |= variadic;
1377 }
1378 else
1379 {
1381 variadic = false;
1382 }
1383
1384
1385
1386
1387 if (pronargs > nargs && expand_defaults)
1388 {
1389
1390 if (nargs + procform->pronargdefaults < pronargs)
1391 continue;
1392 use_defaults = true;
1393 any_special = true;
1394 }
1395 else
1396 use_defaults = false;
1397
1398
1399 if (nargs >= 0 && pronargs != nargs && !variadic && !use_defaults)
1400 continue;
1401
1402
1404 }
1405
1406
1407
1408
1409
1410
1411
1415 effective_nargs * sizeof(Oid));
1416 newResult->pathpos = pathpos;
1417 newResult->oid = procform->oid;
1419 newResult->nargs = effective_nargs;
1421 if (argnumbers)
1422 {
1423
1425 newResult->args[j] = proargtypes[argnumbers[j]];
1426 }
1427 else
1428 {
1429
1430 memcpy(newResult->args, proargtypes, pronargs * sizeof(Oid));
1431 }
1432 if (variadic)
1433 {
1435
1436 for (int j = pronargs - 1; j < effective_nargs; j++)
1437 newResult->args[j] = va_elem_type;
1438 }
1439 else
1440 newResult->nvargs = 0;
1441 newResult->ndargs = use_defaults ? pronargs - nargs : 0;
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451 if (resultList != NULL &&
1452 (any_special || (namespaceId)))
1453 {
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1466
1467 if (catlist->ordered && !any_special)
1468 {
1469
1470 if (effective_nargs == resultList->nargs &&
1471 memcmp(newResult->args,
1472 resultList->args,
1473 effective_nargs * sizeof(Oid)) == 0)
1474 prevResult = resultList;
1475 else
1476 prevResult = NULL;
1477 }
1478 else
1479 {
1480 int cmp_nargs = newResult->nargs - newResult->ndargs;
1481
1482 for (prevResult = resultList;
1483 prevResult;
1484 prevResult = prevResult->next)
1485 {
1486 if (cmp_nargs == prevResult->nargs - prevResult->ndargs &&
1487 memcmp(newResult->args,
1488 prevResult->args,
1489 cmp_nargs * sizeof(Oid)) == 0)
1490 break;
1491 }
1492 }
1493
1494 if (prevResult)
1495 {
1496
1497
1498
1499
1500
1501
1502
1503 int preference;
1504
1505 if (pathpos != prevResult->pathpos)
1506 {
1507
1508
1509
1510 preference = pathpos - prevResult->pathpos;
1511 }
1512 else if (variadic && prevResult->nvargs == 0)
1513 {
1514
1515
1516
1517
1518
1519
1520 preference = 1;
1521 }
1522 else if (!variadic && prevResult->nvargs > 0)
1523 {
1524 preference = -1;
1525 }
1526 else
1527 {
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537 preference = 0;
1538 }
1539
1540 if (preference > 0)
1541 {
1542
1543 pfree(newResult);
1544 continue;
1545 }
1546 else if (preference < 0)
1547 {
1548
1549 if (prevResult == resultList)
1550 resultList = prevResult->next;
1551 else
1552 {
1554
1555 for (prevPrevResult = resultList;
1556 prevPrevResult;
1557 prevPrevResult = prevPrevResult->next)
1558 {
1559 if (prevResult == prevPrevResult->next)
1560 {
1561 prevPrevResult->next = prevResult->next;
1562 break;
1563 }
1564 }
1565 Assert(prevPrevResult);
1566 }
1567 pfree(prevResult);
1568
1569 }
1570 else
1571 {
1572
1574 pfree(newResult);
1575 continue;
1576 }
1577 }
1578 }
1579
1580
1581
1582
1583 newResult->next = resultList;
1584 resultList = newResult;
1585 }
1586
1588
1589 return resultList;
1590}
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615static bool
1617 bool include_out_arguments, int pronargs,
1618 int **argnumbers, int *fgc_flags)
1619{
1621 int numposargs = nargs - list_length(argnames);
1622 int pronallargs;
1623 Oid *p_argtypes;
1624 char **p_argnames;
1625 char *p_argmodes;
1627 bool arg_filled_twice = false;
1628 bool isnull;
1629 int ap;
1630 int pp;
1632
1634 Assert(numposargs >= 0);
1636
1637
1638 (void) SysCacheGetAttr(PROCOID, proctup, Anum_pg_proc_proargnames,
1639 &isnull);
1640 if (isnull)
1641 return false;
1642
1643
1645 &p_argtypes, &p_argnames, &p_argmodes);
1646 Assert(p_argnames != NULL);
1647
1648 Assert(include_out_arguments ? (pronargs == pronallargs) : (pronargs <= pronallargs));
1649
1650
1651 *argnumbers = (int *) palloc(pronargs * sizeof(int));
1652 memset(arggiven, false, pronargs * sizeof(bool));
1653
1654
1655 for (ap = 0; ap < numposargs; ap++)
1656 {
1657 (*argnumbers)[ap] = ap;
1658 arggiven[ap] = true;
1659 }
1660
1661
1662 foreach(lc, argnames)
1663 {
1664 char *argname = (char *) lfirst(lc);
1665 bool found;
1666 int i;
1667
1668 pp = 0;
1669 found = false;
1670 for (i = 0; i < pronallargs; i++)
1671 {
1672
1673 if (!include_out_arguments &&
1674 p_argmodes &&
1678 continue;
1679 if (p_argnames[i] && strcmp(p_argnames[i], argname) == 0)
1680 {
1681
1682 if (arggiven[pp])
1683 arg_filled_twice = true;
1684 arggiven[pp] = true;
1685 (*argnumbers)[ap] = pp;
1686 found = true;
1687 break;
1688 }
1689
1690 pp++;
1691 }
1692
1693 if (!found)
1694 return false;
1695 ap++;
1696 }
1697
1698 Assert(ap == nargs);
1699
1700
1702
1703
1704 if (arg_filled_twice)
1705 return false;
1706
1707
1709
1710
1712 {
1713 int first_arg_with_default = pronargs - procform->pronargdefaults;
1714
1715 for (pp = numposargs; pp < pronargs; pp++)
1716 {
1717 if (arggiven[pp])
1718 continue;
1719
1720 if (pp < first_arg_with_default)
1721 return false;
1722 (*argnumbers)[ap++] = pp;
1723 }
1724 }
1725
1727
1728
1730
1731 return true;
1732}
1733
1734
1735
1736
1737
1738
1739
1740bool
1742{
1744}
1745
1746
1747
1748
1749
1750
1751
1752static bool
1754{
1757 Oid pronamespace;
1758 bool visible;
1759
1762 {
1763 if (is_missing != NULL)
1764 {
1765 *is_missing = true;
1766 return false;
1767 }
1768 elog(ERROR, "cache lookup failed for function %u", funcid);
1769 }
1771
1773
1774
1775
1776
1777
1778
1779 pronamespace = procform->pronamespace;
1780 if (pronamespace != PG_CATALOG_NAMESPACE &&
1782 visible = false;
1783 else
1784 {
1785
1786
1787
1788
1789
1790
1792 int nargs = procform->pronargs;
1794 int fgc_flags;
1795
1796 visible = false;
1797
1799 nargs, NIL, false, false, false, false,
1800 &fgc_flags);
1801
1802 for (; clist; clist = clist->next)
1803 {
1804 if (memcmp(clist->args, procform->proargtypes.values,
1805 nargs * sizeof(Oid)) == 0)
1806 {
1807
1808 visible = (clist->oid == funcid);
1809 break;
1810 }
1811 }
1812 }
1813
1815
1816 return visible;
1817}
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1833{
1834 char *schemaname;
1835 char *opername;
1838
1839
1841
1842 if (schemaname)
1843 {
1844
1845 Oid namespaceId;
1846
1849 {
1851
1858 {
1860 Oid result = operclass->oid;
1861
1863 return result;
1864 }
1865 }
1866
1868 }
1869
1870
1875
1877 {
1878
1881 }
1882
1883
1884
1885
1886
1887
1889
1891 {
1893 int i;
1894
1896 continue;
1897
1899 {
1902
1903 if (operform->oprnamespace == namespaceId)
1904 {
1905 Oid result = operform->oid;
1906
1908 return result;
1909 }
1910 }
1911 }
1912
1915}
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1946 int *fgc_flags)
1947{
1949 char *resultSpace = NULL;
1950 int nextResult = 0;
1951 char *schemaname;
1952 char *opername;
1953 Oid namespaceId;
1955 int i;
1956
1957
1958 *fgc_flags = 0;
1959
1960
1962
1963 if (schemaname)
1964 {
1965
1966 *fgc_flags |= FGC_SCHEMA_GIVEN;
1969 return NULL;
1970 *fgc_flags |= FGC_SCHEMA_EXISTS;
1971 }
1972 else
1973 {
1974
1977 }
1978
1979
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991#define SPACE_PER_OP MAXALIGN(offsetof(struct _FuncCandidateList, args) + \
1992 2 * sizeof(Oid))
1993
1996
1998 {
2001 int pathpos = 0;
2003
2004
2005 if (oprkind && operform->oprkind != oprkind)
2006 continue;
2007
2008 *fgc_flags |= FGC_NAME_EXISTS;
2009
2011 {
2012
2013 if (operform->oprnamespace != namespaceId)
2014 continue;
2015
2016 }
2017 else
2018 {
2019
2020
2021
2022
2024
2026 {
2027 if (operform->oprnamespace == lfirst_oid(nsp) &&
2029 break;
2030 pathpos++;
2031 }
2032 if (nsp == NULL)
2033 continue;
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046 if (resultList)
2047 {
2049
2051 {
2052 if (operform->oprleft == resultList->args[0] &&
2053 operform->oprright == resultList->args[1])
2054 prevResult = resultList;
2055 else
2056 prevResult = NULL;
2057 }
2058 else
2059 {
2060 for (prevResult = resultList;
2061 prevResult;
2062 prevResult = prevResult->next)
2063 {
2064 if (operform->oprleft == prevResult->args[0] &&
2065 operform->oprright == prevResult->args[1])
2066 break;
2067 }
2068 }
2069 if (prevResult)
2070 {
2071
2073 if (pathpos > prevResult->pathpos)
2074 continue;
2075
2076 prevResult->pathpos = pathpos;
2077 prevResult->oid = operform->oid;
2078 continue;
2079 }
2080 }
2081 }
2082
2083 *fgc_flags |= FGC_NAME_VISIBLE;
2084
2085
2086
2087
2090
2091 newResult->pathpos = pathpos;
2092 newResult->oid = operform->oid;
2094 newResult->nargs = 2;
2095 newResult->nvargs = 0;
2096 newResult->ndargs = 0;
2098 newResult->args[0] = operform->oprleft;
2099 newResult->args[1] = operform->oprright;
2100 newResult->next = resultList;
2101 resultList = newResult;
2102 }
2103
2105
2106 return resultList;
2107}
2108
2109
2110
2111
2112
2113
2114
2115bool
2117{
2119}
2120
2121
2122
2123
2124
2125
2126
2127static bool
2129{
2132 Oid oprnamespace;
2133 bool visible;
2134
2137 {
2138 if (is_missing != NULL)
2139 {
2140 *is_missing = true;
2141 return false;
2142 }
2143 elog(ERROR, "cache lookup failed for operator %u", oprid);
2144 }
2146
2148
2149
2150
2151
2152
2153
2154 oprnamespace = oprform->oprnamespace;
2155 if (oprnamespace != PG_CATALOG_NAMESPACE &&
2157 visible = false;
2158 else
2159 {
2160
2161
2162
2163
2164
2165
2166 char *oprname = NameStr(oprform->oprname);
2167
2169 oprform->oprleft, oprform->oprright)
2171 }
2172
2174
2175 return visible;
2176}
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2189{
2190 Oid opcid;
2192
2194
2196 {
2198
2200 continue;
2201
2202 opcid = GetSysCacheOid3(CLAAMNAMENSP, Anum_pg_opclass_oid,
2207 return opcid;
2208 }
2209
2210
2212}
2213
2214
2215
2216
2217
2218
2219
2220bool
2222{
2224}
2225
2226
2227
2228
2229
2230
2231
2232static bool
2234{
2237 Oid opcnamespace;
2238 bool visible;
2239
2242 {
2243 if (is_missing != NULL)
2244 {
2245 *is_missing = true;
2246 return false;
2247 }
2248 elog(ERROR, "cache lookup failed for opclass %u", opcid);
2249 }
2251
2253
2254
2255
2256
2257
2258
2259 opcnamespace = opcform->opcnamespace;
2260 if (opcnamespace != PG_CATALOG_NAMESPACE &&
2262 visible = false;
2263 else
2264 {
2265
2266
2267
2268
2269
2270
2271 char *opcname = NameStr(opcform->opcname);
2272
2274 }
2275
2277
2278 return visible;
2279}
2280
2281
2282
2283
2284
2285
2286
2287
2288
2291{
2292 Oid opfid;
2294
2296
2298 {
2300
2302 continue;
2303
2304 opfid = GetSysCacheOid3(OPFAMILYAMNAMENSP, Anum_pg_opfamily_oid,
2309 return opfid;
2310 }
2311
2312
2314}
2315
2316
2317
2318
2319
2320
2321
2322bool
2324{
2326}
2327
2328
2329
2330
2331
2332
2333
2334static bool
2336{
2339 Oid opfnamespace;
2340 bool visible;
2341
2344 {
2345 if (is_missing != NULL)
2346 {
2347 *is_missing = true;
2348 return false;
2349 }
2350 elog(ERROR, "cache lookup failed for opfamily %u", opfid);
2351 }
2353
2355
2356
2357
2358
2359
2360
2361 opfnamespace = opfform->opfnamespace;
2362 if (opfnamespace != PG_CATALOG_NAMESPACE &&
2364 visible = false;
2365 else
2366 {
2367
2368
2369
2370
2371
2372
2373 char *opfname = NameStr(opfform->opfname);
2374
2376 }
2377
2379
2380 return visible;
2381}
2382
2383
2384
2385
2386
2387
2388static Oid
2390{
2394
2395
2402
2403
2404
2405
2406
2407
2408
2416 if (collform->collprovider == COLLPROVIDER_ICU)
2417 {
2419 collid = collform->oid;
2420 else
2422 }
2423 else
2424 {
2425 collid = collform->oid;
2426 }
2429}
2430
2431
2432
2433
2434
2435
2436
2437
2438
2441{
2444
2446
2448 {
2451
2453 continue;
2454
2458 }
2459
2460
2462}
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473bool
2475{
2477}
2478
2479
2480
2481
2482
2483
2484
2485static bool
2487{
2490 Oid collnamespace;
2491 bool visible;
2492
2495 {
2496 if (is_missing != NULL)
2497 {
2498 *is_missing = true;
2499 return false;
2500 }
2501 elog(ERROR, "cache lookup failed for collation %u", collid);
2502 }
2504
2506
2507
2508
2509
2510
2511
2512 collnamespace = collform->collnamespace;
2513 if (collnamespace != PG_CATALOG_NAMESPACE &&
2515 visible = false;
2516 else
2517 {
2518
2519
2520
2521
2522
2523
2524
2525 char *collname = NameStr(collform->collname);
2526
2528 }
2529
2531
2532 return visible;
2533}
2534
2535
2536
2537
2538
2539
2540
2541
2542
2545{
2546 Oid conid;
2548
2550
2552 {
2554
2556 continue;
2557
2558 conid = GetSysCacheOid2(CONNAMENSP, Anum_pg_conversion_oid,
2562 return conid;
2563 }
2564
2565
2567}
2568
2569
2570
2571
2572
2573
2574
2575bool
2577{
2579}
2580
2581
2582
2583
2584
2585
2586
2587static bool
2589{
2592 Oid connamespace;
2593 bool visible;
2594
2597 {
2598 if (is_missing != NULL)
2599 {
2600 *is_missing = true;
2601 return false;
2602 }
2603 elog(ERROR, "cache lookup failed for conversion %u", conid);
2604 }
2606
2608
2609
2610
2611
2612
2613
2614 connamespace = conform->connamespace;
2615 if (connamespace != PG_CATALOG_NAMESPACE &&
2617 visible = false;
2618 else
2619 {
2620
2621
2622
2623
2624
2625
2626 char *conname = NameStr(conform->conname);
2627
2629 }
2630
2632
2633 return visible;
2634}
2635
2636
2637
2638
2639
2640
2643{
2644 char *schemaname;
2645 char *stats_name;
2646 Oid namespaceId;
2649
2650
2652
2653 if (schemaname)
2654 {
2655
2657 if (missing_ok && (namespaceId))
2659 else
2660 stats_oid = GetSysCacheOid2(STATEXTNAMENSP, Anum_pg_statistic_ext_oid,
2663 }
2664 else
2665 {
2666
2668
2670 {
2672
2674 continue;
2675 stats_oid = GetSysCacheOid2(STATEXTNAMENSP, Anum_pg_statistic_ext_oid,
2679 break;
2680 }
2681 }
2682
2683 if ((stats_oid) && !missing_ok)
2685 (errcode(ERRCODE_UNDEFINED_OBJECT),
2686 errmsg("statistics object \"%s\" does not exist",
2688
2689 return stats_oid;
2690}
2691
2692
2693
2694
2695
2696
2697
2698bool
2700{
2702}
2703
2704
2705
2706
2707
2708
2709
2710static bool
2712{
2715 Oid stxnamespace;
2716 bool visible;
2717
2720 {
2721 if (is_missing != NULL)
2722 {
2723 *is_missing = true;
2724 return false;
2725 }
2726 elog(ERROR, "cache lookup failed for statistics object %u", stxid);
2727 }
2729
2731
2732
2733
2734
2735
2736
2737 stxnamespace = stxform->stxnamespace;
2738 if (stxnamespace != PG_CATALOG_NAMESPACE &&
2740 visible = false;
2741 else
2742 {
2743
2744
2745
2746
2747
2748 char *stxname = NameStr(stxform->stxname);
2750
2751 visible = false;
2753 {
2755
2757 continue;
2758
2759 if (namespaceId == stxnamespace)
2760 {
2761
2762 visible = true;
2763 break;
2764 }
2768 {
2769
2770 break;
2771 }
2772 }
2773 }
2774
2776
2777 return visible;
2778}
2779
2780
2781
2782
2783
2784
2787{
2788 char *schemaname;
2789 char *parser_name;
2790 Oid namespaceId;
2793
2794
2796
2797 if (schemaname)
2798 {
2799
2801 if (missing_ok && (namespaceId))
2803 else
2804 prsoid = GetSysCacheOid2(TSPARSERNAMENSP, Anum_pg_ts_parser_oid,
2807 }
2808 else
2809 {
2810
2812
2814 {
2816
2818 continue;
2819
2820 prsoid = GetSysCacheOid2(TSPARSERNAMENSP, Anum_pg_ts_parser_oid,
2824 break;
2825 }
2826 }
2827
2828 if ((prsoid) && !missing_ok)
2830 (errcode(ERRCODE_UNDEFINED_OBJECT),
2831 errmsg("text search parser \"%s\" does not exist",
2833
2834 return prsoid;
2835}
2836
2837
2838
2839
2840
2841
2842
2843bool
2845{
2847}
2848
2849
2850
2851
2852
2853
2854
2855static bool
2857{
2860 Oid namespace;
2861 bool visible;
2862
2865 {
2866 if (is_missing != NULL)
2867 {
2868 *is_missing = true;
2869 return false;
2870 }
2871 elog(ERROR, "cache lookup failed for text search parser %u", prsId);
2872 }
2874
2876
2877
2878
2879
2880
2881
2882 namespace = form->prsnamespace;
2883 if (namespace != PG_CATALOG_NAMESPACE &&
2885 visible = false;
2886 else
2887 {
2888
2889
2890
2891
2892
2895
2896 visible = false;
2898 {
2900
2902 continue;
2903
2904 if (namespaceId == namespace)
2905 {
2906
2907 visible = true;
2908 break;
2909 }
2913 {
2914
2915 break;
2916 }
2917 }
2918 }
2919
2921
2922 return visible;
2923}
2924
2925
2926
2927
2928
2929
2932{
2933 char *schemaname;
2934 char *dict_name;
2935 Oid namespaceId;
2938
2939
2941
2942 if (schemaname)
2943 {
2944
2946 if (missing_ok && (namespaceId))
2948 else
2949 dictoid = GetSysCacheOid2(TSDICTNAMENSP, Anum_pg_ts_dict_oid,
2952 }
2953 else
2954 {
2955
2957
2959 {
2961
2963 continue;
2964
2965 dictoid = GetSysCacheOid2(TSDICTNAMENSP, Anum_pg_ts_dict_oid,
2969 break;
2970 }
2971 }
2972
2973 if ((dictoid) && !missing_ok)
2975 (errcode(ERRCODE_UNDEFINED_OBJECT),
2976 errmsg("text search dictionary \"%s\" does not exist",
2978
2979 return dictoid;
2980}
2981
2982
2983
2984
2985
2986
2987
2988bool
2990{
2992}
2993
2994
2995
2996
2997
2998
2999
3000static bool
3002{
3005 Oid namespace;
3006 bool visible;
3007
3010 {
3011 if (is_missing != NULL)
3012 {
3013 *is_missing = true;
3014 return false;
3015 }
3016 elog(ERROR, "cache lookup failed for text search dictionary %u",
3017 dictId);
3018 }
3020
3022
3023
3024
3025
3026
3027
3028 namespace = form->dictnamespace;
3029 if (namespace != PG_CATALOG_NAMESPACE &&
3031 visible = false;
3032 else
3033 {
3034
3035
3036
3037
3038
3041
3042 visible = false;
3044 {
3046
3048 continue;
3049
3050 if (namespaceId == namespace)
3051 {
3052
3053 visible = true;
3054 break;
3055 }
3059 {
3060
3061 break;
3062 }
3063 }
3064 }
3065
3067
3068 return visible;
3069}
3070
3071
3072
3073
3074
3075
3078{
3079 char *schemaname;
3080 char *template_name;
3081 Oid namespaceId;
3084
3085
3087
3088 if (schemaname)
3089 {
3090
3092 if (missing_ok && (namespaceId))
3094 else
3095 tmploid = GetSysCacheOid2(TSTEMPLATENAMENSP, Anum_pg_ts_template_oid,
3098 }
3099 else
3100 {
3101
3103
3105 {
3107
3109 continue;
3110
3111 tmploid = GetSysCacheOid2(TSTEMPLATENAMENSP, Anum_pg_ts_template_oid,
3115 break;
3116 }
3117 }
3118
3119 if ((tmploid) && !missing_ok)
3121 (errcode(ERRCODE_UNDEFINED_OBJECT),
3122 errmsg("text search template \"%s\" does not exist",
3124
3125 return tmploid;
3126}
3127
3128
3129
3130
3131
3132
3133
3134bool
3136{
3138}
3139
3140
3141
3142
3143
3144
3145
3146static bool
3148{
3151 Oid namespace;
3152 bool visible;
3153
3156 {
3157 if (is_missing != NULL)
3158 {
3159 *is_missing = true;
3160 return false;
3161 }
3162 elog(ERROR, "cache lookup failed for text search template %u", tmplId);
3163 }
3165
3167
3168
3169
3170
3171
3172
3173 namespace = form->tmplnamespace;
3174 if (namespace != PG_CATALOG_NAMESPACE &&
3176 visible = false;
3177 else
3178 {
3179
3180
3181
3182
3183
3186
3187 visible = false;
3189 {
3191
3193 continue;
3194
3195 if (namespaceId == namespace)
3196 {
3197
3198 visible = true;
3199 break;
3200 }
3204 {
3205
3206 break;
3207 }
3208 }
3209 }
3210
3212
3213 return visible;
3214}
3215
3216
3217
3218
3219
3220
3223{
3224 char *schemaname;
3225 char *config_name;
3226 Oid namespaceId;
3229
3230
3232
3233 if (schemaname)
3234 {
3235
3237 if (missing_ok && (namespaceId))
3239 else
3240 cfgoid = GetSysCacheOid2(TSCONFIGNAMENSP, Anum_pg_ts_config_oid,
3243 }
3244 else
3245 {
3246
3248
3250 {
3252
3254 continue;
3255
3256 cfgoid = GetSysCacheOid2(TSCONFIGNAMENSP, Anum_pg_ts_config_oid,
3260 break;
3261 }
3262 }
3263
3264 if ((cfgoid) && !missing_ok)
3266 (errcode(ERRCODE_UNDEFINED_OBJECT),
3267 errmsg("text search configuration \"%s\" does not exist",
3269
3270 return cfgoid;
3271}
3272
3273
3274
3275
3276
3277
3278
3279bool
3281{
3283}
3284
3285
3286
3287
3288
3289
3290
3291static bool
3293{
3296 Oid namespace;
3297 bool visible;
3298
3301 {
3302 if (is_missing != NULL)
3303 {
3304 *is_missing = true;
3305 return false;
3306 }
3307 elog(ERROR, "cache lookup failed for text search configuration %u",
3308 cfgid);
3309 }
3311
3313
3314
3315
3316
3317
3318
3319 namespace = form->cfgnamespace;
3320 if (namespace != PG_CATALOG_NAMESPACE &&
3322 visible = false;
3323 else
3324 {
3325
3326
3327
3328
3329
3332
3333 visible = false;
3335 {
3337
3339 continue;
3340
3341 if (namespaceId == namespace)
3342 {
3343
3344 visible = true;
3345 break;
3346 }
3350 {
3351
3352 break;
3353 }
3354 }
3355 }
3356
3358
3359 return visible;
3360}
3361
3362
3363
3364
3365
3366
3367
3368
3369
3370void
3372 char **nspname_p,
3373 char **objname_p)
3374{
3375 char *catalogname;
3376 char *schemaname = NULL;
3377 char *objname = NULL;
3378
3380 {
3381 case 1:
3383 break;
3384 case 2:
3387 break;
3388 case 3:
3392
3393
3394
3395
3398 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3399 errmsg("cross-database references are not implemented: %s",
3401 break;
3402 default:
3404 (errcode(ERRCODE_SYNTAX_ERROR),
3405 errmsg("improper qualified name (too many dotted names): %s",
3407 break;
3408 }
3409
3410 *nspname_p = schemaname;
3411 *objname_p = objname;
3412}
3413
3414
3415
3416
3417
3418
3419
3420
3421
3422
3423
3426{
3427
3428 if (strcmp(nspname, "pg_temp") == 0)
3429 {
3431 {
3434 }
3435
3436
3437
3438
3439
3440
3442 }
3443
3445}
3446
3447
3448
3449
3450
3451
3452
3453
3456{
3457 Oid namespaceId;
3459
3460
3461 if (strcmp(nspname, "pg_temp") == 0)
3462 {
3465
3466
3467
3468
3469
3470
3471 }
3472
3474 if (missing_ok && (namespaceId))
3476
3480 nspname);
3481
3483
3484 return namespaceId;
3485}
3486
3487
3488
3489
3490
3491
3492
3493
3494
3495
3496
3499{
3500 Oid namespaceId;
3502
3503
3504 if (strcmp(nspname, "pg_temp") == 0)
3505 {
3506
3509 }
3510
3512
3516 nspname);
3517
3518 return namespaceId;
3519}
3520
3521
3522
3523
3524
3525
3526
3527
3528void
3530{
3531
3534 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3535 errmsg("cannot move objects into or out of temporary schemas")));
3536
3537
3538 if (nspOid == PG_TOAST_NAMESPACE || oldNspOid == PG_TOAST_NAMESPACE)
3540 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3541 errmsg("cannot move objects into or out of TOAST schema")));
3542}
3543
3544
3545
3546
3547
3548
3549
3550
3551
3552
3553
3554
3555
3558{
3559 char *schemaname;
3560 Oid namespaceId;
3561
3562
3564
3565 if (schemaname)
3566 {
3567
3568 if (strcmp(schemaname, "pg_temp") == 0)
3569 {
3570
3573 }
3574
3576
3577 }
3578 else
3579 {
3580
3583 {
3584
3587 }
3591 (errcode(ERRCODE_UNDEFINED_SCHEMA),
3592 errmsg("no schema has been selected to create in")));
3593 }
3594
3595 return namespaceId;
3596}
3597
3598
3599
3600
3601
3602
3603
3606{
3607 Oid oid;
3608
3609 oid = GetSysCacheOid1(NAMESPACENAME, Anum_pg_namespace_oid,
3611 if ((oid) && !missing_ok)
3613 (errcode(ERRCODE_UNDEFINED_SCHEMA),
3614 errmsg("schema \"%s\" does not exist", nspname)));
3615
3616 return oid;
3617}
3618
3619
3620
3621
3622
3625{
3627
3629 {
3630 case 1:
3632 break;
3633 case 2:
3636 break;
3637 case 3:
3641 break;
3642 default:
3644 (errcode(ERRCODE_SYNTAX_ERROR),
3645 errmsg("improper relation name (too many dotted names): %s",
3647 break;
3648 }
3649
3650 return rel;
3651}
3652
3653
3654
3655
3656
3657
3658
3659
3660
3661
3662
3663char *
3665{
3668
3670
3671 foreach(l, names)
3672 {
3674
3677
3682 else
3683 elog(ERROR, "unexpected node type in name list: %d",
3685 }
3686
3687 return string.data;
3688}
3689
3690
3691
3692
3693
3694
3695
3696
3697char *
3699{
3702
3704
3705 foreach(l, names)
3706 {
3710 }
3711
3712 return string.data;
3713}
3714
3715
3716
3717
3718bool
3720{
3722 return true;
3723 return false;
3724}
3725
3726
3727
3728
3729
3730bool
3732{
3734 return true;
3735 return false;
3736}
3737
3738
3739
3740
3741
3742bool
3744{
3747 return true;
3748 return false;
3749}
3750
3751
3752
3753
3754
3755
3756bool
3758{
3759 bool result;
3760 char *nspname;
3761
3762
3764 if (!nspname)
3765 return false;
3766 result = (strncmp(nspname, "pg_temp_", 8) == 0) ||
3767 (strncmp(nspname, "pg_toast_temp_", 14) == 0);
3769 return result;
3770}
3771
3772
3773
3774
3775
3776
3777
3778
3779bool
3781{
3782
3784 return false;
3785
3787}
3788
3789
3790
3791
3792
3793
3794
3795
3796
3797
3800{
3803
3805
3807
3808
3811
3812
3814 if (proc == NULL)
3816
3817
3820
3821
3824
3825
3827}
3828
3829
3830
3831
3832
3833
3834
3837{
3838 int result;
3839 char *nspname;
3840
3841
3843 if (!nspname)
3845 if (strncmp(nspname, "pg_temp_", 8) == 0)
3846 result = atoi(nspname + 8);
3847 else if (strncmp(nspname, "pg_toast_temp_", 14) == 0)
3848 result = atoi(nspname + 14);
3849 else
3852 return result;
3853}
3854
3855
3856
3857
3858
3859
3862{
3865}
3866
3867
3868
3869
3870
3871
3872
3873
3874void
3876{
3877
3880}
3881
3882
3883
3884
3885
3886
3887
3888
3889
3890void
3892{
3893
3897
3898
3901
3902
3903
3904
3905
3906
3907
3908
3911}
3912
3913
3914
3915
3916
3917
3918
3919
3920
3923{
3925 List *schemas;
3927
3929
3931
3935 {
3938 else
3939 {
3942 }
3944 }
3945 result->schemas = schemas;
3947
3949
3950 return result;
3951}
3952
3953
3954
3955
3956
3957
3960{
3962
3968
3969 return result;
3970}
3971
3972
3973
3974
3975
3976
3977
3978
3979
3980bool
3982{
3984 *lcp;
3985
3987
3988
3990 return true;
3991
3992
3994
3995
3997 {
4000 else
4001 return false;
4002 }
4003
4005 {
4006 if (lc && lfirst_oid(lc) == PG_CATALOG_NAMESPACE)
4008 else
4009 return false;
4010 }
4011
4013 return false;
4014
4015 foreach(lcp, path->schemas)
4016 {
4019 else
4020 return false;
4021 }
4022 if (lc)
4023 return false;
4024
4025
4026
4027
4028
4030
4031 return true;
4032}
4033
4034
4035
4036
4037
4038
4039
4042{
4043 char *schemaname;
4044 char *collation_name;
4046 Oid namespaceId;
4047 Oid colloid;
4049
4050
4052
4053 if (schemaname)
4054 {
4055
4057 if (missing_ok && (namespaceId))
4059
4060 colloid = lookup_collation(collation_name, namespaceId, dbencoding);
4062 return colloid;
4063 }
4064 else
4065 {
4066
4068
4070 {
4072
4074 continue;
4075
4076 colloid = lookup_collation(collation_name, namespaceId, dbencoding);
4078 return colloid;
4079 }
4080 }
4081
4082
4083 if (!missing_ok)
4085 (errcode(ERRCODE_UNDEFINED_OBJECT),
4086 errmsg("collation \"%s\" for encoding \"%s\" does not exist",
4089}
4090
4091
4092
4093
4096{
4097 char *schemaname;
4098 char *conversion_name;
4099 Oid namespaceId;
4102
4103
4105
4106 if (schemaname)
4107 {
4108
4110 if (missing_ok && (namespaceId))
4112 else
4113 conoid = GetSysCacheOid2(CONNAMENSP, Anum_pg_conversion_oid,
4116 }
4117 else
4118 {
4119
4121
4123 {
4125
4127 continue;
4128
4129 conoid = GetSysCacheOid2(CONNAMENSP, Anum_pg_conversion_oid,
4133 return conoid;
4134 }
4135 }
4136
4137
4138 if ((conoid) && !missing_ok)
4140 (errcode(ERRCODE_UNDEFINED_OBJECT),
4141 errmsg("conversion \"%s\" does not exist",
4143 return conoid;
4144}
4145
4146
4147
4148
4151{
4152 Oid proc;
4154
4156
4158 {
4160
4162 continue;
4163
4166 return proc;
4167 }
4168
4169
4171}
4172
4173
4174
4175
4176static List *
4178 bool *temp_missing)
4179{
4180 char *rawname;
4181 List *namelist;
4182 List *oidlist;
4184
4185
4186 rawname = pstrdup(searchPath);
4187
4188
4190 {
4191
4192
4193 elog(ERROR, "invalid list syntax");
4194 }
4195
4196
4197
4198
4199
4200
4201
4202 oidlist = NIL;
4203 *temp_missing = false;
4204 foreach(l, namelist)
4205 {
4206 char *curname = (char *) lfirst(l);
4207 Oid namespaceId;
4208
4209 if (strcmp(curname, "$user") == 0)
4210 {
4211
4213
4216 {
4217 char *rname;
4218
4223 object_aclcheck(NamespaceRelationId, namespaceId, roleid,
4225 oidlist = lappend_oid(oidlist, namespaceId);
4226 }
4227 }
4228 else if (strcmp(curname, "pg_temp") == 0)
4229 {
4230
4233 else
4234 {
4235
4236 if (oidlist == NIL)
4237 *temp_missing = true;
4238 }
4239 }
4240 else
4241 {
4242
4245 object_aclcheck(NamespaceRelationId, namespaceId, roleid,
4247 oidlist = lappend_oid(oidlist, namespaceId);
4248 }
4249 }
4250
4253
4254 return oidlist;
4255}
4256
4257
4258
4259
4260
4261
4262
4263
4264
4265
4266
4267static List *
4269{
4272
4273 foreach(lc, oidlist)
4274 {
4276
4278 {
4280 finalPath = lappend_oid(finalPath, namespaceId);
4281 }
4282 }
4283
4284
4285
4286
4287
4288
4289 if (finalPath == NIL)
4291 else
4293
4294
4295
4296
4297
4298
4300 finalPath = lcons_oid(PG_CATALOG_NAMESPACE, finalPath);
4301
4305
4306 return finalPath;
4307}
4308
4309
4310
4311
4312
4315{
4318
4320
4322
4323
4324
4325
4326
4327
4329 {
4334 }
4335
4336
4337
4338
4339
4340
4341
4344 {
4347
4352
4353
4354
4355
4356
4357
4358
4360 }
4361
4362 return entry;
4363}
4364
4365
4366
4367
4368static void
4370{
4372 bool pathChanged;
4374
4375
4377 return;
4378
4380
4384 {
4385 pathChanged = false;
4386 }
4387 else
4388 {
4390 List *newpath;
4391
4392 pathChanged = true;
4393
4394
4398
4399
4404 }
4405
4406
4409
4410
4414
4415
4416
4417
4418
4419 if (pathChanged)
4421}
4422
4423
4424
4425
4426
4427
4428
4429
4430
4431static void
4433{
4434
4435
4436
4437
4439
4440
4441
4442
4443
4444
4446 return;
4447
4448
4449
4450
4451
4453}
4454
4455
4456
4457
4458
4459static void
4461{
4463 Oid namespaceId;
4464 Oid toastspaceId;
4465
4467
4468
4469
4470
4471
4472
4473
4474
4475
4476
4477
4481 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
4482 errmsg("permission denied to create temporary tables in database \"%s\"",
4484
4485
4486
4487
4488
4489
4490
4491
4492
4493
4494
4497 (errcode(ERRCODE_READ_ONLY_SQL_TRANSACTION),
4498 errmsg("cannot create temporary tables during recovery")));
4499
4500
4503 (errcode(ERRCODE_READ_ONLY_SQL_TRANSACTION),
4504 errmsg("cannot create temporary tables during a parallel operation")));
4505
4507
4510 {
4511
4512
4513
4514
4515
4516
4517
4518
4519 namespaceId = NamespaceCreate(namespaceName, BOOTSTRAP_SUPERUSERID,
4520 true);
4521
4523 }
4524 else
4525 {
4526
4527
4528
4529
4531 }
4532
4533
4534
4535
4536
4537
4538 snprintf(namespaceName, sizeof(namespaceName), "pg_toast_temp_%d",
4540
4543 {
4544 toastspaceId = NamespaceCreate(namespaceName, BOOTSTRAP_SUPERUSERID,
4545 true);
4546
4548 }
4549
4550
4551
4552
4553
4554
4557
4558
4559
4560
4561
4562
4563
4564
4565
4566
4567
4569
4570
4573
4576}
4577
4578
4579
4580
4581void
4583{
4584
4585
4586
4587
4588
4589
4590
4591
4593 {
4594 if (isCommit)
4596 else
4597 {
4602
4603
4604
4605
4606
4607
4608
4609
4610
4611
4613 }
4615 }
4616
4617}
4618
4619
4620
4621
4622
4623
4624
4625
4626
4627void
4630{
4631
4633 {
4634 if (isCommit)
4636 else
4637 {
4639
4644
4645
4646
4647
4648
4649
4650
4651
4652
4653
4655 }
4656 }
4657}
4658
4659
4660
4661
4662
4663
4664
4665
4666
4667static void
4669{
4671
4672
4673
4674
4675
4676
4677
4678
4679 object.classId = NamespaceRelationId;
4680 object.objectId = tempNamespaceId;
4681 object.objectSubId = 0;
4682
4688}
4689
4690
4691
4692
4693static void
4695{
4697 {
4698
4702
4704
4707 }
4708}
4709
4710
4711
4712
4713void
4715{
4718}
4719
4720
4721
4722
4723
4724
4725
4726bool
4728{
4730 const char *searchPath = *newval;
4731 char *rawname;
4732 List *namelist;
4734
4735
4736
4737
4738
4739
4740
4741
4742
4743
4744
4745
4746 if (use_cache)
4747 {
4749
4751
4753 return true;
4754 }
4755
4756
4757
4758
4759
4760 rawname = pstrdup(searchPath);
4761
4762
4764 {
4765
4769 return false;
4770 }
4773
4774
4775 if (use_cache)
4777
4778 return true;
4779}
4780
4781
4782void
4784{
4785
4787
4788
4789
4790
4791
4792
4793
4794
4795
4796
4798}
4799
4800
4801
4802
4803
4804
4805void
4807{
4809 {
4810
4811
4812
4813
4815
4827 }
4828 else
4829 {
4830
4831
4832
4833
4834
4835
4839
4840
4844
4845
4849
4850
4854
4855
4858 }
4859}
4860
4861
4862
4863
4864
4865static void
4867{
4868
4869
4870
4871
4872
4875}
4876
4877
4878
4879
4880
4881
4882
4883
4884
4885
4886
4887
4890{
4891 List *result;
4892
4894
4895
4896
4897
4898
4899
4900
4901
4903 {
4906 }
4907
4909 if (!includeImplicit)
4910 {
4913 }
4914
4915 return result;
4916}
4917
4918
4919
4920
4921
4922
4923
4924
4925
4926
4927
4928int
4930{
4931 int count = 0;
4933
4935
4937 {
4939
4941 continue;
4942
4943 if (count < sarray_len)
4944 sarray[count] = namespaceId;
4945 count++;
4946 }
4947
4948 return count;
4949}
4950
4951
4952
4953
4954
4955
4956
4957
4958
4959
4960
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 bool result;
5080 bool is_missing = false;
5081
5083
5084 if (is_missing)
5087}
5088
5091{
5093 bool result;
5094 bool is_missing = false;
5095
5097
5098 if (is_missing)
5101}
5102
5105{
5107 bool result;
5108 bool is_missing = false;
5109
5111
5112 if (is_missing)
5115}
5116
5119{
5121 bool result;
5122 bool is_missing = false;
5123
5125
5126 if (is_missing)
5129}
5130
5133{
5135 bool result;
5136 bool is_missing = false;
5137
5139
5140 if (is_missing)
5143}
5144
5147{
5149}
5150
5153{
5155
5157}
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)
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 palloc_object(type)
#define palloc0_object(type)
#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_database_name(Oid dbid)
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)
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)
static bool MatchNamedCall(HeapTuple proctup, int nargs, List *argnames, bool include_out_arguments, int pronargs, int **argnumbers, int *fgc_flags)
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 OpernameGetCandidates(List *names, char oprkind, bool missing_schema_ok, int *fgc_flags)
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)
FuncCandidateList FuncnameGetCandidates(List *names, int nargs, List *argnames, bool expand_variadic, bool expand_defaults, bool include_out_arguments, bool missing_ok, int *fgc_flags)
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 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)
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)
#define FGC_ARGNAMES_VALID
#define FGC_ARGNAMES_MATCH
@ TEMP_NAMESPACE_NOT_TEMP
#define FGC_ARGCOUNT_MATCH
struct _FuncCandidateList * FuncCandidateList
#define FGC_SCHEMA_EXISTS
#define FGC_ARGNAMES_NONDUP
#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)