|
30 | 30 | #include <io.h>
|
31 | 31 | #endif
|
32 | 32 |
|
| 33 | +#include "catalog/pg_class_d.h" |
33 | 34 | #include "common/string.h"
|
34 | 35 | #include "compress_io.h"
|
35 | 36 | #include "dumputils.h"
|
@@ -62,6 +63,8 @@ static void _becomeOwner(ArchiveHandle *AH, TocEntry *te);
|
62 | 63 | static void _selectOutputSchema(ArchiveHandle *AH, const char *schemaName);
|
63 | 64 | static void _selectTablespace(ArchiveHandle *AH, const char *tablespace);
|
64 | 65 | static void _selectTableAccessMethod(ArchiveHandle *AH, const char *tableam);
|
| 66 | +static void _printTableAccessMethodNoStorage(ArchiveHandle *AH, |
| 67 | + TocEntry *te); |
65 | 68 | static void processEncodingEntry(ArchiveHandle *AH, TocEntry *te);
|
66 | 69 | static void processStdStringsEntry(ArchiveHandle *AH, TocEntry *te);
|
67 | 70 | static void processSearchPathEntry(ArchiveHandle *AH, TocEntry *te);
|
@@ -1222,6 +1225,7 @@ ArchiveEntry(Archive *AHX, CatalogId catalogId, DumpId dumpId,
|
1222 | 1225 | newToc->namespace = opts->namespace ? pg_strdup(opts->namespace) : NULL;
|
1223 | 1226 | newToc->tablespace = opts->tablespace ? pg_strdup(opts->tablespace) : NULL;
|
1224 | 1227 | newToc->tableam = opts->tableam ? pg_strdup(opts->tableam) : NULL;
|
| 1228 | + newToc->relkind = opts->relkind; |
1225 | 1229 | newToc->owner = opts->owner ? pg_strdup(opts->owner) : NULL;
|
1226 | 1230 | newToc->desc = pg_strdup(opts->description);
|
1227 | 1231 | newToc->defn = opts->createStmt ? pg_strdup(opts->createStmt) : NULL;
|
@@ -2602,6 +2606,7 @@ WriteToc(ArchiveHandle *AH)
|
2602 | 2606 | WriteStr(AH, te->namespace);
|
2603 | 2607 | WriteStr(AH, te->tablespace);
|
2604 | 2608 | WriteStr(AH, te->tableam);
|
| 2609 | + WriteInt(AH, te->relkind); |
2605 | 2610 | WriteStr(AH, te->owner);
|
2606 | 2611 | WriteStr(AH, "false");
|
2607 | 2612 |
|
@@ -2707,6 +2712,9 @@ ReadToc(ArchiveHandle *AH)
|
2707 | 2712 | if (AH->version >= K_VERS_1_14)
|
2708 | 2713 | te->tableam = ReadStr(AH);
|
2709 | 2714 |
|
| 2715 | + if (AH->version >= K_VERS_1_16) |
| 2716 | + te->relkind = ReadInt(AH); |
| 2717 | + |
2710 | 2718 | te->owner = ReadStr(AH);
|
2711 | 2719 | is_supported = true;
|
2712 | 2720 | if (AH->version < K_VERS_1_9)
|
@@ -3567,6 +3575,51 @@ _selectTableAccessMethod(ArchiveHandle *AH, const char *tableam)
|
3567 | 3575 | AH->currTableAm = pg_strdup(want);
|
3568 | 3576 | }
|
3569 | 3577 |
|
| 3578 | +/* |
| 3579 | + * Set the proper default table access method for a table without storage. |
| 3580 | + * Currently, this is required only for partitioned tables with a table AM. |
| 3581 | + */ |
| 3582 | +static void |
| 3583 | +_printTableAccessMethodNoStorage(ArchiveHandle *AH, TocEntry *te) |
| 3584 | +{ |
| 3585 | + RestoreOptions *ropt = AH->public.ropt; |
| 3586 | + const char *tableam = te->tableam; |
| 3587 | + PQExpBuffer cmd; |
| 3588 | + |
| 3589 | + /* do nothing in --no-table-access-method mode */ |
| 3590 | + if (ropt->noTableAm) |
| 3591 | + return; |
| 3592 | + |
| 3593 | + if (!tableam) |
| 3594 | + return; |
| 3595 | + |
| 3596 | + Assert(te->relkind == RELKIND_PARTITIONED_TABLE); |
| 3597 | + |
| 3598 | + cmd = createPQExpBuffer(); |
| 3599 | + |
| 3600 | + appendPQExpBufferStr(cmd, "ALTER TABLE "); |
| 3601 | + appendPQExpBuffer(cmd, "%s ", fmtQualifiedId(te->namespace, te->tag)); |
| 3602 | + appendPQExpBuffer(cmd, "SET ACCESS METHOD %s;", |
| 3603 | + fmtId(tableam)); |
| 3604 | + |
| 3605 | + if (RestoringToDB(AH)) |
| 3606 | + { |
| 3607 | + PGresult *res; |
| 3608 | + |
| 3609 | + res = PQexec(AH->connection, cmd->data); |
| 3610 | + |
| 3611 | + if (!res || PQresultStatus(res) != PGRES_COMMAND_OK) |
| 3612 | + warn_or_exit_horribly(AH, |
| 3613 | + "could not alter table access method: %s", |
| 3614 | + PQerrorMessage(AH->connection)); |
| 3615 | + PQclear(res); |
| 3616 | + } |
| 3617 | + else |
| 3618 | + ahprintf(AH, "%s\n\n", cmd->data); |
| 3619 | + |
| 3620 | + destroyPQExpBuffer(cmd); |
| 3621 | +} |
| 3622 | + |
3570 | 3623 | /*
|
3571 | 3624 | * Extract an object description for a TOC entry, and append it to buf.
|
3572 | 3625 | *
|
@@ -3673,11 +3726,17 @@ _printTocEntry(ArchiveHandle *AH, TocEntry *te, bool isData)
|
3673 | 3726 | {
|
3674 | 3727 | RestoreOptions *ropt = AH->public.ropt;
|
3675 | 3728 |
|
3676 |
| - /* Select owner, schema, tablespace and default AM as necessary */ |
| 3729 | + /* |
| 3730 | + * Select owner, schema, tablespace and default AM as necessary. The |
| 3731 | + * default access method for partitioned tables is handled after |
| 3732 | + * generating the object definition, as it requires an ALTER command |
| 3733 | + * rather than SET. |
| 3734 | + */ |
3677 | 3735 | _becomeOwner(AH, te);
|
3678 | 3736 | _selectOutputSchema(AH, te->namespace);
|
3679 | 3737 | _selectTablespace(AH, te->tablespace);
|
3680 |
| - _selectTableAccessMethod(AH, te->tableam); |
| 3738 | + if (te->relkind != RELKIND_PARTITIONED_TABLE) |
| 3739 | + _selectTableAccessMethod(AH, te->tableam); |
3681 | 3740 |
|
3682 | 3741 | /* Emit header comment for item */
|
3683 | 3742 | if (!AH->noTocComments)
|
@@ -3812,6 +3871,13 @@ _printTocEntry(ArchiveHandle *AH, TocEntry *te, bool isData)
|
3812 | 3871 | }
|
3813 | 3872 | }
|
3814 | 3873 |
|
| 3874 | + /* |
| 3875 | + * Select a partitioned table's default AM, once the table definition has |
| 3876 | + * been generated. |
| 3877 | + */ |
| 3878 | + if (te->relkind == RELKIND_PARTITIONED_TABLE) |
| 3879 | + _printTableAccessMethodNoStorage(AH, te); |
| 3880 | + |
3815 | 3881 | /*
|
3816 | 3882 | * If it's an ACL entry, it might contain SET SESSION AUTHORIZATION
|
3817 | 3883 | * commands, so we can no longer assume we know the current auth setting.
|
|
0 commit comments