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:
Michael Bayne
2008-10-31 00:17:36 +00:00
parent ec76d4d29f
commit 2b8bc0c97f
5 changed files with 59 additions and 20 deletions
@@ -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;
}
+10 -1
View File
@@ -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.