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 | 42B79B34.5000609@paradise.net.nz Whole thread Raw |
In response to | Re: TODO Item - Return compressed length of TOAST datatypes (Mark Kirkwood <markir@paradise.net.nz>) |
Responses |
Re: TODO Item - Return compressed length of TOAST datatypes
|
List | pgsql-patches |
I did a few cleanups on the last patch. Please examine this one instead. The changes are: 1. Add documentation for pg_datum_length builtin. 2. Correct some typos in the code comments. 3. Move the code in toastfuncs.c to varlena.c as it is probably the correct place. 4. Use ereport instead of elog. 5 Quiet compiler warning in pg_datum_length. Best wishes Mark Mark Kirkwood wrote: > 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! > diff -Nacr ./doc/src/sgml/func.sgml.orig ./doc/src/sgml/func.sgml *** ./doc/src/sgml/func.sgml.orig Mon Jun 20 15:38:23 2005 --- ./doc/src/sgml/func.sgml Mon Jun 20 15:45:51 2005 *************** *** 2187,2192 **** --- 2187,2200 ---- </row> <row> + <entry><literal><function>pg_datum_length</function>(<parameter>string</parameter>)</literal></entry> + <entry><type>integer</type></entry> + <entry>Number of bytes (before toast decompression) in string</entry> + <entry><literal>pg_datum_length( 'jo\\000se'::bytea)</literal></entry> + <entry><literal>5</literal></entry> + </row> + + <row> <entry><literal><function>position</function>(<parameter>substring</parameter> in <parameter>string</parameter>)</literal></entry> <entry><type>integer</type></entry> <entry>Location of specified substring</entry> diff -Nacr ./src/backend/access/heap/tuptoaster.c.orig ./src/backend/access/heap/tuptoaster.c *** ./src/backend/access/heap/tuptoaster.c.orig Mon Jun 20 17:11:37 2005 --- ./src/backend/access/heap/tuptoaster.c Mon Jun 20 17:11:44 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/varlena.c.orig ./src/backend/utils/adt/varlena.c *** ./src/backend/utils/adt/varlena.c.orig Mon Jun 20 14:28:03 2005 --- ./src/backend/utils/adt/varlena.c Mon Jun 20 17:17:58 2005 *************** *** 28,33 **** --- 28,34 ---- #include "utils/builtins.h" #include "utils/lsyscache.h" #include "utils/pg_locale.h" + #include "utils/syscache.h" typedef struct varlena unknown; *************** *** 2330,2333 **** --- 2331,2396 ---- result_text = PG_STR_GET_TEXT(hexsum); PG_RETURN_TEXT_P(result_text); + } + + /* + * Show the (possibly compressed) length of a datum. + */ + Datum + pg_datum_length(PG_FUNCTION_ARGS) + { + + Datum value = PG_GETARG_DATUM(0); + int result; + + + if (fcinfo->flinfo->fn_extra == NULL) + { + /* + * On the first call 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 = 0; + + + 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. */ + ereport(ERROR, + (errcode(ERRCODE_INTERNAL_ERROR), + errmsg("invalid typid: %u", argtypeid))); + } + + + if ( typlen != -1 ) + { + /* Not a varlena. */ + ereport(ERROR, + (errcode(ERRCODE_DATATYPE_MISMATCH), + errmsg("function is only applicable to varlena types"))); + } + + + /* + * Allocate fn_extra so we don't go here again! + */ + fcinfo->flinfo->fn_extra = MemoryContextAlloc(fcinfo->flinfo->fn_mcxt, + sizeof(int)); + } + + + result = toast_datum_size(value) - VARHDRSZ; + + PG_RETURN_INT32(result); } 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 Mon Jun 20 15:59:09 2005 *************** *** 601,606 **** --- 601,607 ---- extern Datum byteapos(PG_FUNCTION_ARGS); extern Datum bytea_substr(PG_FUNCTION_ARGS); extern Datum bytea_substr_no_len(PG_FUNCTION_ARGS); + extern Datum pg_datum_length(PG_FUNCTION_ARGS); /* version.c */ extern Datum pgsql_version(PG_FUNCTION_ARGS);
pgsql-patches by date: