示例#1
0
static void
RenameRelationInternal(Oid myrelid, const char *newrelname, Oid namespaceId)
{
    bool	save_allowSystemTableMods = allowSystemTableMods;

    allowSystemTableMods = true;
    PG_TRY();
    {
        renamerel(myrelid, newrelname, OBJECT_TABLE);
        allowSystemTableMods = save_allowSystemTableMods;
    }
    PG_CATCH();
    {
        allowSystemTableMods = save_allowSystemTableMods;
        PG_RE_THROW();
    }
    PG_END_TRY();
}
示例#2
0
/*
 * Executes an ALTER OBJECT / RENAME TO statement.	Based on the object
 * type, the function appropriate to that type is executed.
 */
void
ExecRenameStmt(RenameStmt *stmt)
{
    switch (stmt->renameType)
    {
    case OBJECT_AGGREGATE:
        RenameAggregate(stmt->object, stmt->objarg, stmt->newname);
        break;

    case OBJECT_CONVERSION:
        RenameConversion(stmt->object, stmt->newname);
        break;

    case OBJECT_DATABASE:
        RenameDatabase(stmt->subname, stmt->newname);
        break;

    case OBJECT_FUNCTION:
        RenameFunction(stmt->object, stmt->objarg, stmt->newname);
        break;

    case OBJECT_LANGUAGE:
        RenameLanguage(stmt->subname, stmt->newname);
        break;

    case OBJECT_OPCLASS:
        RenameOpClass(stmt->object, stmt->subname, stmt->newname);
        break;

    case OBJECT_ROLE:
        RenameRole(stmt->subname, stmt->newname);
        break;

    case OBJECT_SCHEMA:
        RenameSchema(stmt->subname, stmt->newname);
        break;

    case OBJECT_TABLESPACE:
        RenameTableSpace(stmt->subname, stmt->newname);
        break;

    case OBJECT_TABLE:
    case OBJECT_INDEX:
    case OBJECT_COLUMN:
    case OBJECT_TRIGGER:
    {
        Oid			relid;

        CheckRelationOwnership(stmt->relation, true);

        relid = RangeVarGetRelid(stmt->relation, false);

        switch (stmt->renameType)
        {
        case OBJECT_TABLE:
        case OBJECT_INDEX:
        {
            /*
             * RENAME TABLE requires that we (still) hold
             * CREATE rights on the containing namespace, as
             * well as ownership of the table.
             */
            Oid			namespaceId = get_rel_namespace(relid);
            AclResult	aclresult;

            aclresult = pg_namespace_aclcheck(namespaceId,
                                              GetUserId(),
                                              ACL_CREATE);
            if (aclresult != ACLCHECK_OK)
                aclcheck_error(aclresult, ACL_KIND_NAMESPACE,
                               get_namespace_name(namespaceId));

            renamerel(relid, stmt->newname);
            break;
        }
        case OBJECT_COLUMN:
            renameatt(relid,
                      stmt->subname,		/* old att name */
                      stmt->newname,		/* new att name */
                      interpretInhOption(stmt->relation->inhOpt),	/* recursive? */
                      false);		/* recursing already? */
            break;
        case OBJECT_TRIGGER:
            renametrig(relid,
                       stmt->subname,		/* old att name */
                       stmt->newname);		/* new att name */
            break;
        default:
            /* can't happen */
            ;
        }
        break;
    }

    default:
        elog(ERROR, "unrecognized rename stmt type: %d",
             (int) stmt->renameType);
    }
}
示例#3
0
/*
 * cluster
 *
 *   Check that the relation is a relation in the appropriate user
 *   ACL. I will use the same security that limits users on the
 *   renamerel() function.
 *
 *   Check that the index specified is appropriate for the task
 *   ( ie it's an index over this relation ). This is trickier.
 *
 *   Create a list of all the other indicies on this relation. Because
 *   the cluster will wreck all the tids, I'll need to destroy bogus
 *   indicies. The user will have to re-create them. Not nice, but
 *   I'm not a nice guy. The alternative is to try some kind of post
 *   destroy re-build. This may be possible. I'll check out what the
 *   index create functiond want in the way of paramaters. On the other
 *   hand, re-creating n indicies may blow out the space. 
 *
 *   Create new (temporary) relations for the base heap and the new 
 *   index. 
 *  
 *   Exclusively lock the relations.
 * 
 *   Create new clustered index and base heap relation.
 *
 */
