@@ -1072,11 +1072,35 @@ dumpTablespaces(PGconn *conn)
1072
1072
/*
1073
1073
* Get all tablespaces except built-in ones (which we assume are named
1074
1074
* pg_xxx)
1075
+ *
1076
+ * For the tablespace ACLs, as of 9.6, we extract both the positive (as
1077
+ * spcacl) and negative (as rspcacl) ACLs, relative to the default ACL for
1078
+ * tablespaces, which are then passed to buildACLCommands() below.
1079
+ *
1080
+ * See buildACLQueries() and buildACLCommands().
1081
+ *
1082
+ * Note that we do not support initial privileges (pg_init_privs) on
1083
+ * tablespaces.
1075
1084
*/
1076
- if (server_version >= 90200 )
1085
+ if (server_version >= 90600 )
1077
1086
res = executeQuery (conn , "SELECT oid, spcname, "
1078
1087
"pg_catalog.pg_get_userbyid(spcowner) AS spcowner, "
1079
- "pg_catalog.pg_tablespace_location(oid), spcacl, "
1088
+ "pg_catalog.pg_tablespace_location(oid), "
1089
+ "(SELECT pg_catalog.array_agg(acl) FROM (SELECT pg_catalog.unnest(coalesce(spcacl,pg_catalog.acldefault('t',spcowner))) AS acl "
1090
+ "EXCEPT SELECT pg_catalog.unnest(pg_catalog.acldefault('t',spcowner))) as foo)"
1091
+ "AS spcacl,"
1092
+ "(SELECT pg_catalog.array_agg(acl) FROM (SELECT pg_catalog.unnest(pg_catalog.acldefault('t',spcowner)) AS acl "
1093
+ "EXCEPT SELECT pg_catalog.unnest(coalesce(spcacl,pg_catalog.acldefault('t',spcowner)))) as foo)"
1094
+ "AS rspcacl,"
1095
+ "array_to_string(spcoptions, ', '),"
1096
+ "pg_catalog.shobj_description(oid, 'pg_tablespace') "
1097
+ "FROM pg_catalog.pg_tablespace "
1098
+ "WHERE spcname !~ '^pg_' "
1099
+ "ORDER BY 1" );
1100
+ else if (server_version >= 90200 )
1101
+ res = executeQuery (conn , "SELECT oid, spcname, "
1102
+ "pg_catalog.pg_get_userbyid(spcowner) AS spcowner, "
1103
+ "pg_catalog.pg_tablespace_location(oid), spcacl, '' as rspcacl, "
1080
1104
"array_to_string(spcoptions, ', '),"
1081
1105
"pg_catalog.shobj_description(oid, 'pg_tablespace') "
1082
1106
"FROM pg_catalog.pg_tablespace "
@@ -1085,7 +1109,7 @@ dumpTablespaces(PGconn *conn)
1085
1109
else if (server_version >= 90000 )
1086
1110
res = executeQuery (conn , "SELECT oid, spcname, "
1087
1111
"pg_catalog.pg_get_userbyid(spcowner) AS spcowner, "
1088
- "spclocation, spcacl, "
1112
+ "spclocation, spcacl, '' as rspcacl, "
1089
1113
"array_to_string(spcoptions, ', '),"
1090
1114
"pg_catalog.shobj_description(oid, 'pg_tablespace') "
1091
1115
"FROM pg_catalog.pg_tablespace "
@@ -1094,15 +1118,15 @@ dumpTablespaces(PGconn *conn)
1094
1118
else if (server_version >= 80200 )
1095
1119
res = executeQuery (conn , "SELECT oid, spcname, "
1096
1120
"pg_catalog.pg_get_userbyid(spcowner) AS spcowner, "
1097
- "spclocation, spcacl, null, "
1121
+ "spclocation, spcacl, '' as rspcacl, null, "
1098
1122
"pg_catalog.shobj_description(oid, 'pg_tablespace') "
1099
1123
"FROM pg_catalog.pg_tablespace "
1100
1124
"WHERE spcname !~ '^pg_' "
1101
1125
"ORDER BY 1" );
1102
1126
else
1103
1127
res = executeQuery (conn , "SELECT oid, spcname, "
1104
1128
"pg_catalog.pg_get_userbyid(spcowner) AS spcowner, "
1105
- "spclocation, spcacl, "
1129
+ "spclocation, spcacl, '' as rspcacl, "
1106
1130
"null, null "
1107
1131
"FROM pg_catalog.pg_tablespace "
1108
1132
"WHERE spcname !~ '^pg_' "
@@ -1119,8 +1143,9 @@ dumpTablespaces(PGconn *conn)
1119
1143
char * spcowner = PQgetvalue (res , i , 2 );
1120
1144
char * spclocation = PQgetvalue (res , i , 3 );
1121
1145
char * spcacl = PQgetvalue (res , i , 4 );
1122
- char * spcoptions = PQgetvalue (res , i , 5 );
1123
- char * spccomment = PQgetvalue (res , i , 6 );
1146
+ char * rspcacl = PQgetvalue (res , i , 5 );
1147
+ char * spcoptions = PQgetvalue (res , i , 6 );
1148
+ char * spccomment = PQgetvalue (res , i , 7 );
1124
1149
char * fspcname ;
1125
1150
1126
1151
/* needed for buildACLCommands() */
@@ -1138,7 +1163,7 @@ dumpTablespaces(PGconn *conn)
1138
1163
fspcname , spcoptions );
1139
1164
1140
1165
if (!skip_acls &&
1141
- !buildACLCommands (fspcname , NULL , "TABLESPACE" , spcacl , "" ,
1166
+ !buildACLCommands (fspcname , NULL , "TABLESPACE" , spcacl , rspcacl ,
1142
1167
spcowner , "" , server_version , buf ))
1143
1168
{
1144
1169
fprintf (stderr , _ ("%s: could not parse ACL list (%s) for tablespace \"%s\"\n" ),
@@ -1284,14 +1309,43 @@ dumpCreateDB(PGconn *conn)
1284
1309
1285
1310
PQclear (res );
1286
1311
1287
- /* Now collect all the information about databases to dump */
1288
- if (server_version >= 90300 )
1312
+
1313
+ /*
1314
+ * Now collect all the information about databases to dump.
1315
+ *
1316
+ * For the database ACLs, as of 9.6, we extract both the positive (as
1317
+ * datacl) and negative (as rdatacl) ACLs, relative to the default ACL for
1318
+ * databases, which are then passed to buildACLCommands() below.
1319
+ *
1320
+ * See buildACLQueries() and buildACLCommands().
1321
+ *
1322
+ * Note that we do not support initial privileges (pg_init_privs) on
1323
+ * databases.
1324
+ */
1325
+ if (server_version >= 90600 )
1326
+ res = executeQuery (conn ,
1327
+ "SELECT datname, "
1328
+ "coalesce(rolname, (select rolname from pg_authid where oid=(select datdba from pg_database where datname='template0'))), "
1329
+ "pg_encoding_to_char(d.encoding), "
1330
+ "datcollate, datctype, datfrozenxid, datminmxid, "
1331
+ "datistemplate, "
1332
+ "(SELECT pg_catalog.array_agg(acl) FROM (SELECT pg_catalog.unnest(coalesce(datacl,pg_catalog.acldefault('d',datdba))) AS acl "
1333
+ "EXCEPT SELECT pg_catalog.unnest(pg_catalog.acldefault('d',datdba))) as foo)"
1334
+ "AS datacl,"
1335
+ "(SELECT pg_catalog.array_agg(acl) FROM (SELECT pg_catalog.unnest(pg_catalog.acldefault('d',datdba)) AS acl "
1336
+ "EXCEPT SELECT pg_catalog.unnest(coalesce(datacl,pg_catalog.acldefault('d',datdba)))) as foo)"
1337
+ "AS rdatacl,"
1338
+ "datconnlimit, "
1339
+ "(SELECT spcname FROM pg_tablespace t WHERE t.oid = d.dattablespace) AS dattablespace "
1340
+ "FROM pg_database d LEFT JOIN pg_authid u ON (datdba = u.oid) "
1341
+ "WHERE datallowconn ORDER BY 1" );
1342
+ else if (server_version >= 90300 )
1289
1343
res = executeQuery (conn ,
1290
1344
"SELECT datname, "
1291
1345
"coalesce(rolname, (select rolname from pg_authid where oid=(select datdba from pg_database where datname='template0'))), "
1292
1346
"pg_encoding_to_char(d.encoding), "
1293
1347
"datcollate, datctype, datfrozenxid, datminmxid, "
1294
- "datistemplate, datacl, datconnlimit, "
1348
+ "datistemplate, datacl, '' as rdatacl, datconnlimit, "
1295
1349
"(SELECT spcname FROM pg_tablespace t WHERE t.oid = d.dattablespace) AS dattablespace "
1296
1350
"FROM pg_database d LEFT JOIN pg_authid u ON (datdba = u.oid) "
1297
1351
"WHERE datallowconn ORDER BY 1" );
@@ -1301,7 +1355,7 @@ dumpCreateDB(PGconn *conn)
1301
1355
"coalesce(rolname, (select rolname from pg_authid where oid=(select datdba from pg_database where datname='template0'))), "
1302
1356
"pg_encoding_to_char(d.encoding), "
1303
1357
"datcollate, datctype, datfrozenxid, 0 AS datminmxid, "
1304
- "datistemplate, datacl, datconnlimit, "
1358
+ "datistemplate, datacl, '' as rdatacl, datconnlimit, "
1305
1359
"(SELECT spcname FROM pg_tablespace t WHERE t.oid = d.dattablespace) AS dattablespace "
1306
1360
"FROM pg_database d LEFT JOIN pg_authid u ON (datdba = u.oid) "
1307
1361
"WHERE datallowconn ORDER BY 1" );
@@ -1311,7 +1365,7 @@ dumpCreateDB(PGconn *conn)
1311
1365
"coalesce(rolname, (select rolname from pg_authid where oid=(select datdba from pg_database where datname='template0'))), "
1312
1366
"pg_encoding_to_char(d.encoding), "
1313
1367
"null::text AS datcollate, null::text AS datctype, datfrozenxid, 0 AS datminmxid, "
1314
- "datistemplate, datacl, datconnlimit, "
1368
+ "datistemplate, datacl, '' as rdatacl, datconnlimit, "
1315
1369
"(SELECT spcname FROM pg_tablespace t WHERE t.oid = d.dattablespace) AS dattablespace "
1316
1370
"FROM pg_database d LEFT JOIN pg_authid u ON (datdba = u.oid) "
1317
1371
"WHERE datallowconn ORDER BY 1" );
@@ -1321,7 +1375,7 @@ dumpCreateDB(PGconn *conn)
1321
1375
"coalesce(usename, (select usename from pg_shadow where usesysid=(select datdba from pg_database where datname='template0'))), "
1322
1376
"pg_encoding_to_char(d.encoding), "
1323
1377
"null::text AS datcollate, null::text AS datctype, datfrozenxid, 0 AS datminmxid, "
1324
- "datistemplate, datacl, -1 as datconnlimit, "
1378
+ "datistemplate, datacl, '' as rdatacl, -1 as datconnlimit, "
1325
1379
"(SELECT spcname FROM pg_tablespace t WHERE t.oid = d.dattablespace) AS dattablespace "
1326
1380
"FROM pg_database d LEFT JOIN pg_shadow u ON (datdba = usesysid) "
1327
1381
"WHERE datallowconn ORDER BY 1" );
@@ -1331,7 +1385,7 @@ dumpCreateDB(PGconn *conn)
1331
1385
"coalesce(usename, (select usename from pg_shadow where usesysid=(select datdba from pg_database where datname='template0'))), "
1332
1386
"pg_encoding_to_char(d.encoding), "
1333
1387
"null::text AS datcollate, null::text AS datctype, datfrozenxid, 0 AS datminmxid, "
1334
- "datistemplate, datacl, -1 as datconnlimit, "
1388
+ "datistemplate, datacl, '' as rdatacl, -1 as datconnlimit, "
1335
1389
"'pg_default' AS dattablespace "
1336
1390
"FROM pg_database d LEFT JOIN pg_shadow u ON (datdba = usesysid) "
1337
1391
"WHERE datallowconn ORDER BY 1" );
@@ -1343,7 +1397,7 @@ dumpCreateDB(PGconn *conn)
1343
1397
"(select usename from pg_shadow where usesysid=(select datdba from pg_database where datname='template0'))), "
1344
1398
"pg_encoding_to_char(d.encoding), "
1345
1399
"null::text AS datcollate, null::text AS datctype, 0 AS datfrozenxid, 0 AS datminmxid, "
1346
- "datistemplate, '' as datacl, -1 as datconnlimit, "
1400
+ "datistemplate, '' as datacl, '' as rdatacl, -1 as datconnlimit, "
1347
1401
"'pg_default' AS dattablespace "
1348
1402
"FROM pg_database d "
1349
1403
"WHERE datallowconn ORDER BY 1" );
@@ -1359,7 +1413,7 @@ dumpCreateDB(PGconn *conn)
1359
1413
"pg_encoding_to_char(d.encoding), "
1360
1414
"null::text AS datcollate, null::text AS datctype, 0 AS datfrozenxid, 0 AS datminmxid, "
1361
1415
"'f' as datistemplate, "
1362
- "'' as datacl, -1 as datconnlimit, "
1416
+ "'' as datacl, '' as rdatacl, -1 as datconnlimit, "
1363
1417
"'pg_default' AS dattablespace "
1364
1418
"FROM pg_database d "
1365
1419
"ORDER BY 1" );
@@ -1376,8 +1430,9 @@ dumpCreateDB(PGconn *conn)
1376
1430
uint32 dbminmxid = atooid (PQgetvalue (res , i , 6 ));
1377
1431
char * dbistemplate = PQgetvalue (res , i , 7 );
1378
1432
char * dbacl = PQgetvalue (res , i , 8 );
1379
- char * dbconnlimit = PQgetvalue (res , i , 9 );
1380
- char * dbtablespace = PQgetvalue (res , i , 10 );
1433
+ char * rdbacl = PQgetvalue (res , i , 9 );
1434
+ char * dbconnlimit = PQgetvalue (res , i , 10 );
1435
+ char * dbtablespace = PQgetvalue (res , i , 11 );
1381
1436
char * fdbname ;
1382
1437
1383
1438
fdbname = pg_strdup (fmtId (dbname ));
@@ -1469,7 +1524,7 @@ dumpCreateDB(PGconn *conn)
1469
1524
}
1470
1525
1471
1526
if (!skip_acls &&
1472
- !buildACLCommands (fdbname , NULL , "DATABASE" , dbacl , "" , dbowner ,
1527
+ !buildACLCommands (fdbname , NULL , "DATABASE" , dbacl , rdbacl , dbowner ,
1473
1528
"" , server_version , buf ))
1474
1529
{
1475
1530
fprintf (stderr , _ ("%s: could not parse ACL list (%s) for database \"%s\"\n" ),
0 commit comments