You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by th...@apache.org on 2012/03/09 17:52:04 UTC
svn commit: r1298914 - in /jackrabbit/sandbox/jackrabbit-microkernel/src:
main/java/org/apache/jackrabbit/query/
main/java/org/apache/jackrabbit/query/qom/
main/java/org/apache/jackrabbit/query/qom/tree/
main/java/org/apache/jackrabbit/query/reader/ te...
Author: thomasm
Date: Fri Mar 9 16:52:03 2012
New Revision: 1298914
URL: http://svn.apache.org/viewvc?rev=1298914&view=rev
Log:
Query implementation (WIP) - outer joins, explain plan feature
Removed:
jackrabbit/sandbox/jackrabbit-microkernel/src/test/java/org/apache/jackrabbit/query/SQL2Test.java
Modified:
jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/query/ParserSQL2.java
jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/query/qom/QueryObjectModelImpl.java
jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/query/qom/tree/JoinImpl.java
jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/query/qom/tree/SelectorImpl.java
jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/query/qom/tree/SourceImpl.java
jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/query/reader/NodeReader.java
jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/query/reader/TraversingReader.java
jackrabbit/sandbox/jackrabbit-microkernel/src/test/java/org/apache/jackrabbit/query/QueryTest.java
jackrabbit/sandbox/jackrabbit-microkernel/src/test/resources/queryTest.txt
Modified: jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/query/ParserSQL2.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/query/ParserSQL2.java?rev=1298914&r1=1298913&r2=1298914&view=diff
==============================================================================
--- jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/query/ParserSQL2.java (original)
+++ jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/query/ParserSQL2.java Fri Mar 9 16:52:03 2012
@@ -104,6 +104,7 @@ public class ParserSQL2 {
expected = new ArrayList<String>();
bindVariables = new HashMap<String, BindVariableValue>();
read();
+ boolean explain = readIf("EXPLAIN");
read("SELECT");
ArrayList<ColumnOrWildcard> list = parseColumns();
read("FROM");
@@ -121,7 +122,9 @@ public class ParserSQL2 {
if (currentToken.length() > 0) {
throw getSyntaxError("<end>");
}
- return factory.createQuery(source, constraint, orderings, columnArray);
+ QueryObjectModelImpl q = factory.createQuery(source, constraint, orderings, columnArray);
+ q.setExplain(explain);
+ return q;
}
private Selector parseSelector() throws RepositoryException {
Modified: jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/query/qom/QueryObjectModelImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/query/qom/QueryObjectModelImpl.java?rev=1298914&r1=1298913&r2=1298914&view=diff
==============================================================================
--- jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/query/qom/QueryObjectModelImpl.java (original)
+++ jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/query/qom/QueryObjectModelImpl.java Fri Mar 9 16:52:03 2012
@@ -13,6 +13,7 @@
*/
package org.apache.jackrabbit.query.qom;
+import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import javax.jcr.Node;
@@ -60,6 +61,7 @@ public class QueryObjectModelImpl implem
private final OrderingImpl[] orderings;
private final ColumnImpl[] columns;
final HashMap<String, Value> bindVariableMap = new HashMap<String, Value>();
+ private boolean explain;
private long limit;
private long offset;
private boolean prepared;
@@ -273,10 +275,17 @@ public class QueryObjectModelImpl implem
return valueFactory;
}
+ public void setExplain(boolean explain) {
+ this.explain = explain;
+ };
+
public Iterator<String> executeQuery(String revisionId) {
prepare();
- ResultIterator result = new ResultIterator(revisionId);
- return result;
+ if (explain) {
+ return Arrays.asList(source.getPlan()).iterator();
+ } else {
+ return new ResultIterator(revisionId);
+ }
}
private void prepare() {
@@ -347,6 +356,6 @@ public class QueryObjectModelImpl implem
throw new UnsupportedOperationException();
}
- };
+ }
}
Modified: jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/query/qom/tree/JoinImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/query/qom/tree/JoinImpl.java?rev=1298914&r1=1298913&r2=1298914&view=diff
==============================================================================
--- jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/query/qom/tree/JoinImpl.java (original)
+++ jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/query/qom/tree/JoinImpl.java Fri Mar 9 16:52:03 2012
@@ -23,12 +23,13 @@ import org.apache.jackrabbit.query.qom.Q
*/
public class JoinImpl extends SourceImpl implements Join {
- private final SourceImpl left;
- private final SourceImpl right;
- private final JoinType joinType;
- private final JoinConditionImpl joinCondition;
+ private JoinType joinType;
+ private SourceImpl left;
+ private SourceImpl right;
+ private JoinConditionImpl joinCondition;
private boolean leftNeedExecute, rightNeedExecute;
private boolean leftNeedNext;
+ private boolean foundJoinedRow;
private boolean end;
private String revisionId;
@@ -61,6 +62,10 @@ public class JoinImpl extends SourceImpl
return v.visit(this);
}
+ public String getPlan() {
+ return left.getPlan() + " " + joinType.name() + " JOIN " + right.getPlan();
+ }
+
public String toString() {
return joinType.formatSql(left, right, joinCondition);
}
@@ -90,6 +95,13 @@ public class JoinImpl extends SourceImpl
left.setJoinCondition(joinCondition);
right.init(qom);
left.init(qom);
+ // TODO right outer join: verify whether converting
+ // to left outer join is always correct (given the current restrictions)
+ joinType = JoinType.LEFT;
+ // swap left and right
+ SourceImpl temp = left;
+ left = right;
+ right = temp;
break;
}
}
@@ -137,15 +149,22 @@ public class JoinImpl extends SourceImpl
}
if (rightNeedExecute) {
right.execute(revisionId);
+ foundJoinedRow = false;
rightNeedExecute = false;
}
if (!right.next()) {
leftNeedNext = true;
} else {
if (joinCondition.evaluate()) {
+ foundJoinedRow = true;
return true;
}
}
+ // for an outer join, if no matching result was found,
+ // one row returned (with all values set to null)
+ if (right.outerJoin && leftNeedNext && !foundJoinedRow) {
+ return true;
+ }
}
}
Modified: jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/query/qom/tree/SelectorImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/query/qom/tree/SelectorImpl.java?rev=1298914&r1=1298913&r2=1298914&view=diff
==============================================================================
--- jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/query/qom/tree/SelectorImpl.java (original)
+++ jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/query/qom/tree/SelectorImpl.java Fri Mar 9 16:52:03 2012
@@ -19,7 +19,13 @@
package org.apache.jackrabbit.query.qom.tree;
import javax.jcr.query.qom.Selector;
+import org.apache.jackrabbit.mk.api.MicroKernel;
+import org.apache.jackrabbit.mk.simple.NodeImpl;
import org.apache.jackrabbit.query.qom.QueryObjectModelImpl;
+import org.apache.jackrabbit.query.reader.Cursor;
+import org.apache.jackrabbit.query.reader.Filter;
+import org.apache.jackrabbit.query.reader.NodeReader;
+import org.apache.jackrabbit.query.reader.TraversingReader;
/**
* The implementation of the corresponding JCR interface.
@@ -27,6 +33,8 @@ import org.apache.jackrabbit.query.qom.Q
public class SelectorImpl extends SourceImpl implements Selector {
private final String nodeTypeName, selectorName;
+ protected NodeReader reader;
+ private Cursor cursor;
public SelectorImpl(String nodeTypeName, String selectorName) {
this.nodeTypeName = nodeTypeName;
@@ -51,6 +59,36 @@ public class SelectorImpl extends Source
return nodeTypeName + " AS " + getSelectorName();
}
+
+ public void prepare(MicroKernel mk) {
+ reader = new TraversingReader(mk);
+ }
+
+ @Override
+ public void execute(String revisionId) {
+ cursor = reader.query(getFilter(), revisionId);
+ }
+
+ public String getPlan() {
+ return nodeTypeName + " AS " + getSelectorName() + " /* " + reader.getPlan(getFilter()) + " */";
+ }
+
+ private Filter getFilter() {
+ return new Filter();
+ }
+
+ public boolean next() {
+ return cursor.next();
+ }
+
+ public String currentPath() {
+ return cursor.currentPath();
+ }
+
+ public NodeImpl currentNode() {
+ return cursor.currentNode();
+ }
+
@Override
public void init(QueryObjectModelImpl qom) {
// TODO Auto-generated method stub
Modified: jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/query/qom/tree/SourceImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/query/qom/tree/SourceImpl.java?rev=1298914&r1=1298913&r2=1298914&view=diff
==============================================================================
--- jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/query/qom/tree/SourceImpl.java (original)
+++ jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/query/qom/tree/SourceImpl.java Fri Mar 9 16:52:03 2012
@@ -22,10 +22,6 @@ import javax.jcr.query.qom.Source;
import org.apache.jackrabbit.mk.api.MicroKernel;
import org.apache.jackrabbit.mk.simple.NodeImpl;
import org.apache.jackrabbit.query.qom.QueryObjectModelImpl;
-import org.apache.jackrabbit.query.reader.Cursor;
-import org.apache.jackrabbit.query.reader.Filter;
-import org.apache.jackrabbit.query.reader.NodeReader;
-import org.apache.jackrabbit.query.reader.TraversingReader;
public abstract class SourceImpl extends QOMNode implements Source {
@@ -33,8 +29,6 @@ public abstract class SourceImpl extends
protected JoinConditionImpl joinCondition;
protected boolean join;
protected boolean outerJoin;
- private NodeReader reader;
- private Cursor cursor;
public void setQueryConstraint(ConstraintImpl queryConstraint) {
this.queryConstraint = queryConstraint;
@@ -52,24 +46,16 @@ public abstract class SourceImpl extends
public abstract SelectorImpl getSelector(String selectorName);
- public void prepare(MicroKernel mk) {
- reader = new TraversingReader(mk);
- }
+ public abstract String getPlan();
- public void execute(String revisionId) {
- cursor = reader.query(new Filter(), revisionId);
- }
+ public abstract void prepare(MicroKernel mk);
- public boolean next() {
- return cursor.next();
- }
+ public abstract void execute(String revisionId);
- public String currentPath() {
- return cursor.currentPath();
- }
+ public abstract boolean next();
- public NodeImpl currentNode() {
- return cursor.currentNode();
- }
+ public abstract String currentPath();
+
+ public abstract NodeImpl currentNode();
}
Modified: jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/query/reader/NodeReader.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/query/reader/NodeReader.java?rev=1298914&r1=1298913&r2=1298914&view=diff
==============================================================================
--- jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/query/reader/NodeReader.java (original)
+++ jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/query/reader/NodeReader.java Fri Mar 9 16:52:03 2012
@@ -42,4 +42,12 @@ public interface NodeReader {
*/
Cursor query(Filter filter, String revisionId);
+ /**
+ * Get the query plan for the given reader.
+ *
+ * @param filter the filter
+ * @return the query plan
+ */
+ String getPlan(Filter filter);
+
}
Modified: jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/query/reader/TraversingReader.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/query/reader/TraversingReader.java?rev=1298914&r1=1298913&r2=1298914&view=diff
==============================================================================
--- jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/query/reader/TraversingReader.java (original)
+++ jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/query/reader/TraversingReader.java Fri Mar 9 16:52:03 2012
@@ -53,4 +53,8 @@ public class TraversingReader implements
return nodeCount;
}
+ public String getPlan(Filter filter) {
+ return "traverse \"" + filter.getPath() + "\"";
+ }
+
}
Modified: jackrabbit/sandbox/jackrabbit-microkernel/src/test/java/org/apache/jackrabbit/query/QueryTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/jackrabbit-microkernel/src/test/java/org/apache/jackrabbit/query/QueryTest.java?rev=1298914&r1=1298913&r2=1298914&view=diff
==============================================================================
--- jackrabbit/sandbox/jackrabbit-microkernel/src/test/java/org/apache/jackrabbit/query/QueryTest.java (original)
+++ jackrabbit/sandbox/jackrabbit-microkernel/src/test/java/org/apache/jackrabbit/query/QueryTest.java Fri Mar 9 16:52:03 2012
@@ -84,7 +84,7 @@ public class QueryTest {
if (!line.equals(got)) {
errors = true;
}
- } else if (line.startsWith("select")) {
+ } else if (line.startsWith("select") || line.startsWith("explain")) {
w.println(line);
Iterator<String> result = qe.executeQuery(line, null);
boolean readEnd = true;
Modified: jackrabbit/sandbox/jackrabbit-microkernel/src/test/resources/queryTest.txt
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/jackrabbit-microkernel/src/test/resources/queryTest.txt?rev=1298914&r1=1298913&r2=1298914&view=diff
==============================================================================
--- jackrabbit/sandbox/jackrabbit-microkernel/src/test/resources/queryTest.txt (original)
+++ jackrabbit/sandbox/jackrabbit-microkernel/src/test/resources/queryTest.txt Fri Mar 9 16:52:03 2012
@@ -1,6 +1,7 @@
# Syntax:
# * lines starting with "#" are remarks.
# * lines starting with "select" are queries, followed by expected results and an empty line
+# * lines starting with "explain" are followed by expected query plan and an empty line
# * all other lines are are committed into the microkernel (line by line)
# * new tests are typically be added on top, after the syntax docs
# * use ascii character only
@@ -8,11 +9,34 @@
+ "parents": { "p0": {"id": "0"}, "p1": {"id": "1"}, "p2": {"id": "2"}}
+ "children": { "c1": {"p": "1"}, "c2": {"p": "1"}, "c3": {"p": "2"}, "c4": {"p": "3"}}
+select * from [nt:base] as c right outer join [nt:base] as p on p.id = c.p where p.id is not null
+/parents/p0
+/parents/p1
+/parents/p1
+/parents/p2
+
+select * from [nt:base] as p left outer join [nt:base] as c on p.id = c.p where p.id is not null
+/parents/p0
+/parents/p1
+/parents/p1
+/parents/p2
+
+select * from [nt:base] as p left outer join [nt:base] as c on p.id = c.p where p.id is not null and c.p is null
+/parents/p0
+
+select * from [nt:base] as p left outer join [nt:base] as c on p.id = c.p where p.id is not null and c.p is not null
+/parents/p1
+/parents/p1
+/parents/p2
+
select * from [nt:base] as p inner join [nt:base] as c on p.id = c.p
/parents/p1
/parents/p1
/parents/p2
+explain select * from [nt:base] as p inner join [nt:base] as c on p.id = c.p
+nt:base AS p /* traverse "/" */ INNER JOIN nt:base AS c /* traverse "/" */
+
- "parents"
- "children"