0

My query looks like this, and performs well:

select * 
from table t 
where (t.one,t.two,t.three) in ( (11,12,13), (21,22,23) );

Now the number of these triplets within the in statement will vary, so I'm trying to do the following with JDBC:

String sql = "select * from table where (one, two, three) in (select * from unnest(?::smallint[], ?::integer[], ?::integer[]))"
// conn is the java.sql.Connection
PreparedStatement ps = conn.prepareStatement(sql);
ps.setArray(1, conn.createArrayOf("smallint", new Short[]{11, 21}));
ps.setArray(2, conn.createArrayOf("integer", new Integer[]{12,22}));
ps.setArray(3, conn.createArrayOf("integer", new Integer[]{13,23}));
return ps;

And that performs terribly bad. So is there a way to send the triplets using jdbc such that the end result is equivalent to the sql query?

I'd have two btree indexes one on one, two and another on one, three I need to use any of those in order to make this performant

pablo
  • 747
  • 1
  • 10
  • 24

2 Answers2

0

You could create a composite type like

CREATE TYPE triple AS (
   a smallint,
   b integer,
   c integer
);

Then you could write the query like this:

SELECT * 
FROM t 
WHERE (t.one, t.two, t.three) = ANY (?::triple[]);

You'd supply the array as a single string that looks like

{(11\,12\,13), (21\,22\,23)}

= ANY does the same as IN, but it can be used with an array on the right hand side.

Laurenz Albe
  • 209,280
  • 17
  • 206
  • 263
0

I could accomplish that using NamedParameterJdbcTemplate

String sql = "select * from table " +
        "where (one, two, three) in (:valuesMap)";

List<Integer[]> valuesMap = new ArrayList<>();
valuesMap.add(new Integer[]{11,12,13});
valuesMap.add(new Integer[]{21,22,23});
SqlParameterSource params = new MapSqlParameterSource("valuesMap", valuesMap);

return jdbc.query(sql, params, resultSetExtractor);

This works despite one being a smallint

pablo
  • 747
  • 1
  • 10
  • 24