From 97e9e6ae669996275407ccdc923a77d897668715 Mon Sep 17 00:00:00 2001 From: yuhuanhuan <1500773557@qq.com> Date: Thu, 28 Dec 2023 16:29:14 +0800 Subject: [PATCH] =?UTF-8?q?=E8=A7=A3=E5=86=B3=E5=B8=A6modify=20first|=20af?= =?UTF-8?q?ter=20core=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../optimizer/commands/tablecmds.cpp | 173 +++++++++-- src/test/regress/expected/alter_table_003.out | 283 +++++++++++++++++- src/test/regress/sql/alter_table_003.sql | 127 +++++++- 3 files changed, 558 insertions(+), 25 deletions(-) diff --git a/src/gausskernel/optimizer/commands/tablecmds.cpp b/src/gausskernel/optimizer/commands/tablecmds.cpp index c570f98605..66eb41e6ae 100755 --- a/src/gausskernel/optimizer/commands/tablecmds.cpp +++ b/src/gausskernel/optimizer/commands/tablecmds.cpp @@ -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); } diff --git a/src/test/regress/expected/alter_table_003.out b/src/test/regress/expected/alter_table_003.out index 515572d59e..16580ed8df 100644 --- a/src/test/regress/expected/alter_table_003.out +++ b/src/test/regress/expected/alter_table_003.out @@ -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; diff --git a/src/test/regress/sql/alter_table_003.sql b/src/test/regress/sql/alter_table_003.sql index d2740a09dc..eda2e57782 100644 --- a/src/test/regress/sql/alter_table_003.sql +++ b/src/test/regress/sql/alter_table_003.sql @@ -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; \ No newline at end of file -- Gitee