|
8 | 8 | *
|
9 | 9 | *
|
10 | 10 | * IDENTIFICATION
|
11 |
| - * $PostgreSQL: pgsql/src/backend/utils/adt/varlena.c,v 1.124 2005/07/04 18:56:44 momjian Exp $ |
| 11 | + * $PostgreSQL: pgsql/src/backend/utils/adt/varlena.c,v 1.125 2005/07/06 19:02:52 momjian Exp $ |
12 | 12 | *
|
13 | 13 | *-------------------------------------------------------------------------
|
14 | 14 | */
|
|
28 | 28 | #include "utils/builtins.h"
|
29 | 29 | #include "utils/lsyscache.h"
|
30 | 30 | #include "utils/pg_locale.h"
|
| 31 | +#include "utils/syscache.h" |
31 | 32 |
|
32 | 33 |
|
33 | 34 | typedef struct varlena unknown;
|
@@ -2348,3 +2349,47 @@ md5_bytea(PG_FUNCTION_ARGS)
|
2348 | 2349 | result_text = PG_STR_GET_TEXT(hexsum);
|
2349 | 2350 | PG_RETURN_TEXT_P(result_text);
|
2350 | 2351 | }
|
| 2352 | + |
| 2353 | +/* |
| 2354 | + * Return the length of a datum, possibly compressed |
| 2355 | + */ |
| 2356 | +Datum |
| 2357 | +pg_column_size(PG_FUNCTION_ARGS) |
| 2358 | +{ |
| 2359 | + Datum value = PG_GETARG_DATUM(0); |
| 2360 | + int result; |
| 2361 | + |
| 2362 | + /* fn_extra stores the fixed column length, or -1 for varlena. */ |
| 2363 | + if (fcinfo->flinfo->fn_extra == NULL) /* first call? */ |
| 2364 | + { |
| 2365 | + /* On the first call lookup the datatype of the supplied argument */ |
| 2366 | + Oid argtypeid = get_fn_expr_argtype(fcinfo->flinfo, 0); |
| 2367 | + HeapTuple tp; |
| 2368 | + int typlen; |
| 2369 | + |
| 2370 | + tp = SearchSysCache(TYPEOID, |
| 2371 | + ObjectIdGetDatum(argtypeid), |
| 2372 | + 0, 0, 0); |
| 2373 | + if (!HeapTupleIsValid(tp)) |
| 2374 | + { |
| 2375 | + /* Oid not in pg_type, should never happen. */ |
| 2376 | + ereport(ERROR, |
| 2377 | + (errcode(ERRCODE_INTERNAL_ERROR), |
| 2378 | + errmsg("invalid typid: %u", argtypeid))); |
| 2379 | + } |
| 2380 | + |
| 2381 | + typlen = ((Form_pg_type)GETSTRUCT(tp))->typlen; |
| 2382 | + ReleaseSysCache(tp); |
| 2383 | + fcinfo->flinfo->fn_extra = MemoryContextAlloc(fcinfo->flinfo->fn_mcxt, |
| 2384 | + sizeof(int)); |
| 2385 | + *(int *)fcinfo->flinfo->fn_extra = typlen; |
| 2386 | + } |
| 2387 | + |
| 2388 | + if (*(int *)fcinfo->flinfo->fn_extra != -1) |
| 2389 | + PG_RETURN_INT32(*(int *)fcinfo->flinfo->fn_extra); |
| 2390 | + else |
| 2391 | + { |
| 2392 | + result = toast_datum_size(value) - VARHDRSZ; |
| 2393 | + PG_RETURN_INT32(result); |
| 2394 | + } |
| 2395 | +} |
0 commit comments