Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit3b925e9

Browse files
committed
tableam: Add pg_dump support.
This adds pg_dump support for table AMs in a similar manner to howtablespaces are handled. That is, instead of specifying the AM forevery CREATE TABLE etc, emit SET default_table_access_methodstatements. That makes it easier to change the AM for all/most tablesin a dump, and allows restore to succeed even if some AM is notavailable.This increases the dump archive version, as a tables/matview's AMneeds to be tracked therein.Author: Dimitri Dolgov, Andres FreundDiscussion:https://postgr.es/m/20180703070645.wchpu5muyto5n647@alap3.anarazel.dehttps://postgr.es/m/20190304234700.w5tmhducs5wxgzls@alap3.anarazel.de
1 parent8586bf7 commit3b925e9

File tree

5 files changed

+142
-4
lines changed

5 files changed

+142
-4
lines changed

‎src/bin/pg_dump/pg_backup_archiver.c

Lines changed: 56 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ static void _becomeUser(ArchiveHandle *AH, const char *user);
8585
staticvoid_becomeOwner(ArchiveHandle*AH,TocEntry*te);
8686
staticvoid_selectOutputSchema(ArchiveHandle*AH,constchar*schemaName);
8787
staticvoid_selectTablespace(ArchiveHandle*AH,constchar*tablespace);
88+
staticvoid_selectTableAccessMethod(ArchiveHandle*AH,constchar*tableam);
8889
staticvoidprocessEncodingEntry(ArchiveHandle*AH,TocEntry*te);
8990
staticvoidprocessStdStringsEntry(ArchiveHandle*AH,TocEntry*te);
9091
staticvoidprocessSearchPathEntry(ArchiveHandle*AH,TocEntry*te);
@@ -1090,6 +1091,7 @@ ArchiveEntry(Archive *AHX, CatalogId catalogId, DumpId dumpId,
10901091
newToc->tag=pg_strdup(opts->tag);
10911092
newToc->namespace=opts->namespace ?pg_strdup(opts->namespace) :NULL;
10921093
newToc->tablespace=opts->tablespace ?pg_strdup(opts->tablespace) :NULL;
1094+
newToc->tableam=opts->tableam ?pg_strdup(opts->tableam) :NULL;
10931095
newToc->owner=pg_strdup(opts->owner);
10941096
newToc->desc=pg_strdup(opts->description);
10951097
newToc->defn=pg_strdup(opts->createStmt);
@@ -2350,6 +2352,7 @@ _allocAH(const char *FileSpec, const ArchiveFormat fmt,
23502352
AH->currUser=NULL;/* unknown */
23512353
AH->currSchema=NULL;/* ditto */
23522354
AH->currTablespace=NULL;/* ditto */
2355+
AH->currTableAm=NULL;/* ditto */
23532356

23542357
AH->toc= (TocEntry*)pg_malloc0(sizeof(TocEntry));
23552358

@@ -2576,6 +2579,7 @@ WriteToc(ArchiveHandle *AH)
25762579
WriteStr(AH,te->copyStmt);
25772580
WriteStr(AH,te->namespace);
25782581
WriteStr(AH,te->tablespace);
2582+
WriteStr(AH,te->tableam);
25792583
WriteStr(AH,te->owner);
25802584
WriteStr(AH,"false");
25812585

@@ -2678,6 +2682,9 @@ ReadToc(ArchiveHandle *AH)
26782682
if (AH->version >=K_VERS_1_10)
26792683
te->tablespace=ReadStr(AH);
26802684

2685+
if (AH->version >=K_VERS_1_14)
2686+
te->tableam=ReadStr(AH);
2687+
26812688
te->owner=ReadStr(AH);
26822689
if (AH->version<K_VERS_1_9||strcmp(ReadStr(AH),"true")==0)
26832690
write_msg(modulename,
@@ -3431,6 +3438,48 @@ _selectTablespace(ArchiveHandle *AH, const char *tablespace)
34313438
destroyPQExpBuffer(qry);
34323439
}
34333440

3441+
/*
3442+
* Set the proper default_table_access_method value for the table.
3443+
*/
3444+
staticvoid
3445+
_selectTableAccessMethod(ArchiveHandle*AH,constchar*tableam)
3446+
{
3447+
PQExpBuffercmd;
3448+
constchar*want,*have;
3449+
3450+
have=AH->currTableAm;
3451+
want=tableam;
3452+
3453+
if (!want)
3454+
return;
3455+
3456+
if (have&&strcmp(want,have)==0)
3457+
return;
3458+
3459+
cmd=createPQExpBuffer();
3460+
appendPQExpBuffer(cmd,"SET default_table_access_method = %s;",fmtId(want));
3461+
3462+
if (RestoringToDB(AH))
3463+
{
3464+
PGresult*res;
3465+
3466+
res=PQexec(AH->connection,cmd->data);
3467+
3468+
if (!res||PQresultStatus(res)!=PGRES_COMMAND_OK)
3469+
warn_or_exit_horribly(AH,modulename,
3470+
"could not set default_table_access_method: %s",
3471+
PQerrorMessage(AH->connection));
3472+
3473+
PQclear(res);
3474+
}
3475+
else
3476+
ahprintf(AH,"%s\n\n",cmd->data);
3477+
3478+
destroyPQExpBuffer(cmd);
3479+
3480+
AH->currTableAm=pg_strdup(want);
3481+
}
3482+
34343483
/*
34353484
* Extract an object description for a TOC entry, and append it to buf.
34363485
*
@@ -3526,10 +3575,11 @@ _printTocEntry(ArchiveHandle *AH, TocEntry *te, bool isData)
35263575
{
35273576
RestoreOptions*ropt=AH->public.ropt;
35283577

3529-
/* Select owner, schema, andtablespace as necessary */
3578+
/* Select owner, schema,tablespaceanddefault AM as necessary */
35303579
_becomeOwner(AH,te);
35313580
_selectOutputSchema(AH,te->namespace);
35323581
_selectTablespace(AH,te->tablespace);
3582+
_selectTableAccessMethod(AH,te->tableam);
35333583

35343584
/* Emit header comment for item */
35353585
if (!AH->noTocComments)
@@ -4006,6 +4056,9 @@ restore_toc_entries_prefork(ArchiveHandle *AH, TocEntry *pending_list)
40064056
if (AH->currTablespace)
40074057
free(AH->currTablespace);
40084058
AH->currTablespace=NULL;
4059+
if (AH->currTableAm)
4060+
free(AH->currTableAm);
4061+
AH->currTableAm=NULL;
40094062
}
40104063

40114064
/*
@@ -4891,6 +4944,8 @@ DeCloneArchive(ArchiveHandle *AH)
48914944
free(AH->currSchema);
48924945
if (AH->currTablespace)
48934946
free(AH->currTablespace);
4947+
if (AH->currTableAm)
4948+
free(AH->currTableAm);
48944949
if (AH->savedPassword)
48954950
free(AH->savedPassword);
48964951

‎src/bin/pg_dump/pg_backup_archiver.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ typedef z_stream *z_streamp;
9494
* entries */
9595
#defineK_VERS_1_13 MAKE_ARCHIVE_VERSION(1, 13, 0)/* change search_path
9696
* behavior */
97+
#defineK_VERS_1_14 MAKE_ARCHIVE_VERSION(1, 14, 0)/* add tableam */
9798

9899
/*
99100
* Current archive version number (the format we can output)
@@ -102,7 +103,7 @@ typedef z_stream *z_streamp;
102103
* https://postgr.es/m/20190227123217.GA27552@alvherre.pgsql
103104
*/
104105
#defineK_VERS_MAJOR 1
105-
#defineK_VERS_MINOR13
106+
#defineK_VERS_MINOR14
106107
#defineK_VERS_REV 0
107108
#defineK_VERS_SELF MAKE_ARCHIVE_VERSION(K_VERS_MAJOR, K_VERS_MINOR, K_VERS_REV);
108109

@@ -352,6 +353,7 @@ struct _archiveHandle
352353
char*currUser;/* current username, or NULL if unknown */
353354
char*currSchema;/* current schema, or NULL */
354355
char*currTablespace;/* current tablespace, or NULL */
356+
char*currTableAm;/* current table access method, or NULL */
355357

356358
void*lo_buf;
357359
size_tlo_buf_used;
@@ -378,6 +380,7 @@ struct _tocEntry
378380
char*namespace;/* null or empty string if not in a schema */
379381
char*tablespace;/* null if not in a tablespace; empty string
380382
* means use database default */
383+
char*tableam;/* table access method, only for TABLE tags */
381384
char*owner;
382385
char*desc;
383386
char*defn;
@@ -416,6 +419,7 @@ typedef struct _archiveOpts
416419
constchar*tag;
417420
constchar*namespace;
418421
constchar*tablespace;
422+
constchar*tableam;
419423
constchar*owner;
420424
constchar*description;
421425
teSectionsection;

‎src/bin/pg_dump/pg_dump.c

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5856,6 +5856,7 @@ getTables(Archive *fout, int *numTables)
58565856
inti_partkeydef;
58575857
inti_ispartition;
58585858
inti_partbound;
5859+
inti_amname;
58595860

58605861
/*
58615862
* Find all the tables and table-like objects.
@@ -5941,7 +5942,7 @@ getTables(Archive *fout, int *numTables)
59415942
"tc.relfrozenxid AS tfrozenxid, "
59425943
"tc.relminmxid AS tminmxid, "
59435944
"c.relpersistence, c.relispopulated, "
5944-
"c.relreplident, c.relpages, "
5945+
"c.relreplident, c.relpages,am.amname,"
59455946
"CASE WHEN c.reloftype <> 0 THEN c.reloftype::pg_catalog.regtype ELSE NULL END AS reloftype, "
59465947
"d.refobjid AS owning_tab, "
59475948
"d.refobjsubid AS owning_col, "
@@ -5972,6 +5973,7 @@ getTables(Archive *fout, int *numTables)
59725973
"d.objsubid = 0 AND "
59735974
"d.refclassid = c.tableoid AND d.deptype IN ('a', 'i')) "
59745975
"LEFT JOIN pg_class tc ON (c.reltoastrelid = tc.oid) "
5976+
"LEFT JOIN pg_am am ON (c.relam = am.oid) "
59755977
"LEFT JOIN pg_init_privs pip ON "
59765978
"(c.oid = pip.objoid "
59775979
"AND pip.classoid = 'pg_class'::regclass "
@@ -6439,6 +6441,7 @@ getTables(Archive *fout, int *numTables)
64396441
i_partkeydef = PQfnumber(res, "partkeydef");
64406442
i_ispartition = PQfnumber(res, "ispartition");
64416443
i_partbound = PQfnumber(res, "partbound");
6444+
i_amname = PQfnumber(res, "amname");
64426445

64436446
if (dopt->lockWaitTimeout)
64446447
{
@@ -6508,6 +6511,10 @@ getTables(Archive *fout, int *numTables)
65086511
else
65096512
tblinfo[i].checkoption = pg_strdup(PQgetvalue(res, i, i_checkoption));
65106513
tblinfo[i].toast_reloptions = pg_strdup(PQgetvalue(res, i, i_toastreloptions));
6514+
if (PQgetisnull(res, i, i_amname))
6515+
tblinfo[i].amname = NULL;
6516+
else
6517+
tblinfo[i].amname = pg_strdup(PQgetvalue(res, i, i_amname));
65116518

65126519
/* other fields were zeroed above */
65136520

@@ -12632,6 +12639,9 @@ dumpAccessMethod(Archive *fout, AccessMethodInfo *aminfo)
1263212639
case AMTYPE_INDEX:
1263312640
appendPQExpBuffer(q, "TYPE INDEX ");
1263412641
break;
12642+
case AMTYPE_TABLE:
12643+
appendPQExpBuffer(q, "TYPE TABLE ");
12644+
break;
1263512645
default:
1263612646
write_msg(NULL, "WARNING: invalid type \"%c\" of access method \"%s\"\n",
1263712647
aminfo->amtype, qamname);
@@ -16067,18 +16077,26 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo)
1606716077
tbinfo->dobj.namespace->dobj.name);
1606816078

