Index: jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/JackrabbitIndexSearcher.java
===================================================================
--- jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/JackrabbitIndexSearcher.java (revision 744293)
+++ jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/JackrabbitIndexSearcher.java (working copy)
@@ -16,14 +16,14 @@
*/
package org.apache.jackrabbit.core.query.lucene;
+import java.io.IOException;
+
+import org.apache.jackrabbit.core.SessionImpl;
+import org.apache.lucene.index.IndexReader;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.Sort;
-import org.apache.lucene.index.IndexReader;
-import org.apache.jackrabbit.core.SessionImpl;
-import java.io.IOException;
-
/**
* JackrabbitIndexSearcher implements an index searcher with
* jackrabbit specific optimizations.
@@ -75,6 +75,7 @@
*/
public QueryHits evaluate(Query query, Sort sort) throws IOException {
query = query.rewrite(reader);
+
QueryHits hits = null;
if (query instanceof JackrabbitQuery) {
hits = ((JackrabbitQuery) query).execute(this, session, sort);
Index: jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/ParentAxisQuery.java
===================================================================
--- jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/ParentAxisQuery.java (revision 744293)
+++ jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/ParentAxisQuery.java (working copy)
@@ -124,9 +124,16 @@
* @return 'ParentAxisQuery'.
*/
public String toString(String field) {
- return "ParentAxisQuery";
+ StringBuffer sb = new StringBuffer();
+ sb.append("ParentAxisQuery(");
+ sb.append(contextQuery);
+ sb.append(", ");
+ sb.append(nameTest);
+ sb.append(")");
+ return sb.toString();
}
+
//-----------------------< ParentAxisWeight >-------------------------------
/**
Index: jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/LuceneQueryBuilder.java
===================================================================
--- jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/LuceneQueryBuilder.java (revision 744293)
+++ jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/LuceneQueryBuilder.java (working copy)
@@ -494,12 +494,18 @@
NameQuery nameTest = null;
if (node.getNameTest() != null) {
+ if (node.getNameTest().equals(LocationStepQueryNode.PARENT_NAME)) {
+ andQuery.add(new ParentAxisQuery(context, null, indexFormatVersion, nsMappings), Occur.MUST);
+ return andQuery;
+ }
nameTest = new NameQuery(node.getNameTest(), indexFormatVersion, nsMappings);
}
if (node.getIncludeDescendants()) {
if (nameTest != null) {
- andQuery.add(new DescendantSelfAxisQuery(context, nameTest, false), Occur.MUST);
+ andQuery.add(nameTest, Occur.MUST);
+ return new DescendantSelfAxisQuery(context, andQuery, false);
+// andQuery.add(new DescendantSelfAxisQuery(context, nameTest, false), Occur.MUST);
} else {
// descendant-or-self with nametest=*
if (predicates.length > 0) {
@@ -863,12 +869,13 @@
+ node.getOperation());
}
}
-
+
if (relPath.getLength() > 1) {
// child axis in relation
Path.Element[] elements = relPath.getElements();
// elements.length - 1 = property name
// elements.length - 2 = last child axis name test
+ boolean selectParent = true;
for (int i = elements.length - 2; i >= 0; i--) {
Name name = null;
if (!elements[i].getName().equals(RelationQueryNode.STAR_NAME_TEST)) {
@@ -877,25 +884,55 @@
if (i == elements.length - 2) {
// join name test with property query if there is one
if (name != null) {
- Query nameTest = new NameQuery(name,
- indexFormatVersion, nsMappings);
- BooleanQuery and = new BooleanQuery();
- and.add(query, Occur.MUST);
- and.add(nameTest, Occur.MUST);
- query = and;
+ if (!name.equals(LocationStepQueryNode.PARENT_NAME)) {
+ Query nameTest = new NameQuery(name,
+ indexFormatVersion, nsMappings);
+ BooleanQuery and = new BooleanQuery();
+ and.add(query, Occur.MUST);
+ and.add(nameTest, Occur.MUST);
+
+ query = and;
+ } else {
+ // If we're searching the parent, we want to return the child axis,
+ // not the parent because this is part of the predicate. For instance,
+ // if the query is //child[../base], this part of the code is operating
+ // on the "../base" portion. So we want to return all the child nodes
+ // of "base", which will then be matched against the non predicate part.
+ query = new ChildAxisQuery(sharedItemMgr,
+ query,
+ null,
+ indexFormatVersion,
+ nsMappings);
+ selectParent = false;
+ }
} else {
// otherwise the query can be used as is
}
+ } else if (name.equals(LocationStepQueryNode.PARENT_NAME)) {
+ // We need to select the of the properties if we haven't already.
+ if (selectParent) {
+ query = new ParentAxisQuery(query, null,
+ indexFormatVersion, nsMappings);
+
+ selectParent = false;
+ }
+
+ // See the note above on searching parents
+ query = new ChildAxisQuery(sharedItemMgr,
+ query,
+ null,
+ indexFormatVersion,
+ nsMappings);
} else {
query = new ParentAxisQuery(query, name,
- indexFormatVersion, nsMappings);
+ indexFormatVersion, nsMappings);
}
}
- // finally select the parent of the selected nodes
- query = new ParentAxisQuery(query, null,
- indexFormatVersion, nsMappings);
+
+ if (selectParent) {
+ query = new ParentAxisQuery(query, null, indexFormatVersion, nsMappings);
+ }
}
-
return query;
}
Index: jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/query/LocationStepQueryNode.java
===================================================================
--- jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/query/LocationStepQueryNode.java (revision 744293)
+++ jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/query/LocationStepQueryNode.java (working copy)
@@ -47,6 +47,8 @@
*/
public static final Name EMPTY_NAME = NameFactoryImpl.getInstance().create("", "");
+ public static final Name PARENT_NAME = NameFactoryImpl.getInstance().create("internal", "__PARENT__");
+
/** Empty QueryNode array for us as return value */
private static final QueryNode[] EMPTY = new QueryNode[0];
Index: jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/query/xpath/XPathQueryBuilder.java
===================================================================
--- jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/query/xpath/XPathQueryBuilder.java (revision 744293)
+++ jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/query/xpath/XPathQueryBuilder.java (working copy)
@@ -545,7 +545,11 @@
}
break;
case JJTDOTDOT:
- exceptions.add(new InvalidQueryException("Parent axis is not supported"));
+ if (queryNode instanceof LocationStepQueryNode) {
+ ((LocationStepQueryNode) queryNode).setNameTest(LocationStepQueryNode.PARENT_NAME);
+ } else {
+ ((RelationQueryNode) queryNode).addPathElement(PATH_FACTORY.createElement(LocationStepQueryNode.PARENT_NAME));
+ }
break;
default:
// per default traverse