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

Commitca9e792

Browse files
committed
Fix pg_dump's failure to honor dependencies of SQL functions.
A new-style SQL function can contain a parse-time dependencyon a unique index, much as views and matviews can (such casesarise from GROUP BY and ON CONFLICT clauses, for example).To dump and restore such a function successfully, pg_dump mustpostpone the function until after the unique index is created,which will happen in the post-data part of the dump. Thereforewe have to remove the normal constraint that functions aredumped in pre-data. Add code similar to the existing logicthat handles this for matviews. I added test cases for bothas well, since code coverage tests showed that we weren'ttesting the matview logic.Per report from Sami Imseih. Back-patch to v14 wherenew-style SQL functions came in.Discussion:https://postgr.es/m/2C1933AB-C2F8-499B-9D18-4AC1882256A0@amazon.com
1 parent751ba1a commitca9e792

File tree

4 files changed

+89
-1
lines changed

4 files changed

+89
-1
lines changed

‎src/bin/pg_dump/pg_dump.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5950,6 +5950,7 @@ getAggregates(Archive *fout, int *numAggs)
59505950
agginfo[i].aggfn.argtypes,
59515951
agginfo[i].aggfn.nargs);
59525952
}
5953+
agginfo[i].aggfn.postponed_def = false; /* might get set during sort */
59535954

59545955
/* Decide whether we want to dump it */
59555956
selectDumpableObject(&(agginfo[i].aggfn.dobj), fout);
@@ -6148,6 +6149,7 @@ getFuncs(Archive *fout, int *numFuncs)
61486149
parseOidArray(PQgetvalue(res, i, i_proargtypes),
61496150
finfo[i].argtypes, finfo[i].nargs);
61506151
}
6152+
finfo[i].postponed_def = false; /* might get set during sort */
61516153

61526154
/* Decide whether we want to dump it */
61536155
selectDumpableObject(&(finfo[i].dobj), fout);
@@ -12019,7 +12021,8 @@ dumpFunc(Archive *fout, const FuncInfo *finfo)
1201912021
.namespace = finfo->dobj.namespace->dobj.name,
1202012022
.owner = finfo->rolname,
1202112023
.description = keyword,
12022-
.section = SECTION_PRE_DATA,
12024+
.section = finfo->postponed_def ?
12025+
SECTION_POST_DATA : SECTION_PRE_DATA,
1202312026
.createStmt = q->data,
1202412027
.dropStmt = delqry->data));
1202512028

‎src/bin/pg_dump/pg_dump.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,7 @@ typedef struct _funcInfo
227227
intnargs;
228228
Oid*argtypes;
229229
Oidprorettype;
230+
boolpostponed_def;/* function must be postponed into post-data */
230231
}FuncInfo;
231232

232233
/* AggInfo is a superset of FuncInfo */

‎src/bin/pg_dump/pg_dump_sort.c

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -868,6 +868,28 @@ repairMatViewBoundaryMultiLoop(DumpableObject *boundaryobj,
868868
}
869869
}
870870