1606916079
if (tbinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
16080+
{
16081+
char *tableam = NULL;
16082+
16083+
if (tbinfo->relkind == RELKIND_RELATION ||
16084+
tbinfo->relkind == RELKIND_MATVIEW)
16085+
tableam = tbinfo->amname;
16086+
1607016087
ArchiveEntry(fout, tbinfo->dobj.catId, tbinfo->dobj.dumpId,
1607116088
ARCHIVE_OPTS(.tag = tbinfo->dobj.name,
1607216089
.namespace = tbinfo->dobj.namespace->dobj.name,
1607316090
.tablespace = (tbinfo->relkind == RELKIND_VIEW) ?
1607416091
NULL : tbinfo->reltablespace,
16092+
.tableam = tableam,
1607516093
.owner = tbinfo->rolname,
1607616094
.description = reltypename,
1607716095
.section = tbinfo->postponed_def ?
1607816096
SECTION_POST_DATA : SECTION_PRE_DATA,
1607916097
.createStmt = q->data,
1608016098
.dropStmt = delq->data));
16081-
16099+
}
1608216100

1608316101
/* Dump Table Comments */
1608416102
if (tbinfo->dobj.dump & DUMP_COMPONENT_COMMENT)

‎src/bin/pg_dump/pg_dump.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -324,6 +324,7 @@ typedef struct _tableInfo
324324
char*partkeydef;/* partition key definition */
325325
char*partbound;/* partition bound definition */
326326
boolneeds_override;/* has GENERATED ALWAYS AS IDENTITY */
327+
char*amname;/* relation access method */
327328

328329
/*
329330
* Stuff computed only for dumpable tables.

‎src/bin/pg_dump/t/002_pg_dump.pl

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3070,6 +3070,66 @@
30703070
unlike => { no_privs => 1, },
30713071
},
30723072
3073+
3074+
'CREATE ACCESS METHOD regress_test_table_am' => {
3075+
create_order => 11,
3076+
create_sql => 'CREATE ACCESS METHOD regress_table_am TYPE TABLE HANDLER heap_tableam_handler;',
3077+
regexp => qr/^
3078+
\QCREATE ACCESS METHOD regress_table_am TYPE TABLE HANDLER heap_tableam_handler;\E
3079+
\n/xm,
3080+
like => {
3081+
%full_runs,
3082+
section_pre_data=> 1,
3083+
},
3084+
},
3085+
3086+
# It's a bit tricky to ensure that the proper SET of default table
3087+
# AM occurs. To achieve that we create a table with the standard
3088+
# AM, test AM, standard AM. That guarantees that there needs to be
3089+
# a SET interspersed. Then use a regex that prevents interspersed
3090+
# SET ...; statements, followed by the exptected CREATE TABLE. Not
3091+
# pretty, but seems hard to do better in this framework.
3092+
'CREATE TABLE regress_pg_dump_table_am' => {
3093+
create_order => 12,
3094+
create_sql => '
3095+
CREATE TABLE dump_test.regress_pg_dump_table_am_0() USING heap;
3096+
CREATE TABLE dump_test.regress_pg_dump_table_am_1 (col1 int) USING regress_table_am;
3097+
CREATE TABLE dump_test.regress_pg_dump_table_am_2() USING heap;',
3098+
regexp => qr/^
3099+
\QSET default_table_access_method = regress_table_am;\E
3100+
(\n(?!SET[^;]+;)[^\n]*)*
3101+
\n\QCREATE TABLE dump_test.regress_pg_dump_table_am_1 (\E
3102+
\n\s+\Qcol1 integer\E
3103+
\n\);/xm,
3104+
like => {
3105+
%full_runs,
3106+
%dump_test_schema_runs,
3107+
section_pre_data => 1,
3108+
},
3109+
unlike => { exclude_dump_test_schema => 1},
3110+
},
3111+
3112+
'CREATE MATERIALIZED VIEW regress_pg_dump_matview_am' => {
3113+
create_order => 13,
3114+
create_sql => '
3115+
CREATE MATERIALIZED VIEW dump_test.regress_pg_dump_matview_am_0 USING heap AS SELECT 1;
3116+
CREATE MATERIALIZED VIEW dump_test.regress_pg_dump_matview_am_1
3117+
USING regress_table_am AS SELECT count(*) FROM pg_class;
3118+
CREATE MATERIALIZED VIEW dump_test.regress_pg_dump_matview_am_2 USING heap AS SELECT 1;',
3119+
regexp => qr/^
3120+
\QSET default_table_access_method = regress_table_am;\E
3121+
(\n(?!SET[^;]+;)[^\n]*)*
3122+
\QCREATE MATERIALIZED VIEW dump_test.regress_pg_dump_matview_am_1 AS\E
3123+
\n\s+\QSELECT count(*) AS count\E
3124+
\n\s+\QFROM pg_class\E
3125+
\n\s+\QWITH NO DATA;\E\n/xm,
3126+
like => {
3127+
%full_runs,
3128+
%dump_test_schema_runs,
3129+
section_pre_data => 1,
3130+
},
3131+
unlike => { exclude_dump_test_schema => 1},
3132+
}
30733133
);
30743134
30753135
#########################################

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp