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:
@@ -37,6 +37,7 @@ import com.samskivert.jdbc.JDBCUtil;
|
|||||||
|
|
||||||
import com.samskivert.jdbc.depot.Modifier.*;
|
import com.samskivert.jdbc.depot.Modifier.*;
|
||||||
import com.samskivert.jdbc.depot.clause.DeleteClause;
|
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.InsertClause;
|
||||||
import com.samskivert.jdbc.depot.clause.QueryClause;
|
import com.samskivert.jdbc.depot.clause.QueryClause;
|
||||||
import com.samskivert.jdbc.depot.clause.UpdateClause;
|
import com.samskivert.jdbc.depot.clause.UpdateClause;
|
||||||
@@ -147,6 +148,11 @@ public abstract class DepotRepository
|
|||||||
boolean useExplicit =
|
boolean useExplicit =
|
||||||
(marsh.getTableName() == null) || !marsh.hasPrimaryKey() || !_ctx.isUsingCache();
|
(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 ?
|
return _ctx.invoke(useExplicit ?
|
||||||
new FindAllQuery.Explicitly<T>(_ctx, type, clauses) :
|
new FindAllQuery.Explicitly<T>(_ctx, type, clauses) :
|
||||||
new FindAllQuery.WithCache<T>(_ctx, type, clauses));
|
new FindAllQuery.WithCache<T>(_ctx, type, clauses));
|
||||||
|
|||||||
@@ -30,21 +30,17 @@ import java.util.List;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import com.samskivert.io.PersistenceException;
|
import com.samskivert.io.PersistenceException;
|
||||||
import com.samskivert.util.ArrayUtil;
|
|
||||||
|
|
||||||
import com.samskivert.jdbc.DatabaseLiaison;
|
import com.samskivert.jdbc.DatabaseLiaison;
|
||||||
import com.samskivert.jdbc.JDBCUtil;
|
import com.samskivert.jdbc.JDBCUtil;
|
||||||
|
|
||||||
import com.samskivert.jdbc.depot.clause.FieldDefinition;
|
import com.samskivert.jdbc.depot.clause.FieldOverride;
|
||||||
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.QueryClause;
|
import com.samskivert.jdbc.depot.clause.QueryClause;
|
||||||
import com.samskivert.jdbc.depot.clause.SelectClause;
|
import com.samskivert.jdbc.depot.clause.SelectClause;
|
||||||
import com.samskivert.jdbc.depot.clause.Where;
|
import com.samskivert.jdbc.depot.clause.Where;
|
||||||
import com.samskivert.jdbc.depot.expression.SQLExpression;
|
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.Logic.*;
|
||||||
|
import com.samskivert.jdbc.depot.operator.Conditionals.*;
|
||||||
|
|
||||||
import static com.samskivert.jdbc.depot.Log.log;
|
import static com.samskivert.jdbc.depot.Log.log;
|
||||||
|
|
||||||
@@ -64,6 +60,18 @@ public abstract class FindAllQuery<T extends PersistentRecord>
|
|||||||
throws PersistenceException
|
throws PersistenceException
|
||||||
{
|
{
|
||||||
super(ctx, type);
|
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);
|
DepotTypes types = DepotTypes.getDepotTypes(ctx, clauses);
|
||||||
types.addClass(ctx, type);
|
types.addClass(ctx, type);
|
||||||
_builder = _ctx.getSQLBuilder(types);
|
_builder = _ctx.getSQLBuilder(types);
|
||||||
@@ -103,42 +111,26 @@ public abstract class FindAllQuery<T extends PersistentRecord>
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (fetchKeys.size() > 0) {
|
if (fetchKeys.size() > 0) {
|
||||||
// make a new array of query clauses for the second pass
|
SQLExpression condition;
|
||||||
int jj = 0;
|
|
||||||
QueryClause[] newClauses = new QueryClause[_clauses.length + 1];
|
|
||||||
SQLExpression originalWhereCondition = null;
|
|
||||||
|
|
||||||
for (int ii = 0; ii < _clauses.length; ii ++) {
|
if (_marsh.getPrimaryKeyFields().length == 1) {
|
||||||
// we do not need ORDER BY in the second pass query
|
Comparable[] keyFieldValues = new Comparable[fetchKeys.size()];
|
||||||
if (_clauses[ii] instanceof OrderBy) {
|
for (int ii = 0; ii < keyFieldValues.length; ii ++) {
|
||||||
continue;
|
keyFieldValues[ii] = fetchKeys.get(ii).condition.getValues()[0];
|
||||||
}
|
}
|
||||||
if (_clauses[ii] instanceof Where) {
|
condition = new In(_type, _marsh.getPrimaryKeyFields()[0], keyFieldValues);
|
||||||
originalWhereCondition = ((Where) _clauses[ii]).getCondition();
|
|
||||||
continue;
|
} 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()];
|
Where keyWhere = new Where(condition);
|
||||||
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);
|
|
||||||
|
|
||||||
// finally build the new query
|
// 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);
|
stmt = _builder.prepare(conn);
|
||||||
|
|
||||||
// and execute it
|
// and execute it
|
||||||
|
|||||||
Reference in New Issue
Block a user