← Back to Overview

src/backend/commands/tablecmds.c

Coverage: 4/5 lines (80.0%)
Total Lines
5
modified
Covered
4
80.0%
Uncovered
1
20.0%
키보드 네비게이션
gettext_noop() lines 316-322
Modified Lines Coverage: 0/0 lines (0.0%)
LineHitsSourceCommit
316 - gettext_noop("Use DROP PROPERTY GRAPH to remove a property graph.")}, 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
317 - {'\0', 0, NULL, NULL, NULL, NULL} -
318 - }; -
319 - -
320 - /* communication between RemoveRelations and RangeVarCallbackForDropRelation */ -
321 - struct DropRelationCallbackState -
322 - { -
RemoveRelations() lines 1539-1698
Modified Lines Coverage: 3/3 lines (100.0%)
LineHitsSourceCommit
1539 - RemoveRelations(DropStmt *drop) -
1540 - { -
1541 - ObjectAddresses *objects; -
1542 - char relkind; -
1543 - ListCell *cell; -
1544 - int flags = 0; -
1545 - LOCKMODE lockmode = AccessExclusiveLock; -
1546 - -
1547 - /* DROP CONCURRENTLY uses a weaker lock, and has some restrictions */ -
1548 - if (drop->concurrent) -
1549 - { -
1550 - /* -
1551 - * Note that for temporary relations this lock may get upgraded later -
1552 - * on, but as no other session can access a temporary relation, this -
1553 - * is actually fine. -
1554 - */ -
1555 - lockmode = ShareUpdateExclusiveLock; -
1556 - Assert(drop->removeType == OBJECT_INDEX); -
1557 - if (list_length(drop->objects) != 1) -
1558 - ereport(ERROR, -
1559 - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), -
1560 - errmsg("DROP INDEX CONCURRENTLY does not support dropping multiple objects"))); -
1561 - if (drop->behavior == DROP_CASCADE) -
1562 - ereport(ERROR, -
1563 - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), -
1564 - errmsg("DROP INDEX CONCURRENTLY does not support CASCADE"))); -
1565 - } -
1566 - -
1567 - /* -
1568 - * First we identify all the relations, then we delete them in a single -
1569 - * performMultipleDeletions() call. This is to avoid unwanted DROP -
1570 - * RESTRICT errors if one of the relations depends on another. -
1571 - */ -
1572 - -
1573 - /* Determine required relkind */ -
1574 - switch (drop->removeType) -
1575 - { -
1576 - case OBJECT_TABLE: -
1577 - relkind = RELKIND_RELATION; -
1578 - break; -
1579 - -
1580 - case OBJECT_INDEX: -
1581 - relkind = RELKIND_INDEX; -
1582 - break; -
1583 - -
1584 - case OBJECT_SEQUENCE: -
1585 - relkind = RELKIND_SEQUENCE; -
1586 - break; -
1587 - -
1588 - case OBJECT_VIEW: -
1589 - relkind = RELKIND_VIEW; -
1590 - break; -
1591 - -
1592 - case OBJECT_MATVIEW: -
1593 - relkind = RELKIND_MATVIEW; -
1594 - break; -
1595 - -
1596 - case OBJECT_FOREIGN_TABLE: -
1597 - relkind = RELKIND_FOREIGN_TABLE; -
1598 - break; -
1599 - -
1600 24 case OBJECT_PROPGRAPH: 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1601 24 relkind = RELKIND_PROPGRAPH; 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1602 24 break; 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1603 - 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1604 - default: -
1605 - elog(ERROR, "unrecognized drop object type: %d", -
1606 - (int) drop->removeType); -
1607 - relkind = 0; /* keep compiler quiet */ -
1608 - break; -
1609 - } -
1610 - -
1611 - /* Lock and validate each relation; build a list of object addresses */ -
1612 - objects = new_object_addresses(); -
1613 - -
1614 - foreach(cell, drop->objects) -
1615 - { -
1616 - RangeVar *rel = makeRangeVarFromNameList((List *) lfirst(cell)); -
1617 - Oid relOid; -
1618 - ObjectAddress obj; -
1619 - struct DropRelationCallbackState state; -
1620 - -
1621 - /* -
1622 - * These next few steps are a great deal like relation_openrv, but we -
1623 - * don't bother building a relcache entry since we don't need it. -
1624 - * -
1625 - * Check for shared-cache-inval messages before trying to access the -
1626 - * relation. This is needed to cover the case where the name -
1627 - * identifies a rel that has been dropped and recreated since the -
1628 - * start of our transaction: if we don't flush the old syscache entry, -
1629 - * then we'll latch onto that entry and suffer an error later. -
1630 - */ -
1631 - AcceptInvalidationMessages(); -
1632 - -
1633 - /* Look up the appropriate relation using namespace search. */ -
1634 - state.expected_relkind = relkind; -
1635 - state.heap_lockmode = drop->concurrent ? -
1636 - ShareUpdateExclusiveLock : AccessExclusiveLock; -
1637 - /* We must initialize these fields to show that no locks are held: */ -
1638 - state.heapOid = InvalidOid; -
1639 - state.partParentOid = InvalidOid; -
1640 - -
1641 - relOid = RangeVarGetRelidExtended(rel, lockmode, RVR_MISSING_OK, -
1642 - RangeVarCallbackForDropRelation, -
1643 - &state); -
1644 - -
1645 - /* Not there? */ -
1646 - if (!OidIsValid(relOid)) -
1647 - { -
1648 - DropErrorMsgNonExistent(rel, relkind, drop->missing_ok); -
1649 - continue; -
1650 - } -
1651 - -
1652 - /* -
1653 - * Decide if concurrent mode needs to be used here or not. The -
1654 - * callback retrieved the rel's persistence for us. -
1655 - */ -
1656 - if (drop->concurrent && -
1657 - state.actual_relpersistence != RELPERSISTENCE_TEMP) -
1658 - { -
1659 - Assert(list_length(drop->objects) == 1 && -
1660 - drop->removeType == OBJECT_INDEX); -
1661 - flags |= PERFORM_DELETION_CONCURRENTLY; -
1662 - } -
1663 - -
1664 - /* -
1665 - * Concurrent index drop cannot be used with partitioned indexes, -
1666 - * either. -
1667 - */ -
1668 - if ((flags & PERFORM_DELETION_CONCURRENTLY) != 0 && -
1669 - state.actual_relkind == RELKIND_PARTITIONED_INDEX) -
1670 - ereport(ERROR, -
1671 - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), -
1672 - errmsg("cannot drop partitioned index \"%s\" concurrently", -
1673 - rel->relname))); -
1674 - -
1675 - /* -
1676 - * If we're told to drop a partitioned index, we must acquire lock on -
1677 - * all the children of its parent partitioned table before proceeding. -
1678 - * Otherwise we'd try to lock the child index partitions before their -
1679 - * tables, leading to potential deadlock against other sessions that -
1680 - * will lock those objects in the other order. -
1681 - */ -
1682 - if (state.actual_relkind == RELKIND_PARTITIONED_INDEX) -
1683 - (void) find_all_inheritors(state.heapOid, -
1684 - state.heap_lockmode, -
1685 - NULL); -
1686 - -
1687 - /* OK, we're ready to delete this one */ -
1688 - obj.classId = RelationRelationId; -
1689 - obj.objectId = relOid; -
1690 - obj.objectSubId = 0; -
1691 - -
1692 - add_exact_object_address(&obj, objects); -
1693 - } -
1694 - -
1695 - performMultipleDeletions(objects, drop->behavior, flags); -
1696 - -
1697 - free_object_addresses(objects); -
1698 - } -
ATExecChangeOwner() lines 16110-16343
Modified Lines Coverage: 0/0 lines (0.0%)
LineHitsSourceCommit
16110 - ATExecChangeOwner(Oid relationOid, Oid newOwnerId, bool recursing, LOCKMODE lockmode) -
16111 - { -
16112 - Relation target_rel; -
16113 - Relation class_rel; -
16114 - HeapTuple tuple; -
16115 - Form_pg_class tuple_class; -
16116 - -
16117 - /* -
16118 - * Get exclusive lock till end of transaction on the target table. Use -
16119 - * relation_open so that we can work on indexes and sequences. -
16120 - */ -
16121 - target_rel = relation_open(relationOid, lockmode); -
16122 - -
16123 - /* Get its pg_class tuple, too */ -
16124 - class_rel = table_open(RelationRelationId, RowExclusiveLock); -
16125 - -
16126 - tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(relationOid)); -
16127 - if (!HeapTupleIsValid(tuple)) -
16128 - elog(ERROR, "cache lookup failed for relation %u", relationOid); -
16129 - tuple_class = (Form_pg_class) GETSTRUCT(tuple); -
16130 - -
16131 - /* Can we change the ownership of this tuple? */ -
16132 - switch (tuple_class->relkind) -
16133 - { -
16134 - case RELKIND_RELATION: -
16135 - case RELKIND_VIEW: -
16136 - case RELKIND_MATVIEW: -
16137 - case RELKIND_FOREIGN_TABLE: -
16138 - case RELKIND_PARTITIONED_TABLE: -
16139 - case RELKIND_PROPGRAPH: 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
16140 - /* ok to change owner */ -
16141 - break; -
16142 - case RELKIND_INDEX: -
16143 - if (!recursing) -
16144 - { -
16145 - /* -
16146 - * Because ALTER INDEX OWNER used to be allowed, and in fact -
16147 - * is generated by old versions of pg_dump, we give a warning -
16148 - * and do nothing rather than erroring out. Also, to avoid -
16149 - * unnecessary chatter while restoring those old dumps, say -
16150 - * nothing at all if the command would be a no-op anyway. -
16151 - */ -
16152 - if (tuple_class->relowner != newOwnerId) -
16153 - ereport(WARNING, -
16154 - (errcode(ERRCODE_WRONG_OBJECT_TYPE), -
16155 - errmsg("cannot change owner of index \"%s\"", -
16156 - NameStr(tuple_class->relname)), -
16157 - errhint("Change the ownership of the index's table instead."))); -
16158 - /* quick hack to exit via the no-op path */ -
16159 - newOwnerId = tuple_class->relowner; -
16160 - } -
16161 - break; -
16162 - case RELKIND_PARTITIONED_INDEX: -
16163 - if (recursing) -
16164 - break; -
16165 - ereport(ERROR, -
16166 - (errcode(ERRCODE_WRONG_OBJECT_TYPE), -
16167 - errmsg("cannot change owner of index \"%s\"", -
16168 - NameStr(tuple_class->relname)), -
16169 - errhint("Change the ownership of the index's table instead."))); -
16170 - break; -
16171 - case RELKIND_SEQUENCE: -
16172 - if (!recursing && -
16173 - tuple_class->relowner != newOwnerId) -
16174 - { -
16175 - /* if it's an owned sequence, disallow changing it by itself */ -
16176 - Oid tableId; -
16177 - int32 colId; -
16178 - -
16179 - if (sequenceIsOwned(relationOid, DEPENDENCY_AUTO, &tableId, &colId) || -
16180 - sequenceIsOwned(relationOid, DEPENDENCY_INTERNAL, &tableId, &colId)) -
16181 - ereport(ERROR, -
16182 - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), -
16183 - errmsg("cannot change owner of sequence \"%s\"", -
16184 - NameStr(tuple_class->relname)), -
16185 - errdetail("Sequence \"%s\" is linked to table \"%s\".", -
16186 - NameStr(tuple_class->relname), -
16187 - get_rel_name(tableId)))); -
16188 - } -
16189 - break; -
16190 - case RELKIND_COMPOSITE_TYPE: -
16191 - if (recursing) -
16192 - break; -
16193 - ereport(ERROR, -
16194 - (errcode(ERRCODE_WRONG_OBJECT_TYPE), -
16195 - errmsg("\"%s\" is a composite type", -
16196 - NameStr(tuple_class->relname)), -
16197 - /* translator: %s is an SQL ALTER command */ -
16198 - errhint("Use %s instead.", -
16199 - "ALTER TYPE"))); -
16200 - break; -
16201 - case RELKIND_TOASTVALUE: -
16202 - if (recursing) -
16203 - break; -
16204 - /* FALL THRU */ -
16205 - default: -
16206 - ereport(ERROR, -
16207 - (errcode(ERRCODE_WRONG_OBJECT_TYPE), -
16208 - errmsg("cannot change owner of relation \"%s\"", -
16209 - NameStr(tuple_class->relname)), -
16210 - errdetail_relkind_not_supported(tuple_class->relkind))); -
16211 - } -
16212 - -
16213 - /* -
16214 - * If the new owner is the same as the existing owner, consider the -
16215 - * command to have succeeded. This is for dump restoration purposes. -
16216 - */ -
16217 - if (tuple_class->relowner != newOwnerId) -
16218 - { -
16219 - Datum repl_val[Natts_pg_class]; -
16220 - bool repl_null[Natts_pg_class]; -
16221 - bool repl_repl[Natts_pg_class]; -
16222 - Acl *newAcl; -
16223 - Datum aclDatum; -
16224 - bool isNull; -
16225 - HeapTuple newtuple; -
16226 - -
16227 - /* skip permission checks when recursing to index or toast table */ -
16228 - if (!recursing) -
16229 - { -
16230 - /* Superusers can always do it */ -
16231 - if (!superuser()) -
16232 - { -
16233 - Oid namespaceOid = tuple_class->relnamespace; -
16234 - AclResult aclresult; -
16235 - -
16236 - /* Otherwise, must be owner of the existing object */ -
16237 - if (!object_ownercheck(RelationRelationId, relationOid, GetUserId())) -
16238 - aclcheck_error(ACLCHECK_NOT_OWNER, get_relkind_objtype(get_rel_relkind(relationOid)), -
16239 - RelationGetRelationName(target_rel)); -
16240 - -
16241 - /* Must be able to become new owner */ -
16242 - check_can_set_role(GetUserId(), newOwnerId); -
16243 - -
16244 - /* New owner must have CREATE privilege on namespace */ -
16245 - aclresult = object_aclcheck(NamespaceRelationId, namespaceOid, newOwnerId, -
16246 - ACL_CREATE); -
16247 - if (aclresult != ACLCHECK_OK) -
16248 - aclcheck_error(aclresult, OBJECT_SCHEMA, -
16249 - get_namespace_name(namespaceOid)); -
16250 - } -
16251 - } -
16252 - -
16253 - memset(repl_null, false, sizeof(repl_null)); -
16254 - memset(repl_repl, false, sizeof(repl_repl)); -
16255 - -
16256 - repl_repl[Anum_pg_class_relowner - 1] = true; -
16257 - repl_val[Anum_pg_class_relowner - 1] = ObjectIdGetDatum(newOwnerId); -
16258 - -
16259 - /* -
16260 - * Determine the modified ACL for the new owner. This is only -
16261 - * necessary when the ACL is non-null. -
16262 - */ -
16263 - aclDatum = SysCacheGetAttr(RELOID, tuple, -
16264 - Anum_pg_class_relacl, -
16265 - &isNull); -
16266 - if (!isNull) -
16267 - { -
16268 - newAcl = aclnewowner(DatumGetAclP(aclDatum), -
16269 - tuple_class->relowner, newOwnerId); -
16270 - repl_repl[Anum_pg_class_relacl - 1] = true; -
16271 - repl_val[Anum_pg_class_relacl - 1] = PointerGetDatum(newAcl); -
16272 - } -
16273 - -
16274 - newtuple = heap_modify_tuple(tuple, RelationGetDescr(class_rel), repl_val, repl_null, repl_repl); -
16275 - -
16276 - CatalogTupleUpdate(class_rel, &newtuple->t_self, newtuple); -
16277 - -
16278 - heap_freetuple(newtuple); -
16279 - -
16280 - /* -
16281 - * We must similarly update any per-column ACLs to reflect the new -
16282 - * owner; for neatness reasons that's split out as a subroutine. -
16283 - */ -
16284 - change_owner_fix_column_acls(relationOid, -
16285 - tuple_class->relowner, -
16286 - newOwnerId); -
16287 - -
16288 - /* -
16289 - * Update owner dependency reference, if any. A composite type has -
16290 - * none, because it's tracked for the pg_type entry instead of here; -
16291 - * indexes and TOAST tables don't have their own entries either. -
16292 - */ -
16293 - if (tuple_class->relkind != RELKIND_COMPOSITE_TYPE && -
16294 - tuple_class->relkind != RELKIND_INDEX && -
16295 - tuple_class->relkind != RELKIND_PARTITIONED_INDEX && -
16296 - tuple_class->relkind != RELKIND_TOASTVALUE) -
16297 - changeDependencyOnOwner(RelationRelationId, relationOid, -
16298 - newOwnerId); -
16299 - -
16300 - /* -
16301 - * Also change the ownership of the table's row type, if it has one -
16302 - */ -
16303 - if (OidIsValid(tuple_class->reltype)) -
16304 - AlterTypeOwnerInternal(tuple_class->reltype, newOwnerId); -
16305 - -
16306 - /* -
16307 - * If we are operating on a table or materialized view, also change -
16308 - * the ownership of any indexes and sequences that belong to the -
16309 - * relation, as well as its toast table (if it has one). -
16310 - */ -
16311 - if (tuple_class->relkind == RELKIND_RELATION || -
16312 - tuple_class->relkind == RELKIND_PARTITIONED_TABLE || -
16313 - tuple_class->relkind == RELKIND_MATVIEW || -
16314 - tuple_class->relkind == RELKIND_TOASTVALUE) -
16315 - { -
16316 - List *index_oid_list; -
16317 - ListCell *i; -
16318 - -
16319 - /* Find all the indexes belonging to this relation */ -
16320 - index_oid_list = RelationGetIndexList(target_rel); -
16321 - -
16322 - /* For each index, recursively change its ownership */ -
16323 - foreach(i, index_oid_list) -
16324 - ATExecChangeOwner(lfirst_oid(i), newOwnerId, true, lockmode); -
16325 - -
16326 - list_free(index_oid_list); -
16327 - } -
16328 - -
16329 - /* If it has a toast table, recurse to change its ownership */ -
16330 - if (tuple_class->reltoastrelid != InvalidOid) -
16331 - ATExecChangeOwner(tuple_class->reltoastrelid, newOwnerId, -
16332 - true, lockmode); -
16333 - -
16334 - /* If it has dependent sequences, recurse to change them too */ -
16335 - change_owner_recurse_to_sequences(relationOid, newOwnerId, lockmode); -
16336 - } -
16337 - -
16338 - InvokeObjectPostAlterHook(RelationRelationId, relationOid, 0); -
16339 - -
16340 - ReleaseSysCache(tuple); -
16341 - table_close(class_rel, RowExclusiveLock); -
16342 - relation_close(target_rel, NoLock); -
16343 - } -
RangeVarCallbackForAlterRelation() lines 19623-19761
Modified Lines Coverage: 1/2 lines (50.0%)
LineHitsSourceCommit
19623 - RangeVarCallbackForAlterRelation(const RangeVar *rv, Oid relid, Oid oldrelid, -
19624 - void *arg) -
19625 - { -
19626 - Node *stmt = (Node *) arg; -
19627 - ObjectType reltype; -
19628 - HeapTuple tuple; -
19629 - Form_pg_class classform; -
19630 - AclResult aclresult; -
19631 - char relkind; -
19632 - -
19633 - tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(relid)); -
19634 - if (!HeapTupleIsValid(tuple)) -
19635 - return; /* concurrently dropped */ -
19636 - classform = (Form_pg_class) GETSTRUCT(tuple); -
19637 - relkind = classform->relkind; -
19638 - -
19639 - /* Must own relation. */ -
19640 - if (!object_ownercheck(RelationRelationId, relid, GetUserId())) -
19641 - aclcheck_error(ACLCHECK_NOT_OWNER, get_relkind_objtype(get_rel_relkind(relid)), rv->relname); -
19642 - -
19643 - /* No system table modifications unless explicitly allowed. */ -
19644 - if (!allowSystemTableMods && IsSystemClass(relid, classform)) -
19645 - ereport(ERROR, -
19646 - (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), -
19647 - errmsg("permission denied: \"%s\" is a system catalog", -
19648 - rv->relname))); -
19649 - -
19650 - /* -
19651 - * Extract the specified relation type from the statement parse tree. -
19652 - * -
19653 - * Also, for ALTER .. RENAME, check permissions: the user must (still) -
19654 - * have CREATE rights on the containing namespace. -
19655 - */ -
19656 - if (IsA(stmt, RenameStmt)) -
19657 - { -
19658 - aclresult = object_aclcheck(NamespaceRelationId, classform->relnamespace, -
19659 - GetUserId(), ACL_CREATE); -
19660 - if (aclresult != ACLCHECK_OK) -
19661 - aclcheck_error(aclresult, OBJECT_SCHEMA, -
19662 - get_namespace_name(classform->relnamespace)); -
19663 - reltype = ((RenameStmt *) stmt)->renameType; -
19664 - } -
19665 - else if (IsA(stmt, AlterObjectSchemaStmt)) -
19666 - reltype = ((AlterObjectSchemaStmt *) stmt)->objectType; -
19667 - -
19668 - else if (IsA(stmt, AlterTableStmt)) -
19669 - reltype = ((AlterTableStmt *) stmt)->objtype; -
19670 - else -
19671 - { -
19672 - elog(ERROR, "unrecognized node type: %d", (int) nodeTag(stmt)); -
19673 - reltype = OBJECT_TABLE; /* placate compiler */ -
19674 - } -
19675 - -
19676 - /* -
19677 - * For compatibility with prior releases, we allow ALTER TABLE to be used -
19678 - * with most other types of relations (but not composite types). We allow -
19679 - * similar flexibility for ALTER INDEX in the case of RENAME, but not -
19680 - * otherwise. Otherwise, the user must select the correct form of the -
19681 - * command for the relation at issue. -
19682 - */ -
19683 - if (reltype == OBJECT_SEQUENCE && relkind != RELKIND_SEQUENCE) -
19684 - ereport(ERROR, -
19685 - (errcode(ERRCODE_WRONG_OBJECT_TYPE), -
19686 - errmsg("\"%s\" is not a sequence", rv->relname))); -
19687 - -
19688 - if (reltype == OBJECT_VIEW && relkind != RELKIND_VIEW) -
19689 - ereport(ERROR, -
19690 - (errcode(ERRCODE_WRONG_OBJECT_TYPE), -
19691 - errmsg("\"%s\" is not a view", rv->relname))); -
19692 - -
19693 - if (reltype == OBJECT_MATVIEW && relkind != RELKIND_MATVIEW) -
19694 - ereport(ERROR, -
19695 - (errcode(ERRCODE_WRONG_OBJECT_TYPE), -
19696 - errmsg("\"%s\" is not a materialized view", rv->relname))); -
19697 - -
19698 - if (reltype == OBJECT_FOREIGN_TABLE && relkind != RELKIND_FOREIGN_TABLE) -
19699 - ereport(ERROR, -
19700 - (errcode(ERRCODE_WRONG_OBJECT_TYPE), -
19701 - errmsg("\"%s\" is not a foreign table", rv->relname))); -
19702 - -
19703 - if (reltype == OBJECT_TYPE && relkind != RELKIND_COMPOSITE_TYPE) -
19704 - ereport(ERROR, -
19705 - (errcode(ERRCODE_WRONG_OBJECT_TYPE), -
19706 - errmsg("\"%s\" is not a composite type", rv->relname))); -
19707 - -
19708 18081 if (reltype == OBJECT_PROPGRAPH && relkind != RELKIND_PROPGRAPH) 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
19709 0 ereport(ERROR, 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
19710 - (errcode(ERRCODE_WRONG_OBJECT_TYPE), 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
19711 - errmsg("\"%s\" is not a property graph", rv->relname))); 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
19712 - 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
19713 - if (reltype == OBJECT_INDEX && relkind != RELKIND_INDEX && -
19714 - relkind != RELKIND_PARTITIONED_INDEX -
19715 - && !IsA(stmt, RenameStmt)) -
19716 - ereport(ERROR, -
19717 - (errcode(ERRCODE_WRONG_OBJECT_TYPE), -
19718 - errmsg("\"%s\" is not an index", rv->relname))); -
19719 - -
19720 - /* -
19721 - * Don't allow ALTER TABLE on composite types. We want people to use ALTER -
19722 - * TYPE for that. -
19723 - */ -
19724 - if (reltype != OBJECT_TYPE && relkind == RELKIND_COMPOSITE_TYPE) -
19725 - ereport(ERROR, -
19726 - (errcode(ERRCODE_WRONG_OBJECT_TYPE), -
19727 - errmsg("\"%s\" is a composite type", rv->relname), -
19728 - /* translator: %s is an SQL ALTER command */ -
19729 - errhint("Use %s instead.", -
19730 - "ALTER TYPE"))); -
19731 - -
19732 - /* -
19733 - * Don't allow ALTER TABLE .. SET SCHEMA on relations that can't be moved -
19734 - * to a different schema, such as indexes and TOAST tables. -
19735 - */ -
19736 - if (IsA(stmt, AlterObjectSchemaStmt)) -
19737 - { -
19738 - if (relkind == RELKIND_INDEX || relkind == RELKIND_PARTITIONED_INDEX) -
19739 - ereport(ERROR, -
19740 - (errcode(ERRCODE_WRONG_OBJECT_TYPE), -
19741 - errmsg("cannot change schema of index \"%s\"", -
19742 - rv->relname), -
19743 - errhint("Change the schema of the table instead."))); -
19744 - else if (relkind == RELKIND_COMPOSITE_TYPE) -
19745 - ereport(ERROR, -
19746 - (errcode(ERRCODE_WRONG_OBJECT_TYPE), -
19747 - errmsg("cannot change schema of composite type \"%s\"", -
19748 - rv->relname), -
19749 - /* translator: %s is an SQL ALTER command */ -
19750 - errhint("Use %s instead.", -
19751 - "ALTER TYPE"))); -
19752 - else if (relkind == RELKIND_TOASTVALUE) -
19753 - ereport(ERROR, -
19754 - (errcode(ERRCODE_WRONG_OBJECT_TYPE), -
19755 - errmsg("cannot change schema of TOAST table \"%s\"", -
19756 - rv->relname), -
19757 - errhint("Change the schema of the table instead."))); -
19758 - } -
19759 - -
19760 - ReleaseSysCache(tuple); -
19761 - } -