Reputation: 4380
I need to pass an array of bytea to a stored procedure (the declared type if bytea[]).
The data get's passed to my stored procedure, however, I cannot get the individual bytea from the bytea[]. The array_lower and array_upper functions report a dimension of one, but tumb_data[1] always returns NULL.
If I print the whole bytea[] object from my stored proc, I get something that starts with "{{-1,-40,-1,-32,0,16,74,70,73,70,0,1,1", so I know data is making it to the procedure.
This is some example code that shows the problem:
Class.forName("org.postgresql.Driver");
String url = "jdbc:postgresql://localhost/test";
Connection c = DriverManager.getConnection(url,"andres","xxx");
List<byte[]> thumbData=new ArrayList<byte[]>();
thumbData.add("Test #1".getBytes());
thumbData.add("Test #1".getBytes());
Object[] thumbs=thumbData.toArray();
Array thumbArray=c.createArrayOf("bytea", thumbs);
PreparedStatement stmt=c.prepareStatement("SELECT test_funct(?)");
stmt.setArray(1,thumbArray);
stmt.execute();
And this is the stored procedure:
CREATE OR REPLACE FUNCTION test_funct(a_bytes bytea[])
RETURNS boolean AS
$BODY$DECLARE
v_bytes bytea;
BEGIN
FOR i IN array_lower(a_bytes,1) .. array_upper(a_bytes,1) LOOP
v_bytes:= a_bytes[i];
IF (v_bytes IS NULL) THEN
RAISE EXCEPTION 'error';
END IF;
END LOOP;
RETURN true;
END$BODY$
LANGUAGE plpgsql VOLATILE
COST 100;
Finally, here's the log output when I run my test program:
2013-02-17 21:03:52 EST LOG: execute <unnamed>: SET extra_float_digits = 3
2013-02-17 21:03:52 EST LOG: execute <unnamed>: SELECT oid FROM pg_catalog.pg_type WHERE typname = $1
2013-02-17 21:03:52 EST DETAIL: parameters: $1 = '_bytea'
2013-02-17 21:03:52 EST LOG: execute <unnamed>: SELECT e.typdelim FROM pg_catalog.pg_type t, pg_catalog.pg_type e WHERE t.oid = $1 and t.typelem = e.oid
2013-02-17 21:03:52 EST DETAIL: parameters: $1 = '1001'
2013-02-17 21:03:52 EST LOG: execute <unnamed>: SELECT test_funct($1)
2013-02-17 21:03:52 EST DETAIL: parameters: $1 = '{{"\\x3834","\\x313031","\\x313135","\\x313136","\\x3332","\\x3335","\\x3439"},{"\\x3834","\\x313031","\\x313135","\\x313136","\\x3332","\\x3335","\\x3439"}}'
2013-02-17 21:03:52 EST ERROR: error
2013-02-17 21:03:52 EST STATEMENT: SELECT test_funct($1)
2013-02-17 21:03:52 EST LOG: unexpected EOF on client connection
Any idea how to pass this to my stored procedure?
Upvotes: 2
Views: 2403
Reputation: 324445
I suspect that your array has two dimensions; instead of a one dimensional (linear) array of bytea
, you have a two-dimensional array of bytea
. Indexing such an array's first dimension will produce an empty result. Note that PostgreSQL arrays of any dimensions still have the basic array data type, there is no bytea[][]
etc. Use array_ndims(anyarray)
to get the array dimensions.
Observe one dimensional:
WITH t1(ba) AS (VALUES(ARRAY[ '\x0a', '\x0c', '\x0e' ] :: bytea[]))
SELECT ba, ba[1], ba[1][1] FROM t1;
ba | ba | ba
---------------------------+------+----
{"\\x0a","\\x0c","\\x0e"} | \x0a |
(1 row)
vs two-dimensional:
WITH t1(ba) AS (VALUES(ARRAY[[ '\x0a', '\x0c', '\x0e' ]] :: bytea[]))
SELECT ba, ba[1], ba[1][1] FROM t1;
ba | ba | ba
-----------------------------+----+------
{{"\\x0a","\\x0c","\\x0e"}} | | \x0a
(1 row)
Since you have not shown the full value or your SQL, it's hard to say more.
If you suspect a JDBC driver problem it would help if you could perhaps provide a self-contained compileable test case that demonstrated the problem, including SQL script to set up a test database.
Please show the actual SQL that gets run including the parameters passed. You can get this from the PostgreSQL log files with log_statement
enabled.
Upvotes: 2