解决带modify first| after core的问题

This commit is contained in:
yuhuanhuan
2023-12-28 16:29:14 +08:00
parent 738bca5fc0
commit 97e9e6ae66
3 changed files with 558 additions and 25 deletions

View File

@ -277,6 +277,7 @@ typedef struct NewColumnValue {
> 0 denote modify with first|after */
char *col_name;
AttrNumber generate_attnum;
bool is_updated;
} NewColumnValue;
/*
@ -497,6 +498,8 @@ static void ExecChangeTableSpaceForCStorePartition(AlteredTableInfo*, LOCKMODE);
static int GetAfterColumnAttnum(Oid attrelid, const char *after_name);
static Node *UpdateVarattnoAfterAddColumn(Node *node, int startattnum, int endattnum, bool is_increase);
static void UpdatePgStatisticFirstAfter(Relation rel, int startattnum, int endattnum, bool is_increase);
static void UpdatePgStatisticExtFirstAfter(Relation rel, int startattnum, int endattnum, bool is_increase);
static void UpdatePgDescriptionFirstAfter(Relation rel, int startattnum, int endattnum, bool is_increase);
static void UpdatePgAttributeFirstAfter(Relation attr_rel, Oid attrelid, int startattnum, int endattnum,
bool is_increase);
@ -11054,6 +11057,111 @@ static Node *UpdateVarattnoAfterAddColumn(Node *node, int startattnum, int endat
return NULL;
}
/*
* update pg_statistic
* 1. add column with first or after column
* 2. modify column to first or after column
*/
static void UpdatePgStatisticFirstAfter(Relation rel, int startattnum, int endattnum, bool is_increase)
{
Relation stat_rel;
HeapTuple stat_tuple;
ScanKeyData key[3];
SysScanDesc scan;
Form_pg_statistic stat_form;
stat_rel = heap_open(StatisticRelationId, RowExclusiveLock);
for (int i = (is_increase ? endattnum : startattnum);
(is_increase ? i >= startattnum : i <= endattnum); (is_increase ? i-- : i++)) {
ScanKeyInit(&key[0], Anum_pg_statistic_starelid, BTEqualStrategyNumber, F_OIDEQ,
ObjectIdGetDatum(RelationGetRelid(rel)));
ScanKeyInit(&key[1], Anum_pg_statistic_starelkind, BTEqualStrategyNumber, F_CHAREQ, ObjectIdGetDatum(STARELKIND_CLASS));
ScanKeyInit(&key[2], Anum_pg_statistic_staattnum, BTEqualStrategyNumber, F_INT2EQ, Int16GetDatum(i));
scan = systable_beginscan(stat_rel, StatisticRelidKindAttnumInhIndexId, true, NULL, 3, key);
while (HeapTupleIsValid(stat_tuple = systable_getnext(scan))) {
Datum values[Natts_pg_statistic] = { 0 };
bool nulls[Natts_pg_statistic] = { 0 };
bool replaces[Natts_pg_statistic] = { 0 };
HeapTuple new_stat_tuple;
stat_form = (Form_pg_statistic)GETSTRUCT(stat_tuple);
values[Anum_pg_statistic_staattnum - 1] = is_increase ? Int16GetDatum(stat_form->staattnum + 1) :
Int16GetDatum(stat_form->staattnum - 1);
replaces[Anum_pg_statistic_staattnum - 1] = true;
new_stat_tuple = heap_modify_tuple(stat_tuple, RelationGetDescr(stat_rel), values, nulls, replaces);
simple_heap_update(stat_rel, &new_stat_tuple->t_self, new_stat_tuple);
CatalogUpdateIndexes(stat_rel, new_stat_tuple);
heap_freetuple_ext(new_stat_tuple);
}
systable_endscan(scan);
}
heap_close(stat_rel, RowExclusiveLock);
}
/*
* update pg_statistic_ext
* 1. add column with first or after column
* 2. modify column to first or after column
*/
static void UpdatePgStatisticExtFirstAfter(Relation rel, int startattnum, int endattnum, bool is_increase)
{
Relation stat_ext_rel;
HeapTuple stat_ext_tuple;
ScanKeyData key[2];
SysScanDesc scan;
int curattnum = is_increase ? endattnum + 1 : startattnum - 1;
int newattnum = is_increase ? startattnum : endattnum;
ScanKeyInit(&key[0], Anum_pg_statistic_ext_starelid, BTEqualStrategyNumber, F_OIDEQ,
ObjectIdGetDatum(RelationGetRelid(rel)));
ScanKeyInit(&key[1], Anum_pg_statistic_ext_starelkind, BTEqualStrategyNumber, F_CHAREQ, ObjectIdGetDatum(STARELKIND_CLASS));
stat_ext_rel = heap_open(StatisticExtRelationId, RowExclusiveLock);
scan = systable_beginscan(stat_ext_rel, StatisticExtRelidKindInhKeyIndexId, true, NULL, 2, key);
while (HeapTupleIsValid(stat_ext_tuple = systable_getnext(scan))) {
bool is_null = false;
Datum values[Natts_pg_statistic_ext] = { 0 };
bool nulls[Natts_pg_statistic_ext] = { 0 };
bool replaces[Natts_pg_statistic_ext] = { 0 };
int2vector *stakey = NULL;
int2vector *new_stakey = NULL;
HeapTuple new_stat_ext_tuple;
Datum stakey_datum = fastgetattr(stat_ext_tuple, Anum_pg_statistic_ext_stakey, RelationGetDescr(stat_ext_rel), &is_null);
stakey = (int2vector *)DatumGetPointer(stakey_datum);
int2 *stakey_values = (int2 *)palloc0(stakey->dim1 * sizeof(int2));
for (int i = 0; i < stakey->dim1; i++) {
if (stakey->values[i] >= startattnum && stakey->values[i] <= endattnum) {
stakey_values[i] = is_increase ? (stakey->values[i] + 1) : (stakey->values[i] - 1);
} else if (stakey->values[i] == curattnum) {
stakey_values[i] = newattnum;
} else {
stakey_values[i] = stakey->values[i];
}
}
new_stakey = buildint2vector(stakey_values, stakey->dim1);
values[Anum_pg_statistic_ext_stakey - 1] = PointerGetDatum(new_stakey);
replaces[Anum_pg_statistic_ext_stakey - 1] = true;
new_stat_ext_tuple = heap_modify_tuple(stat_ext_tuple, RelationGetDescr(stat_ext_rel), values, nulls, replaces);
simple_heap_update(stat_ext_rel, &new_stat_ext_tuple->t_self, new_stat_ext_tuple);
CatalogUpdateIndexes(stat_ext_rel, new_stat_ext_tuple);
pfree_ext(new_stakey);
pfree_ext(stakey_values);
heap_freetuple_ext(new_stat_ext_tuple);
}
systable_endscan(scan);
heap_close(stat_ext_rel, RowExclusiveLock);
}
/*
* update pg_description
* 1. add column with first or after col_name.
@ -11209,16 +11317,17 @@ static void UpdatePgIndexFirstAfter(Relation rel, int startattnum, int endattnum
AssertEreport(!is_null, MOD_OPT, "");
indkey = (int2vector *)DatumGetPointer(indkey_datum);
Assert(indkey->dim1 == numatts);
new_indkey = buildint2vector(NULL, numatts);
int2 *indkey_values = (int2 *)palloc0(numatts * sizeof(int2));
for (int i = 0; i < numatts; i++) {
if (indkey->values[i] >= startattnum && indkey->values[i] <= endattnum) {
new_indkey->values[i] = is_increase ? (indkey->values[i] + 1) : (indkey->values[i] - 1);
indkey_values[i] = is_increase ? (indkey->values[i] + 1) : (indkey->values[i] - 1);
} else if (indkey->values[i] == curattnum) {
new_indkey->values[i] = newattnum;
indkey_values[i] = newattnum;
} else {
new_indkey->values[i] = indkey->values[i];
indkey_values[i] = indkey->values[i];
}
}
new_indkey = buildint2vector(indkey_values, numatts);
values[Anum_pg_index_indkey - 1] = PointerGetDatum(new_indkey);
replaces[Anum_pg_index_indkey - 1] = true;
@ -11267,6 +11376,7 @@ static void UpdatePgIndexFirstAfter(Relation rel, int startattnum, int endattnum
CatalogUpdateIndexes(index_rel, new_index_tuple);
pfree_ext(new_indkey);
pfree_ext(indkey_values);
heap_freetuple_ext(new_index_tuple);
}
@ -11507,7 +11617,7 @@ static void UpdateIndexFirstAfter(Relation rel)
HeapTuple index_tuple;
ScanKeyData key;
SysScanDesc scan;
Form_pg_index index_form;
MemoryContext oldcontext;
/* Prepare to scan pg_index for entries having indrelid = this rel. */
ScanKeyInit(&key, Anum_pg_index_indrelid, BTEqualStrategyNumber, F_OIDEQ,
@ -11516,11 +11626,15 @@ static void UpdateIndexFirstAfter(Relation rel)
scan = systable_beginscan(pg_index_rel, IndexIndrelidIndexId, true, NULL, 1, &key);
while (HeapTupleIsValid(index_tuple = systable_getnext(scan))) {
index_form = (Form_pg_index)GETSTRUCT(index_tuple);
Form_pg_index index_form = (Form_pg_index)GETSTRUCT(index_tuple);
table_index_rel = index_open(index_form->indexrelid, RowExclusiveLock);
table_index_rel->rd_index = index_form;
oldcontext = MemoryContextSwitchTo(LocalMyDBCacheMemCxt());
pfree_ext(table_index_rel->rd_indextuple);
table_index_rel->rd_indextuple = heap_copytuple(index_tuple);
table_index_rel->rd_index = (Form_pg_index)GETSTRUCT(table_index_rel->rd_indextuple);
(void)MemoryContextSwitchTo(oldcontext);
index_close(table_index_rel, RowExclusiveLock);
}
@ -11703,23 +11817,25 @@ static void UpdatePgPartitionFirstAfter(Relation rel, int startattnum, int endat
HeapTuple new_par_tuple;
partkey = (int2vector *)DatumGetPointer(partkey_datum);
new_partKey = buildint2vector(NULL, partkey->dim1);
int2 *partkey_values = (int2 *)palloc0(partkey->dim1 * sizeof(int2));
for (int i = 0; i < partkey->dim1; i++) {
if (partkey->values[i] >= startattnum && partkey->values[i] <= endattnum) {
new_partKey->values[i] = is_increase ? (partkey->values[i] + 1) : (partkey->values[i] - 1);
partkey_values[i] = is_increase ? (partkey->values[i] + 1) : (partkey->values[i] - 1);
} else if (partkey->values[i] == curattnum) {
if (is_modified) {
if (has_partition != NULL) {
*has_partition = true;
}
new_partKey->values[i] = 0;
partkey_values[i] = 0;
} else {
new_partKey->values[i] = newattnum;
partkey_values[i] = newattnum;
}
} else {
new_partKey->values[i] = partkey->values[i];
partkey_values[i] = partkey->values[i];
}
}
new_partKey = buildint2vector(partkey_values, partkey->dim1);
values[Anum_pg_partition_partkey - 1] = PointerGetDatum(new_partKey);
replaces[Anum_pg_partition_partkey - 1] = true;
@ -11728,6 +11844,7 @@ static void UpdatePgPartitionFirstAfter(Relation rel, int startattnum, int endat
CatalogUpdateIndexes(par_rel, new_par_tuple);
pfree_ext(new_partKey);
pfree_ext(partkey_values);
heap_freetuple_ext(new_par_tuple);
}
}
@ -12002,21 +12119,24 @@ static void UpdatePgTriggerFirstAfter(Relation rel, int startattnum, int endattn
bool nulls[Natts_pg_trigger] = { 0 };
bool replaces[Natts_pg_trigger] = { 0 };
HeapTuple new_tri_tuple;
int2vector *new_tgattr = NULL;
int2 *tgattr_values = NULL;
Datum tgattr_datum = fastgetattr(tri_tuple, Anum_pg_trigger_tgattr, tri_rel->rd_att, &is_null);
if (!is_null) {
int2vector *tgattr = (int2vector *)DatumGetPointer(tgattr_datum);
int2vector *new_tgattr = buildint2vector(NULL, tgattr->dim1);
int2 *tgattr_values = (int2 *)palloc0(tgattr->dim1 * sizeof(int2));
for (int i = 0; i < tgattr->dim1; i++) {
if (tgattr->values[i] >= startattnum && tgattr->values[i] <= endattnum) {
new_tgattr->values[i] = is_increase ? (tgattr->values[i] + 1) : (tgattr->values[i] - 1);
tgattr_values[i] = is_increase ? (tgattr->values[i] + 1) : (tgattr->values[i] - 1);
} else if (tgattr->values[i] == curattnum) {
new_tgattr->values[i] = newattnum;
tgattr_values[i] = newattnum;
} else {
new_tgattr->values[i] = tgattr->values[i];
tgattr_values[i] = tgattr->values[i];
}
}
new_tgattr = buildint2vector(tgattr_values, tgattr->dim1);
values[Anum_pg_trigger_tgattr - 1] = PointerGetDatum(new_tgattr);
replaces[Anum_pg_trigger_tgattr - 1] = true;
}
@ -12040,6 +12160,10 @@ static void UpdatePgTriggerFirstAfter(Relation rel, int startattnum, int endattn
new_tri_tuple = heap_modify_tuple(tri_tuple, RelationGetDescr(tri_rel), values, nulls, replaces);
simple_heap_update(tri_rel, &new_tri_tuple->t_self, new_tri_tuple);
CatalogUpdateIndexes(tri_rel, new_tri_tuple);
pfree_ext(tgattr_values);
pfree_ext(new_tgattr);
heap_freetuple_ext(new_tri_tuple);
}
systable_endscan(scan);
@ -12090,6 +12214,8 @@ static void UpdatePgRlspolicyFirstAfter(Relation rel, int startattnum, int endat
new_rls_tuple = heap_modify_tuple(rls_tuple, RelationGetDescr(rls_rel), values, nulls, replaces);
simple_heap_update(rls_rel, &new_rls_tuple->t_self, new_rls_tuple);
CatalogUpdateIndexes(rls_rel, new_rls_tuple);
heap_freetuple_ext(new_rls_tuple);
}
systable_endscan(scan);
@ -12336,6 +12462,8 @@ static ObjectAddress ATExecAddColumn(List** wqueue, AlteredTableInfo* tab, Relat
if (is_addloc) {
UpdatePgAttributeFirstAfter(attrdesc, myrelid, newattnum, currattnum, true);
UpdatePgDescriptionFirstAfter(rel, newattnum, currattnum, true);
UpdatePgStatisticFirstAfter(rel, newattnum, currattnum, true);
UpdatePgStatisticExtFirstAfter(rel, newattnum, currattnum, true);
UpdatePgIndexFirstAfter(rel, newattnum, currattnum, true);
UpdatePgConstraintFirstAfter(rel, newattnum, currattnum, true);
UpdatePgConstraintConfkeyFirstAfter(rel, newattnum, currattnum, true);
@ -15918,6 +16046,7 @@ static void ATPrepAlterColumnType(List** wqueue, AlteredTableInfo* tab, Relation
newval->newattnum = 0;
newval->col_name = pstrdup(colName);
newval->generate_attnum = 0;
newval->is_updated = false;
tab->newvals = lappend(tab->newvals, newval);
if (ATColumnChangeRequiresRewrite(transform, attnum))
@ -16345,6 +16474,8 @@ static void AlterColumnToFirstAfter(AlteredTableInfo* tab, Relation rel, AlterTa
UpdatePgPartitionFirstAfter(rel, startattnum, endattnum, is_increase, true, &has_partition);
UpdatePgAttributeFirstAfter(attr_rel, myrelid, startattnum, endattnum, is_increase);
UpdatePgDescriptionFirstAfter(rel, startattnum, endattnum, is_increase);
UpdatePgStatisticFirstAfter(rel, startattnum, endattnum, is_increase);
UpdatePgStatisticExtFirstAfter(rel, startattnum, endattnum, is_increase);
UpdatePgIndexFirstAfter(rel, startattnum, endattnum, is_increase);
UpdatePgConstraintFirstAfter(rel, startattnum, endattnum, is_increase);
UpdatePgConstraintConfkeyFirstAfter(rel, startattnum, endattnum, is_increase);
@ -16435,7 +16566,7 @@ static void UpdateNewvalsAttnum(AlteredTableInfo* tab, Relation rel, AlterTableC
continue;
}
if (strcmp(ex->col_name, col_name) == 0) {
if (strcmp(ex->col_name, col_name) == 0 && !ex->is_updated) {
HeapTuple heap_tup;
Form_pg_attribute att_tup;
@ -16447,8 +16578,10 @@ static void UpdateNewvalsAttnum(AlteredTableInfo* tab, Relation rel, AlterTableC
att_tup = (Form_pg_attribute)GETSTRUCT(heap_tup);
ex->attnum = att_tup->attnum;
ex->newattnum = GetNewattnumFirstAfter(rel, cmd, ex->attnum);
ex->is_updated = true;
tableam_tops_free_tuple(heap_tup);
return;
}
}
}
@ -16872,6 +17005,10 @@ static ObjectAddress ATExecAlterColumnType(AlteredTableInfo* tab, Relation rel,
heap_close(depRel, RowExclusiveLock);
if (tab->is_first_after) {
UpdateNewvalsAttnum(tab, rel, cmd, colName);
}
/*
* Here we go --- change the recorded column type and collation. (Note
* heapTup is a copy of the syscache entry, so okay to scribble on.)
@ -32815,7 +32952,7 @@ static void ATExecAlterModifyColumn(AlteredTableInfo* tab, Relation rel, AlterTa
tab->new_notnull = true;
}
if (is_first_after) {
if (is_first_after || tab->is_first_after) {
UpdateNewvalsAttnum(tab, rel, cmd, col_name);
}

View File

@ -8844,12 +8844,12 @@ Indexes:
Has OIDs: no
Options: orientation=row, compression=no
SELECT n.nspname, c.relname from pg_class c, pg_namespace n where n.oid = c.relnamespace and c.relname in ('test', 'test_pkey', 'test_b_idx', 'tttt');
SELECT n.nspname, c.relname from pg_class c, pg_namespace n where n.oid = c.relnamespace and c.relname in ('test', 'test_pkey', 'test_b_idx', 'tttt') order by c.relname;
nspname | relname
---------+------------
test1 | test
test1 | test_pkey
test1 | test_b_idx
test1 | test_pkey
(3 rows)
SELECT * FROM test1.test;
@ -8879,12 +8879,12 @@ Indexes:
Has OIDs: no
Options: orientation=row, compression=no
SELECT n.nspname, c.relname from pg_class c, pg_namespace n where n.oid = c.relnamespace and c.relname in ('test', 'test_pkey', 'test_b_idx', 'tttt');
SELECT n.nspname, c.relname from pg_class c, pg_namespace n where n.oid = c.relnamespace and c.relname in ('test', 'test_pkey', 'test_b_idx', 'tttt') order by c.relname;
nspname | relname
---------+------------
test2 | tttt
test2 | test_pkey
test2 | test_b_idx
test2 | test_pkey
test2 | tttt
(3 rows)
INSERT INTO test2.tttt VALUES (2, 2);
@ -9123,5 +9123,278 @@ select * from t_after_first;
| 3 | 4 | |
(2 rows)
drop table if exists test_dts;
NOTICE: table "test_dts" does not exist, skipping
create table test_dts(
f1 int primary key,
f2 varchar(8),
f3 timestamp
);
NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "test_dts_pkey" for table "test_dts"
insert into test_dts(f1, f2, f3) values(1, 'data1', '2023-07-31 12:34:56'), (2, 'date2', '2023-07-31 13:45:30'),
(3, 'data3', '2023-07-31 14:56:15'), (4, 'data1', '2023-07-31 12:34:56'), (5, 'date2', '2023-07-31 13:45:30'),
(6, 'data3', '2023-07-31 14:56:15');
analyze test_dts;
analyze test_dts((f1, f3));
INFO: Please set default_statistics_target to a negative value to collect extended statistics.
select staattnum, stavalues1 from pg_statistic where starelid = 'test_dts'::regclass order by staattnum;
staattnum | stavalues1
-----------+------------------------------------------------------------------------------------
1 | {1,2,3,4,5,6}
2 | {data1,data3,date2}
3 | {"Mon Jul 31 12:34:56 2023","Mon Jul 31 13:45:30 2023","Mon Jul 31 14:56:15 2023"}
(3 rows)
select stakey from pg_statistic_ext where starelid = 'test_dts'::regclass;
stakey
--------
(0 rows)
alter table test_dts add column f4 int default 0 after f1;
select staattnum, stavalues1 from pg_statistic where starelid = 'test_dts'::regclass order by staattnum;
staattnum | stavalues1
-----------+------------------------------------------------------------------------------------
1 | {1,2,3,4,5,6}
3 | {data1,data3,date2}
4 | {"Mon Jul 31 12:34:56 2023","Mon Jul 31 13:45:30 2023","Mon Jul 31 14:56:15 2023"}
(3 rows)
select stakey from pg_statistic_ext where starelid = 'test_dts'::regclass;
stakey
--------
(0 rows)
alter table test_dts add column f5 varchar(20) default 'f5' first;
select staattnum, stavalues1 from pg_statistic where starelid = 'test_dts'::regclass order by staattnum;
staattnum | stavalues1
-----------+------------------------------------------------------------------------------------
2 | {1,2,3,4,5,6}
4 | {data1,data3,date2}
5 | {"Mon Jul 31 12:34:56 2023","Mon Jul 31 13:45:30 2023","Mon Jul 31 14:56:15 2023"}
(3 rows)
select stakey from pg_statistic_ext where starelid = 'test_dts'::regclass;
stakey
--------
(0 rows)
alter table test_dts modify f5 varchar(20) after f4;
select staattnum, stavalues1 from pg_statistic where starelid = 'test_dts'::regclass order by staattnum;
staattnum | stavalues1
-----------+------------------------------------------------------------------------------------
1 | {1,2,3,4,5,6}
4 | {data1,data3,date2}
5 | {"Mon Jul 31 12:34:56 2023","Mon Jul 31 13:45:30 2023","Mon Jul 31 14:56:15 2023"}
(3 rows)
select stakey from pg_statistic_ext where starelid = 'test_dts'::regclass;
stakey
--------
(0 rows)
alter table test_dts modify f1 int first;
select staattnum, stavalues1 from pg_statistic where starelid = 'test_dts'::regclass order by staattnum;
staattnum | stavalues1
-----------+------------------------------------------------------------------------------------
4 | {data1,data3,date2}
5 | {"Mon Jul 31 12:34:56 2023","Mon Jul 31 13:45:30 2023","Mon Jul 31 14:56:15 2023"}
(2 rows)
select stakey from pg_statistic_ext where starelid = 'test_dts'::regclass;
stakey
--------
(0 rows)
drop table if exists test_dts;
drop table if exists t_after_first;
create table t_after_first(c4 int, c5 int);
insert into t_after_first values(1, 2), (3, 4);
alter table t_after_first add column c11 varchar(2), add column c22 varchar(2) after c11, add column c57 int first;
select * from t_after_first;
c57 | c4 | c5 | c11 | c22
-----+----+----+-----+-----
| 1 | 2 | |
| 3 | 4 | |
(2 rows)
drop table if exists t_after_first;
-- test for modify type
drop table if exists fat0;
NOTICE: table "fat0" does not exist, skipping
create table fat0(c41 int, c17 int);
insert into fat0 values(-104 not in (58, -123, -109), -49), (64, -28);
alter table fat0 modify column c17 int first, modify column c41 text, add column c4 int after c17, add column c61 int after c41, add constraint cc0 unique fai0(c17);
NOTICE: ALTER TABLE / ADD UNIQUE will create implicit index "fai0" for table "fat0"
insert into fat0 values(-51, 2, -20, default), (-34, 81, -24, default);
select * from fat0;
c17 | c4 | c41 | c61
-----+----+-----+-----
-49 | | 1 |
-28 | | 64 |
-51 | 2 | -20 |
-34 | 81 | -24 |
(4 rows)
drop table if exists fat0;
create table fat0(c41 int, c17 text);
insert into fat0 values(-104 not in(58, -123, -109), -49), (64, -28);
alter table fat0 modify c17 int first, modify column c41 int, add column c4 int after c17;
select * from fat0;
c17 | c4 | c41
-----+----+-----
-49 | | 1
-28 | | 64
(2 rows)
drop table if exists fat0;
create table fat0(c41 int, c17 int, c21 int);
insert into fat0 values(-104 not in(58, -123, -109), -49, -12),(64, -28, 20);
alter table fat0 modify column c17 text, modify column c41 text, add column c21 int after c41;
ERROR: column "c21" of relation "fat0" already exists
insert into fat0 values(-51, 2, -20), (-34, 81, -24);
select * from fat0;
c41 | c17 | c21
-----+-----+-----
1 | -49 | -12
64 | -28 | 20
-51 | 2 | -20
-34 | 81 | -24
(4 rows)
drop table if exists fat0;
create table fat0(c41 int, c17 int, c21 int);
insert into fat0 values(-104 not in (58, -123, -109), -49, -12), (64, -28, 20);
alter table fat0 modify column c17 text first, modify column c41 text, add column c21 int after c41;
ERROR: column "c21" of relation "fat0" already exists
insert into fat0 values(-51, 2, -20), (-34, 81, -24);
select * from fat0;
c41 | c17 | c21
-----+-----+-----
1 | -49 | -12
64 | -28 | 20
-51 | 2 | -20
-34 | 81 | -24
(4 rows)
drop table if exists fat0;
-- test for modify type not has column
create table fat0(c41 int, c17 int);
insert into fat0 values(-104 not in(58, -123, -109), -49), (64, -28);
alter table fat0 modify c17 int first, modify c41 text, add c4 int after c17, add c61 int after c41, add constraint cc0 unique fai0(c17);
NOTICE: ALTER TABLE / ADD UNIQUE will create implicit index "fai0" for table "fat0"
select * from fat0;
c17 | c4 | c41 | c61
-----+----+-----+-----
-49 | | 1 |
-28 | | 64 |
(2 rows)
drop table if exists fat0;
create table fat0(c41 int, c17 int);
insert into fat0 values(-104 not in (58, -123, -109), -49), (64, -28);
alter table fat0 modify column c17 int first, modify column c41 text;
drop table if exists fat0;
create table fat0(c41 int, c17 int);
insert into fat0 values(-104 not in (58, -123, -109), -49), (64, -28);
alter table fat0 modify c17 int first, modify c41 text;
drop table if exists fat0;
drop table if exists t0;
NOTICE: table "t0" does not exist, skipping
create table t0(c32 int, c6 text default (substring (-108, true) is null));
insert into t0 values (55, -34), (-123, -49);
alter table t0 change column c32 c59 int after c6, modify column c59 bigint;
select * from t0;
c6 | c59
-----+------
-34 | 55
-49 | -123
(2 rows)
drop table if exists t0;
create table t0(c32 int, c6 text default (substring (-108, true) is null));
insert into t0 values(55, -34), (-123, -49);
alter table t0 change column c32 c59 int after c6, modify column c59 bigint;
select * from t0;
c6 | c59
-----+------
-34 | 55
-49 | -123
(2 rows)
alter table t0 change column c6 c int first, add x int default 11 first, modify column c text;
select * from t0;
x | c | c59
----+-----+------
11 | -34 | 55
11 | -49 | -123
(2 rows)
drop table if exists t0;
create table t0(c32 int, c6 text default (substring (-108, true) is null));
insert into t0 values(55, -34), (-123, -49);
alter table t0 change column c32 c59 int after c6, modify c59 bigint;
select * from t0;
c6 | c59
-----+------
-34 | 55
-49 | -123
(2 rows)
alter table t0 add x int default 11 first, change column c6 c int first, modify c text;
select * from t0;
x | c | c59
----+-----+------
11 | -34 | 55
11 | -49 | -123
(2 rows)
drop table if exists t0;
drop table if exists t0;
NOTICE: table "t0" does not exist, skipping
create table t0(c32 int, c6 text default (substring(-108, true) is null));
insert into t0 values(55, -34), (-123, -49);
alter table t0 change column c32 c59 int after c6, modify c59 bigint;
select * from t0;
c6 | c59
-----+------
-34 | 55
-49 | -123
(2 rows)
alter table t0 change column c6 c int first, add x int default 11 first, modify c text;
select * from t0;
x | c | c59
----+-----+------
11 | -34 | 55
11 | -49 | -123
(2 rows)
drop table if exists t0;
drop table if exists t0;
NOTICE: table "t0" does not exist, skipping
create table t0(c32 int, c6 text default (substring (-108, true) is null));
insert into t0 change column c32 c59 int after c6, modify c59 bigint;
ERROR: syntax error at or near "change"
LINE 1: insert into t0 change column c32 c59 int after c6, modify c5...
^
select * from t0;
c32 | c6
-----+----
(0 rows)
alter table t0 add x int default 11 first;
select * from t0;
x | c32 | c6
---+-----+----
(0 rows)
alter table t0 change column c6 c int first, modify c text after x, change column c59 c32 bigint first, modify column c32 text after c;
ERROR: column "c59" does not exist
select * from t0;
x | c32 | c6
---+-----+----
(0 rows)
drop table if exists t0;
\c postgres
drop database test_first_after_B;

View File

@ -3263,14 +3263,14 @@ CREATE TABLE test1.test(a int primary key, b int not null);
CREATE INDEX ON test1.test using btree(b);
INSERT INTO test1.test VALUES (1, 1);
\d+ test1.test
SELECT n.nspname, c.relname from pg_class c, pg_namespace n where n.oid = c.relnamespace and c.relname in ('test', 'test_pkey', 'test_b_idx', 'tttt');
SELECT n.nspname, c.relname from pg_class c, pg_namespace n where n.oid = c.relnamespace and c.relname in ('test', 'test_pkey', 'test_b_idx', 'tttt') order by c.relname;
SELECT * FROM test1.test;
-- check about type
SELECT n.nspname, t.typname FROM pg_type t, pg_namespace n where t.typnamespace = n.oid and t.typname in ('test','tttt');
ALTER TABLE test1.test RENAME TO test2.tttt;
\d+ test1.test
\d+ test2.tttt
SELECT n.nspname, c.relname from pg_class c, pg_namespace n where n.oid = c.relnamespace and c.relname in ('test', 'test_pkey', 'test_b_idx', 'tttt');
SELECT n.nspname, c.relname from pg_class c, pg_namespace n where n.oid = c.relnamespace and c.relname in ('test', 'test_pkey', 'test_b_idx', 'tttt') order by c.relname;
INSERT INTO test2.tttt VALUES (2, 2);
SELECT * FROM test1.test;
SELECT * FROM test2.tttt;
@ -3388,5 +3388,128 @@ CREATE TABLE t_after_first ( c4 INT , c5 INT ) ;
INSERT INTO t_after_first VALUES ( 1 , 2 ) , ( 3 , 4 ) ;
ALTER TABLE t_after_first ADD COLUMN c11 VARCHAR ( 2 ) , ADD COLUMN c22 VARCHAR ( 2 ) AFTER c11 , ADD COLUMN c57 INT FIRST;
select * from t_after_first;
drop table if exists test_dts;
create table test_dts(
f1 int primary key,
f2 varchar(8),
f3 timestamp
);
insert into test_dts(f1, f2, f3) values(1, 'data1', '2023-07-31 12:34:56'), (2, 'date2', '2023-07-31 13:45:30'),
(3, 'data3', '2023-07-31 14:56:15'), (4, 'data1', '2023-07-31 12:34:56'), (5, 'date2', '2023-07-31 13:45:30'),
(6, 'data3', '2023-07-31 14:56:15');
analyze test_dts;
analyze test_dts((f1, f3));
select staattnum, stavalues1 from pg_statistic where starelid = 'test_dts'::regclass order by staattnum;
select stakey from pg_statistic_ext where starelid = 'test_dts'::regclass;
alter table test_dts add column f4 int default 0 after f1;
select staattnum, stavalues1 from pg_statistic where starelid = 'test_dts'::regclass order by staattnum;
select stakey from pg_statistic_ext where starelid = 'test_dts'::regclass;
alter table test_dts add column f5 varchar(20) default 'f5' first;
select staattnum, stavalues1 from pg_statistic where starelid = 'test_dts'::regclass order by staattnum;
select stakey from pg_statistic_ext where starelid = 'test_dts'::regclass;
alter table test_dts modify f5 varchar(20) after f4;
select staattnum, stavalues1 from pg_statistic where starelid = 'test_dts'::regclass order by staattnum;
select stakey from pg_statistic_ext where starelid = 'test_dts'::regclass;
alter table test_dts modify f1 int first;
select staattnum, stavalues1 from pg_statistic where starelid = 'test_dts'::regclass order by staattnum;
select stakey from pg_statistic_ext where starelid = 'test_dts'::regclass;
drop table if exists test_dts;
drop table if exists t_after_first;
create table t_after_first(c4 int, c5 int);
insert into t_after_first values(1, 2), (3, 4);
alter table t_after_first add column c11 varchar(2), add column c22 varchar(2) after c11, add column c57 int first;
select * from t_after_first;
drop table if exists t_after_first;
-- test for modify type
drop table if exists fat0;
create table fat0(c41 int, c17 int);
insert into fat0 values(-104 not in (58, -123, -109), -49), (64, -28);
alter table fat0 modify column c17 int first, modify column c41 text, add column c4 int after c17, add column c61 int after c41, add constraint cc0 unique fai0(c17);
insert into fat0 values(-51, 2, -20, default), (-34, 81, -24, default);
select * from fat0;
drop table if exists fat0;
create table fat0(c41 int, c17 text);
insert into fat0 values(-104 not in(58, -123, -109), -49), (64, -28);
alter table fat0 modify c17 int first, modify column c41 int, add column c4 int after c17;
select * from fat0;
drop table if exists fat0;
create table fat0(c41 int, c17 int, c21 int);
insert into fat0 values(-104 not in(58, -123, -109), -49, -12),(64, -28, 20);
alter table fat0 modify column c17 text, modify column c41 text, add column c21 int after c41;
insert into fat0 values(-51, 2, -20), (-34, 81, -24);
select * from fat0;
drop table if exists fat0;
create table fat0(c41 int, c17 int, c21 int);
insert into fat0 values(-104 not in (58, -123, -109), -49, -12), (64, -28, 20);
alter table fat0 modify column c17 text first, modify column c41 text, add column c21 int after c41;
insert into fat0 values(-51, 2, -20), (-34, 81, -24);
select * from fat0;
drop table if exists fat0;
-- test for modify type not has column
create table fat0(c41 int, c17 int);
insert into fat0 values(-104 not in(58, -123, -109), -49), (64, -28);
alter table fat0 modify c17 int first, modify c41 text, add c4 int after c17, add c61 int after c41, add constraint cc0 unique fai0(c17);
select * from fat0;
drop table if exists fat0;
create table fat0(c41 int, c17 int);
insert into fat0 values(-104 not in (58, -123, -109), -49), (64, -28);
alter table fat0 modify column c17 int first, modify column c41 text;
drop table if exists fat0;
create table fat0(c41 int, c17 int);
insert into fat0 values(-104 not in (58, -123, -109), -49), (64, -28);
alter table fat0 modify c17 int first, modify c41 text;
drop table if exists fat0;
drop table if exists t0;
create table t0(c32 int, c6 text default (substring (-108, true) is null));
insert into t0 values (55, -34), (-123, -49);
alter table t0 change column c32 c59 int after c6, modify column c59 bigint;
select * from t0;
drop table if exists t0;
create table t0(c32 int, c6 text default (substring (-108, true) is null));
insert into t0 values(55, -34), (-123, -49);
alter table t0 change column c32 c59 int after c6, modify column c59 bigint;
select * from t0;
alter table t0 change column c6 c int first, add x int default 11 first, modify column c text;
select * from t0;
drop table if exists t0;
create table t0(c32 int, c6 text default (substring (-108, true) is null));
insert into t0 values(55, -34), (-123, -49);
alter table t0 change column c32 c59 int after c6, modify c59 bigint;
select * from t0;
alter table t0 add x int default 11 first, change column c6 c int first, modify c text;
select * from t0;
drop table if exists t0;
drop table if exists t0;
create table t0(c32 int, c6 text default (substring(-108, true) is null));
insert into t0 values(55, -34), (-123, -49);
alter table t0 change column c32 c59 int after c6, modify c59 bigint;
select * from t0;
alter table t0 change column c6 c int first, add x int default 11 first, modify c text;
select * from t0;
drop table if exists t0;
drop table if exists t0;
create table t0(c32 int, c6 text default (substring (-108, true) is null));
insert into t0 change column c32 c59 int after c6, modify c59 bigint;
select * from t0;
alter table t0 add x int default 11 first;
select * from t0;
alter table t0 change column c6 c int first, modify c text after x, change column c59 c32 bigint first, modify column c32 text after c;
select * from t0;
drop table if exists t0;
\c postgres
drop database test_first_after_B;