8
8
*
9
9
*
10
10
* IDENTIFICATION
11
- * $Header: /cvsroot/pgsql/src/backend/utils/adt/arrayfuncs.c,v 1.63 2000/07/23 01:35:58 tgl Exp $
11
+ * $Header: /cvsroot/pgsql/src/backend/utils/adt/arrayfuncs.c,v 1.64 2000/07/27 03:50:52 tgl Exp $
12
12
*
13
13
*-------------------------------------------------------------------------
14
14
*/
33
33
* <dim_lower>- lower boundary of each dimension
34
34
* <actual data> - whatever is the stored data
35
35
* The actual data starts on a MAXALIGN boundary.
36
+ *
37
+ * NOTE: it is important that array elements of toastable datatypes NOT be
38
+ * toasted, since the tupletoaster won't know they are there. (We could
39
+ * support compressed toasted items; only out-of-line items are dangerous.
40
+ * However, it seems preferable to store such items uncompressed and allow
41
+ * the toaster to compress the whole array as one input.)
36
42
*/
37
43
38
44
@@ -459,6 +465,8 @@ ReadArrayStr(char *arrayStr,
459
465
{
460
466
if (values [i ]!= (Datum )0 )
461
467
{
468
+ /* let's just make sure data is not toasted */
469
+ values [i ]= PointerGetDatum (PG_DETOAST_DATUM (values [i ]));
462
470
if (typalign == 'd' )
463
471
* nbytes += MAXALIGN (VARSIZE (DatumGetPointer (values [i ])));
464
472
else
@@ -485,6 +493,10 @@ ReadArrayStr(char *arrayStr,
485
493
* typbyval, typlen, typalign: info about element datatype
486
494
* freedata: if TRUE and element type is pass-by-ref, pfree data values
487
495
* referenced by Datums after copying them.
496
+ *
497
+ * If the input data is of varlena type, the caller must have ensured that
498
+ * the values are not toasted. (Doing it here doesn't work since the
499
+ * caller has already allocated space for the array...)
488
500
*----------
489
501
*/
490
502
static void
@@ -961,6 +973,10 @@ array_set(ArrayType *array,
961
973
return newarray ;
962
974
}
963
975
976
+ /* make sure item to be inserted is not toasted */
977
+ if (elmlen < 0 )
978
+ dataValue = PointerGetDatum (PG_DETOAST_DATUM (dataValue ));
979
+
964
980
/* detoast input if necessary */
965
981
array = DatumGetArrayTypeP (PointerGetDatum (array ));
966
982
@@ -1120,6 +1136,8 @@ array_set_slice(ArrayType *array,
1120
1136
array = DatumGetArrayTypeP (PointerGetDatum (array ));
1121
1137
srcArray = DatumGetArrayTypeP (PointerGetDatum (srcArray ));
1122
1138
1139
+ /* note: we assume srcArray contains no toasted elements */
1140
+
1123
1141
ndim = ARR_NDIM (array );
1124
1142
if (ndim != nSubscripts || ndim <=0 || ndim > MAXDIM )
1125
1143
elog (ERROR ,"Invalid array subscripts" );
@@ -1368,12 +1386,14 @@ array_map(FunctionCallInfo fcinfo, Oid inpType, Oid retType)
1368
1386
if (fcinfo -> isnull )
1369
1387
elog (ERROR ,"array_map: cannot handle NULL in array" );
1370
1388
1371
- /*Update total result size */
1372
- if (typbyval )
1389
+ /*Ensure data is not toasted, and update total result size */
1390
+ if (typbyval || typlen > 0 )
1373
1391
nbytes += typlen ;
1374
1392
else
1375
- nbytes += ((typlen > 0 ) ?typlen :
1376
- INTALIGN (VARSIZE (DatumGetPointer (values [i ]))));
1393
+ {
1394
+ values [i ]= PointerGetDatum (PG_DETOAST_DATUM (values [i ]));
1395
+ nbytes += INTALIGN (VARSIZE (DatumGetPointer (values [i ])));
1396
+ }
1377
1397
}
1378
1398
1379
1399
/* Allocate and initialize the result array */
@@ -1420,10 +1440,13 @@ construct_array(Datum *elems, int nelems,
1420
1440
}
1421
1441
else
1422
1442
{
1423
- /* varlena type */
1443
+ /* varlena type... make sure it is untoasted */
1424
1444
nbytes = 0 ;
1425
1445
for (i = 0 ;i < nelems ;i ++ )
1446
+ {
1447
+ elems [i ]= PointerGetDatum (PG_DETOAST_DATUM (elems [i ]));
1426
1448
nbytes += INTALIGN (VARSIZE (DatumGetPointer (elems [i ])));
1449
+ }
1427
1450
}
1428
1451
1429
1452
/* Allocate and initialize 1-D result array */