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: