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

Commitd479d00

Browse files
committed
Don't crash on reference to an un-available system column.
Adopt a more consistent policy about what slot-type-specificgetsysattr functions should do when system attributes are notavailable. To wit, they should all throw the same user-orientederror, rather than variously crashing or emitting developer-orientedmessages.This closes a identifiable problem in commitsa71cfc5 and3fb9310 (in v13 and v12), so back-patch into those branches,along with a test case to try to ensure we don't break it again.It is not known that any of the former crash cases are reachablein HEAD, but this seems like a good safety improvement in any case.Discussion:https://postgr.es/m/141051591267657@mail.yandex.ru
1 parent197d33c commitd479d00

File tree

3 files changed

+120
-5
lines changed

3 files changed

+120
-5
lines changed

‎src/backend/executor/execTuples.c

Lines changed: 35 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -122,20 +122,28 @@ tts_virtual_clear(TupleTableSlot *slot)
122122
}
123123

124124
/*
125-
* Attribute values are readily available in tts_values and tts_isnull array
126-
* in a VirtualTupleTableSlot. So there should be no need to call either of the
127-
* following two functions.
125+
* VirtualTupleTableSlots always have fully populated tts_values and
126+
* tts_isnull arrays. So this function should never be called.
128127
*/
129128
staticvoid
130129
tts_virtual_getsomeattrs(TupleTableSlot*slot,intnatts)
131130
{
132131
elog(ERROR,"getsomeattrs is not required to be called on a virtual tuple table slot");
133132
}
134133

134+
/*
135+
* VirtualTupleTableSlots never provide system attributes (except those
136+
* handled generically, such as tableoid). We generally shouldn't get
137+
* here, but provide a user-friendly message if we do.
138+
*/
135139
staticDatum
136140
tts_virtual_getsysattr(TupleTableSlot*slot,intattnum,bool*isnull)
137141
{
138-
elog(ERROR,"virtual tuple table slot does not have system attributes");
142+
Assert(!TTS_EMPTY(slot));
143+
144+
ereport(ERROR,
145+
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
146+
errmsg("cannot retrieve a system column in this context")));
139147

140148
return0;/* silence compiler warnings */
141149
}
@@ -335,6 +343,15 @@ tts_heap_getsysattr(TupleTableSlot *slot, int attnum, bool *isnull)
335343

336344
Assert(!TTS_EMPTY(slot));
337345

346+
/*
347+
* In some code paths it's possible to get here with a non-materialized
348+
* slot, in which case we can't retrieve system columns.
349+
*/
350+
if (!hslot->tuple)
351+
ereport(ERROR,
352+
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
353+
errmsg("cannot retrieve a system column in this context")));
354+
338355
returnheap_getsysattr(hslot->tuple,attnum,
339356
slot->tts_tupleDescriptor,isnull);
340357
}
@@ -497,7 +514,11 @@ tts_minimal_getsomeattrs(TupleTableSlot *slot, int natts)
497514
staticDatum
498515
tts_minimal_getsysattr(TupleTableSlot*slot,intattnum,bool*isnull)
499516
{
500-
elog(ERROR,"minimal tuple table slot does not have system attributes");
517+
Assert(!TTS_EMPTY(slot));
518+
519+
ereport(ERROR,
520+
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
521+
errmsg("cannot retrieve a system column in this context")));
501522

502523
return0;/* silence compiler warnings */
503524
}
@@ -681,6 +702,15 @@ tts_buffer_heap_getsysattr(TupleTableSlot *slot, int attnum, bool *isnull)
681702

682703
Assert(!TTS_EMPTY(slot));
683704

