Reputation: 123
I have a postgres function which takes a complex user defined type as an input.
CREATE OR REPLACE FUNCTION addUser(user IN O_USER) RETURNS VOID
AS
$$
BEGIN
end;
$$ language plpgsql;
CREATE TYPE O_USER AS (
id NUMERIC,
name VARCHAR(50),
addresses O_ADDRESS[]
);
CREATE TYPE O_ADDRESS AS (
id NUMERIC,
city VARCHAR(50)
);
Now I need to call the function from Java. What I understood is that I need to pass a String which will be typecasted to the UDT by db.
When I am passing the user without the address, then its working fine. But if I pass the array of address as well, then it is giving me the error.
ERROR: malformed array literal: "{(1"
DETAIL: Unexpected end of input.
SQL state: 22P02
Character: 23
I could reproduce the issue with the postgres select statement as well. For example following works fine
Select * from addUser('(1, "Vishal", {})');
But when I pass the addresses, then its a problem
Select * from addUser('(1, "Vishal", {(1,"tet")})');
Select * from addUser('(1, "Vishal", {"(1,)"})');
Select * from addUser('(1, "Vishal", {"(1,null)"})')
I believe I am not able to construct the string properly. Any idea what is wrong here?
Update
Java code to call the function
import org.springframework.jdbc.core.SqlParameter;
import org.springframework.jdbc.object.StoredProcedure;
import javax.sql.DataSource;
import java.sql.Types;
import java.util.HashMap;
import java.util.Map;
public class AddUserProcedurePostgres extends StoredProcedure {
public AddUserProcedurePostgres(DataSource dataSource) {
super(dataSource, "addUser");
setFunction(true);
declareParameter(new SqlParameter("i_User", Types.OTHER, "O_USER"));
compile();
}
public void execute() {
Map<String, Object> input = new HashMap<>();
input.put("i_User", "(1, Vishal, array[(1,tet)]::O_ADDRESS[])");
execute(input);
}
}
Error returned by the jdbc is:
Caused by: org.postgresql.util.PSQLException: ERROR: malformed array literal: " array[(1"
Detail: Array value must start with "{" or dimension information.
Upvotes: 3
Views: 3150
Reputation: 123
I found 2 ways to pass the required value to the function:
I choose the 2nd approach as it is easy to maintain.
Upvotes: 2
Reputation: 5995
You need to pass the O_ADDRESS
array with array
literal and typecasting the array to O_ADDRESS[]
. The following select
statements are valid.
select * from addUser(cast(row(1, 'Vishal', array[cast(row(1,'tet') as O_ADDRESS)]) as O_USER));
select * from addUser((1, 'Vishal', array[]::O_ADDRESS[])::O_USER);
select * from addUser((1, 'Vishal', array[]::O_ADDRESS[]));
select * from addUser((1, 'Vishal', array[(1,'tet')]::O_ADDRESS[]));
Upvotes: 1