Fall back to the simple case: a query on a concrete record without overrides can be stripped of all JOINs and external WHERE clauses in the second pass.

This commit is contained in:
Par Winzell
2007-08-27 16:11:26 +00:00
parent 8e9279c242
commit 8081e7bfad
2 changed files with 34 additions and 36 deletions
@@ -37,6 +37,7 @@ import com.samskivert.jdbc.JDBCUtil;
import com.samskivert.jdbc.depot.Modifier.*;
import com.samskivert.jdbc.depot.clause.DeleteClause;
import com.samskivert.jdbc.depot.clause.FieldOverride;
import com.samskivert.jdbc.depot.clause.InsertClause;
import com.samskivert.jdbc.depot.clause.QueryClause;
import com.samskivert.jdbc.depot.clause.UpdateClause;
@@ -147,6 +148,11 @@ public abstract class DepotRepository
boolean useExplicit =
(marsh.getTableName() == null) || !marsh.hasPrimaryKey() || !_ctx.isUsingCache();
// queries on @Computed records or the presence of FieldOverrides use the simple algorithm
for (QueryClause clause : clauses) {
useExplicit |= (clause instanceof FieldOverride);
}
return _ctx.invoke(useExplicit ?
new FindAllQuery.Explicitly<T>(_ctx, type, clauses) :
new FindAllQuery.WithCache<T>(_ctx, type, clauses));
@@ -30,21 +30,17 @@ import java.util.List;
import java.util.Map;
import com.samskivert.io.PersistenceException;
import com.samskivert.util.ArrayUtil;
import com.samskivert.jdbc.DatabaseLiaison;
import com.samskivert.jdbc.JDBCUtil;
import com.samskivert.jdbc.depot.clause.FieldDefinition;
import com.samskivert.jdbc.depot.clause.Join;
import com.samskivert.jdbc.depot.clause.Limit;
import com.samskivert.jdbc.depot.clause.OrderBy;
import com.samskivert.jdbc.depot.clause.FieldOverride;
import com.samskivert.jdbc.depot.clause.QueryClause;
import com.samskivert.jdbc.depot.clause.SelectClause;
import com.samskivert.jdbc.depot.clause.Where;
import com.samskivert.jdbc.depot.expression.SQLExpression;
import com.samskivert.jdbc.depot.operator.SQLOperator;
import com.samskivert.jdbc.depot.operator.Logic.*;
import com.samskivert.jdbc.depot.operator.Conditionals.*;
import static com.samskivert.jdbc.depot.Log.log;
@@ -64,6 +60,18 @@ public abstract class FindAllQuery<T extends PersistentRecord>
throws PersistenceException
{
super(ctx, type);
if (_marsh.getComputed() != null) {
throw new IllegalArgumentException(
"This algorithm doesn't work on @Computed records.");
}
for (QueryClause clause : clauses) {
if (clause instanceof FieldOverride) {
throw new IllegalArgumentException(
"This algorithm doesn't work with FieldOverrides.");
}
}
DepotTypes types = DepotTypes.getDepotTypes(ctx, clauses);
types.addClass(ctx, type);
_builder = _ctx.getSQLBuilder(types);
@@ -103,42 +111,26 @@ public abstract class FindAllQuery<T extends PersistentRecord>
}
if (fetchKeys.size() > 0) {
// make a new array of query clauses for the second pass
int jj = 0;
QueryClause[] newClauses = new QueryClause[_clauses.length + 1];
SQLExpression originalWhereCondition = null;
SQLExpression condition;
for (int ii = 0; ii < _clauses.length; ii ++) {
// we do not need ORDER BY in the second pass query
if (_clauses[ii] instanceof OrderBy) {
continue;
if (_marsh.getPrimaryKeyFields().length == 1) {
Comparable[] keyFieldValues = new Comparable[fetchKeys.size()];
for (int ii = 0; ii < keyFieldValues.length; ii ++) {
keyFieldValues[ii] = fetchKeys.get(ii).condition.getValues()[0];
}
if (_clauses[ii] instanceof Where) {
originalWhereCondition = ((Where) _clauses[ii]).getCondition();
continue;
condition = new In(_type, _marsh.getPrimaryKeyFields()[0], keyFieldValues);
} else {
SQLExpression[] keyArray = new SQLExpression[fetchKeys.size()];
for (int ii = 0; ii < keyArray.length; ii ++) {
keyArray[ii] = fetchKeys.get(ii).condition;
}
newClauses[jj ++] = _clauses[ii];
condition = new Or(keyArray);
}
SQLExpression[] keyArray = new SQLExpression[fetchKeys.size()];
for (int ii = 0; ii < keyArray.length; ii ++) {
keyArray[ii] = fetchKeys.get(ii).condition;
}
// create our special key-matching condition
SQLExpression newCondition = new Or(keyArray);
// add in the old condition, if there was one
if (originalWhereCondition != null) {
newCondition = new And(newCondition, originalWhereCondition);
}
// and add it in as a WHERE
newClauses[jj ++] = new Where(newCondition);
newClauses = ArrayUtil.splice(newClauses, jj);
Where keyWhere = new Where(condition);
// finally build the new query
_builder.newQuery(new SelectClause<T>(_type, _marsh.getFieldNames(), newClauses));
_builder.newQuery(new SelectClause<T>(_type, _marsh.getFieldNames(), keyWhere));
stmt = _builder.prepare(conn);
// and execute it