void
cluster(char oldrelname[], char oldindexname[])
{
    Oid OIDOldHeap, OIDOldIndex, OIDNewHeap;
    
    Relation OldHeap, OldIndex;
    Relation NewHeap;
    
    char *NewIndexName;
    char *szNewHeapName;
    
    /*
     *
     * I'm going to force all checking back into the commands.c function.
     *
     * Get the list if indicies for this relation. If the index we want
     * is among them, do not add it to the 'kill' list, as it will be
     * handled by the 'clean up' code which commits this transaction.
     *
     * I'm not using the SysCache, because this will happen but
     * once, and the slow way is the sure way in this case.
     *
     */
    /*
     * Like vacuum, cluster spans transactions, so I'm going to handle it in
     * the same way.
     */
    
    /* matches the StartTransaction in PostgresMain() */
    
    OldHeap = heap_openr(oldrelname);
    if (!RelationIsValid(OldHeap)) {
	elog(WARN, "cluster: unknown relation: \"%-.*s\"",
	     NAMEDATALEN, oldrelname);
    }
    OIDOldHeap = OldHeap->rd_id; /* Get OID for the index scan   */
    
    OldIndex=index_openr(oldindexname);/* Open old index relation  */
    if (!RelationIsValid(OldIndex)) {
	elog(WARN, "cluster: unknown index: \"%-.*s\"",
	     NAMEDATALEN, oldindexname);
    }
    OIDOldIndex = OldIndex->rd_id;     /* OID for the index scan         */
    
    heap_close(OldHeap);
    index_close(OldIndex);
    
    /*
     * I need to build the copies of the heap and the index. The Commit()
     * between here is *very* bogus. If someone is appending stuff, they will
     * get the lock after being blocked and add rows which won't be present in
     * the new table. Bleagh! I'd be best to try and ensure that no-one's
     * in the tables for the entire duration of this process with a pg_vlock.
     */
    NewHeap    = copy_heap(OIDOldHeap);
    OIDNewHeap = NewHeap->rd_id;
    szNewHeapName = pstrdup(NewHeap->rd_rel->relname.data);

     /* Need to do this to make the new heap visible. */
    CommandCounterIncrement();
    
    rebuildheap(OIDNewHeap, OIDOldHeap, OIDOldIndex);
    
    /* Need to do this to make the new heap visible. */
    CommandCounterIncrement();

    /* can't be found in the SysCache. */
    copy_index(OIDOldIndex, OIDNewHeap); /* No contention with the old */
    
    /* 
     * make this really happen. Flush all the buffers.
     */
    CommitTransactionCommand();
    StartTransactionCommand();
    
    /*
     * Questionable bit here. Because the renamerel destroys all trace of the
     * pre-existing relation, I'm going to Destroy old, and then rename new
     * to old. If this fails, it fails, and you lose your old. Tough - say
     * I. Have good backups!
     */

    /*
       Here lies the bogosity. The RelationNameGetRelation returns a bad
       list of TupleDescriptors. Damn. Can't work out why this is.
       */
    
    heap_destroy(oldrelname); /* AAAAAAAAGH!! */
    
    CommandCounterIncrement();
    
    /*
     * The Commit flushes all palloced memory, so I have to grab the 
     * New stuff again. This is annoying, but oh heck!
     */
/*
    renamerel(szNewHeapName.data, oldrelname);
    TypeRename(&szNewHeapName, &szOldRelName);
    
    sprintf(NewIndexName.data, "temp_%x", OIDOldIndex);
    renamerel(NewIndexName.data, szOldIndexName.data);
*/
    NewIndexName = palloc(NAMEDATALEN+1); /* XXX */
    sprintf(NewIndexName, "temp_%x", OIDOldIndex);
    renamerel(NewIndexName, oldindexname);
}
示例#4
0
文件: alter.c 项目: chrishajas/gpdb
/*
 * Executes an ALTER OBJECT / RENAME TO statement.	Based on the object
 * type, the function appropriate to that type is executed.
 */
