Fix bug in DROP OWNED BY.

Commit 6566133c5f broke the case where
the role passed to DROP OWNED BY owns a database.

Report by Rushabh Lathia, who also provided a patch, but this patch
takes a slightly different approach to fixing the problem.

Discussion: http://postgr.es/m/CAGPqQf2vO+nbo=3yAdZ8v26Rbug7bY4YjPaPLZx=L1NZ9-CC3w@mail.gmail.com
This commit is contained in:
Robert Haas 2022-09-28 10:42:07 -04:00
parent a448e49bcb
commit 7188b9b0fd
2 changed files with 37 additions and 10 deletions

View File

@ -1412,19 +1412,28 @@ shdepDropOwned(List *roleids, DropBehavior behavior)
break;
}
/* FALLTHROUGH */
case SHARED_DEPENDENCY_OWNER:
/* Save it for deletion below */
obj.classId = sdepForm->classid;
obj.objectId = sdepForm->objid;
obj.objectSubId = sdepForm->objsubid;
/* as above */
AcquireDeletionLock(&obj, 0);
if (!systable_recheck_tuple(scan, tuple))
/*
* Save it for deletion below, if it's a local object or a
* role grant. Other shared objects, such as databases,
* should not be removed here.
*/
if (sdepForm->dbid == MyDatabaseId ||
sdepForm->classid == AuthMemRelationId)
{
ReleaseDeletionLock(&obj);
break;
obj.classId = sdepForm->classid;
obj.objectId = sdepForm->objid;
obj.objectSubId = sdepForm->objsubid;
/* as above */
AcquireDeletionLock(&obj, 0);
if (!systable_recheck_tuple(scan, tuple))
{
ReleaseDeletionLock(&obj);
break;
}
add_exact_object_address(&obj, deleteobjs);
}
add_exact_object_address(&obj, deleteobjs);
break;
}
}

View File

@ -158,4 +158,22 @@ $node->issues_sql_like(
qr/statement: CREATE DATABASE foobar7 STRATEGY file_copy TEMPLATE foobar2/,
'create database with FILE_COPY strategy');
# Create database owned by role_foobar.
$node->issues_sql_like(
[ 'createdb', '-T', 'foobar2', '-O', 'role_foobar', 'foobar8' ],
qr/statement: CREATE DATABASE foobar8 OWNER role_foobar TEMPLATE foobar2/,
'create database with owner role_foobar');
($ret, $stdout, $stderr) = $node->psql(
'foobar2',
'DROP OWNED BY role_foobar;',
on_error_die => 1,
);
ok($ret == 0, "DROP OWNED BY role_foobar");
($ret, $stdout, $stderr) = $node->psql(
'foobar2',
'DROP DATABASE foobar8;',
on_error_die => 1,
);
ok($ret == 0, "DROP DATABASE foobar8");
done_testing();