You are viewing a plain text version of this content. The canonical link for it is here.
Posted to oak-commits@jackrabbit.apache.org by th...@apache.org on 2017/06/19 14:50:26 UTC

svn commit: r1799219 - in /jackrabbit/oak/trunk/oak-core/src: main/java/org/apache/jackrabbit/oak/query/xpath/Statement.java test/java/org/apache/jackrabbit/oak/query/XPathTest.java

Author: thomasm
Date: Mon Jun 19 14:50:26 2017
New Revision: 1799219

URL: http://svn.apache.org/viewvc?rev=1799219&view=rev
Log:
OAK-6359 Change behavior for very complex queries

Modified:
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/xpath/Statement.java
    jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/XPathTest.java

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/xpath/Statement.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/xpath/Statement.java?rev=1799219&r1=1799218&r2=1799219&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/xpath/Statement.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/xpath/Statement.java Mon Jun 19 14:50:26 2017
@@ -29,6 +29,10 @@ import org.apache.jackrabbit.oak.spi.que
  * An xpath statement.
  */
 public class Statement {
+    
+    private static final UnsupportedOperationException TOO_MANY_UNION = 
+            new UnsupportedOperationException("Too many union queries");
+    private final static int MAX_UNION = Integer.getInteger("oak.xpathMaxUnion", 1000);
 
     boolean explain;
     boolean measure;
@@ -62,7 +66,12 @@ public class Statement {
         where = where.optimize();
         optimizeSelectorNodeTypes();
         ArrayList<Expression> unionList = new ArrayList<Expression>();
-        addToUnionList(where, unionList);
+        try {
+            addToUnionList(where, unionList);
+        } catch (UnsupportedOperationException e) {
+            // too many union
+            return this;
+        }
         if (unionList.size() == 1) {
             return this;
         }
@@ -141,6 +150,9 @@ public class Statement {
                 return;
             }
         }
+        if (unionList.size() > MAX_UNION) {
+            throw TOO_MANY_UNION;
+        }
         unionList.add(condition);
     }
     
@@ -304,7 +316,12 @@ public class Statement {
             if (measure) {
                 buff.append("measure ");
             }
-            buff.append(s1).append(" union ").append(s2);
+            try {
+                buff.append(s1).append(" union ").append(s2);
+            } catch (OutOfMemoryError | StackOverflowError e) {
+System.out.println("OOME");                
+                throw e;
+            }
             // order by ...
             if (orderList != null && !orderList.isEmpty()) {
                 buff.append(" order by ");

Modified: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/XPathTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/XPathTest.java?rev=1799219&r1=1799218&r2=1799219&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/XPathTest.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/XPathTest.java Mon Jun 19 14:50:26 2017
@@ -18,6 +18,7 @@ package org.apache.jackrabbit.oak.query;
 
 import static org.apache.jackrabbit.oak.InitialContent.INITIAL_CONTENT;
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
 import java.text.ParseException;
@@ -36,6 +37,37 @@ public class XPathTest {
             new NodeStateNodeTypeInfoProvider(INITIAL_CONTENT);
     
     @Test
+    public void complexQuery() throws ParseException {
+        for(int n = 1; n < 15; n++) {
+            for(int m = 1; m < 15; m++) {
+                complexQuery(n, m);
+            }            
+        }
+    }
+    
+    private void complexQuery(int n, int m) throws ParseException {
+        StringBuilder buff = new StringBuilder();
+        buff.append("/jcr:root//*[");
+        for (int i = 0; i < n; i++) {
+            if (i > 0) {
+                buff.append("and ");
+            }
+            buff.append("(");
+            for (int j = 0; j < m; j++) {
+                if (j > 0) {
+                    buff.append("or ");
+                }
+                buff.append("@x" + j + " = " + j);
+            }
+            buff.append(")\n");
+        }
+        buff.append("]");
+        String xpath = buff.toString();
+        String sql2 = new XPathToSQL2Converter().convert(xpath);
+        assertTrue("Length: " + sql2.length(), sql2.length() < 200000);
+    }
+    
+    @Test
     public void queryOptions() throws ParseException {
         verify("(/jcr:root/a//* | /jcr:root/b//*) order by @jcr:score", 
                 "select [jcr:path], [jcr:score], * " +