void
ExecRenameStmt(RenameStmt *stmt)
{
	switch (stmt->renameType)
	{
		case OBJECT_AGGREGATE:
			RenameAggregate(stmt->object, stmt->objarg, stmt->newname);
			break;

		case OBJECT_CONVERSION:
			RenameConversion(stmt->object, stmt->newname);
			break;

		case OBJECT_DATABASE:
			RenameDatabase(stmt->subname, stmt->newname);
			break;

		case OBJECT_EXTPROTOCOL:
			RenameExtProtocol(stmt->subname, stmt->newname);
			break;

		case OBJECT_FUNCTION:
			RenameFunction(stmt->object, stmt->objarg, stmt->newname);
			break;

		case OBJECT_LANGUAGE:
			RenameLanguage(stmt->subname, stmt->newname);
			break;

		case OBJECT_OPCLASS:
			RenameOpClass(stmt->object, stmt->subname, stmt->newname);
			break;

		case OBJECT_OPFAMILY:
			RenameOpFamily(stmt->object, stmt->subname, stmt->newname);
			break;

		case OBJECT_ROLE:
			RenameRole(stmt->subname, stmt->newname);
			break;

		case OBJECT_SCHEMA:
			RenameSchema(stmt->subname, stmt->newname);
			break;

		case OBJECT_TABLESPACE:
			RenameTableSpace(stmt->subname, stmt->newname);
			break;

		case OBJECT_FILESPACE:
			RenameFileSpace(stmt->subname, stmt->newname);
			break;

		case OBJECT_TABLE:
		case OBJECT_SEQUENCE:
		case OBJECT_VIEW:
		case OBJECT_INDEX:
		{
			if (Gp_role == GP_ROLE_DISPATCH)
			{
				CheckRelationOwnership(stmt->relation, true);
				stmt->objid = RangeVarGetRelid(stmt->relation, false);
			}

			/*
			 * RENAME TABLE requires that we (still) hold
			 * CREATE rights on the containing namespace, as
			 * well as ownership of the table.
			 */
			Oid			namespaceId = get_rel_namespace(stmt->objid);
			AclResult	aclresult;

			aclresult = pg_namespace_aclcheck(namespaceId,
											  GetUserId(),
											  ACL_CREATE);
			if (aclresult != ACLCHECK_OK)
				aclcheck_error(aclresult, ACL_KIND_NAMESPACE,
							   get_namespace_name(namespaceId));

			renamerel(stmt->objid, stmt->newname, stmt->renameType, stmt);
			break;
		}

		case OBJECT_COLUMN:
		case OBJECT_TRIGGER:
			{
				Oid			relid;

				CheckRelationOwnership(stmt->relation, true);

				relid = RangeVarGetRelid(stmt->relation, false);

				switch (stmt->renameType)
				{
					case OBJECT_COLUMN:
						renameatt(relid,
								  stmt->subname,		/* old att name */
								  stmt->newname,		/* new att name */
								  interpretInhOption(stmt->relation->inhOpt),	/* recursive? */
								  false);		/* recursing already? */
						break;
					case OBJECT_TRIGGER:
						renametrig(relid,
								   stmt->subname,		/* old att name */
								   stmt->newname);		/* new att name */
						break;
					default:
						 /* can't happen */ ;
				}
				break;
			}

		case OBJECT_TSPARSER:
			RenameTSParser(stmt->object, stmt->newname);
			break;

		case OBJECT_TSDICTIONARY:
			RenameTSDictionary(stmt->object, stmt->newname);
			break;

		case OBJECT_TSTEMPLATE:
			RenameTSTemplate(stmt->object, stmt->newname);
			break;

		case OBJECT_TSCONFIGURATION:
			RenameTSConfiguration(stmt->object, stmt->newname);
			break;

		default:
			elog(ERROR, "unrecognized rename stmt type: %d",
				 (int) stmt->renameType);
	}
	if (Gp_role == GP_ROLE_DISPATCH)
	{
		CdbDispatchUtilityStatement((Node *) stmt, "ExecRenameStmt");
	}

}