Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 542975a

Browse files
committed
Fix dumping of casts and transforms using built-in functions
In pg_dump.c dumpCast() and dumpTransform(), we would happily ignore the cast or transform if it happened to use a built-in function because we weren't including the information about built-in functions when querying pg_proc from getFuncs(). Modify the query in getFuncs() to also gather information about functions which are used by user-defined casts and transforms (where "user-defined" means "has an OID >= FirstNormalObjectId"). This also adds to the TAP regression tests for 9.6 and master to cover these types of objects. Back-patch all the way for casts, back to 9.5 for transforms. Discussion: https://www.postgresql.org/message-id/flat/20160504183952.GE10850%40tamriel.snowman.net
1 parent e45319b commit 542975a

File tree

2 files changed

+88
-40
lines changed

2 files changed

+88
-40
lines changed

src/bin/pg_dump/pg_dump.c

Lines changed: 37 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4978,8 +4978,11 @@ getFuncs(Archive *fout, int *numFuncs)
49784978
* 3. Otherwise, we normally exclude functions in pg_catalog. However, if
49794979
* they're members of extensions and we are in binary-upgrade mode then
49804980
* include them, since we want to dump extension members individually in
4981-
* that mode. Also, in 9.6 and up, include functions in pg_catalog if
4982-
* they have an ACL different from what's shown in pg_init_privs.
4981+
* that mode. Also, if they are used by casts or transforms then we need
4982+
* to gather the information about them, though they won't be dumped if
4983+
* they are built-in. Also, in 9.6 and up, include functions in
4984+
* pg_catalog if they have an ACL different from what's shown in
4985+
* pg_init_privs.
49834986
*/
49844987
if (fout->remoteVersion >= 90600)
49854988
{
@@ -5013,12 +5016,21 @@ getFuncs(Archive *fout, int *numFuncs)
50135016
"\n AND ("
50145017
"\n pronamespace != "
50155018
"(SELECT oid FROM pg_namespace "
5016-
"WHERE nspname = 'pg_catalog')",
5019+
"WHERE nspname = 'pg_catalog')"
5020+
"\n OR EXISTS (SELECT 1 FROM pg_cast"
5021+
"\n WHERE pg_cast.oid > %u "
5022+
"\n AND p.oid = pg_cast.castfunc)"
5023+
"\n OR EXISTS (SELECT 1 FROM pg_transform"
5024+
"\n WHERE pg_transform.oid > %u AND "
5025+
"\n (p.oid = pg_transform.trffromsql"
5026+
"\n OR p.oid = pg_transform.trftosql))",
50175027
acl_subquery->data,
50185028
racl_subquery->data,
50195029
initacl_subquery->data,
50205030
initracl_subquery->data,
5021-
username_subquery);
5031+
username_subquery,
5032+
g_last_builtin_oid,
5033+
g_last_builtin_oid);
50225034
if (dopt->binary_upgrade)
50235035
appendPQExpBufferStr(query,
50245036
"\n OR EXISTS(SELECT 1 FROM pg_depend WHERE "
@@ -5052,11 +5064,24 @@ getFuncs(Archive *fout, int *numFuncs)
50525064
"\n AND NOT EXISTS (SELECT 1 FROM pg_depend "
50535065
"WHERE classid = 'pg_proc'::regclass AND "
50545066
"objid = p.oid AND deptype = 'i')");
5055-
appendPQExpBufferStr(query,
5067+
appendPQExpBuffer(query,
50565068
"\n AND ("
50575069
"\n pronamespace != "
50585070
"(SELECT oid FROM pg_namespace "
5059-
"WHERE nspname = 'pg_catalog')");
5071+
"WHERE nspname = 'pg_catalog')"
5072+
"\n OR EXISTS (SELECT 1 FROM pg_cast"
5073+
"\n WHERE pg_cast.oid > '%u'::oid"
5074+
"\n AND p.oid = pg_cast.castfunc)",
5075+
g_last_builtin_oid);
5076+
5077+
if (fout->remoteVersion >= 90500)
5078+
appendPQExpBuffer(query,
5079+
"\n OR EXISTS (SELECT 1 FROM pg_transform"
5080+
"\n WHERE pg_transform.oid > '%u'::oid"
5081+
"\n AND (p.oid = pg_transform.trffromsql"
5082+
"\n OR p.oid = pg_transform.trftosql))",
5083+
g_last_builtin_oid);
5084+
50605085
if (dopt->binary_upgrade && fout->remoteVersion >= 90100)
50615086
appendPQExpBufferStr(query,
50625087
"\n OR EXISTS(SELECT 1 FROM pg_depend WHERE "
@@ -11871,7 +11896,8 @@ dumpCast(Archive *fout, CastInfo *cast)
1187111896
{
1187211897
funcInfo = findFuncByOid(cast->castfunc);
1187311898
if (funcInfo == NULL)
11874-
return;
11899+
exit_horribly(NULL, "unable to find function definition for OID %u",
11900+
cast->castfunc);
1187511901
}
1187611902

1187711903
/*
@@ -11980,13 +12006,15 @@ dumpTransform(Archive *fout, TransformInfo *transform)
1198012006
{
1198112007
fromsqlFuncInfo = findFuncByOid(transform->trffromsql);
1198212008
if (fromsqlFuncInfo == NULL)
11983-
return;
12009+
exit_horribly(NULL, "unable to find function definition for OID %u",
12010+
transform->trffromsql);
1198412011
}
1198512012
if (OidIsValid(transform->trftosql))
1198612013
{
1198712014
tosqlFuncInfo = findFuncByOid(transform->trftosql);
1198812015
if (tosqlFuncInfo == NULL)
11989-
return;
12016+
exit_horribly(NULL, "unable to find function definition for OID %u",
12017+
transform->trftosql);
1199012018
}
1199112019

1199212020
/* Make sure we are in proper schema (needed for getFormattedTypeName) */

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

Lines changed: 51 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -913,6 +913,32 @@
913913
section_pre_data => 1,
914914
section_post_data => 1,
915915
test_schema_plus_blobs => 1, }, },
916+
'CREATE CAST FOR timestamptz' => {
917+
create_order => 51,
918+
create_sql => 'CREATE CAST (timestamptz AS interval) WITH FUNCTION age(timestamptz) AS ASSIGNMENT;',
919+
regexp => qr/CREATE CAST \(timestamp with time zone AS interval\) WITH FUNCTION pg_catalog\.age\(timestamp with time zone\) AS ASSIGNMENT;/m,
920+
like => {
921+
binary_upgrade => 1,
922+
clean => 1,
923+
clean_if_exists => 1,
924+
createdb => 1,
925+
defaults => 1,
926+
exclude_dump_test_schema => 1,
927+
exclude_test_table => 1,
928+
exclude_test_table_data => 1,
929+
no_blobs => 1,
930+
no_privs => 1,
931+
no_owner => 1,
932+
pg_dumpall_dbprivs => 1,
933+
schema_only => 1,
934+
section_pre_data => 1,
935+
},
936+
unlike => {
937+
only_dump_test_schema => 1,
938+
only_dump_test_table => 1,
939+
pg_dumpall_globals => 1,
940+
section_post_data => 1,
941+
test_schema_plus_blobs => 1, }, },
916942
'CREATE DATABASE postgres' => {
917943
regexp => qr/^
918944
\QCREATE DATABASE postgres WITH TEMPLATE = template0 \E
@@ -1515,37 +1541,31 @@
15151541
pg_dumpall_globals_clean => 1,
15161542
section_post_data => 1,
15171543
test_schema_plus_blobs => 1, }, },
1518-
#######################################
1519-
# Currently broken.
1520-
#######################################
1521-
#
1522-
# 'CREATE TRANSFORM FOR int' => {
1523-
# create_order => 34,
1524-
# create_sql => 'CREATE TRANSFORM FOR int LANGUAGE SQL (FROM SQL WITH FUNCTION varchar_transform(internal), TO SQL WITH FUNCTION int4recv(internal));',
1525-
# regexp => qr/CREATE TRANSFORM FOR int LANGUAGE SQL \(FROM SQL WITH FUNCTION varchar_transform\(internal\), TO SQL WITH FUNCTION int4recv\(internal\)\);/m,
1526-
# like => {
1527-
# binary_upgrade => 1,
1528-
# clean => 1,
1529-
# clean_if_exists => 1,
1530-
# createdb => 1,
1531-
# defaults => 1,
1532-
# exclude_dump_test_schema => 1,
1533-
# exclude_test_table => 1,
1534-
# exclude_test_table_data => 1,
1535-
# no_privs => 1,
1536-
# no_owner => 1,
1537-
# pg_dumpall_dbprivs => 1,
1538-
# schema_only => 1,
1539-
# section_post_data => 1,
1540-
# },
1541-
# unlike => {
1542-
# section_pre_data => 1,
1543-
# only_dump_test_schema => 1,
1544-
# only_dump_test_table => 1,
1545-
# pg_dumpall_globals => 1,
1546-
# test_schema_plus_blobs => 1,
1547-
# },
1548-
# },
1544+
'CREATE TRANSFORM FOR int' => {
1545+
create_order => 34,
1546+
create_sql => 'CREATE TRANSFORM FOR int LANGUAGE SQL (FROM SQL WITH FUNCTION varchar_transform(internal), TO SQL WITH FUNCTION int4recv(internal));',
1547+
regexp => qr/CREATE TRANSFORM FOR integer LANGUAGE sql \(FROM SQL WITH FUNCTION pg_catalog\.varchar_transform\(internal\), TO SQL WITH FUNCTION pg_catalog\.int4recv\(internal\)\);/m,
1548+
like => {
1549+
binary_upgrade => 1,
1550+
clean => 1,
1551+
clean_if_exists => 1,
1552+
createdb => 1,
1553+
defaults => 1,
1554+
exclude_dump_test_schema => 1,
1555+
exclude_test_table => 1,
1556+
exclude_test_table_data => 1,
1557+
no_privs => 1,
1558+
no_owner => 1,
1559+
pg_dumpall_dbprivs => 1,
1560+
schema_only => 1,
1561+
section_pre_data => 1,
1562+
},
1563+
unlike => {
1564+
only_dump_test_schema => 1,
1565+
only_dump_test_table => 1,
1566+
pg_dumpall_globals => 1,
1567+
section_post_data => 1,
1568+
test_schema_plus_blobs => 1, }, },
15491569
'CREATE LANGUAGE pltestlang' => {
15501570
create_order => 18,
15511571
create_sql => 'CREATE LANGUAGE pltestlang

0 commit comments

Comments
 (0)