Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitd97c9b3

Browse files
committed
Apply fixes for problems with dropped columns whose types have also been
dropped. The simplest fix for INSERT/UPDATE cases turns out to be forpreptlist.c to insert NULLs of a known-good type (I used INT4) ratherthan making them match the deleted column's type. Since the representationof NULL is actually datatype-independent, this should work fine.I also re-reverted the patch to disable the use_physical_tlist optimizationin the presence of dropped columns. It still doesn't look worth thetrouble to be smarter, if there are no other bugs to fix.Added a regression test to catch future problems in this area.
1 parenta7c50cd commitd97c9b3

File tree

6 files changed

+167
-27
lines changed

6 files changed

+167
-27
lines changed

‎src/backend/catalog/heap.c

Lines changed: 40 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.243 2003/05/08 22:19:56 tgl Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.244 2003/05/12 00:17:02 tgl Exp $
1212
*
1313
*
1414
* INTERFACE ROUTINES
@@ -76,7 +76,7 @@ static void StoreAttrDefault(Relation rel, AttrNumber attnum, char *adbin);
7676
staticvoidStoreRelCheck(Relationrel,char*ccname,char*ccbin);
7777
staticvoidStoreConstraints(Relationrel,TupleDesctupdesc);
7878
staticvoidSetRelationNumChecks(Relationrel,intnumchecks);
79-
staticvoidRemoveStatistics(Relationrel);
79+
staticvoidRemoveStatistics(Relationrel,AttrNumberattnum);
8080

8181

8282
/* ----------------------------------------------------------------
@@ -925,8 +925,9 @@ DeleteAttributeTuples(Oid relid)
925925
*RemoveAttributeById
926926
*
927927
* This is the guts of ALTER TABLE DROP COLUMN: actually mark the attribute
928-
* deleted in pg_attribute. (Everything else needed, such as getting rid
929-
* of any pg_attrdef entry, is handled by dependency.c.)
928+
* deleted in pg_attribute. We also remove pg_statistic entries for it.
929+
* (Everything else needed, such as getting rid of any pg_attrdef entry,
930+
* is handled by dependency.c.)
930931
*/
931932
void
932933
RemoveAttributeById(Oidrelid,AttrNumberattnum)
@@ -960,6 +961,16 @@ RemoveAttributeById(Oid relid, AttrNumber attnum)
960961
/* Mark the attribute as dropped */
961962
attStruct->attisdropped= true;
962963

964+
/*
965+
* Set the type OID to invalid. A dropped attribute's type link cannot
966+
* be relied on (once the attribute is dropped, the type might be too).
967+
* Fortunately we do not need the type row --- the only really essential
968+
* information is the type's typlen and typalign, which are preserved in
969+
* the attribute's attlen and attalign. We set atttypid to zero here
970+
* as a means of catching code that incorrectly expects it to be valid.
971+
*/
972+
attStruct->atttypid=InvalidOid;
973+
963974
/* Remove any NOT NULL constraint the column may have */
964975
attStruct->attnotnull= false;
965976

@@ -984,6 +995,8 @@ RemoveAttributeById(Oid relid, AttrNumber attnum)
984995

985996
heap_close(attr_rel,RowExclusiveLock);
986997

998+
RemoveStatistics(rel,attnum);
999+
9871000
relation_close(rel,NoLock);
9881001
}
9891002

@@ -1158,7 +1171,7 @@ heap_drop_with_catalog(Oid rid)
11581171
/*
11591172
* delete statistics
11601173
*/
1161-
RemoveStatistics(rel);
1174+
RemoveStatistics(rel,0);
11621175

11631176
/*
11641177
* delete attribute tuples
@@ -1819,27 +1832,45 @@ RemoveRelConstraints(Relation rel, const char *constrName,
18191832
}
18201833

18211834

1835+
/*
1836+
* RemoveStatistics --- remove entries in pg_statistic for a rel or column
1837+
*
1838+
* If attnum is zero, remove all entries for rel; else remove only the one
1839+
* for that column.
1840+
*/
18221841
staticvoid
1823-
RemoveStatistics(Relationrel)
1842+
RemoveStatistics(Relationrel,AttrNumberattnum)
18241843
{
18251844
Relationpgstatistic;
18261845
SysScanDescscan;
1827-
ScanKeyDatakey;
1846+
ScanKeyDatakey[2];
1847+
intnkeys;
18281848
HeapTupletuple;
18291849

18301850
pgstatistic=heap_openr(StatisticRelationName,RowExclusiveLock);
18311851

1832-
ScanKeyEntryInitialize(&key,0x0,
1852+
ScanKeyEntryInitialize(&key[0],0x0,
18331853
Anum_pg_statistic_starelid,F_OIDEQ,
18341854
ObjectIdGetDatum(RelationGetRelid(rel)));
18351855

1856+
if (attnum==0)
1857+
nkeys=1;
1858+
else
1859+
{
1860+
ScanKeyEntryInitialize(&key[1],0x0,
1861+
Anum_pg_statistic_staattnum,F_INT2EQ,
1862+
Int16GetDatum(attnum));
1863+
nkeys=2;
1864+
}
1865+
18361866
scan=systable_beginscan(pgstatistic,StatisticRelidAttnumIndex, true,
1837-
SnapshotNow,1,&key);
1867+
SnapshotNow,nkeys,key);
18381868

18391869
while (HeapTupleIsValid(tuple=systable_getnext(scan)))
18401870
simple_heap_delete(pgstatistic,&tuple->t_self);
18411871

18421872
systable_endscan(scan);
1873+
18431874
heap_close(pgstatistic,RowExclusiveLock);
18441875
}
18451876

