Author: ssegu
Date: Thu Mar 22 13:26:18 2007
New Revision: 521443

URL: http://svn.apache.org/viewvc?view=rev&rev=521443
Log:
OPENJPA-175. PagingResultObjectProvider to use FetchBatchSize when set for 
eager selects. Fix to handle Oracle in-clause limit of 1000

Modified:
    
incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/PagingResultObjectProvider.java
    
incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/InExpression.java
    
incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DBDictionary.java
    
incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/OracleDictionary.java

Modified: 
incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/PagingResultObjectProvider.java
URL: 
http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/PagingResultObjectProvider.java?view=diff&rev=521443&r1=521442&r2=521443
==============================================================================
--- 
incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/PagingResultObjectProvider.java
 (original)
+++ 
incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/PagingResultObjectProvider.java
 Thu Mar 22 13:26:18 2007
@@ -22,6 +22,7 @@
 import org.apache.openjpa.jdbc.meta.ClassMapping;
 import org.apache.openjpa.jdbc.meta.FieldMapping;
 import org.apache.openjpa.jdbc.schema.Column;
+import org.apache.openjpa.jdbc.sql.DBDictionary;
 import org.apache.openjpa.jdbc.sql.Result;
 import org.apache.openjpa.jdbc.sql.SQLBuffer;
 import org.apache.openjpa.jdbc.sql.Select;
@@ -149,28 +150,24 @@
         // try to find a good page size.  if the known size < batch size, use
         // it.  if the batch size is set, then use that; if it's sorta close
         // to the size, then use the size / 2 to get two full pages rather
-        // than a possible big one and small one.  cap everything at 50.
+        // than a possible big one and small one
         int batch = getFetchConfiguration().getFetchBatchSize();
         int pageSize;
-        if (size <= batch && size <= 50)
+        if (batch < 0)
             pageSize = (int) size;
-        else if (batch > 0 && batch <= 50) {
-            if (size <= batch * 2) {
+        else {
+            if (batch == 0)
+                batch = 50; // reasonable default
+            if (size <= batch)
+                pageSize = (int) size;
+            else if (size <= batch * 2) {
                 if (size % 2 == 0)
                     pageSize = (int) (size / 2);
                 else
                     pageSize = (int) (size / 2 + 1);
             } else
                 pageSize = batch;
-        } else if (size <= 50)
-            pageSize = (int) size;
-        else if (size <= 100) {
-            if (size % 2 == 0)
-                pageSize = (int) (size / 2);
-            else
-                pageSize = (int) (size / 2 + 1);
-        } else
-            pageSize = 50;
+        }
 
         _page = new Object[pageSize];
         if (_paged.length > 1)
@@ -341,10 +338,11 @@
         // create where condition limiting instances to this page
         JDBCStore store = getStore();
         Select sel = store.getSQLFactory().newSelect();
-        SQLBuffer buf = new SQLBuffer(store.getDBDictionary());
+        DBDictionary dict = store.getDBDictionary();
+        SQLBuffer buf = new SQLBuffer(dict);
         Column[] pks = mapping.getPrimaryKeyColumns();
         if (pks.length == 1)
-            inContains(sel, buf, mapping, pks, start, end);
+            createInContains(sel, dict, buf, mapping, pks, start, end);
         else
             orContains(sel, buf, mapping, pks, start, end);
         sel.where(buf);
@@ -388,6 +386,32 @@
         }
     }
 
+    /**
+     *  Based on the DBDictionary, create the needed IN clauses.
+     */
+    private void createInContains(Select sel, DBDictionary dict, SQLBuffer 
buf, 
+        ClassMapping mapping, Column[] pks, int start, int end) {
+        int inClauseLimit = dict.inClauseLimit;
+        if ((inClauseLimit == -1) || ((end - start) <= inClauseLimit))
+            inContains(sel, buf, mapping, pks, start, end);
+        else {
+            buf.append("(");
+
+            int low = start;
+            for (int i = 1, stop = (end - start)/inClauseLimit; i <= stop; 
i++) {
+                inContains(sel, buf, mapping, pks, low, low + inClauseLimit);
+                low += inClauseLimit;
+                if (low < end)
+                    buf.append(" OR ");
+            }
+            // Remaining
+            if (low < end)
+                inContains(sel, buf, mapping, pks, low, end);
+
+            buf.append(")");
+        }
+    }
+    
     /**
      * Create an IN clause limiting the results to the current page.
      */

Modified: 
incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/InExpression.java
URL: 
http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/InExpression.java?view=diff&rev=521443&r1=521442&r2=521443
==============================================================================
--- 
incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/InExpression.java
 (original)
+++ 
incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/InExpression.java
 Thu Mar 22 13:26:18 2007
@@ -19,6 +19,7 @@
 import java.util.Collection;
 import java.util.Collections;
 import java.util.Iterator;
+import java.util.List;
 import java.util.Map;
 
 import org.apache.openjpa.jdbc.schema.Column;
@@ -90,13 +91,13 @@
         _const.calculateValue(sel, ctx, istate.constantState, null, null);
         _val.calculateValue(sel, ctx, istate.valueState, null, null);
 
+        List list = null;
         Collection coll = getCollection(ctx, istate.constantState);
         if (coll != null) {
-            Collection ds = new ArrayList(coll.size());
+            list = new ArrayList(coll.size());
             for (Iterator itr = coll.iterator(); itr.hasNext();)
-                ds.add(_val.toDataStoreValue(sel, ctx, istate.valueState, 
+                list.add(_val.toDataStoreValue(sel, ctx, istate.valueState, 
                     itr.next()));
-            coll = ds;
         }
 
         Column[] cols = null;
@@ -105,13 +106,44 @@
         else if (_val instanceof GetObjectId)
             cols = ((GetObjectId) _val).getColumns(istate.valueState);
 
-        if (coll == null || coll.isEmpty())
+        if (list == null || list.isEmpty())
             buf.append("1 <> 1");
         else if (_val.length(sel, ctx, istate.valueState) == 1)
-            inContains(sel, ctx, istate.valueState, buf, coll, cols);
+            createInContains(sel, ctx, istate.valueState, buf, list, cols);
         else
-            orContains(sel, ctx, istate.valueState, buf, coll, cols);
+            orContains(sel, ctx, istate.valueState, buf, list, cols);
         sel.append(buf, state.joins);
+    }
+
+    /**
+     * Based on the inClauseLimit of the DBDictionary, create the needed IN 
+     * clauses
+     */
+    private void createInContains(Select sel, ExpContext ctx, ExpState state, 
+        SQLBuffer buf, List list, Column[] cols) {
+
+        int inClauseLimit = ctx.store.getDBDictionary().inClauseLimit;
+        if ((inClauseLimit == -1) || (list.size() < inClauseLimit))
+            inContains(sel, ctx, state, buf, list, cols);
+        else {
+            buf.append("(");
+
+            int low = 0;
+            for (int i = 1, stop = list.size()/inClauseLimit; i <= stop; i++) {
+                List subList = list.subList(low, low + inClauseLimit);
+                inContains(sel, ctx, state, buf, subList, cols);
+                low += inClauseLimit;
+                if (low < list.size())
+                    buf.append(" OR ");
+            }
+            // Remaining
+            if (low < list.size()) {
+                List rem = list.subList(low, list.size());
+                inContains(sel, ctx, state, buf, rem, cols);
+            }
+
+            buf.append(")");
+        }
     }
 
     /**

Modified: 
incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DBDictionary.java
URL: 
http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DBDictionary.java?view=diff&rev=521443&r1=521442&r2=521443
==============================================================================
--- 
incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DBDictionary.java
 (original)
+++ 
incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DBDictionary.java
 Thu Mar 22 13:26:18 2007
@@ -237,6 +237,7 @@
     public boolean useSetStringForClobs = false;
     public int maxEmbeddedBlobSize = -1;
     public int maxEmbeddedClobSize = -1;
+    public int inClauseLimit = -1;
     public int datePrecision = MILLI;
     public int characterColumnSize = 255;
     public String arrayTypeName = "ARRAY";

Modified: 
incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/OracleDictionary.java
URL: 
http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/OracleDictionary.java?view=diff&rev=521443&r1=521442&r2=521443
==============================================================================
--- 
incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/OracleDictionary.java
 (original)
+++ 
incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/OracleDictionary.java
 Thu Mar 22 13:26:18 2007
@@ -116,6 +116,7 @@
         maxConstraintNameLength = 30;
         maxEmbeddedBlobSize = 4000;
         maxEmbeddedClobSize = 4000;
+        inClauseLimit = 1000;
 
         supportsDeferredConstraints = true;
         supportsLockingWithDistinctClause = false;


Reply via email to