Re: plpythonu and bytea - Mailing list pgsql-general

From Michael Fuhr
Subject Re: plpythonu and bytea
Date
Msg-id 20050703062102.GA34637@winnie.fuhr.org
Whole thread Raw
In response to plpythonu and bytea  (Greg Steffensen <greg.steffensen@gmail.com>)
List pgsql-general
On Sat, Jul 02, 2005 at 04:49:23PM -0400, Greg Steffensen wrote:
>
> Hey, I'm trying to write some plpython procedures that read binary data from
> images on the disk and store it in bytea fields. I'm basically trying to
> write a plpython procedure that accepts a varchar and returns a bytea, with
> these procedure contents:
>
> data = file(args[0]).read()
> return data
>
> (The actual procedure will have more in it, but that's the tricky part). But
> the returned data is always severely truncated. Is returning a bytea from
> plpython impossible, or is there some way I should escape the data string?

I think the return value is a cstring that's cast to whatever type
the function is declared to return; I'd guess it's being truncated
because it contains NUL (\000) values.  Example:

CREATE FUNCTION foo() RETURNS bytea AS $$
data = '\001\002\000\003\004'
return data
$$ LANGUAGE plpythonu;

SELECT foo(), length(foo());
   foo    | length
----------+--------
 \001\002 |      2
(1 row)

The function should work if the data is escaped.  I don't know the
best Python way to do that, but the following appears to work:

CREATE FUNCTION foo() RETURNS bytea AS $$
data = '\001\002\000\003\004'
return ''.join(['\\%03o' % ord(x) for x in data])
$$ LANGUAGE plpythonu;

SELECT foo(), length(foo());
         foo          | length
----------------------+--------
 \001\002\000\003\004 |      5
(1 row)

It seems like there ought to be a better way than the list comprehension
shown; maybe you or somebody else with better Python skills can improve
on it.

--
Michael Fuhr
http://www.fuhr.org/~mfuhr/

pgsql-general by date:

Previous
From: Greg Steffensen
Date:
Subject: plpythonu and bytea
Next
From: "Sim Zacks"
Date:
Subject: trigger update delete