* dumpSearchPath: record the active search_path in the archive */
| 3837 | * dumpSearchPath: record the active search_path in the archive |
| 3838 | */ |
| 3839 | static void |
| 3840 | dumpSearchPath(Archive *AH) |
| 3841 | { |
| 3842 | PQExpBuffer qry = createPQExpBuffer(); |
| 3843 | PQExpBuffer path = createPQExpBuffer(); |
| 3844 | PGresult *res; |
| 3845 | char **schemanames = NULL; |
| 3846 | int nschemanames = 0; |
| 3847 | int i; |
| 3848 | |
| 3849 | /* |
| 3850 | * We use the result of current_schemas(), not the search_path GUC, |
| 3851 | * because that might contain wildcards such as "$user", which won't |
| 3852 | * necessarily have the same value during restore. Also, this way avoids |
| 3853 | * listing schemas that may appear in search_path but not actually exist, |
| 3854 | * which seems like a prudent exclusion. |
| 3855 | */ |
| 3856 | res = ExecuteSqlQueryForSingleRow(AH, |
| 3857 | "SELECT pg_catalog.current_schemas(false)"); |
| 3858 | |
| 3859 | if (!parsePGArray(PQgetvalue(res, 0, 0), &schemanames, &nschemanames)) |
| 3860 | fatal("could not parse result of current_schemas()"); |
| 3861 | |
| 3862 | /* |
| 3863 | * We use set_config(), not a simple "SET search_path" command, because |
| 3864 | * the latter has less-clean behavior if the search path is empty. While |
| 3865 | * that's likely to get fixed at some point, it seems like a good idea to |
| 3866 | * be as backwards-compatible as possible in what we put into archives. |
| 3867 | */ |
| 3868 | for (i = 0; i < nschemanames; i++) |
| 3869 | { |
| 3870 | if (i > 0) |
| 3871 | appendPQExpBufferStr(path, ", "); |
| 3872 | appendPQExpBufferStr(path, fmtId(schemanames[i])); |
| 3873 | } |
| 3874 | |
| 3875 | appendPQExpBufferStr(qry, "SELECT pg_catalog.set_config('search_path', "); |
| 3876 | appendStringLiteralAH(qry, path->data, AH); |
| 3877 | appendPQExpBufferStr(qry, ", false);\n"); |
| 3878 | |
| 3879 | pg_log_info("saving search_path = %s", path->data); |
| 3880 | |
| 3881 | ArchiveEntry(AH, nilCatalogId, createDumpId(), |
| 3882 | ARCHIVE_OPTS(.tag = "SEARCHPATH", |
| 3883 | .description = "SEARCHPATH", |
| 3884 | .section = SECTION_PRE_DATA, |
| 3885 | .createStmt = qry->data)); |
| 3886 | |
| 3887 | /* Also save it in AH->searchpath, in case we're doing plain text dump */ |
| 3888 | AH->searchpath = pg_strdup(qry->data); |
| 3889 | |
| 3890 | if (schemanames) |
| 3891 | free(schemanames); |
| 3892 | PQclear(res); |
| 3893 | destroyPQExpBuffer(qry); |
| 3894 | destroyPQExpBuffer(path); |
| 3895 | } |
| 3896 |
no test coverage detected