aboutsummaryrefslogtreecommitdiff
path: root/src/backend/utils/adt/varlena.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/utils/adt/varlena.c')
-rw-r--r--src/backend/utils/adt/varlena.c52
1 files changed, 39 insertions, 13 deletions
diff --git a/src/backend/utils/adt/varlena.c b/src/backend/utils/adt/varlena.c
index 1f6c176f640..dd877c7d3f0 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.139 2005/10/29 00:31:51 petere Exp $
+ * $PostgreSQL: pgsql/src/backend/utils/adt/varlena.c,v 1.140 2005/11/18 02:38:23 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -2491,16 +2491,18 @@ array_to_text(PG_FUNCTION_ARGS)
int nitems,
*dims,
ndims;
- char *p;
Oid element_type;
int typlen;
bool typbyval;
char typalign;
StringInfo result_str = makeStringInfo();
+ bool printed = false;
+ char *p;
+ bits8 *bitmap;
+ int bitmask;
int i;
ArrayMetaState *my_extra;
- p = ARR_DATA_PTR(v);
ndims = ARR_NDIM(v);
dims = ARR_DIMS(v);
nitems = ArrayGetNItems(ndims, dims);
@@ -2522,7 +2524,7 @@ array_to_text(PG_FUNCTION_ARGS)
fcinfo->flinfo->fn_extra = MemoryContextAlloc(fcinfo->flinfo->fn_mcxt,
sizeof(ArrayMetaState));
my_extra = (ArrayMetaState *) fcinfo->flinfo->fn_extra;
- my_extra->element_type = InvalidOid;
+ my_extra->element_type = ~element_type;
}
if (my_extra->element_type != element_type)
@@ -2542,23 +2544,47 @@ array_to_text(PG_FUNCTION_ARGS)
typbyval = my_extra->typbyval;
typalign = my_extra->typalign;
+ p = ARR_DATA_PTR(v);
+ bitmap = ARR_NULLBITMAP(v);
+ bitmask = 1;
+
for (i = 0; i < nitems; i++)
{
Datum itemvalue;
char *value;
- itemvalue = fetch_att(p, typbyval, typlen);
+ /* Get source element, checking for NULL */
+ if (bitmap && (*bitmap & bitmask) == 0)
+ {
+ /* we ignore nulls */
+ }
+ else
+ {
+ itemvalue = fetch_att(p, typbyval, typlen);
- value = DatumGetCString(FunctionCall1(&my_extra->proc,
- itemvalue));
+ value = DatumGetCString(FunctionCall1(&my_extra->proc,
+ itemvalue));
- if (i > 0)
- appendStringInfo(result_str, "%s%s", fldsep, value);
- else
- appendStringInfoString(result_str, value);
+ if (printed)
+ appendStringInfo(result_str, "%s%s", fldsep, value);
+ else
+ appendStringInfoString(result_str, value);
+ printed = true;
+
+ p = att_addlength(p, typlen, PointerGetDatum(p));
+ p = (char *) att_align(p, typalign);
+ }
- p = att_addlength(p, typlen, PointerGetDatum(p));
- p = (char *) att_align(p, typalign);
+ /* advance bitmap pointer if any */
+ if (bitmap)
+ {
+ bitmask <<= 1;
+ if (bitmask == 0x100)
+ {
+ bitmap++;
+ bitmask = 1;
+ }
+ }
}
PG_RETURN_TEXT_P(PG_STR_GET_TEXT(result_str->data));