@@ -458,8 +458,6 @@ static ObjectAddress ATExecAlterColumnType(AlteredTableInfo *tab, Relation rel,
458
458
AlterTableCmd *cmd, LOCKMODE lockmode);
459
459
static void RememberConstraintForRebuilding(Oid conoid, AlteredTableInfo *tab);
460
460
static void RememberIndexForRebuilding(Oid indoid, AlteredTableInfo *tab);
461
- static ObjectAddress ATExecAlterColumnGenericOptions(Relation rel, const char *colName,
462
- List *options, LOCKMODE lockmode);
463
461
static void ATPostAlterTypeCleanup(List **wqueue, AlteredTableInfo *tab,
464
462
LOCKMODE lockmode);
465
463
static void ATPostAlterTypeParse(Oid oldId, Oid oldRelId, Oid refRelId,
@@ -470,6 +468,8 @@ static void RebuildConstraintComment(AlteredTableInfo *tab, int pass,
470
468
const char *conname);
471
469
static void TryReuseIndex(Oid oldId, IndexStmt *stmt);
472
470
static void TryReuseForeignKey(Oid oldId, Constraint *con);
471
+ static ObjectAddress ATExecAlterColumnGenericOptions(Relation rel, const char *colName,
472
+ List *options, LOCKMODE lockmode);
473
473
static void change_owner_fix_column_acls(Oid relationOid,
474
474
Oid oldOwnerId, Oid newOwnerId);
475
475
static void change_owner_recurse_to_sequences(Oid relationOid,
@@ -11048,118 +11048,12 @@ RememberIndexForRebuilding(Oid indoid, AlteredTableInfo *tab)
11048
11048
}
11049
11049
}
11050
11050
11051
- /*
11052
- * Returns the address of the modified column
11053
- */
11054
- static ObjectAddress
11055
- ATExecAlterColumnGenericOptions(Relation rel,
11056
- const char *colName,
11057
- List *options,
11058
- LOCKMODE lockmode)
11059
- {
11060
- Relation ftrel;
11061
- Relation attrel;
11062
- ForeignServer *server;
11063
- ForeignDataWrapper *fdw;
11064
- HeapTuple tuple;
11065
- HeapTuple newtuple;
11066
- bool isnull;
11067
- Datum repl_val[Natts_pg_attribute];
11068
- bool repl_null[Natts_pg_attribute];
11069
- bool repl_repl[Natts_pg_attribute];
11070
- Datum datum;
11071
- Form_pg_foreign_table fttableform;
11072
- Form_pg_attribute atttableform;
11073
- AttrNumber attnum;
11074
- ObjectAddress address;
11075
-
11076
- if (options == NIL)
11077
- return InvalidObjectAddress;
11078
-
11079
- /* First, determine FDW validator associated to the foreign table. */
11080
- ftrel = table_open(ForeignTableRelationId, AccessShareLock);
11081
- tuple = SearchSysCache1(FOREIGNTABLEREL, rel->rd_id);
11082
- if (!HeapTupleIsValid(tuple))
11083
- ereport(ERROR,
11084
- (errcode(ERRCODE_UNDEFINED_OBJECT),
11085
- errmsg("foreign table \"%s\" does not exist",
11086
- RelationGetRelationName(rel))));
11087
- fttableform = (Form_pg_foreign_table) GETSTRUCT(tuple);
11088
- server = GetForeignServer(fttableform->ftserver);
11089
- fdw = GetForeignDataWrapper(server->fdwid);
11090
-
11091
- table_close(ftrel, AccessShareLock);
11092
- ReleaseSysCache(tuple);
11093
-
11094
- attrel = table_open(AttributeRelationId, RowExclusiveLock);
11095
- tuple = SearchSysCacheAttName(RelationGetRelid(rel), colName);
11096
- if (!HeapTupleIsValid(tuple))
11097
- ereport(ERROR,
11098
- (errcode(ERRCODE_UNDEFINED_COLUMN),
11099
- errmsg("column \"%s\" of relation \"%s\" does not exist",
11100
- colName, RelationGetRelationName(rel))));
11101
-
11102
- /* Prevent them from altering a system attribute */
11103
- atttableform = (Form_pg_attribute) GETSTRUCT(tuple);
11104
- attnum = atttableform->attnum;
11105
- if (attnum <= 0)
11106
- ereport(ERROR,
11107
- (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
11108
- errmsg("cannot alter system column \"%s\"", colName)));
11109
-
11110
-
11111
- /* Initialize buffers for new tuple values */
11112
- memset(repl_val, 0, sizeof(repl_val));
11113
- memset(repl_null, false, sizeof(repl_null));
11114
- memset(repl_repl, false, sizeof(repl_repl));
11115
-
11116
- /* Extract the current options */
11117
- datum = SysCacheGetAttr(ATTNAME,
11118
- tuple,
11119
- Anum_pg_attribute_attfdwoptions,
11120
- &isnull);
11121
- if (isnull)
11122
- datum = PointerGetDatum(NULL);
11123
-
11124
- /* Transform the options */
11125
- datum = transformGenericOptions(AttributeRelationId,
11126
- datum,
11127
- options,
11128
- fdw->fdwvalidator);
11129
-
11130
- if (PointerIsValid(DatumGetPointer(datum)))
11131
- repl_val[Anum_pg_attribute_attfdwoptions - 1] = datum;
11132
- else
11133
- repl_null[Anum_pg_attribute_attfdwoptions - 1] = true;
11134
-
11135
- repl_repl[Anum_pg_attribute_attfdwoptions - 1] = true;
11136
-
11137
- /* Everything looks good - update the tuple */
11138
-
11139
- newtuple = heap_modify_tuple(tuple, RelationGetDescr(attrel),
11140
- repl_val, repl_null, repl_repl);
11141
-
11142
- CatalogTupleUpdate(attrel, &newtuple->t_self, newtuple);
11143
-
11144
- InvokeObjectPostAlterHook(RelationRelationId,
11145
- RelationGetRelid(rel),
11146
- atttableform->attnum);
11147
- ObjectAddressSubSet(address, RelationRelationId,
11148
- RelationGetRelid(rel), attnum);
11149
-
11150
- ReleaseSysCache(tuple);
11151
-
11152
- table_close(attrel, RowExclusiveLock);
11153
-
11154
- heap_freetuple(newtuple);
11155
-
11156
- return address;
11157
- }
11158
-
11159
11051
/*
11160
11052
* Cleanup after we've finished all the ALTER TYPE operations for a
11161
11053
* particular relation. We have to drop and recreate all the indexes
11162
- * and constraints that depend on the altered columns.
11054
+ * and constraints that depend on the altered columns. We do the
11055
+ * actual dropping here, but re-creation is managed by adding work
11056
+ * queue entries to do those steps later.
11163
11057
*/
11164
11058
static void
11165
11059
ATPostAlterTypeCleanup(List **wqueue, AlteredTableInfo *tab, LOCKMODE lockmode)
@@ -11272,6 +11166,14 @@ ATPostAlterTypeCleanup(List **wqueue, AlteredTableInfo *tab, LOCKMODE lockmode)
11272
11166
*/
11273
11167
}
11274
11168
11169
+ /*
11170
+ * Parse the previously-saved definition string for a constraint or index
11171
+ * against the newly-established column data type(s), and queue up the
11172
+ * resulting command parsetrees for execution.
11173
+ *
11174
+ * This might fail if, for example, you have a WHERE clause that uses an
11175
+ * operator that's not available for the new column type.
11176
+ */
11275
11177
static void
11276
11178
ATPostAlterTypeParse(Oid oldId, Oid oldRelId, Oid refRelId, char *cmd,
11277
11179
List **wqueue, LOCKMODE lockmode, bool rewrite)
@@ -11566,6 +11468,116 @@ TryReuseForeignKey(Oid oldId, Constraint *con)
11566
11468
ReleaseSysCache(tup);
11567
11469
}
11568
11470
11471
+ /*
11472
+ * ALTER COLUMN .. OPTIONS ( ... )
11473
+ *
11474
+ * Returns the address of the modified column
11475
+ */
11476
+ static ObjectAddress
11477
+ ATExecAlterColumnGenericOptions(Relation rel,
11478
+ const char *colName,
11479
+ List *options,
11480
+ LOCKMODE lockmode)
11481
+ {
11482
+ Relation ftrel;
11483
+ Relation attrel;
11484
+ ForeignServer *server;
11485
+ ForeignDataWrapper *fdw;
11486
+ HeapTuple tuple;
11487
+ HeapTuple newtuple;
11488
+ bool isnull;
11489
+ Datum repl_val[Natts_pg_attribute];
11490
+ bool repl_null[Natts_pg_attribute];
11491
+ bool repl_repl[Natts_pg_attribute];
11492
+ Datum datum;
11493
+ Form_pg_foreign_table fttableform;
11494
+ Form_pg_attribute atttableform;
11495
+ AttrNumber attnum;
11496
+ ObjectAddress address;
11497
+
11498
+ if (options == NIL)
11499
+ return InvalidObjectAddress;
11500
+
11501
+ /* First, determine FDW validator associated to the foreign table. */
11502
+ ftrel = table_open(ForeignTableRelationId, AccessShareLock);
11503
+ tuple = SearchSysCache1(FOREIGNTABLEREL, rel->rd_id);
11504
+ if (!HeapTupleIsValid(tuple))
11505
+ ereport(ERROR,
11506
+ (errcode(ERRCODE_UNDEFINED_OBJECT),
11507
+ errmsg("foreign table \"%s\" does not exist",
11508
+ RelationGetRelationName(rel))));
11509
+ fttableform = (Form_pg_foreign_table) GETSTRUCT(tuple);
11510
+ server = GetForeignServer(fttableform->ftserver);
11511
+ fdw = GetForeignDataWrapper(server->fdwid);
11512
+
11513
+ table_close(ftrel, AccessShareLock);
11514
+ ReleaseSysCache(tuple);
11515
+
11516
+ attrel = table_open(AttributeRelationId, RowExclusiveLock);
11517
+ tuple = SearchSysCacheAttName(RelationGetRelid(rel), colName);
11518
+ if (!HeapTupleIsValid(tuple))
11519
+ ereport(ERROR,
11520
+ (errcode(ERRCODE_UNDEFINED_COLUMN),
11521
+ errmsg("column \"%s\" of relation \"%s\" does not exist",
11522
+ colName, RelationGetRelationName(rel))));
11523
+
11524
+ /* Prevent them from altering a system attribute */
11525
+ atttableform = (Form_pg_attribute) GETSTRUCT(tuple);
11526
+ attnum = atttableform->attnum;
11527
+ if (attnum <= 0)
11528
+ ereport(ERROR,
11529
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
11530
+ errmsg("cannot alter system column \"%s\"", colName)));
11531
+
11532
+
11533
+ /* Initialize buffers for new tuple values */
11534
+ memset(repl_val, 0, sizeof(repl_val));
11535
+ memset(repl_null, false, sizeof(repl_null));
11536
+ memset(repl_repl, false, sizeof(repl_repl));
11537
+
11538
+ /* Extract the current options */
11539
+ datum = SysCacheGetAttr(ATTNAME,
11540
+ tuple,
11541
+ Anum_pg_attribute_attfdwoptions,
11542
+ &isnull);
11543
+ if (isnull)
11544
+ datum = PointerGetDatum(NULL);
11545
+
11546
+ /* Transform the options */
11547
+ datum = transformGenericOptions(AttributeRelationId,
11548
+ datum,
11549
+ options,
11550
+ fdw->fdwvalidator);
11551
+
11552
+ if (PointerIsValid(DatumGetPointer(datum)))
11553
+ repl_val[Anum_pg_attribute_attfdwoptions - 1] = datum;
11554
+ else
11555
+ repl_null[Anum_pg_attribute_attfdwoptions - 1] = true;
11556
+
11557
+ repl_repl[Anum_pg_attribute_attfdwoptions - 1] = true;
11558
+
11559
+ /* Everything looks good - update the tuple */
11560
+
11561
+ newtuple = heap_modify_tuple(tuple, RelationGetDescr(attrel),
11562
+ repl_val, repl_null, repl_repl);
11563
+
11564
+ CatalogTupleUpdate(attrel, &newtuple->t_self, newtuple);
11565
+
11566
+ InvokeObjectPostAlterHook(RelationRelationId,
11567
+ RelationGetRelid(rel),
11568
+ atttableform->attnum);
11569
+ ObjectAddressSubSet(address, RelationRelationId,
11570
+ RelationGetRelid(rel), attnum);
11571
+
11572
+ ReleaseSysCache(tuple);
11573
+
11574
+ table_close(attrel, RowExclusiveLock);
11575
+
11576
+ heap_freetuple(newtuple);
11577
+
11578
+ return address;
11579
+ }
11580
+
11569
11581
/*
11570
11582
* ALTER TABLE OWNER
11571
11583
*
0 commit comments