1 /*
2 * pg_upgrade_support.c
3 *
4 * server-side functions to set backend global variables
5 * to control oid and relfilenode assignment, and do other special
6 * hacks needed for pg_upgrade.
7 *
8 * Copyright (c) 2010-2016, PostgreSQL Global Development Group
9 * src/backend/utils/adt/pg_upgrade_support.c
10 */
11
12 #include "postgres.h"
13
14 #include "catalog/binary_upgrade.h"
15 #include "catalog/namespace.h"
16 #include "catalog/pg_type.h"
17 #include "commands/extension.h"
18 #include "miscadmin.h"
19 #include "utils/array.h"
20 #include "utils/builtins.h"
21
22
23 Datum binary_upgrade_set_next_pg_type_oid(PG_FUNCTION_ARGS);
24 Datum binary_upgrade_set_next_array_pg_type_oid(PG_FUNCTION_ARGS);
25 Datum binary_upgrade_set_next_toast_pg_type_oid(PG_FUNCTION_ARGS);
26 Datum binary_upgrade_set_next_heap_pg_class_oid(PG_FUNCTION_ARGS);
27 Datum binary_upgrade_set_next_index_pg_class_oid(PG_FUNCTION_ARGS);
28 Datum binary_upgrade_set_next_toast_pg_class_oid(PG_FUNCTION_ARGS);
29 Datum binary_upgrade_set_next_pg_enum_oid(PG_FUNCTION_ARGS);
30 Datum binary_upgrade_set_next_pg_authid_oid(PG_FUNCTION_ARGS);
31 Datum binary_upgrade_create_empty_extension(PG_FUNCTION_ARGS);
32 Datum binary_upgrade_set_record_init_privs(PG_FUNCTION_ARGS);
33
34
35 #define CHECK_IS_BINARY_UPGRADE \
36 do { \
37 if (!IsBinaryUpgrade) \
38 ereport(ERROR, \
39 (errcode(ERRCODE_CANT_CHANGE_RUNTIME_PARAM), \
40 (errmsg("function can only be called when server is in binary upgrade mode")))); \
41 } while (0)
42
43 Datum
binary_upgrade_set_next_pg_type_oid(PG_FUNCTION_ARGS)44 binary_upgrade_set_next_pg_type_oid(PG_FUNCTION_ARGS)
45 {
46 Oid typoid = PG_GETARG_OID(0);
47
48 CHECK_IS_BINARY_UPGRADE;
49 binary_upgrade_next_pg_type_oid = typoid;
50
51 PG_RETURN_VOID();
52 }
53
54 Datum
binary_upgrade_set_next_array_pg_type_oid(PG_FUNCTION_ARGS)55 binary_upgrade_set_next_array_pg_type_oid(PG_FUNCTION_ARGS)
56 {
57 Oid typoid = PG_GETARG_OID(0);
58
59 CHECK_IS_BINARY_UPGRADE;
60 binary_upgrade_next_array_pg_type_oid = typoid;
61
62 PG_RETURN_VOID();
63 }
64
65 Datum
binary_upgrade_set_next_toast_pg_type_oid(PG_FUNCTION_ARGS)66 binary_upgrade_set_next_toast_pg_type_oid(PG_FUNCTION_ARGS)
67 {
68 Oid typoid = PG_GETARG_OID(0);
69
70 CHECK_IS_BINARY_UPGRADE;
71 binary_upgrade_next_toast_pg_type_oid = typoid;
72
73 PG_RETURN_VOID();
74 }
75
76 Datum
binary_upgrade_set_next_heap_pg_class_oid(PG_FUNCTION_ARGS)77 binary_upgrade_set_next_heap_pg_class_oid(PG_FUNCTION_ARGS)
78 {
79 Oid reloid = PG_GETARG_OID(0);
80
81 CHECK_IS_BINARY_UPGRADE;
82 binary_upgrade_next_heap_pg_class_oid = reloid;
83
84 PG_RETURN_VOID();
85 }
86
87 Datum
binary_upgrade_set_next_index_pg_class_oid(PG_FUNCTION_ARGS)88 binary_upgrade_set_next_index_pg_class_oid(PG_FUNCTION_ARGS)
89 {
90 Oid reloid = PG_GETARG_OID(0);
91
92 CHECK_IS_BINARY_UPGRADE;
93 binary_upgrade_next_index_pg_class_oid = reloid;
94
95 PG_RETURN_VOID();
96 }
97
98 Datum
binary_upgrade_set_next_toast_pg_class_oid(PG_FUNCTION_ARGS)99 binary_upgrade_set_next_toast_pg_class_oid(PG_FUNCTION_ARGS)
100 {
101 Oid reloid = PG_GETARG_OID(0);
102
103 CHECK_IS_BINARY_UPGRADE;
104 binary_upgrade_next_toast_pg_class_oid = reloid;
105
106 PG_RETURN_VOID();
107 }
108
109 Datum
binary_upgrade_set_next_pg_enum_oid(PG_FUNCTION_ARGS)110 binary_upgrade_set_next_pg_enum_oid(PG_FUNCTION_ARGS)
111 {
112 Oid enumoid = PG_GETARG_OID(0);
113
114 CHECK_IS_BINARY_UPGRADE;
115 binary_upgrade_next_pg_enum_oid = enumoid;
116
117 PG_RETURN_VOID();
118 }
119
120 Datum
binary_upgrade_set_next_pg_authid_oid(PG_FUNCTION_ARGS)121 binary_upgrade_set_next_pg_authid_oid(PG_FUNCTION_ARGS)
122 {
123 Oid authoid = PG_GETARG_OID(0);
124
125 CHECK_IS_BINARY_UPGRADE;
126 binary_upgrade_next_pg_authid_oid = authoid;
127 PG_RETURN_VOID();
128 }
129
130 Datum
binary_upgrade_create_empty_extension(PG_FUNCTION_ARGS)131 binary_upgrade_create_empty_extension(PG_FUNCTION_ARGS)
132 {
133 text *extName;
134 text *schemaName;
135 bool relocatable;
136 text *extVersion;
137 Datum extConfig;
138 Datum extCondition;
139 List *requiredExtensions;
140
141 CHECK_IS_BINARY_UPGRADE;
142
143 /* We must check these things before dereferencing the arguments */
144 if (PG_ARGISNULL(0) ||
145 PG_ARGISNULL(1) ||
146 PG_ARGISNULL(2) ||
147 PG_ARGISNULL(3))
148 elog(ERROR, "null argument to binary_upgrade_create_empty_extension is not allowed");
149
150 extName = PG_GETARG_TEXT_PP(0);
151 schemaName = PG_GETARG_TEXT_PP(1);
152 relocatable = PG_GETARG_BOOL(2);
153 extVersion = PG_GETARG_TEXT_PP(3);
154
155 if (PG_ARGISNULL(4))
156 extConfig = PointerGetDatum(NULL);
157 else
158 extConfig = PG_GETARG_DATUM(4);
159
160 if (PG_ARGISNULL(5))
161 extCondition = PointerGetDatum(NULL);
162 else
163 extCondition = PG_GETARG_DATUM(5);
164
165 requiredExtensions = NIL;
166 if (!PG_ARGISNULL(6))
167 {
168 ArrayType *textArray = PG_GETARG_ARRAYTYPE_P(6);
169 Datum *textDatums;
170 int ndatums;
171 int i;
172
173 deconstruct_array(textArray,
174 TEXTOID, -1, false, 'i',
175 &textDatums, NULL, &ndatums);
176 for (i = 0; i < ndatums; i++)
177 {
178 text *txtname = DatumGetTextPP(textDatums[i]);
179 char *extName = text_to_cstring(txtname);
180 Oid extOid = get_extension_oid(extName, false);
181
182 requiredExtensions = lappend_oid(requiredExtensions, extOid);
183 }
184 }
185
186 InsertExtensionTuple(text_to_cstring(extName),
187 GetUserId(),
188 get_namespace_oid(text_to_cstring(schemaName), false),
189 relocatable,
190 text_to_cstring(extVersion),
191 extConfig,
192 extCondition,
193 requiredExtensions);
194
195 PG_RETURN_VOID();
196 }
197
198 Datum
binary_upgrade_set_record_init_privs(PG_FUNCTION_ARGS)199 binary_upgrade_set_record_init_privs(PG_FUNCTION_ARGS)
200 {
201 bool record_init_privs = PG_GETARG_BOOL(0);
202
203 CHECK_IS_BINARY_UPGRADE;
204 binary_upgrade_record_init_privs = record_init_privs;
205
206 PG_RETURN_VOID();
207 }
208