When we can switch entirely to 1.6 we can use Postgres's value = any(?::int[])
form to pass as many damned keys we want in a giant array. At that time we can nix all the >32,768 key fiddly business.
This commit is contained in:
@@ -21,6 +21,7 @@
|
||||
package com.samskivert.jdbc.depot;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.SQLException;
|
||||
import java.util.Map;
|
||||
@@ -261,9 +262,10 @@ public class BindVisitor implements ExpressionVisitor
|
||||
deleteClause.getWhereClause().accept(this);
|
||||
}
|
||||
|
||||
protected BindVisitor (DepotTypes types, PreparedStatement stmt)
|
||||
protected BindVisitor (DepotTypes types, Connection conn, PreparedStatement stmt)
|
||||
{
|
||||
_types = types;
|
||||
_conn = conn;
|
||||
_stmt = stmt;
|
||||
_argIdx = 1;
|
||||
}
|
||||
@@ -299,6 +301,7 @@ public class BindVisitor implements ExpressionVisitor
|
||||
}
|
||||
|
||||
protected DepotTypes _types;
|
||||
protected Connection _conn;
|
||||
protected PreparedStatement _stmt;
|
||||
protected int _argIdx;
|
||||
}
|
||||
|
||||
@@ -52,13 +52,22 @@ public class KeySet<T extends PersistentRecord> extends WhereClause
|
||||
_condition = new LiteralExp("false");
|
||||
|
||||
} else if (keyFields.length == 1) {
|
||||
// TODO: remove when we update to 1.6 and change Postgres In handling
|
||||
if (keys.size() > Conditionals.In.MAX_KEYS) {
|
||||
throw new IllegalArgumentException("Cannot create where clause for more than " +
|
||||
Conditionals.In.MAX_KEYS + " at a time.");
|
||||
}
|
||||
|
||||
// Single-column keys result in the compact IN(keyVal1, keyVal2, ...)
|
||||
Comparable<?>[] keyFieldValues = new Comparable<?>[keys.size()];
|
||||
Comparable<?> first = keys.iterator().next().getValues().get(0);
|
||||
Comparable<?>[] keyFieldValues;
|
||||
if (first instanceof Integer) {
|
||||
keyFieldValues = new Integer[keys.size()];
|
||||
} else if (first instanceof Integer) {
|
||||
keyFieldValues = new String[keys.size()];
|
||||
} else {
|
||||
keyFieldValues = new Comparable<?>[keys.size()];
|
||||
}
|
||||
int ii = 0;
|
||||
for (Key<T> key : keys) {
|
||||
keyFieldValues[ii++] = key.getValues().get(0);
|
||||
|
||||
@@ -117,8 +117,8 @@ public class MySQLBuilder
|
||||
|
||||
public class MSBindVisitor extends BindVisitor
|
||||
{
|
||||
protected MSBindVisitor (DepotTypes types, PreparedStatement stmt) {
|
||||
super(types, stmt);
|
||||
protected MSBindVisitor (DepotTypes types, Connection conn, PreparedStatement stmt) {
|
||||
super(types, conn, stmt);
|
||||
}
|
||||
|
||||
@Override public void visit (FullTextMatch match) {
|
||||
@@ -195,9 +195,9 @@ public class MySQLBuilder
|
||||
}
|
||||
|
||||
@Override
|
||||
protected BindVisitor getBindVisitor (PreparedStatement stmt)
|
||||
protected BindVisitor getBindVisitor (Connection conn, PreparedStatement stmt)
|
||||
{
|
||||
return new MSBindVisitor(_types, stmt);
|
||||
return new MSBindVisitor(_types, conn, stmt);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -48,6 +48,7 @@ import com.samskivert.jdbc.depot.FieldMarshaller.ShortMarshaller;
|
||||
import com.samskivert.jdbc.depot.annotation.FullTextIndex;
|
||||
import com.samskivert.jdbc.depot.expression.EpochSeconds;
|
||||
import com.samskivert.jdbc.depot.operator.Conditionals.FullTextMatch;
|
||||
import com.samskivert.jdbc.depot.operator.Conditionals.In;
|
||||
import com.samskivert.util.ArrayUtil;
|
||||
import com.samskivert.util.StringUtil;
|
||||
|
||||
@@ -58,26 +59,28 @@ public class PostgreSQLBuilder
|
||||
{
|
||||
public class PGBuildVisitor extends BuildVisitor
|
||||
{
|
||||
@Override public void visit (FullTextMatch match)
|
||||
{
|
||||
@Override public void visit (FullTextMatch match) {
|
||||
appendIdentifier("ftsCol_" + match.getName());
|
||||
_builder.append(" @@ TO_TSQUERY('default', ?)");
|
||||
}
|
||||
|
||||
public void visit (EpochSeconds epochSeconds)
|
||||
{
|
||||
@Override public void visit (EpochSeconds epochSeconds) {
|
||||
_builder.append("date_part('epoch', ");
|
||||
epochSeconds.getArgument().accept(this);
|
||||
_builder.append(")");
|
||||
}
|
||||
|
||||
protected PGBuildVisitor (DepotTypes types)
|
||||
{
|
||||
// TODO: enable when we can require 1.6 support
|
||||
// @Override public void visit (In in) {
|
||||
// in.getColumn().accept(this);
|
||||
// _builder.append(" = any (?)");
|
||||
// }
|
||||
|
||||
protected PGBuildVisitor (DepotTypes types) {
|
||||
super(types);
|
||||
}
|
||||
|
||||
@Override protected void appendIdentifier (String field)
|
||||
{
|
||||
@Override protected void appendIdentifier (String field) {
|
||||
_builder.append("\"").append(field).append("\"");
|
||||
}
|
||||
}
|
||||
@@ -103,8 +106,32 @@ public class PostgreSQLBuilder
|
||||
}
|
||||
}
|
||||
|
||||
protected PGBindVisitor (DepotTypes types, PreparedStatement stmt) {
|
||||
super(types, stmt);
|
||||
// TODO: enable when we can require 1.6 support
|
||||
// @Override public void visit (In in) {
|
||||
// Comparable<?>[] values = in.getValues();
|
||||
// try {
|
||||
// _stmt.setObject(
|
||||
// _argIdx++, _conn.createArrayOf(getElementType(values), (Object[])values));
|
||||
// } catch (SQLException sqe) {
|
||||
// throw new DatabaseException(
|
||||
// "Failed to write value to statement [idx=" + (_argIdx-1) +
|
||||
// ", values=" + StringUtil.safeToString(values) + "]", sqe);
|
||||
// }
|
||||
// }
|
||||
|
||||
// protected String getElementType (Comparable<?>[] values) {
|
||||
// if (values instanceof Integer[]) {
|
||||
// return "integer";
|
||||
// } else if (values instanceof String[]) {
|
||||
// return "character varying";
|
||||
// } else {
|
||||
// throw new DatabaseException(
|
||||
// "Don't know how to make Postgres array for " + values.getClass());
|
||||
// }
|
||||
// }
|
||||
|
||||
protected PGBindVisitor (DepotTypes types, Connection conn, PreparedStatement stmt) {
|
||||
super(types, conn, stmt);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -203,9 +230,9 @@ public class PostgreSQLBuilder
|
||||
}
|
||||
|
||||
@Override
|
||||
protected BindVisitor getBindVisitor (PreparedStatement stmt)
|
||||
protected BindVisitor getBindVisitor (Connection conn, PreparedStatement stmt)
|
||||
{
|
||||
return new PGBindVisitor(_types, stmt);
|
||||
return new PGBindVisitor(_types, conn, stmt);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -78,7 +78,7 @@ public abstract class SQLBuilder
|
||||
}
|
||||
|
||||
PreparedStatement stmt = conn.prepareStatement(_buildVisitor.getQuery());
|
||||
_bindVisitor = getBindVisitor(stmt);
|
||||
_bindVisitor = getBindVisitor(conn, stmt);
|
||||
_clause.accept(_bindVisitor);
|
||||
|
||||
if (PersistenceContext.DEBUG) {
|
||||
@@ -213,7 +213,7 @@ public abstract class SQLBuilder
|
||||
/**
|
||||
* Overridden by subclasses to create a dialect-specific {@link BindVisitor}.
|
||||
*/
|
||||
protected abstract BindVisitor getBindVisitor (PreparedStatement stmt);
|
||||
protected abstract BindVisitor getBindVisitor (Connection conn, PreparedStatement stmt);
|
||||
|
||||
/**
|
||||
* Overridden by subclasses to figure the dialect-specific SQL type of the given field.
|
||||
|
||||
Reference in New Issue
Block a user