Re: TODO Item - Return compressed length of TOAST datatypes - Mailing list pgsql-patches
From | Mark Kirkwood |
---|---|
Subject | Re: TODO Item - Return compressed length of TOAST datatypes |
Date | |
Msg-id | 42B5070B.9010900@paradise.net.nz Whole thread Raw |
In response to | Re: TODO Item - Return compressed length of TOAST datatypes (WIP) (Tom Lane <tgl@sss.pgh.pa.us>) |
Responses |
Re: TODO Item - Return compressed length of TOAST datatypes
|
List | pgsql-patches |
The next iteration - Hopefully I have got the idea basically right. I wonder if I have done the "am I a varlena" the long way.., pls advise if so! Cheers Mark Tom Lane wrote: > > My recollection of that discussion is that we just wanted something > that would return the actual VARSIZE() of the datum. You're building > something way too confusing ... > > A more interesting point is that the way you've declared the function, > it will only work on text values, which is pretty limiting. Ideally > we'd define this thing as "pg_datum_length(any-varlena-type) returns int" > but there is no pseudotype corresponding to "any varlena type". > > I was thinking about this the other day in connection with my proposal > to make something that could return the TOAST value OID of an > out-of-line datum. I think the only non-restrictive way to do it would > be to declare the function as taking "any", and then add a runtime check > using the get_fn_expr_argtype() mechanism to test that what you've been > given is in fact a varlena datatype. > > diff -Nacr ./src/backend/access/heap/tuptoaster.c.orig ./src/backend/access/heap/tuptoaster.c *** ./src/backend/access/heap/tuptoaster.c.orig Mon Mar 21 13:23:58 2005 --- ./src/backend/access/heap/tuptoaster.c Sun Jun 19 14:24:43 2005 *************** *** 1436,1438 **** --- 1436,1482 ---- 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 -Nacr ./src/backend/utils/adt/Makefile.orig ./src/backend/utils/adt/Makefile *** ./src/backend/utils/adt/Makefile.orig Fri Apr 2 09:28:45 2004 --- ./src/backend/utils/adt/Makefile Fri Jun 17 17:52:09 2005 *************** *** 24,30 **** tid.o timestamp.o varbit.o varchar.o varlena.o version.o xid.o \ network.o mac.o inet_net_ntop.o inet_net_pton.o \ ri_triggers.o pg_lzcompress.o pg_locale.o formatting.o \ ! ascii.o quote.o pgstatfuncs.o encode.o like.o: like.c like_match.c --- 24,30 ---- tid.o timestamp.o varbit.o varchar.o varlena.o version.o xid.o \ network.o mac.o inet_net_ntop.o inet_net_pton.o \ ri_triggers.o pg_lzcompress.o pg_locale.o formatting.o \ ! ascii.o quote.o pgstatfuncs.o encode.o toastfuncs.o like.o: like.c like_match.c diff -Nacr ./src/backend/utils/adt/toastfuncs.c.orig ./src/backend/utils/adt/toastfuncs.c *** ./src/backend/utils/adt/toastfuncs.c.orig Fri Jun 17 17:52:09 2005 --- ./src/backend/utils/adt/toastfuncs.c Sun Jun 19 17:35:26 2005 *************** *** 0 **** --- 1,74 ---- + /*------------------------------------------------------------------------- + * + * toastfuncs.c + * Functions for accessing information about toasted data. + * + * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * + * IDENTIFICATION + * $PostgreSQL$ + * + *------------------------------------------------------------------------- + */ + + #include "postgres.h" + #include "fmgr.h" + + #include "catalog/pg_type.h" + #include "access/xact.h" + #include "access/tuptoaster.h" + #include "utils/builtins.h" + #include "utils/syscache.h" + + Datum + pg_datum_length(PG_FUNCTION_ARGS) + { + + Datum value = PG_GETARG_DATUM(0); + int size; + + + if (fcinfo->flinfo->fn_extra == NULL) + { + /* + * On the first call check lookup the datatype of the supplied argument + * and check if is a varlena . + */ + Oid argtypeid = get_fn_expr_argtype(fcinfo->flinfo, 0); + HeapTuple tp; + int typlen; + + fcinfo->flinfo->fn_extra = MemoryContextAlloc(fcinfo->flinfo->fn_mcxt, + sizeof(int)); + + tp = SearchSysCache(TYPEOID, + ObjectIdGetDatum(argtypeid), + 0, 0, 0); + if (HeapTupleIsValid(tp)) + { + Form_pg_type typtup = (Form_pg_type) GETSTRUCT(tp); + typlen = typtup->typlen; + ReleaseSysCache(tp); + } + else + { + /* Oid not in pg_type, should never happen. */ + elog(ERROR, "invalid typid %u", argtypeid); + } + + + + if ( typlen != -1 ) + { + elog(ERROR, "this function is only applicable to varlena types"); + } + } + + + size = toast_datum_size(value) - VARHDRSZ; + + PG_RETURN_INT32(size); + } + diff -Nacr ./src/include/access/tuptoaster.h.orig ./src/include/access/tuptoaster.h *** ./src/include/access/tuptoaster.h.orig Mon Mar 21 13:24:04 2005 --- ./src/include/access/tuptoaster.h Sun Jun 19 14:45:18 2005 *************** *** 138,141 **** --- 138,149 ---- */ extern Size toast_raw_datum_size(Datum value); + /* ---------- + * toast_datum_size - + * + * Return the (possibly compressed) size of a varlena datum + * ---------- + */ + extern Size toast_datum_size(Datum value); + #endif /* TUPTOASTER_H */ diff -Nacr ./src/include/catalog/pg_proc.h.orig ./src/include/catalog/pg_proc.h *** ./src/include/catalog/pg_proc.h.orig Wed Jun 15 09:04:41 2005 --- ./src/include/catalog/pg_proc.h Sun Jun 19 17:08:35 2005 *************** *** 3655,3660 **** --- 3655,3664 ---- DATA(insert OID = 2560 ( pg_postmaster_start_time PGNSP PGUID 12 f f t f s 0 1184 "" _null_ _null_ _null_ pgsql_postmaster_start_time- _null_ )); DESCR("postmaster start time"); + /* Toast compressed length */ + DATA(insert OID = 2561 ( pg_datum_length PGNSP PGUID 12 f f t f i 1 23 "2276" _null_ _null_ _null_ pg_datum_length- _null_ )); + DESCR("length (possibly compressed) of varlena types"); + /* * Symbolic values for provolatile column: these indicate whether the result diff -Nacr ./src/include/utils/builtins.h.orig ./src/include/utils/builtins.h *** ./src/include/utils/builtins.h.orig Fri May 27 12:57:49 2005 --- ./src/include/utils/builtins.h Sun Jun 19 12:48:35 2005 *************** *** 828,831 **** --- 828,834 ---- /* catalog/pg_conversion.c */ extern Datum pg_convert_using(PG_FUNCTION_ARGS); + /* toastfuncs.c */ + extern Datum pg_datum_length(PG_FUNCTION_ARGS); + #endif /* BUILTINS_H */
pgsql-patches by date: