From 85fe8b09c302b0f21c55654c4d545e8b9aa310d4 Mon Sep 17 00:00:00 2001 From: zell Date: Mon, 27 Aug 2007 16:11:26 +0000 Subject: [PATCH] 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. git-svn-id: https://samskivert.googlecode.com/svn/trunk@2216 6335cc39-0255-0410-8fd6-9bcaacd3b74c --- .../jdbc/depot/DepotRepository.java | 6 ++ .../samskivert/jdbc/depot/FindAllQuery.java | 64 ++++++++----------- 2 files changed, 34 insertions(+), 36 deletions(-) diff --git a/src/java/com/samskivert/jdbc/depot/DepotRepository.java b/src/java/com/samskivert/jdbc/depot/DepotRepository.java index 24e254e2..6c398e50 100644 --- a/src/java/com/samskivert/jdbc/depot/DepotRepository.java +++ b/src/java/com/samskivert/jdbc/depot/DepotRepository.java @@ -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(_ctx, type, clauses) : new FindAllQuery.WithCache(_ctx, type, clauses)); diff --git a/src/java/com/samskivert/jdbc/depot/FindAllQuery.java b/src/java/com/samskivert/jdbc/depot/FindAllQuery.java index d56d6d2e..fe514823 100644 --- a/src/java/com/samskivert/jdbc/depot/FindAllQuery.java +++ b/src/java/com/samskivert/jdbc/depot/FindAllQuery.java @@ -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 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 } 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(_type, _marsh.getFieldNames(), newClauses)); + _builder.newQuery(new SelectClause(_type, _marsh.getFieldNames(), keyWhere)); stmt = _builder.prepare(conn); // and execute it