8000 Avoid an Assert failure in deconstruct_array() by making get_attstats… · danielcode/postgres@b8accd6 · GitHub
[go: up one dir, main page]

Skip to content {"props":{"docsUrl":"https://docs.github.com/get-started/accessibility/keyboard-shortcuts"}}

Commit b8accd6

Browse files
committed
Avoid an Assert failure in deconstruct_array() by making get_attstatsslot()
use the actual element type of the array it's disassembling, rather than trusting the type OID passed in by its caller. This is needed because sometimes the planner passes in a type OID that's only binary-compatible with the target column's type, rather than being an exact match. Per an example from Bernd Helmle. Possibly we should refactor get_attstatsslot/free_attstatsslot to not expect the caller to supply type ID data at all, but for now I'll just do the minimum-change fix. Back-patch to 7.4. Bernd's test case only crashes back to 8.0, but since these subroutines are the same in 7.4, I suspect there may be variant cases that would crash 7.4 as well.
1 parent 8bed5e2 commit b8accd6

File tree

1 file changed

+17
-5
lines changed

1 file changed

+17
-5
lines changed

src/backend/utils/cache/lsyscache.c

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1994, Regents of the University of California
88
*
99
* IDENTIFICATION
10-
* $PostgreSQL: pgsql/src/backend/utils/cache/lsyscache.c,v 1.119.4.1 2007/10/13 15:56:08 tgl Exp $
10+
* $PostgreSQL: pgsql/src/backend/utils/cache/lsyscache.c,v 1.119.4.2 2010/07/09 22:58:17 tgl Exp $
1111
*
1212
* NOTES
1313
* Eventually, the index information should go through here, too.
@@ -1888,6 +1888,10 @@ get_attavgwidth(Oid relid, AttrNumber attnum)
18881888
* If the attribute type is pass-by-reference, the values referenced by
18891889
* the values array are themselves palloc'd. The palloc'd stuff can be
18901890
* freed by calling free_attstatsslot.
1891+
*
1892+
* Note: at present, atttype/atttypmod aren't actually used here at all.
1893+
* But the caller must have the correct (or at least binary-compatible)
1894+
* type ID to pass to free_attstatsslot later.
18911895
*/
18921896
bool
18931897
get_attstatsslot(HeapTuple statstuple,
@@ -1902,6 +1906,7 @@ get_attstatsslot(HeapTuple statstuple,
19021906
Datum val;
19031907
bool isnull;
19041908
ArrayType *statarray;
1909+
Oid arrayelemtype;
19051910
int narrayelem;
19061911
HeapTuple typeTuple;
19071912
Form_pg_type typeForm;
@@ -1924,17 +1929,24 @@ get_attstatsslot(HeapTuple statstuple,
19241929
elog(ERROR, "stavalues is null");
19251930
statarray = DatumGetArrayTypeP(val);
19261931

1927-
/* Need to get info about the array element type */
1932+
/*
1933+
* Need to get info about the array element type. We look at the
1934+
* actual element type embedded in the array, which might be only
1935+
* binary-compatible with the passed-in atttype. The info we
1936+
* extract here should be the same either way, but deconstruct_array
1937+
* is picky about having an exact type OID match.
1938+
*/
1939+
arrayelemtype = ARR_ELEMTYPE(statarray);
19281940
typeTuple = SearchSysCache(TYPEOID,
1929-
ObjectIdGetDatum(atttype),
1941+
ObjectIdGetDatum(arrayelemtype),
19301942
0, 0, 0);
19311943
if (!HeapTupleIsValid(typeTuple))
1932-
elog(ERROR, "cache lookup failed for type %u", atttype);
1944+
elog(ERROR, "cache lookup failed for type %u", arrayelemtype);
19331945
typeForm = (Form_pg_type) GETSTRUCT(typeTuple);
19341946

19351947
/* Deconstruct array into Datum elements */
19361948
deconstruct_array(statarray,
1937-
atttype,
1949+
arrayelemtype,
19381950
typeForm->typlen,
19391951
typeForm->typbyval,
19401952
typeForm->typalign,

0 commit comments

Comments
 (0)
0