Index: modeshape-graph/src/main/java/org/modeshape/graph/query/parse/SqlQueryParser.java =================================================================== --- modeshape-graph/src/main/java/org/modeshape/graph/query/parse/SqlQueryParser.java (revision 2226) +++ modeshape-graph/src/main/java/org/modeshape/graph/query/parse/SqlQueryParser.java (working copy) @@ -934,11 +934,15 @@ public class SqlQueryParser implements QueryParser { if (tokens.matches("SELECT")) { // This is a subquery. This object is stateless, so we can reuse this object ... QueryCommand subqueryExpression = parseQueryCommand(tokens, typeSystem); - return new Subquery(subqueryExpression); + return subquery(subqueryExpression); } return parseLiteral(tokens, typeSystem); } + protected Subquery subquery( QueryCommand queryCommand ) { + return new Subquery(queryCommand); + } + protected Literal parseLiteral( TokenStream tokens, TypeSystem typeSystem ) { if (tokens.canConsume("CAST", "(")) { Index: modeshape-jcr-api/src/main/java/org/modeshape/jcr/api/query/qom/QueryObjectModelFactory.java =================================================================== --- modeshape-jcr-api/src/main/java/org/modeshape/jcr/api/query/qom/QueryObjectModelFactory.java (revision 2226) +++ modeshape-jcr-api/src/main/java/org/modeshape/jcr/api/query/qom/QueryObjectModelFactory.java (working copy) @@ -206,6 +206,17 @@ public interface QueryObjectModelFactory extends javax.jcr.query.qom.QueryObject StaticOperand... values ) throws InvalidQueryException, RepositoryException; /** + * Creates a subquery that can be used as a {@link StaticOperand} in another query. + * + * @param subqueryCommand the query command that is to be used as the subquery + * @return the constraint; non-null + * @throws InvalidQueryException if a particular validity test is possible on this method, the implemention chooses to perform + * that test (and not leave it until later, on {@link #createQuery}), and the parameters given fail that test + * @throws RepositoryException if the operation otherwise fails + */ + public Subquery subquery( QueryCommand subqueryCommand ) throws InvalidQueryException, RepositoryException; + + /** * Create an arithmetic dynamic operand that adds the numeric value of the two supplied operand(s). * * @param left the left-hand-side operand; not null Index: modeshape-jcr-api/src/main/java/org/modeshape/jcr/api/query/qom/Subquery.java new file mode 100644 =================================================================== --- /dev/null (revision 2226) +++ modeshape-jcr-api/src/main/java/org/modeshape/jcr/api/query/qom/Subquery.java (working copy) @@ -0,0 +1,38 @@ +/* + * ModeShape (http://www.modeshape.org) + * See the COPYRIGHT.txt file distributed with this work for information + * regarding copyright ownership. Some portions may be licensed + * to Red Hat, Inc. under one or more contributor license agreements. + * See the AUTHORS.txt file in the distribution for a full listing of + * individual contributors. + * + * ModeShape is free software. Unless otherwise indicated, all code in ModeShape + * is licensed to you under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * ModeShape is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.modeshape.jcr.api.query.qom; + +import javax.jcr.query.qom.StaticOperand; + +/** + * Represents a non-correlated subquery used as a {@link StaticOperand}. + */ +public interface Subquery extends StaticOperand { + /** + * Gets the {@link QueryCommand} that makes up the subqery. + * + * @return the query command; non-null + */ + public QueryCommand getQuery(); +} Index: modeshape-jcr/src/main/java/org/modeshape/jcr/query/JcrSql2QueryParser.java =================================================================== --- modeshape-jcr/src/main/java/org/modeshape/jcr/query/JcrSql2QueryParser.java (revision 2226) +++ modeshape-jcr/src/main/java/org/modeshape/jcr/query/JcrSql2QueryParser.java (working copy) @@ -56,6 +56,7 @@ import org.modeshape.graph.query.model.SetCriteria; import org.modeshape.graph.query.model.SetQuery; import org.modeshape.graph.query.model.Source; import org.modeshape.graph.query.model.StaticOperand; +import org.modeshape.graph.query.model.Subquery; import org.modeshape.graph.query.model.TypeSystem; import org.modeshape.graph.query.model.FullTextSearch.Term; import org.modeshape.graph.query.model.SetQuery.Operation; @@ -100,6 +101,7 @@ import org.modeshape.jcr.query.qom.JcrSetCriteria; import org.modeshape.jcr.query.qom.JcrSetQuery; import org.modeshape.jcr.query.qom.JcrSource; import org.modeshape.jcr.query.qom.JcrStaticOperand; +import org.modeshape.jcr.query.qom.JcrSubquery; import org.modeshape.jcr.query.qom.JcrUpperCase; /** @@ -582,6 +584,16 @@ public class JcrSql2QueryParser extends SqlQueryParser { /** * {@inheritDoc} * + * @see org.modeshape.graph.query.parse.SqlQueryParser#subquery(org.modeshape.graph.query.model.QueryCommand) + */ + @Override + protected Subquery subquery( QueryCommand queryCommand ) { + return new JcrSubquery((JcrQueryCommand)queryCommand); + } + + /** + * {@inheritDoc} + * * @see org.modeshape.graph.query.parse.SqlQueryParser#literal(TypeSystem, Object) */ @Override Index: modeshape-jcr/src/main/java/org/modeshape/jcr/query/qom/JcrQueryObjectModelFactory.java =================================================================== --- modeshape-jcr/src/main/java/org/modeshape/jcr/query/qom/JcrQueryObjectModelFactory.java (revision 2226) +++ modeshape-jcr/src/main/java/org/modeshape/jcr/query/qom/JcrQueryObjectModelFactory.java (working copy) @@ -76,6 +76,7 @@ import org.modeshape.jcr.api.query.qom.QueryCommand; import org.modeshape.jcr.api.query.qom.QueryObjectModelConstants; import org.modeshape.jcr.api.query.qom.SetCriteria; import org.modeshape.jcr.api.query.qom.SetQuery; +import org.modeshape.jcr.api.query.qom.Subquery; import org.modeshape.jcr.query.JcrQueryContext; /** @@ -664,6 +665,17 @@ public class JcrQueryObjectModelFactory /** * {@inheritDoc} * + * @see org.modeshape.jcr.api.query.qom.QueryObjectModelFactory#subquery(org.modeshape.jcr.api.query.qom.QueryCommand) + */ + @Override + public Subquery subquery( QueryCommand subqueryCommand ) { + JcrQueryCommand jcrCommand = CheckArg.getInstanceOf(subqueryCommand, JcrQueryCommand.class, "subqueryCommand"); + return new JcrSubquery(jcrCommand); + } + + /** + * {@inheritDoc} + * * @see org.modeshape.jcr.api.query.qom.QueryObjectModelFactory#add(javax.jcr.query.qom.DynamicOperand, * javax.jcr.query.qom.DynamicOperand) */ Index: modeshape-jcr/src/main/java/org/modeshape/jcr/query/qom/JcrSubquery.java new file mode 100644 =================================================================== --- /dev/null (revision 2226) +++ modeshape-jcr/src/main/java/org/modeshape/jcr/query/qom/JcrSubquery.java (working copy) @@ -0,0 +1,52 @@ +/* + * ModeShape (http://www.modeshape.org) + * See the COPYRIGHT.txt file distributed with this work for information + * regarding copyright ownership. Some portions may be licensed + * to Red Hat, Inc. under one or more contributor license agreements. + * See the AUTHORS.txt file in the distribution for a full listing of + * individual contributors. + * + * ModeShape is free software. Unless otherwise indicated, all code in ModeShape + * is licensed to you under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * ModeShape is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.modeshape.jcr.query.qom; + +import org.modeshape.graph.query.model.Subquery; +import org.modeshape.jcr.api.query.qom.QueryCommand; + +/** + * Implementation of the subquery static operand for the JCR Query Object Model and the Graph API. + */ +public class JcrSubquery extends Subquery implements JcrStaticOperand, org.modeshape.jcr.api.query.qom.Subquery { + + private static final long serialVersionUID = 1L; + + /** + * @param subqueryCommand + */ + public JcrSubquery( JcrQueryCommand subqueryCommand ) { + super(subqueryCommand); + } + + /** + * {@inheritDoc} + * + * @see org.modeshape.jcr.api.query.qom.Subquery#getQuery() + */ + @Override + public QueryCommand getQuery() { + return (JcrQueryCommand)query(); + } +}