705+
/*
706+
* In some code paths it's possible to get here with a non-materialized
707+
* slot, in which case we can't retrieve system columns.
708+
*/
709+
if (!bslot->base.tuple)
710+
ereport(ERROR,
711+
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
712+
errmsg("cannot retrieve a system column in this context")));
713+
684714
returnheap_getsysattr(bslot->base.tuple,attnum,
685715
slot->tts_tupleDescriptor,isnull);
686716
}

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

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -795,6 +795,59 @@ DETAIL: Failing row contains (a, 10).
795795
-- ok
796796
UPDATE list_default set a = 'x' WHERE a = 'd';
797797
DROP TABLE list_parted;
798+
-- Test retrieval of system columns with non-consistent partition row types.
799+
-- This is only partially supported, as seen in the results.
800+
create table utrtest (a int, b text) partition by list (a);
801+
create table utr1 (a int check (a in (1)), q text, b text);
802+
create table utr2 (a int check (a in (2)), b text);
803+
alter table utr1 drop column q;
804+
alter table utrtest attach partition utr1 for values in (1);
805+
alter table utrtest attach partition utr2 for values in (2);
806+
insert into utrtest values (1, 'foo')
807+
returning *, tableoid::regclass, xmin = pg_current_xact_id()::xid as xmin_ok;
808+
a | b | tableoid | xmin_ok
809+
---+-----+----------+---------
810+
1 | foo | utr1 | t
811+
(1 row)
812+
813+
insert into utrtest values (2, 'bar')
814+
returning *, tableoid::regclass, xmin = pg_current_xact_id()::xid as xmin_ok; -- fails
815+
ERROR: cannot retrieve a system column in this context
816+
insert into utrtest values (2, 'bar')
817+
returning *, tableoid::regclass;
818+
a | b | tableoid
819+
---+-----+----------
820+
2 | bar | utr2
821+
(1 row)
822+
823+
update utrtest set b = b || b from (values (1), (2)) s(x) where a = s.x
824+
returning *, tableoid::regclass, xmin = pg_current_xact_id()::xid as xmin_ok;
825+
a | b | x | tableoid | xmin_ok
826+
---+--------+---+----------+---------
827+
1 | foofoo | 1 | utr1 | t
828+
2 | barbar | 2 | utr2 | t
829+
(2 rows)
830+
831+
update utrtest set a = 3 - a from (values (1), (2)) s(x) where a = s.x
832+
returning *, tableoid::regclass, xmin = pg_current_xact_id()::xid as xmin_ok; -- fails
833+
ERROR: cannot retrieve a system column in this context
834+
update utrtest set a = 3 - a from (values (1), (2)) s(x) where a = s.x
835+
returning *, tableoid::regclass;
836+
a | b | x | tableoid
837+
---+--------+---+----------
838+
2 | foofoo | 1 | utr2
839+
1 | barbar | 2 | utr1
840+
(2 rows)
841+
842+
delete from utrtest
843+
returning *, tableoid::regclass, xmax = pg_current_xact_id()::xid as xmax_ok;
844+
a | b | tableoid | xmax_ok
845+
---+--------+----------+---------
846+
1 | barbar | utr1 | t
847+
2 | foofoo | utr2 | t
848+
(2 rows)
849+
850+
drop table utrtest;
798851
--------------
799852
-- Some more update-partition-key test scenarios below. This time use list
800853
-- partitions.

‎src/test/regress/sql/update.sql

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -502,6 +502,38 @@ UPDATE list_default set a = 'x' WHERE a = 'd';
502502

503503
DROPTABLE list_parted;
504504

505+
-- Test retrieval of system columns with non-consistent partition row types.
506+
-- This is only partially supported, as seen in the results.
507+
508+
createtableutrtest (aint, btext) partition by list (a);
509+
createtableutr1 (aintcheck (ain (1)), qtext, btext);
510+
createtableutr2 (aintcheck (ain (2)), btext);
511+
altertable utr1 drop column q;
512+
altertable utrtest attach partition utr1 forvaluesin (1);
513+
altertable utrtest attach partition utr2 forvaluesin (2);
514+
515+
insert into utrtestvalues (1,'foo')
516+
returning*, tableoid::regclass, xmin= pg_current_xact_id()::xidas xmin_ok;
517+
insert into utrtestvalues (2,'bar')
518+
returning*, tableoid::regclass, xmin= pg_current_xact_id()::xidas xmin_ok;-- fails
519+
insert into utrtestvalues (2,'bar')
520+
returning*, tableoid::regclass;
521+
522+
update utrtestset b= b|| bfrom (values (1), (2)) s(x)where a=s.x
523+
returning*, tableoid::regclass, xmin= pg_current_xact_id()::xidas xmin_ok;
524+
525+
update utrtestset a=3- afrom (values (1), (2)) s(x)where a=s.x
526+
returning*, tableoid::regclass, xmin= pg_current_xact_id()::xidas xmin_ok;-- fails
527+
528+
update utrtestset a=3- afrom (values (1), (2)) s(x)where a=s.x
529+
returning*, tableoid::regclass;
530+
531+
deletefrom utrtest
532+
returning*, tableoid::regclass, xmax= pg_current_xact_id()::xidas xmax_ok;
533+
534+
droptable utrtest;
535+
536+
505537
--------------
506538
-- Some more update-partition-key test scenarios below. This time use list
507539
-- partitions.

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp