diff options
Diffstat (limited to 'src/backend')
-rw-r--r-- | src/backend/catalog/pg_depend.c | 31 | ||||
-rw-r--r-- | src/backend/commands/tablecmds.c | 2 | ||||
-rw-r--r-- | src/backend/parser/parse_utilcmd.c | 52 | ||||
-rw-r--r-- | src/backend/rewrite/rewriteHandler.c | 19 |
4 files changed, 61 insertions, 43 deletions
diff --git a/src/backend/catalog/pg_depend.c b/src/backend/catalog/pg_depend.c index f85a898de8d..5366f7820c1 100644 --- a/src/backend/catalog/pg_depend.c +++ b/src/backend/catalog/pg_depend.c @@ -23,10 +23,12 @@ #include "catalog/pg_constraint.h" #include "catalog/pg_depend.h" #include "catalog/pg_extension.h" +#include "catalog/partition.h" #include "commands/extension.h" #include "miscadmin.h" #include "utils/fmgroids.h" #include "utils/lsyscache.h" +#include "utils/syscache.h" #include "utils/rel.h" @@ -941,10 +943,35 @@ getOwnedSequences(Oid relid) * Get owned identity sequence, error if not exactly one. */ Oid -getIdentitySequence(Oid relid, AttrNumber attnum, bool missing_ok) +getIdentitySequence(Relation rel, AttrNumber attnum, bool missing_ok) { - List *seqlist = getOwnedSequences_internal(relid, attnum, DEPENDENCY_INTERNAL); + Oid relid; + List *seqlist; + /* + * The identity sequence is associated with the topmost partitioned table, + * which might have column order different than the given partition. + */ + if (RelationGetForm(rel)->relispartition) + { + List *ancestors = + get_partition_ancestors(RelationGetRelid(rel)); + HeapTuple ctup = SearchSysCacheAttNum(RelationGetRelid(rel), attnum); + const char *attname = NameStr(((Form_pg_attribute) GETSTRUCT(ctup))->attname); + HeapTuple ptup; + + relid = llast_oid(ancestors); + ptup = SearchSysCacheAttName(relid, attname); + attnum = ((Form_pg_attribute) GETSTRUCT(ptup))->attnum; + + ReleaseSysCache(ctup); + ReleaseSysCache(ptup); + list_free(ancestors); + } + else + relid = RelationGetRelid(rel); + + seqlist = getOwnedSequences_internal(relid, attnum, DEPENDENCY_INTERNAL); if (list_length(seqlist) > 1) elog(ERROR, "more than one owned sequence found"); else if (seqlist == NIL) diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index a79ac884f7c..5bf5e69c5b8 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -8535,7 +8535,7 @@ ATExecDropIdentity(Relation rel, const char *colName, bool missing_ok, LOCKMODE if (!recursing) { /* drop the internal sequence */ - seqid = getIdentitySequence(RelationGetRelid(rel), attnum, false); + seqid = getIdentitySequence(rel, attnum, false); deleteDependencyRecordsForClass(RelationRelationId, seqid, RelationRelationId, DEPENDENCY_INTERNAL); CommandCounterIncrement(); diff --git a/src/backend/parser/parse_utilcmd.c b/src/backend/parser/parse_utilcmd.c index 9fb6ff86db5..6520bf9baa5 100644 --- a/src/backend/parser/parse_utilcmd.c +++ b/src/backend/parser/parse_utilcmd.c @@ -1136,7 +1136,7 @@ transformTableLikeClause(CreateStmtContext *cxt, TableLikeClause *table_like_cla * find sequence owned by old column; extract sequence parameters; * build new create sequence command */ - seq_relid = getIdentitySequence(RelationGetRelid(relation), attribute->attnum, false); + seq_relid = getIdentitySequence(relation, attribute->attnum, false); seq_options = sequence_options(seq_relid); generateSerialExtraStmts(cxt, def, InvalidOid, seq_options, @@ -3716,28 +3716,36 @@ transformAlterTableStmt(Oid relid, AlterTableStmt *stmt, /* * For identity column, create ALTER SEQUENCE command to - * change the data type of the sequence. + * change the data type of the sequence. Identity sequence + * is associated with the top level partitioned table. + * Hence ignore partitions. */ - attnum = get_attnum(relid, cmd->name); - if (attnum == InvalidAttrNumber) - ereport(ERROR, - (errcode(ERRCODE_UNDEFINED_COLUMN), - errmsg("column \"%s\" of relation \"%s\" does not exist", - cmd->name, RelationGetRelationName(rel)))); - - if (attnum > 0 && - TupleDescAttr(tupdesc, attnum - 1)->attidentity) + if (!RelationGetForm(rel)->relispartition) { - Oid seq_relid = getIdentitySequence(relid, attnum, false); - Oid typeOid = typenameTypeId(pstate, def->typeName); - AlterSeqStmt *altseqstmt = makeNode(AlterSeqStmt); - - altseqstmt->sequence = makeRangeVar(get_namespace_name(get_rel_namespace(seq_relid)), - get_rel_name(seq_relid), - -1); - altseqstmt->options = list_make1(makeDefElem("as", (Node *) makeTypeNameFromOid(typeOid, -1), -1)); - altseqstmt->for_identity = true; - cxt.blist = lappend(cxt.blist, altseqstmt); + attnum = get_attnum(relid, cmd->name); + if (attnum == InvalidAttrNumber) + ereport(ERROR, + (errcode(ERRCODE_UNDEFINED_COLUMN), + errmsg("column \"%s\" of relation \"%s\" does not exist", + cmd->name, RelationGetRelationName(rel)))); + + if (attnum > 0 && + TupleDescAttr(tupdesc, attnum - 1)->attidentity) + { + Oid seq_relid = getIdentitySequence(rel, attnum, false); + Oid typeOid = typenameTypeId(pstate, def->typeName); + AlterSeqStmt *altseqstmt = makeNode(AlterSeqStmt); + + altseqstmt->sequence + = makeRangeVar(get_namespace_name(get_rel_namespace(seq_relid)), + get_rel_name(seq_relid), + -1); + altseqstmt->options = list_make1(makeDefElem("as", + (Node *) makeTypeNameFromOid(typeOid, -1), + -1)); + altseqstmt->for_identity = true; + cxt.blist = lappend(cxt.blist, altseqstmt); + } } newcmds = lappend(newcmds, cmd); @@ -3803,7 +3811,7 @@ transformAlterTableStmt(Oid relid, AlterTableStmt *stmt, errmsg("column \"%s\" of relation \"%s\" does not exist", cmd->name, RelationGetRelationName(rel)))); - seq_relid = getIdentitySequence(relid, attnum, true); + seq_relid = getIdentitySequence(rel, attnum, true); if (seq_relid) { diff --git a/src/backend/rewrite/rewriteHandler.c b/src/backend/rewrite/rewriteHandler.c index 9fd05b15e73..8a29fbbc465 100644 --- a/src/backend/rewrite/rewriteHandler.c +++ b/src/backend/rewrite/rewriteHandler.c @@ -24,7 +24,6 @@ #include "access/sysattr.h" #include "access/table.h" #include "catalog/dependency.h" -#include "catalog/partition.h" #include "commands/trigger.h" #include "executor/executor.h" #include "foreign/fdwapi.h" @@ -1233,24 +1232,8 @@ build_column_default(Relation rel, int attrno) if (att_tup->attidentity) { NextValueExpr *nve = makeNode(NextValueExpr); - Oid reloid; - /* - * The identity sequence is associated with the topmost partitioned - * table. - */ - if (rel->rd_rel->relispartition) - { - List *ancestors = - get_partition_ancestors(RelationGetRelid(rel)); - - reloid = llast_oid(ancestors); - list_free(ancestors); - } - else - reloid = RelationGetRelid(rel); - - nve->seqid = getIdentitySequence(reloid, attrno, false); + nve->seqid = getIdentitySequence(rel, attrno, false); nve->typeId = att_tup->atttypid; return (Node *) nve; |