You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by ju...@apache.org on 2010/10/18 13:48:21 UTC

svn commit: r1023748 - /jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/join/QueryEngine.java

Author: jukka
Date: Mon Oct 18 11:48:21 2010
New Revision: 1023748

URL: http://svn.apache.org/viewvc?rev=1023748&view=rev
Log:
JCR-2715: Improved join query performance

Map single-selector queries to the more efficient SQL1 query engine.

Modified:
    jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/join/QueryEngine.java

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/join/QueryEngine.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/join/QueryEngine.java?rev=1023748&r1=1023747&r2=1023748&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/join/QueryEngine.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/join/QueryEngine.java Mon Oct 18 11:48:21 2010
@@ -26,7 +26,6 @@ import java.util.Collections;
 import java.util.Comparator;
 import java.util.HashMap;
 import java.util.HashSet;
-import java.util.Iterator;
 import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
@@ -35,6 +34,7 @@ import java.util.Set;
 import javax.jcr.Node;
 import javax.jcr.PathNotFoundException;
 import javax.jcr.Property;
+import javax.jcr.PropertyType;
 import javax.jcr.RangeIterator;
 import javax.jcr.RepositoryException;
 import javax.jcr.Session;
@@ -45,6 +45,8 @@ import javax.jcr.Workspace;
 import javax.jcr.nodetype.NodeType;
 import javax.jcr.nodetype.NodeTypeManager;
 import javax.jcr.nodetype.PropertyDefinition;
+import javax.jcr.query.Query;
+import javax.jcr.query.QueryManager;
 import javax.jcr.query.QueryResult;
 import javax.jcr.query.Row;
 import javax.jcr.query.RowIterator;
@@ -82,7 +84,6 @@ import javax.jcr.query.qom.Source;
 import javax.jcr.query.qom.UpperCase;
 
 import org.apache.jackrabbit.commons.JcrUtils;
-import org.apache.jackrabbit.commons.flat.TreeTraverser;
 import org.apache.jackrabbit.commons.iterator.FilteredRangeIterator;
 import org.apache.jackrabbit.commons.iterator.RangeIteratorAdapter;
 import org.apache.jackrabbit.commons.iterator.RowIteratorAdapter;
@@ -522,10 +523,72 @@ public class QueryEngine {
         return paths;
     }
 
+    private String toSqlConstraint(Constraint constraint)
+            throws RepositoryException {
+        if (constraint instanceof And) {
+            And and = (And) constraint;
+            String c1 = toSqlConstraint(and.getConstraint1());
+            String c2 = toSqlConstraint(and.getConstraint2());
+            return "(" + c1 + ") AND (" + c2 + ")";
+        } else if (constraint instanceof Or) {
+            Or or = (Or) constraint;
+            String c1 = toSqlConstraint(or.getConstraint1());
+            String c2 = toSqlConstraint(or.getConstraint2());
+            return "(" + c1 + ") OR (" + c2 + ")";
+        } else if (constraint instanceof Not) {
+            Not or = (Not) constraint;
+            return "NOT (" + toSqlConstraint(or.getConstraint()) + ")";
+        } else if (constraint instanceof Comparison) {
+            Comparison c = (Comparison) constraint;
+            String left = toSqlOperand(c.getOperand1());
+            String right = toSqlOperand(c.getOperand2());
+            if (c.getOperator().equals(JCR_OPERATOR_EQUAL_TO)) {
+                return left + " = " + right;
+            } else {
+                throw new RepositoryException("Unsupported comparison: " + c);
+            }
+        } else if (constraint instanceof ChildNode) {
+            ChildNode cn = (ChildNode) constraint;
+            return "jcr:path LIKE '" + cn.getParentPath() + "/%'";
+        } else  {
+            throw new RepositoryException("Unsupported constraint: " + constraint);
+        }
+    }
+
+    private String toSqlOperand(Operand operand) throws RepositoryException {
+        if (operand instanceof PropertyValue) {
+            PropertyValue pv = (PropertyValue) operand;
+            return pv.getPropertyName();
+        } else if (operand instanceof Literal) {
+            Literal literal = (Literal) operand;
+            Value value = literal.getLiteralValue();
+            int type = value.getType();
+            if (type == PropertyType.LONG || type == PropertyType.DOUBLE) {
+                return value.getString();
+            } else {
+                return "'" + value.getString() + "'";
+            }
+        } else {
+            throw new RepositoryException("Uknown operand type: " + operand);
+        }
+    }
+
     protected QueryResult execute(
             Column[] columns, Selector selector,
             Constraint constraint, Ordering[] orderings)
             throws RepositoryException {
+        StringBuilder builder = new StringBuilder();
+        builder.append("SELECT * FROM ");
+        builder.append(selector.getNodeTypeName());
+        if (constraint != null) {
+            builder.append(" WHERE ");
+            builder.append(toSqlConstraint(constraint));
+        }
+        System.out.println(builder.toString());
+
+        QueryManager manager = session.getWorkspace().getQueryManager();
+        Query query = manager.createQuery(builder.toString(), Query.SQL);
+
         Map<String, NodeType> selectorMap = getSelectorNames(selector);
         final String[] selectorNames =
             selectorMap.keySet().toArray(new String[selectorMap.size()]);
@@ -537,9 +600,9 @@ public class QueryEngine {
 
         final double[] scores = new double[] { 1.0 };
 
-        Iterator<Node> nodes =
-            TreeTraverser.nodeIterator(session.getRootNode());
-        RangeIterator rows = new RangeIteratorAdapter(nodes) {
+//        Iterator<Node> nodes =
+//            TreeTraverser.nodeIterator(session.getRootNode());
+        RangeIterator rows = new RangeIteratorAdapter(query.execute().getNodes()) {
             @Override
             public Object next() {
                 try {
@@ -558,10 +621,10 @@ public class QueryEngine {
             }
         };
 
-        RangeIterator filtered = new FilteredRangeIterator(
-                rows, getPredicate(selector, constraint));
+//        RangeIterator filtered = new FilteredRangeIterator(
+//                rows, getPredicate(selector, constraint));
         QueryResult result = new SimpleQueryResult(
-                columnNames, selectorNames, new RowIteratorAdapter(filtered));
+                columnNames, selectorNames, new RowIteratorAdapter(rows));
         return sort(result, orderings);
     }