diff --git a/src/common/backend/catalog/heap.cpp b/src/common/backend/catalog/heap.cpp index e7bec0ec01c45f5755e38f4d1493c265e33335ab..dedda7885c4bc98a834fbf2c02977db3304f15e9 100755 --- a/src/common/backend/catalog/heap.cpp +++ b/src/common/backend/catalog/heap.cpp @@ -2460,8 +2460,14 @@ void RemoveAttributeById(Oid relid, AttrNumber attnum) heap_close(attr_rel, RowExclusiveLock); - if (attnum > 0) - RemoveStatistics<'c'>(relid, attnum); + if (attnum > 0) { + if (RELATION_IS_GLOBAL_TEMP(rel)) { + remove_gtt_att_statistic(relid, attnum); + } else { + RemoveStatistics<'c'>(relid, attnum); + } + } + /* decrease the relation's relnatts in pg_class */ if (isRedisDropColumn) { pgclass = heap_open(RelationRelationId, RowExclusiveLock); diff --git a/src/common/backend/catalog/storage_gtt.cpp b/src/common/backend/catalog/storage_gtt.cpp index 83c2047319ba9db87447719be520b4695235f6d7..9fab21762ed0544c3b0ab269279e5e1704547850 100644 --- a/src/common/backend/catalog/storage_gtt.cpp +++ b/src/common/backend/catalog/storage_gtt.cpp @@ -709,6 +709,50 @@ bool get_gtt_relstats(Oid relid, BlockNumber* relpages, double* reltuples, Block return true; } +void remove_gtt_att_statistic(Oid reloid, int attnum) +{ + gtt_local_hash_entry* entry = gtt_search_by_relid(reloid, true); + if (entry == NULL) { + return; + } + for (int i = 0; i < entry->natts; i++) { + if (entry->attnum[i] != attnum) { + continue; + } + Assert(entry->att_stat_tups[i]); + entry->attnum[i] = 0; + heap_freetuple(entry->att_stat_tups[i]); + entry->att_stat_tups[i] = NULL; + break; + } + return; +} + +void extend_gtt_att_statistic(gtt_local_hash_entry* entry, int natts) +{ + Assert(entry != NULL); + Assert(entry->natts < natts); + + MemoryContext oldContext = MemoryContextSwitchTo(u_sess->gtt_ctx.gtt_relstats_context); + int* attNum = (int*)palloc0(sizeof(int) * natts); + HeapTuple* attStatTups = (HeapTuple*)palloc0(sizeof(HeapTuple) * natts); + for (int i = 0; i < entry->natts; i++) { + if (entry->attnum[i] == 0) { + continue; + } + attNum[i] = entry->attnum[i]; + attStatTups[i] = entry->att_stat_tups[i]; + } + pfree(entry->attnum); + pfree(entry->att_stat_tups); + + entry->natts = natts; + entry->attnum = attNum; + entry->att_stat_tups = attStatTups; + (void)MemoryContextSwitchTo(oldContext); + return; +} + /* * Update global temp table statistic info(definition is same as pg_statistic) * to local hashtable where ananyze global temp table @@ -725,10 +769,8 @@ void up_gtt_att_statistic(Oid reloid, int attnum, int natts, TupleDesc tupleDesc entry = gtt_search_by_relid(reloid, true); if (entry == NULL) return; - if (entry->natts < natts) { - elog(WARNING, "reloid %u not support update attstat after add colunm", reloid); - return; + extend_gtt_att_statistic(entry, natts); } oldcontext = MemoryContextSwitchTo(u_sess->gtt_ctx.gtt_relstats_context); diff --git a/src/gausskernel/optimizer/commands/tablecmds.cpp b/src/gausskernel/optimizer/commands/tablecmds.cpp index e545dfcb927a73578c001d7b25bed8b87dd2f613..01e5060f760f087be36aa023c3a96aef4ac67966 100644 --- a/src/gausskernel/optimizer/commands/tablecmds.cpp +++ b/src/gausskernel/optimizer/commands/tablecmds.cpp @@ -11115,7 +11115,11 @@ static void ATExecAlterColumnType(AlteredTableInfo* tab, Relation rel, AlterTabl /* * Drop any pg_statistic entry for the column, since it's now wrong type */ - RemoveStatistics<'c'>(RelationGetRelid(rel), attnum); + if (RELATION_IS_GLOBAL_TEMP(rel)) { + remove_gtt_att_statistic(RelationGetRelid(rel), attnum); + } else { + RemoveStatistics<'c'>(RelationGetRelid(rel), attnum); + } /* * Update the default, if present, by brute force --- remove and re-add diff --git a/src/include/catalog/storage_gtt.h b/src/include/catalog/storage_gtt.h index 3ac692e86216de920de59d9e86cd17172ecc73e1..74079bdd8786525545cf346fe112a02648988048 100644 --- a/src/include/catalog/storage_gtt.h +++ b/src/include/catalog/storage_gtt.h @@ -44,4 +44,5 @@ extern void init_gtt_storage(CmdType operation, ResultRelInfo *resultRelInfo); extern Oid gtt_fetch_current_relfilenode(Oid relid); extern void gtt_switch_rel_relfilenode(Oid rel1, Oid relfilenode1, Oid rel2, Oid relfilenode2, bool footprint); extern void gtt_create_storage_files(Oid relid); +extern void remove_gtt_att_statistic(Oid reloid, int attnum); #endif /* STORAGE_GTT_H */ diff --git a/src/test/regress/expected/gtt_function.out b/src/test/regress/expected/gtt_function.out index 2af1b5a3ebbc6ba6c05737518b3c53b3c254c5c4..a53fd63e4a62f53c25f1b599a5d832d7856c1b02 100644 --- a/src/test/regress/expected/gtt_function.out +++ b/src/test/regress/expected/gtt_function.out @@ -176,6 +176,71 @@ select * from gtt_test_new; --ok ALTER TABLE gtt_test_new DROP address; +--gtt statistic test +create global temp table gtt_statistic_test(id int); +insert into gtt_statistic_test values (generate_series(1,1000)); +analyze gtt_statistic_test; +select attname,avg_width from pg_gtt_stats where tablename='gtt_statistic_test'; + attname | avg_width +---------+----------- + id | 4 +(1 row) + +--add column +alter table gtt_statistic_test add column text varchar(128); +\d gtt_statistic_test + Table "gtt_function.gtt_statistic_test" + Column | Type | Modifiers +--------+------------------------+----------- + id | integer | + text | character varying(128) | + +select attname,avg_width from pg_gtt_stats where tablename='gtt_statistic_test'; + attname | avg_width +---------+----------- + id | 4 + text | +(2 rows) + +insert into gtt_statistic_test values (generate_series(1,1000),'hello gtt'); +analyze gtt_statistic_test; +select attname,avg_width from pg_gtt_stats where tablename='gtt_statistic_test'; + attname | avg_width +---------+----------- + id | 4 + text | 10 +(2 rows) + +--modify column +alter table gtt_statistic_test modify id varchar(128); +\d gtt_statistic_test + Table "gtt_function.gtt_statistic_test" + Column | Type | Modifiers +--------+------------------------+----------- + id | character varying(128) | + text | character varying(128) | + +select attname,avg_width from pg_gtt_stats where tablename='gtt_statistic_test'; + attname | avg_width +---------+----------- + id | + text | 10 +(2 rows) + +--drop column +alter table gtt_statistic_test drop text; +\d gtt_statistic_test + Table "gtt_function.gtt_statistic_test" + Column | Type | Modifiers +--------+------------------------+----------- + id | character varying(128) | + +select attname,avg_width from pg_gtt_stats where tablename='gtt_statistic_test'; + attname | avg_width +---------+----------- + id | +(1 row) + CREATE global temp TABLE products ( product_no integer PRIMARY KEY, name text, @@ -382,7 +447,7 @@ create global temp table gtt_test11(c1 int) with(on_commit_delete_rows=''); ERROR: parameter "on_commit_delete_rows" requires a Boolean value reset search_path; drop schema gtt_function cascade; -NOTICE: drop cascades to 34 other objects +NOTICE: drop cascades to 35 other objects DETAIL: drop cascades to table gtt_function.gtt1 drop cascades to table gtt_function.gtt2 drop cascades to table gtt_function.gtt3 @@ -398,6 +463,7 @@ drop cascades to table gtt_function.gtt7 drop cascades to table gtt_function.gtt8 drop cascades to table gtt_function.gtt9 drop cascades to table gtt_function.gtt_test_new +drop cascades to table gtt_function.gtt_statistic_test drop cascades to table gtt_function.products drop cascades to table gtt_function.orders drop cascades to table gtt_function.mytable diff --git a/src/test/regress/sql/gtt_function.sql b/src/test/regress/sql/gtt_function.sql index abe6052dacec51ae00f8efd0df74d287427d5063..339143003f3efb028b465b4c35aab1e3dfefa4b3 100644 --- a/src/test/regress/sql/gtt_function.sql +++ b/src/test/regress/sql/gtt_function.sql @@ -178,6 +178,30 @@ select * from gtt_test_new; --ok ALTER TABLE gtt_test_new DROP address; +--gtt statistic test +create global temp table gtt_statistic_test(id int); +insert into gtt_statistic_test values (generate_series(1,1000)); +analyze gtt_statistic_test; +select attname,avg_width from pg_gtt_stats where tablename='gtt_statistic_test'; + +--add column +alter table gtt_statistic_test add column text varchar(128); +\d gtt_statistic_test +select attname,avg_width from pg_gtt_stats where tablename='gtt_statistic_test'; +insert into gtt_statistic_test values (generate_series(1,1000),'hello gtt'); +analyze gtt_statistic_test; +select attname,avg_width from pg_gtt_stats where tablename='gtt_statistic_test'; + +--modify column +alter table gtt_statistic_test modify id varchar(128); +\d gtt_statistic_test +select attname,avg_width from pg_gtt_stats where tablename='gtt_statistic_test'; + +--drop column +alter table gtt_statistic_test drop text; +\d gtt_statistic_test +select attname,avg_width from pg_gtt_stats where tablename='gtt_statistic_test'; + CREATE global temp TABLE products ( product_no integer PRIMARY KEY, name text,