diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/backend/access/heap/tuptoaster.c | 76 | ||||
-rw-r--r-- | src/backend/utils/adt/varlena.c | 49 | ||||
-rw-r--r-- | src/include/catalog/pg_proc.h | 4 |
3 files changed, 65 insertions, 64 deletions
diff --git a/src/backend/access/heap/tuptoaster.c b/src/backend/access/heap/tuptoaster.c index 77caf79dd19..5359f24fce2 100644 --- a/src/backend/access/heap/tuptoaster.c +++ b/src/backend/access/heap/tuptoaster.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/access/heap/tuptoaster.c,v 1.50 2005/07/06 19:02:52 momjian Exp $ + * $PostgreSQL: pgsql/src/backend/access/heap/tuptoaster.c,v 1.51 2005/08/02 16:11:57 tgl Exp $ * * * INTERFACE ROUTINES @@ -268,6 +268,38 @@ toast_raw_datum_size(Datum value) return result; } +/* ---------- + * toast_datum_size + * + * Return the physical storage size (possibly compressed) of a varlena datum + * ---------- + */ +Size +toast_datum_size(Datum value) +{ + varattrib *attr = (varattrib *) DatumGetPointer(value); + Size result; + + if (VARATT_IS_EXTERNAL(attr)) + { + /* + * Attribute is stored externally - return the extsize whether + * compressed or not. We do not count the size of the toast + * pointer ... should we? + */ + result = attr->va_content.va_external.va_extsize; + } + else + { + /* + * Attribute is stored inline either compressed or not, just + * calculate the size of the datum in either case. + */ + result = VARSIZE(attr); + } + return result; +} + /* ---------- * toast_delete - @@ -1436,45 +1468,3 @@ toast_fetch_datum_slice(varattrib *attr, int32 sliceoffset, int32 length) return result; } - -/* ---------- - * toast_datum_size - * - * Show the (possibly compressed) size of a datum - * ---------- - */ -Size -toast_datum_size(Datum value) -{ - - varattrib *attr = (varattrib *) DatumGetPointer(value); - Size result; - - if (VARATT_IS_EXTERNAL(attr)) - { - /* - * Attribute is stored externally - If it is compressed too, - * then we need to get the external datum and calculate its size, - * otherwise we just use the external rawsize. - */ - if (VARATT_IS_COMPRESSED(attr)) - { - varattrib *attrext = toast_fetch_datum(attr); - result = VARSIZE(attrext); - pfree(attrext); - } - else - result = attr->va_content.va_external.va_rawsize; - } - else - { - /* - * Attribute is stored inline either compressed or not, just - * calculate the size of the datum in either case. - */ - result = VARSIZE(attr); - } - - return result; - -} diff --git a/src/backend/utils/adt/varlena.c b/src/backend/utils/adt/varlena.c index 9ea8a17b025..399da666130 100644 --- a/src/backend/utils/adt/varlena.c +++ b/src/backend/utils/adt/varlena.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/utils/adt/varlena.c,v 1.130 2005/07/29 03:17:55 momjian Exp $ + * $PostgreSQL: pgsql/src/backend/utils/adt/varlena.c,v 1.131 2005/08/02 16:11:57 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -2574,38 +2574,49 @@ md5_bytea(PG_FUNCTION_ARGS) } /* - * Return the length of a datum, possibly compressed + * Return the size of a datum, possibly compressed + * + * Works on any data type */ Datum pg_column_size(PG_FUNCTION_ARGS) { - Datum value = PG_GETARG_DATUM(0); - int result; + Datum value = PG_GETARG_DATUM(0); + int32 result; + int typlen; - /* fn_extra stores the fixed column length, or -1 for varlena. */ - if (fcinfo->flinfo->fn_extra == NULL) /* first call? */ + /* On first call, get the input type's typlen, and save at *fn_extra */ + if (fcinfo->flinfo->fn_extra == NULL) { - /* On the first call lookup the datatype of the supplied argument */ - Oid argtypeid = get_fn_expr_argtype(fcinfo->flinfo, 0); - int typlen = get_typlen(argtypeid); + /* Lookup the datatype of the supplied argument */ + Oid argtypeid = get_fn_expr_argtype(fcinfo->flinfo, 0); - - if (typlen == 0) - { - /* Oid not in pg_type, should never happen. */ + typlen = get_typlen(argtypeid); + if (typlen == 0) /* should not happen */ elog(ERROR, "cache lookup failed for type %u", argtypeid); - } fcinfo->flinfo->fn_extra = MemoryContextAlloc(fcinfo->flinfo->fn_mcxt, sizeof(int)); - *(int *)fcinfo->flinfo->fn_extra = typlen; + *((int *) fcinfo->flinfo->fn_extra) = typlen; } + else + typlen = *((int *) fcinfo->flinfo->fn_extra); - if (*(int *)fcinfo->flinfo->fn_extra != -1) - PG_RETURN_INT32(*(int *)fcinfo->flinfo->fn_extra); + if (typlen == -1) + { + /* varlena type, possibly toasted */ + result = toast_datum_size(value); + } + else if (typlen == -2) + { + /* cstring */ + result = strlen(DatumGetCString(value)) + 1; + } else { - result = toast_datum_size(value) - VARHDRSZ; - PG_RETURN_INT32(result); + /* ordinary fixed-width type */ + result = typlen; } + + PG_RETURN_INT32(result); } diff --git a/src/include/catalog/pg_proc.h b/src/include/catalog/pg_proc.h index 72e23c3f0b5..71f51172dc5 100644 --- a/src/include/catalog/pg_proc.h +++ b/src/include/catalog/pg_proc.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/include/catalog/pg_proc.h,v 1.379 2005/07/29 14:47:01 momjian Exp $ + * $PostgreSQL: pgsql/src/include/catalog/pg_proc.h,v 1.380 2005/08/02 16:11:57 tgl Exp $ * * NOTES * The script catalog/genbki.sh reads this file and generates .bki @@ -3701,7 +3701,7 @@ DATA(insert OID = 2560 ( pg_postmaster_start_time PGNSP PGUID 12 f f t f s 0 11 DESCR("postmaster start time"); /* Column storage size */ -DATA(insert OID = 1269 ( pg_column_size PGNSP PGUID 12 f f t f i 1 23 "2276" _null_ _null_ _null_ pg_column_size - _null_ )); +DATA(insert OID = 1269 ( pg_column_size PGNSP PGUID 12 f f t f s 1 23 "2276" _null_ _null_ _null_ pg_column_size - _null_ )); DESCR("bytes required to store the value, perhaps with compression"); /* new functions for Y-direction rtree opclasses */ |