Skip to content

Commit 5ce63f4

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 2b8a624 commit 5ce63f4

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.170 2010/04/24 16:20:32 sriggs Exp $
10+
* $PostgreSQL: pgsql/src/backend/utils/cache/lsyscache.c,v 1.171 2010/07/09 22:57:39 tgl Exp $
1111
*
1212
* NOTES
1313
* Eventually, the index information should go through here, too.
@@ -2463,6 +2463,10 @@ get_attavgwidth(Oid relid, AttrNumber attnum)
24632463
* If the attribute type is pass-by-reference, the values referenced by
24642464
* the values array are themselves palloc'd. The palloc'd stuff can be
24652465
* freed by calling free_attstatsslot.
2466+
*
2467+
* Note: at present, atttype/atttypmod aren't actually used here at all.
2468+
* But the caller must have the correct (or at least binary-compatible)
2469+
* type ID to pass to free_attstatsslot later.
24662470
*/
24672471
bool
24682472
get_attstatsslot(HeapTuple statstuple,
@@ -2478,6 +2482,7 @@ get_attstatsslot(HeapTuple statstuple,
24782482
Datum val;
24792483
bool isnull;
24802484
ArrayType *statarray;
2485+
Oid arrayelemtype;
24812486
int narrayelem;
24822487
HeapTuple typeTuple;
24832488
Form_pg_type typeForm;
@@ -2503,15 +2508,22 @@ get_attstatsslot(HeapTuple statstuple,
25032508
elog(ERROR, "stavalues is null");
25042509
statarray = DatumGetArrayTypeP(val);
25052510

2506-
/* Need to get info about the array element type */
2507-
typeTuple = SearchSysCache1(TYPEOID, ObjectIdGetDatum(atttype));
2511+
/*
2512+
* Need to get info about the array element type. We look at the
2513+
* actual element type embedded in the array, which might be only
2514+
* binary-compatible with the passed-in atttype. The info we
2515+
* extract here should be the same either way, but deconstruct_array
2516+
* is picky about having an exact type OID match.
2517+
*/
2518+
arrayelemtype = ARR_ELEMTYPE(statarray);
2519+
typeTuple = SearchSysCache1(TYPEOID, ObjectIdGetDatum(arrayelemtype));
25082520
if (!HeapTupleIsValid(typeTuple))
2509-
elog(ERROR, "cache lookup failed for type %u", atttype);
2521+
elog(ERROR, "cache lookup failed for type %u", arrayelemtype);
25102522
typeForm = (Form_pg_type) GETSTRUCT(typeTuple);
25112523

25122524
/* Deconstruct array into Datum elements; NULLs not expected */
25132525
deconstruct_array(statarray,
2514-
atttype,
2526+
arrayelemtype,
25152527
typeForm->typlen,
25162528
typeForm->typbyval,
25172529
typeForm->typalign,

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy