* Transform a relation options list (list of DefElem) into the text array * format that is kept in pg_class.reloptions, including only those options * that are in the passed namespace. The output values do not include the * namespace. * * This is used for three cases: CREATE TABLE/INDEX, ALTER TABLE SET, and * ALTER TABLE RESET. In the ALTER cases, oldOptions is the existing * reloptions
| 1182 | * but we declare them as Datums to avoid including array.h in reloptions.h. |
| 1183 | */ |
| 1184 | Datum |
| 1185 | transformRelOptions(Datum oldOptions, List *defList, const char *namspace, |
| 1186 | char *validnsps[], bool acceptOidsOff, bool isReset) |
| 1187 | { |
| 1188 | Datum result; |
| 1189 | ArrayBuildState *astate; |
| 1190 | ListCell *cell; |
| 1191 | |
| 1192 | /* no change if empty list */ |
| 1193 | if (defList == NIL) |
| 1194 | return oldOptions; |
| 1195 | |
| 1196 | /* We build new array using accumArrayResult */ |
| 1197 | astate = NULL; |
| 1198 | |
| 1199 | /* Copy any oldOptions that aren't to be replaced */ |
| 1200 | if (PointerIsValid(DatumGetPointer(oldOptions))) |
| 1201 | { |
| 1202 | ArrayType *array = DatumGetArrayTypeP(oldOptions); |
| 1203 | Datum *oldoptions; |
| 1204 | int noldoptions; |
| 1205 | int i; |
| 1206 | |
| 1207 | deconstruct_array(array, TEXTOID, -1, false, TYPALIGN_INT, |
| 1208 | &oldoptions, NULL, &noldoptions); |
| 1209 | |
| 1210 | for (i = 0; i < noldoptions; i++) |
| 1211 | { |
| 1212 | char *text_str = VARDATA(oldoptions[i]); |
| 1213 | int text_len = VARSIZE(oldoptions[i]) - VARHDRSZ; |
| 1214 | |
| 1215 | /* Search for a match in defList */ |
| 1216 | foreach(cell, defList) |
| 1217 | { |
| 1218 | DefElem *def = (DefElem *) lfirst(cell); |
| 1219 | int kw_len; |
| 1220 | |
| 1221 | /* ignore if not in the same namespace */ |
| 1222 | if (namspace == NULL) |
| 1223 | { |
| 1224 | if (def->defnamespace != NULL) |
| 1225 | continue; |
| 1226 | } |
| 1227 | else if (def->defnamespace == NULL) |
| 1228 | continue; |
| 1229 | else if (strcmp(def->defnamespace, namspace) != 0) |
| 1230 | continue; |
| 1231 | |
| 1232 | kw_len = strlen(def->defname); |
| 1233 | if (text_len > kw_len && text_str[kw_len] == '=' && |
| 1234 | strncmp(text_str, def->defname, kw_len) == 0) |
| 1235 | break; |
| 1236 | } |
| 1237 | if (!cell) |
| 1238 | { |
| 1239 | /* No match, so keep old option */ |
| 1240 | astate = accumArrayResult(astate, oldoptions[i], |
| 1241 | false, TEXTOID, |
no test coverage detected