871+
/*
872+
* If a function is involved in a multi-object loop, we can't currently fix
873+
* that by splitting it into two DumpableObjects. As a stopgap, we try to fix
874+
* it by dropping the constraint that the function be dumped in the pre-data
875+
* section. This is sufficient to handle cases where a function depends on
876+
* some unique index, as can happen if it has a GROUP BY for example.
877+
*/
878+
staticvoid
879+
repairFunctionBoundaryMultiLoop(DumpableObject*boundaryobj,
880+
DumpableObject*nextobj)
881+
{
882+
/* remove boundary's dependency on object after it in loop */
883+
removeObjectDependency(boundaryobj,nextobj->dumpId);
884+
/* if that object is a function, mark it as postponed into post-data */
885+
if (nextobj->objType==DO_FUNC)
886+
{
887+
FuncInfo*nextinfo= (FuncInfo*)nextobj;
888+
889+
nextinfo->postponed_def= true;
890+
}
891+
}
892+
871893
/*
872894
* Because we make tables depend on their CHECK constraints, while there
873895
* will be an automatic dependency in the other direction, we need to break
@@ -1062,6 +1084,28 @@ repairDependencyLoop(DumpableObject **loop,
10621084
}
10631085
}
10641086

1087+
/* Indirect loop involving function and data boundary */
1088+
if (nLoop>2)
1089+
{
1090+
for (i=0;i<nLoop;i++)
1091+
{
1092+
if (loop[i]->objType==DO_FUNC)
1093+
{
1094+
for (j=0;j<nLoop;j++)
1095+
{
1096+
if (loop[j]->objType==DO_PRE_DATA_BOUNDARY)
1097+
{
1098+
DumpableObject*nextobj;
1099+
1100+
nextobj= (j<nLoop-1) ?loop[j+1] :loop[0];
1101+
repairFunctionBoundaryMultiLoop(loop[j],nextobj);
1102+
return;
1103+
}
1104+
}
1105+
}
1106+
}
1107+
}
1108+
10651109
/* Table and CHECK constraint */
10661110
if (nLoop==2&&
10671111
loop[0]->objType==DO_TABLE&&

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

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2095,6 +2095,27 @@
20952095
unlike => { exclude_dump_test_schema => 1, },
20962096
},
20972097
2098+
'Check ordering of a function that depends on a primary key' => {
2099+
create_order => 41,
2100+
create_sql => '
2101+
CREATE TABLE dump_test.ordering_table (id int primary key, data int);
2102+
CREATE FUNCTION dump_test.ordering_func ()
2103+
RETURNS SETOF dump_test.ordering_table
2104+
LANGUAGE sql BEGIN ATOMIC
2105+
SELECT * FROM dump_test.ordering_table GROUP BY id; END;',
2106+
regexp => qr/^
2107+
\QALTER TABLE ONLY dump_test.ordering_table\E
2108+
\n\s+\QADD CONSTRAINT ordering_table_pkey PRIMARY KEY (id);\E
2109+
.*^
2110+
\QCREATE FUNCTION dump_test.ordering_func\E/xms,
2111+
like =>
2112+
{%full_runs,%dump_test_schema_runs, section_post_data => 1, },
2113+
unlike => {
2114+
exclude_dump_test_schema => 1,
2115+
only_dump_measurement => 1,
2116+
},
2117+
},
2118+
20982119
'CREATE PROCEDURE dump_test.ptest1' => {
20992120
create_order => 41,
21002121
create_sql => 'CREATE PROCEDURE dump_test.ptest1(a int)
@@ -2307,6 +2328,25 @@
23072328
{ exclude_dump_test_schema => 1, no_toast_compression => 1, },
23082329
},
23092330
2331+
'Check ordering of a matview that depends on a primary key' => {
2332+
create_order => 42,
2333+
create_sql => '
2334+
CREATE MATERIALIZED VIEW dump_test.ordering_view AS
2335+
SELECT * FROM dump_test.ordering_table GROUP BY id;',
2336+
regexp => qr/^
2337+
\QALTER TABLE ONLY dump_test.ordering_table\E
2338+
\n\s+\QADD CONSTRAINT ordering_table_pkey PRIMARY KEY (id);\E
2339+
.*^
2340+
\QCREATE MATERIALIZED VIEW dump_test.ordering_view AS\E
2341+
\n\s+\QSELECT ordering_table.id,\E/xms,
2342+
like =>
2343+
{%full_runs,%dump_test_schema_runs, section_post_data => 1, },
2344+
unlike => {
2345+
exclude_dump_test_schema => 1,
2346+
only_dump_measurement => 1,
2347+
},
2348+
},
2349+
23102350
'CREATE POLICY p1 ON test_table' => {
23112351
create_order => 22,
23122352
create_sql => 'CREATE POLICY p1 ON dump_test.test_table

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp