You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
CREATE TYPE place AS ( name TEXT, altitude DECIMAL(10,2), latitude DECIMAL(10,2) )
And we have a composite type 'city' in which they can be many 'places' - 'places' is an array of composite type place:
CREATE TYPE city AS ( city TEXT, zip_code BIGINT, places place[] )
And the main table 'employee' in which there is employeeCities, which is an array of composite type 'city', because he is responsible for few cities: CREATE TABLE employee ( employeeName varchar(100) NOT NULL, employeeId varchar(11) NOT NULL , employeeAddress varchar(100) DEFAULT NULL, employeeEmail varchar(100) DEFAULT NULL, employeeCities city[] DEFAULT NULL, PRIMARY KEY (employeeId) );
There are two ways to insert data to this table.
1st option - using ARRAY and ROW: INSERT INTO employee (employeename, employeeid, employeeaddress, employeeemail, employeecities) VALUES('name_1', 'id_1', 'address_1', 'email_1', ARRAY[ROW('city_1',111,ARRAY[ROW('place_1',22.11,11.22)::place,ROW('place_2',33.44,44.33)::place])::city,ROW('city_2',222,null)::city]);
2nd option - using backspaces and quotes: INSERT INTO employee (employeename, employeeid, employeeaddress, employeeemail, employeecities) VALUES('name_1', 'id_1', 'address_1', 'email_1', '{"(Jerusalem,111,\"{\"\"(place_1,1.11,11.1)\"\",\"\"(place_2,2.11,11.2)\"\"}\")","(TLV,222,{})","(Haifa,333,{})"}');
So where the problem is?
We are trying to insert data to this table using Java, Spring Boot application, and we use PostgreSQL JDBC Driver version 42.2.5.
To format the nested composite types array, we use:
If we have a table with only one nested array - aka employee->employeeCities (without places) it will work!
The problem occurs only when you have 2 level nested composite types arrays:
employee
|-employeeCities
|-places
Did you encounter a scenario of this kind before?
Do you have knowledge of how to solve that problem?
Driver Version - 42.2.5
Java Version - 1.8.0_192
OS Version - macos mojave
PostgreSQL Version - 10.6
To Reproduce
Steps to reproduce the behaviour:
CREATE TYPE place AS ( name TEXT, altitude DECIMAL(10,2), latitude DECIMAL(10,2) )
CREATE TYPE city AS ( city TEXT, zip_code BIGINT, places place[] )
import com.sample.postgress.entity.Employee;
import com.sample.postgress.mapper.EmployeeRowMapper; @repository
public class EmployeeDaoImpl implements EmployeeDao{
public EmployeeDaoImpl(NamedParameterJdbcTemplate template) {
this.template = template;
}
NamedParameterJdbcTemplate template;
@Override
public List<Employee> findAll() {
return template.query("select * from employee", new EmployeeRowMapper());
}
@Override
public void insertEmployee(Employee emp) {
final String sql = "insert into employee(employeeId, employeeName , employeeAddress,employeeEmail, employeeCities) values(:employeeId,:employeeName,:employeeEmail,:employeeAddress, :employeeCities)";
Connection conn;
try {
ArrayList<City> cities = new ArrayList<City>();
List<Place> places1 = new ArrayList<Place>();
places1.add(new Place("place_1",1.11,11.1));
places1.add(new Place("place_2",2.11,11.2));
places1.add(new Place("place_3",3.11,11.3));
cities.add(new City("Jerusalem",111L, places1));
List<Place> places2 = new ArrayList<Place>();
places2.add(new Place("place_4",1.22,22.1));
places2.add(new Place("place_5",2.22,22.2));
places2.add(new Place("place_6",3.22,22.3));
Not sure we've faced the same problem, but my reproducer is rather trivial:
createtabletmp (
"value"int[][]
)
insert into tmp values (array[array[]]) -- errorinsert into tmp values (array[array[]::int[]]) -- okinsert into tmp values ('{{}}') -- error — and this happens with JDBC to meinsert into tmp values ('{{}::int[]}') -- does not helpinsert into tmp values ('{array[]::int[]}') -- neither
I was unable to find how to declare empty arrays with '{}' syntax. Thus, the driver should use array[] syntax, and array[]::type for empty arrays.
I'm submitting a bug
So we have a composite type 'place':
CREATE TYPE place AS ( name TEXT, altitude DECIMAL(10,2), latitude DECIMAL(10,2) )
And we have a composite type 'city' in which they can be many 'places' - 'places' is an array of composite type place:
CREATE TYPE city AS ( city TEXT, zip_code BIGINT, places place[] )
And the main table 'employee' in which there is employeeCities, which is an array of composite type 'city', because he is responsible for few cities:
CREATE TABLE employee ( employeeName varchar(100) NOT NULL, employeeId varchar(11) NOT NULL , employeeAddress varchar(100) DEFAULT NULL, employeeEmail varchar(100) DEFAULT NULL, employeeCities city[] DEFAULT NULL, PRIMARY KEY (employeeId) );
There are two ways to insert data to this table.
1st option - using ARRAY and ROW:
INSERT INTO employee (employeename, employeeid, employeeaddress, employeeemail, employeecities) VALUES('name_1', 'id_1', 'address_1', 'email_1', ARRAY[ROW('city_1',111,ARRAY[ROW('place_1',22.11,11.22)::place,ROW('place_2',33.44,44.33)::place])::city,ROW('city_2',222,null)::city]);
2nd option - using backspaces and quotes:
INSERT INTO employee (employeename, employeeid, employeeaddress, employeeemail, employeecities) VALUES('name_1', 'id_1', 'address_1', 'email_1', '{"(Jerusalem,111,\"{\"\"(place_1,1.11,11.1)\"\",\"\"(place_2,2.11,11.2)\"\"}\")","(TLV,222,{})","(Haifa,333,{})"}');
So where the problem is?
We are trying to insert data to this table using Java, Spring Boot application, and we use PostgreSQL JDBC Driver version 42.2.5.
To format the nested composite types array, we use:
conn = template.getJdbcTemplate().getDataSource().getConnection();
Array citiesArray = conn.createArrayOf("city", citiesItems.toArray());
This is the recommended way to do it.
However, we get the following exception:
org.postgresql.util.PSQLException: ERROR: malformed array literal: "{(place_1,1.11,11.1)"
If we have a table with only one nested array - aka employee->employeeCities (without places) it will work!
The problem occurs only when you have 2 level nested composite types arrays:
employee
|-employeeCities
|-places
Did you encounter a scenario of this kind before?
Do you have knowledge of how to solve that problem?
Driver Version - 42.2.5
Java Version - 1.8.0_192
OS Version - macos mojave
PostgreSQL Version - 10.6
To Reproduce
Steps to reproduce the behaviour:
CREATE TYPE place AS ( name TEXT, altitude DECIMAL(10,2), latitude DECIMAL(10,2) )
CREATE TYPE city AS ( city TEXT, zip_code BIGINT, places place[] )
CREATE TABLE employee ( employeeName varchar(100) NOT NULL, employeeId varchar(11) NOT NULL , employeeAddress varchar(100) DEFAULT NULL, employeeEmail varchar(100) DEFAULT NULL, employeeCities city[] DEFAULT NULL, PRIMARY KEY (employeeId) );
INSERT INTO employee (employeename, employeeid, employeeaddress, employeeemail, employeecities) VALUES('name_1', 'id_1', 'address_1', 'email_1', ARRAY[ROW('city_1',111,ARRAY[ROW('place_1',22.11,11.22)::place,ROW('place_2',33.44,44.33)::place])::city,ROW('city_2',222,null)::city]);
This works.
INSERT INTO employee (employeename, employeeid, employeeaddress, employeeemail, employeecities) VALUES('name_1', 'id_1', 'address_1', 'email_1', '{"(Jerusalem,111,\"{\"\"(place_1,1.11,11.1)\"\",\"\"(place_2,2.11,11.2)\"\"}\")","(TLV,222,{})","(Haifa,333,{})"}');
This also works.
`package com.sample.postgress.entity;
import java.util.List;
public class City {
}
`
`package com.sample.postgress.entity;
import java.sql.Array;
import java.util.List;
public class CityItem {
}
`
`package com.sample.postgress.entity;
public class Place {
}
package com.sample.postgress.entity;
public class Employee {
}
`
`package com.sample.postgress.dao;
import java.sql.Array;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.sample.postgress.entity.City;
import com.sample.postgress.entity.CityItem;
import com.sample.postgress.entity.Place;
import org.postgresql.jdbc.PgArray;
import org.postgresql.util.GT;
import org.postgresql.util.PSQLException;
import org.postgresql.util.PSQLState;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.PreparedStatementCallback;
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.jdbc.core.namedparam.SqlParameterSource;
import org.springframework.jdbc.support.GeneratedKeyHolder;
import org.springframework.jdbc.support.KeyHolder;
import org.springframework.stereotype.Repository;
import com.sample.postgress.entity.Employee;
import com.sample.postgress.mapper.EmployeeRowMapper;
@repository
public class EmployeeDaoImpl implements EmployeeDao{
}
NamedParameterJdbcTemplate template;
// cities.add(new City("TLV",222L, places2));
// cities.add(new City("Haifa",333L, places3));
}
`
The insertEmployee method will throw exception.
Expected behaviour
A record should have been inserted to employee table. However, we get an exception.
Logs
postgress-boot-master-1.log
pgjdbc-trace.log
The text was updated successfully, but these errors were encountered: