You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cayenne.apache.org by an...@apache.org on 2009/09/10 17:43:49 UTC

svn commit: r813477 - in /cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src: main/java/org/apache/cayenne/dba/oracle/ test/java/org/apache/cayenne/exp/

Author: andrey
Date: Thu Sep 10 15:43:48 2009
New Revision: 813477

URL: http://svn.apache.org/viewvc?rev=813477&view=rev
Log:
CAY-1263 Cayenne
Oracle adapter should automatically strip IN clauses with more than 1000 elements

Added:
    cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/dba/oracle/OracleQualifierTranslator.java
Modified:
    cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/dba/oracle/OracleAdapter.java
    cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/exp/ExpressionFactoryTest.java

Modified: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/dba/oracle/OracleAdapter.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/dba/oracle/OracleAdapter.java?rev=813477&r1=813476&r2=813477&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/dba/oracle/OracleAdapter.java (original)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/dba/oracle/OracleAdapter.java Thu Sep 10 15:43:48 2009
@@ -35,7 +35,6 @@
 import org.apache.cayenne.access.jdbc.EJBQLTranslatorFactory;
 import org.apache.cayenne.access.trans.QualifierTranslator;
 import org.apache.cayenne.access.trans.QueryAssembler;
-import org.apache.cayenne.access.trans.TrimmingQualifierTranslator;
 import org.apache.cayenne.access.types.ByteArrayType;
 import org.apache.cayenne.access.types.ByteType;
 import org.apache.cayenne.access.types.CharType;
@@ -43,9 +42,9 @@
 import org.apache.cayenne.access.types.ExtendedType;
 import org.apache.cayenne.access.types.ExtendedTypeMap;
 import org.apache.cayenne.access.types.ShortType;
-import org.apache.cayenne.dba.QuotingStrategy;
 import org.apache.cayenne.dba.JdbcAdapter;
 import org.apache.cayenne.dba.PkGenerator;
+import org.apache.cayenne.dba.QuotingStrategy;
 import org.apache.cayenne.map.DbAttribute;
 import org.apache.cayenne.map.DbEntity;
 import org.apache.cayenne.merge.MergerFactory;
@@ -117,6 +116,7 @@
     /**
      * @deprecated since 3.0, as a generic BLOB method is used to write BLOBs.
      */
+    @Deprecated
     public static Method getOutputStreamFromBlobMethod() {
         return outputStreamFromBlobMethod;
     }
@@ -157,6 +157,7 @@
     /**
      * @deprecated since 3.0, as a generic CLOB method is used to write CLOBs.
      */
+    @Deprecated
     public static Method getWriterFromClobMethod() {
         return writerFromClobMethod;
     }
@@ -322,9 +323,7 @@
      */
     @Override
     public QualifierTranslator getQualifierTranslator(QueryAssembler queryAssembler) {
-        return new TrimmingQualifierTranslator(
-                queryAssembler,
-                OracleAdapter.TRIM_FUNCTION);
+        return new OracleQualifierTranslator(queryAssembler);
     }
 
     /**
@@ -402,6 +401,7 @@
         /**
          * @deprecated since 3.0 as validation should not be done at the DataNode level.
          */
+        @Deprecated
         public boolean validateProperty(
                 Object source,
                 String property,

Added: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/dba/oracle/OracleQualifierTranslator.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/dba/oracle/OracleQualifierTranslator.java?rev=813477&view=auto
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/dba/oracle/OracleQualifierTranslator.java (added)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/dba/oracle/OracleQualifierTranslator.java Thu Sep 10 15:43:48 2009
@@ -0,0 +1,93 @@
+/*****************************************************************
+ *   Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ ****************************************************************/
+package org.apache.cayenne.dba.oracle;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.cayenne.access.trans.QueryAssembler;
+import org.apache.cayenne.access.trans.TrimmingQualifierTranslator;
+import org.apache.cayenne.exp.Expression;
+import org.apache.cayenne.exp.parser.ASTIn;
+import org.apache.cayenne.exp.parser.ASTList;
+import org.apache.cayenne.exp.parser.ASTPath;
+import org.apache.commons.collections.Transformer;
+
+/**
+ * Oracle qualifier translator. In particular, trims INs with more than 1000 elements 
+ * to an OR-set of INs with <= 1000 elements 
+ */
+public class OracleQualifierTranslator extends TrimmingQualifierTranslator {
+
+    public OracleQualifierTranslator(QueryAssembler queryAssembler) {
+        super(queryAssembler, OracleAdapter.TRIM_FUNCTION);
+    }
+
+    @Override
+    protected void doAppendPart(Expression rootNode) throws IOException {
+        if (rootNode == null) {
+            return;
+        }
+        
+        //trimming INs
+        rootNode = rootNode.transform(new INTrimmer());
+        
+        rootNode.traverse(this);
+    }
+    
+    public static class INTrimmer implements Transformer {
+        public Expression trimmedInExpression(Expression exp, int maxInSize) {
+            Expression list = (Expression) exp.getOperand(1);
+            Object[] objects = (Object[]) list.evaluate(null);
+            
+            if (objects.length <= maxInSize) {
+                return exp;
+            }
+            
+            return trimmedInExpression((ASTPath) exp.getOperand(0), objects, maxInSize);
+        }
+        
+        Expression trimmedInExpression(ASTPath path, Object[] values, int maxInSize) {
+            Expression res = null;
+            
+            List<Object> in = new ArrayList<Object>(maxInSize);
+            for (Object v : values) {
+                in.add(v);
+                if (in.size() == maxInSize) {
+                    Expression inExp = new ASTIn(path, new ASTList(in));
+                    res = res != null ? res.orExp(inExp) : inExp;
+                    in = new ArrayList<Object>(maxInSize);
+                }
+            }
+            if (in.size() > 0) {
+                Expression inExp = new ASTIn(path, new ASTList(in));
+                res = res != null ? res.orExp(inExp) : inExp;
+            }
+            return res;
+        }
+
+        public Object transform(Object input) {
+            if (input instanceof Expression && ((Expression) input).getType() == Expression.IN) {
+                return trimmedInExpression((Expression) input, 1000);
+            }
+            return input;
+        }
+    }
+}

Modified: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/exp/ExpressionFactoryTest.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/exp/ExpressionFactoryTest.java?rev=813477&r1=813476&r2=813477&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/exp/ExpressionFactoryTest.java (original)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/exp/ExpressionFactoryTest.java Thu Sep 10 15:43:48 2009
@@ -296,4 +296,18 @@
         Expression in = ExpressionFactory.inExp("paintingArray", p1);
         assertTrue(in.match(a1));
     }
+    
+    /**
+     * Tests INs with more than 1000 elements
+     */
+    public void testLongIn() {
+        //not all adapters strip INs, so we just make sure query with such qualifier fires OK
+        Object[] numbers = new String[2009];
+        for (int i = 0; i < numbers.length; i++) {
+            numbers[i] = "" + i;
+        }
+        
+        SelectQuery query = new SelectQuery(Artist.class, ExpressionFactory.inExp("artistName", numbers));
+        createDataContext().performQuery(query);
+    }
 }