From 68ef051f5cf16f82a5368067a40ffba3c340b0d3 Mon Sep 17 00:00:00 2001 From: Robert Haas Date: Mon, 25 Apr 2011 16:55:11 -0400 Subject: 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. --- src/backend/commands/tablecmds.c | 29 ++++------------------------- 1 file changed, 4 insertions(+), 25 deletions(-) (limited to 'src/backend/commands/tablecmds.c') diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index 7660114ec2c..60eecb14976 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -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); -- cgit v1.2.3