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