‎src/backend/optimizer/plan/createplan.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
*
1111
*
1212
* IDENTIFICATION
13-
* $Header: /cvsroot/pgsql/src/backend/optimizer/plan/createplan.c,v 1.141 2003/05/11 20:25:50 tgl Exp $
13+
* $Header: /cvsroot/pgsql/src/backend/optimizer/plan/createplan.c,v 1.142 2003/05/12 00:17:03 tgl Exp $
1414
*
1515
*-------------------------------------------------------------------------
1616
*/
@@ -295,6 +295,12 @@ use_physical_tlist(RelOptInfo *rel)
295295
*/
296296
if (rel->reloptkind!=RELOPT_BASEREL)
297297
return false;
298+
/*
299+
* Can't do it if relation contains dropped columns. This is detected
300+
* in plancat.c, see notes there.
301+
*/
302+
if (rel->varlist==NIL)
303+
return false;
298304
/*
299305
* Can't do it if any system columns are requested, either. (This could
300306
* possibly be fixed but would take some fragile assumptions in setrefs.c,

‎src/backend/optimizer/prep/preptlist.c

Lines changed: 44 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
* Portions Copyright (c) 1994, Regents of the University of California
1616
*
1717
* IDENTIFICATION
18-
* $Header: /cvsroot/pgsql/src/backend/optimizer/prep/preptlist.c,v 1.60 2003/02/03 21:15:44 tgl Exp $
18+
* $Header: /cvsroot/pgsql/src/backend/optimizer/prep/preptlist.c,v 1.61 2003/05/12 00:17:03 tgl Exp $
1919
*
2020
*-------------------------------------------------------------------------
2121
*/
@@ -171,6 +171,15 @@ expand_targetlist(List *tlist, int command_type,
171171
* the attribute, so that it gets copied to the new tuple. But
172172
* generate a NULL for dropped columns (we want to drop any
173173
* old values).
174+
*
175+
* When generating a NULL constant for a dropped column, we label
176+
* it INT4 (any other guaranteed-to-exist datatype would do as
177+
* well). We can't label it with the dropped column's datatype
178+
* since that might not exist anymore. It does not really
179+
* matter what we claim the type is, since NULL is NULL --- its
180+
* representation is datatype-independent. This could perhaps
181+
* confuse code comparing the finished plan to the target
182+
* relation, however.
174183
*/
175184
Oidatttype=att_tup->atttypid;
176185
int32atttypmod=att_tup->atttypmod;
@@ -179,31 +188,52 @@ expand_targetlist(List *tlist, int command_type,
179188
switch (command_type)
180189
{
181190
caseCMD_INSERT:
182-
new_expr= (Node*)makeConst(atttype,
183-
att_tup->attlen,
184-
(Datum)0,
185-
true,/* isnull */
186-
att_tup->attbyval);
187191
if (!att_tup->attisdropped)
192+
{
193+
new_expr= (Node*)makeConst(atttype,
194+
att_tup->attlen,
195+
(Datum)0,
196+
true,/* isnull */
197+
att_tup->attbyval);
188198
new_expr=coerce_to_domain(new_expr,
189199
InvalidOid,
190200
atttype,
191201
COERCE_IMPLICIT_CAST);
202+
}
203+
else
204+
{
205+
/* Insert NULL for dropped column */
206+
new_expr= (Node*)makeConst(INT4OID,
207+
sizeof(int32),
208+
(Datum)0,
209+
true,/* isnull */
210+
true/* byval */);
211+
/* label resdom with INT4, too */
212+
atttype=INT4OID;
213+
atttypmod=-1;
214+
}
192215
break;
193216
caseCMD_UPDATE:
194-
/* Insert NULLs for dropped columns */
195-
if (att_tup->attisdropped)
196-
new_expr= (Node*)makeConst(atttype,
197-
att_tup->attlen,
198-
(Datum)0,
199-
true,/* isnull */
200-
att_tup->attbyval);
201-
else
217+
if (!att_tup->attisdropped)
218+
{
202219
new_expr= (Node*)makeVar(result_relation,
203220
attrno,
204221
atttype,
205222
atttypmod,
206223
0);
224+
}
225+
else
226+
{
227+
/* Insert NULL for dropped column */
228+
new_expr= (Node*)makeConst(INT4OID,
229+
sizeof(int32),
230+
(Datum)0,
231+
true,/* isnull */
232+
true/* byval */);
233+
/* label resdom with INT4, too */
234+
atttype=INT4OID;
235+
atttypmod=-1;
236+
}
207237
break;
208238
default:
209239
elog(ERROR,"expand_targetlist: unexpected command_type");

‎src/backend/optimizer/util/plancat.c

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
*
1010
*
1111
* IDENTIFICATION
12-
* $Header: /cvsroot/pgsql/src/backend/optimizer/util/plancat.c,v 1.81 2003/05/11 20:25:50 tgl Exp $
12+
* $Header: /cvsroot/pgsql/src/backend/optimizer/util/plancat.c,v 1.82 2003/05/12 00:17:03 tgl Exp $
1313
*
1414
*-------------------------------------------------------------------------
1515
*/
@@ -62,15 +62,29 @@ get_relation_info(Oid relationObjectId, RelOptInfo *rel)
6262
relation=heap_open(relationObjectId,AccessShareLock);
6363

6464
/*
65-
* Make list of physical Vars. Note we do NOT ignore dropped columns;
66-
* the intent is to model the physical tuples of the relation.
65+
* Make list of physical Vars. But if there are any dropped columns,
66+
* punt and set varlist to NIL. (XXX Ideally we would like to include
67+
* dropped columns so that the varlist models the physical tuples
68+
* of the relation. However this creates problems for ExecTypeFromTL,
69+
* which may be asked to build a tupdesc for a tlist that includes vars
70+
* of no-longer-existent types. In theory we could dig out the required
71+
* info from the pg_attribute entries of the relation, but that data is
72+
* not readily available to ExecTypeFromTL. For now, punt and don't
73+
* apply the physical-tlist optimization when there are dropped cols.)
6774
*/
6875
numattrs=RelationGetNumberOfAttributes(relation);
6976

7077
for (attrno=1;attrno <=numattrs;attrno++)
7178
{
7279
Form_pg_attributeatt_tup=relation->rd_att->attrs[attrno-1];
7380

81+
if (att_tup->attisdropped)
82+
{
83+
/* found a dropped col, so punt */
84+
varlist=NIL;
85+
break;
86+
}
87+
7488
varlist=lappend(varlist,
7589
makeVar(varno,
7690
attrno,

‎src/test/regress/expected/alter_table.out

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1253,3 +1253,44 @@ select * from p1;
12531253
drop table p1 cascade;
12541254
NOTICE: Drop cascades to table c1
12551255
NOTICE: Drop cascades to constraint p1_a1 on table c1
1256+
-- test that operations with a dropped column do not try to reference
1257+
-- its datatype
1258+
create domain mytype as text;
1259+
create temp table foo (f1 text, f2 mytype, f3 text);
1260+
insert into foo values('aa','bb','cc');
1261+
select * from foo;
1262+
f1 | f2 | f3
1263+
----+----+----
1264+
aa | bb | cc
1265+
(1 row)
1266+
1267+
drop domain mytype cascade;
1268+
NOTICE: Drop cascades to table foo column f2
1269+
select * from foo;
1270+
f1 | f3
1271+
----+----
1272+
aa | cc
1273+
(1 row)
1274+
1275+
insert into foo values('qq','rr');
1276+
select * from foo;
1277+
f1 | f3
1278+
----+----
1279+
aa | cc
1280+
qq | rr
1281+
(2 rows)
1282+
1283+
update foo set f3 = 'zz';
1284+
select * from foo;
1285+
f1 | f3
1286+
----+----
1287+
aa | zz
1288+
qq | zz
1289+
(2 rows)
1290+
1291+
select f3,max(f1) from foo group by f3;
1292+
f3 | max
1293+
----+-----
1294+
zz | qq
1295+
(1 row)
1296+

‎src/test/regress/sql/alter_table.sql

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -895,3 +895,21 @@ update p1 set a1 = a1 + 1, f2 = upper(f2);
895895
select*from p1;
896896

897897
droptable p1 cascade;
898+
899+
-- test that operations with a dropped column do not try to reference
900+
-- its datatype
901+
902+
createdomainmytypeastext;
903+
create temp table foo (f1text, f2 mytype, f3text);
904+
905+
insert into foovalues('aa','bb','cc');
906+
select*from foo;
907+
908+
dropdomain mytype cascade;
909+
910+
select*from foo;
911+
insert into foovalues('qq','rr');
912+
select*from foo;
913+
update fooset f3='zz';
914+
select*from foo;
915+
select f3,max(f1)from foogroup by f3;

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp