mirror of
https://github.com/postgres/postgres.git
synced 2025-06-16 06:01:02 +03:00
Refactor broken CREATE TABLE IF NOT EXISTS support.
Per bug #5988, reported by Marko Tiikkaja, and further analyzed by Tom Lane, the previous coding was broken in several respects: even if the target table already existed, a subsequent CREATE TABLE IF NOT EXISTS might try to add additional constraints or sequences-for-serial specified in the new CREATE TABLE statement. In passing, this also fixes a minor information leak: it's no longer possible to figure out whether a schema to which you don't have CREATE access contains a sequence named like "x_y_seq" by attempting to create a table in that schema called "x" with a serial column called "y". Some more refactoring of this code in the future might be warranted, but that will need to wait for a later major release.
This commit is contained in:
@ -439,22 +439,10 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId)
|
||||
errmsg("cannot create temporary table within security-restricted operation")));
|
||||
|
||||
/*
|
||||
* Look up the namespace in which we are supposed to create the relation.
|
||||
* Check we have permission to create there. Skip check if bootstrapping,
|
||||
* since permissions machinery may not be working yet.
|
||||
* Look up the namespace in which we are supposed to create the relation,
|
||||
* and check we have permission to create there.
|
||||
*/
|
||||
namespaceId = RangeVarGetCreationNamespace(stmt->relation);
|
||||
|
||||
if (!IsBootstrapProcessingMode())
|
||||
{
|
||||
AclResult aclresult;
|
||||
|
||||
aclresult = pg_namespace_aclcheck(namespaceId, GetUserId(),
|
||||
ACL_CREATE);
|
||||
if (aclresult != ACLCHECK_OK)
|
||||
aclcheck_error(aclresult, ACL_KIND_NAMESPACE,
|
||||
get_namespace_name(namespaceId));
|
||||
}
|
||||
namespaceId = RangeVarGetAndCheckCreationNamespace(stmt->relation);
|
||||
|
||||
/*
|
||||
* Select tablespace to use. If not specified, use default tablespace
|
||||
@ -602,16 +590,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId)
|
||||
stmt->oncommit,
|
||||
reloptions,
|
||||
true,
|
||||
allowSystemTableMods,
|
||||
stmt->if_not_exists);
|
||||
|
||||
/*
|
||||
* If heap_create_with_catalog returns InvalidOid, it means that the user
|
||||
* specified "IF NOT EXISTS" and the relation already exists. In that
|
||||
* case we do nothing further.
|
||||
*/
|
||||
if (relationId == InvalidOid)
|
||||
return InvalidOid;
|
||||
allowSystemTableMods);
|
||||
|
||||
/* Store inheritance information for new rel. */
|
||||
StoreCatalogInheritance(relationId, inheritOids);
|
||||
|
Reference in New Issue
Block a user