Index: src/java/org/apache/jdo/tck/query/QueryTest.java =================================================================== --- src/java/org/apache/jdo/tck/query/QueryTest.java (Revision 608608) +++ src/java/org/apache/jdo/tck/query/QueryTest.java (Arbeitskopie) @@ -137,6 +137,14 @@ } // Company model and mylib helper methods + + /** + * Returns the name of the company test data resource. + * @return name of the company test data resource. + */ + protected String getCompanyTestDataResource() { + return COMPANY_TESTDATA; + } /** * Initializes and returns the company model reader @@ -147,7 +155,7 @@ getCompanyModelReaderForPersistentInstances() { if (companyModelReaderForPersistentInstances == null) { companyModelReaderForPersistentInstances = - new CompanyModelReader(COMPANY_TESTDATA); + new CompanyModelReader(getCompanyTestDataResource()); } return companyModelReaderForPersistentInstances; } @@ -161,7 +169,7 @@ getCompanyModelReaderForTransientInstances() { if (companyModelReaderForTransientInstances == null) { companyModelReaderForTransientInstances = - new CompanyModelReader(COMPANY_TESTDATA); + new CompanyModelReader(getCompanyTestDataResource()); } return companyModelReaderForTransientInstances; } @@ -223,6 +231,7 @@ Transaction tx = pm.currentTransaction(); tx.begin(); try { + if (debug) logger.debug("insert " + pcInstances); pm.makePersistentAll(pcInstances); if (debug) logger.debug("inserted " + pcInstances); tx.commit(); Index: src/java/org/apache/jdo/tck/query/jdoql/subqueries/NullCandidateCollectionExpression.java =================================================================== --- src/java/org/apache/jdo/tck/query/jdoql/subqueries/NullCandidateCollectionExpression.java (Revision 0) +++ src/java/org/apache/jdo/tck/query/jdoql/subqueries/NullCandidateCollectionExpression.java (Revision 0) @@ -0,0 +1,99 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.jdo.tck.query.jdoql.subqueries; + +import java.util.List; + +import javax.jdo.PersistenceManager; +import javax.jdo.Query; +import javax.jdo.Transaction; + +import org.apache.jdo.tck.JDO_Test; +import org.apache.jdo.tck.pc.company.CompanyModelReader; +import org.apache.jdo.tck.pc.company.Employee; +import org.apache.jdo.tck.query.QueryTest; +import org.apache.jdo.tck.util.BatchTestRunner; + +/** + *Title: Null Candidate Collection Expression in addSubquery + *
+ *Keywords: query + *
+ *Assertion ID: A14.6.2-53. + *
+ *Assertion Description: + * The candidateCollectionExpression is the expression from the outer query that + * represents the candidates over which the subquery is evaluated. If the + * trimmed value is the empty String, or the parameter is null, then the + * candidate collection is the extent of the candidate class. + */ +public class NullCandidateCollectionExpression extends SubqueriesTest { + + /** */ + private static final String ASSERTION_FAILED = + "Assertion A14.6.2-53 (NullCandidateCollectionExpression) failed: "; + + /** + * The main is called when the class + * is directly executed from the command line. + * @param args The arguments passed to the program. + */ + public static void main(String[] args) { + BatchTestRunner.run(NullCandidateCollectionExpression.class); + } + + /** */ + public void testPositive() throws Exception { + PersistenceManager pm = getPM(); + + List expectedResult = getTransientCompanyModelInstancesAsList( + new String[]{"emp1","emp2","emp4","emp5","emp6","emp7","emp10"}); + + // select employees who work more than the average of all employees + String singleStringJDOQL = + "SELECT FROM Employee WHERE this.weeklyhours > " + + "(SELECT AVG(e.weeklyhours) FROM Employee e)"; + + // API query + Query sub = pm.newQuery(Employee.class); + sub.setResult("avg(this.weeklyhours)"); + Query apiQuery = pm.newQuery(Employee.class); + apiQuery.setFilter("this.weeklyhours > averageWeeklyhours"); + // null candidate collection + apiQuery.addSubquery(sub, "double averageWeeklyhours", null); + executeJDOQuery(ASSERTION_FAILED, apiQuery, singleStringJDOQL, + false, null, expectedResult, true); + + apiQuery = pm.newQuery(Employee.class); + apiQuery.setFilter("this.weeklyhours > averageWeeklyhours"); + // empty candidate collection + apiQuery.addSubquery(sub, "double averageWeeklyhours", " "); + executeJDOQuery(ASSERTION_FAILED, apiQuery, singleStringJDOQL, + false, null, expectedResult, true); + + } + + /** + * @see JDO_Test#localSetUp() + */ + protected void localSetUp() { + addTearDownClass(CompanyModelReader.getTearDownClasses()); + loadAndPersistCompanyModel(getPM()); + } + +} Index: src/java/org/apache/jdo/tck/query/jdoql/subqueries/MultipleCallsReplaceSubquery.java =================================================================== --- src/java/org/apache/jdo/tck/query/jdoql/subqueries/MultipleCallsReplaceSubquery.java (Revision 0) +++ src/java/org/apache/jdo/tck/query/jdoql/subqueries/MultipleCallsReplaceSubquery.java (Revision 0) @@ -0,0 +1,96 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.jdo.tck.query.jdoql.subqueries; + +import java.util.List; + +import javax.jdo.PersistenceManager; +import javax.jdo.Query; +import javax.jdo.Transaction; + +import org.apache.jdo.tck.JDO_Test; +import org.apache.jdo.tck.pc.company.CompanyModelReader; +import org.apache.jdo.tck.pc.company.Employee; +import org.apache.jdo.tck.query.QueryTest; +import org.apache.jdo.tck.util.BatchTestRunner; + +/** + *Title: Multiple Calls of addSubquery Replaces Previous Instance + *
+ *Keywords: query + *
+ *Assertion ID: A14.6.2-51. + *
+ *Assertion Description: + * If the same value of variableDeclaration is used to add multiple subqueries, + * the subquery replaces the previous subquery for the same named variable. + */ +public class MultipleCallsReplaceSubquery extends SubqueriesTest { + + /** */ + private static final String ASSERTION_FAILED = + "Assertion A14.6.2-51 (MultipleCallsReplaceSubquery) failed: "; + + /** + * The main is called when the class + * is directly executed from the command line. + * @param args The arguments passed to the program. + */ + public static void main(String[] args) { + BatchTestRunner.run(MultipleCallsReplaceSubquery.class); + } + + /** */ + public void testPositive() throws Exception { + PersistenceManager pm = getPM(); + List expectedResult = getTransientCompanyModelInstancesAsList( + new String[]{"emp1","emp2","emp4","emp5","emp6","emp7","emp10"}); + + // select employees who work more than the average of all employees + String singleStringJDOQL = + "SELECT FROM Employee WHERE this.weeklyhours > " + + "(SELECT AVG(e.weeklyhours) FROM Employee e)"; + + // API query + // Query returning the weeklyhours of employee with id 1 + Query tmp = pm.newQuery(Employee.class); + tmp.setResult("this.weeklyhours"); + tmp.setFilter("this.id == 1"); + // Query returning the avg of weeklyhours of all employees + Query sub = pm.newQuery(Employee.class); + sub.setResult("avg(this.weeklyhours)"); + Query apiQuery = pm.newQuery(Employee.class); + apiQuery.setFilter("this.weeklyhours> averageWeeklyhours"); + apiQuery.addSubquery(tmp, "double averageWeeklyhours", null); + // second call of addSubquery using the same variable + // should replace the previous setting, so apiQuery should + // represent the query of singleStringJDOQL + apiQuery.addSubquery(sub, "double averageWeeklyhours", null); + executeJDOQuery(ASSERTION_FAILED, apiQuery, singleStringJDOQL, + false, null, expectedResult, true); + } + + /** + * @see JDO_Test#localSetUp() + */ + protected void localSetUp() { + addTearDownClass(CompanyModelReader.getTearDownClasses()); + loadAndPersistCompanyModel(getPM()); + } + +} Index: src/java/org/apache/jdo/tck/query/jdoql/subqueries/NullVariableDeclaration.java =================================================================== --- src/java/org/apache/jdo/tck/query/jdoql/subqueries/NullVariableDeclaration.java (Revision 0) +++ src/java/org/apache/jdo/tck/query/jdoql/subqueries/NullVariableDeclaration.java (Revision 0) @@ -0,0 +1,92 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.jdo.tck.query.jdoql.subqueries; + +import java.util.List; + +import javax.jdo.JDOException; +import javax.jdo.PersistenceManager; +import javax.jdo.Query; +import javax.jdo.Transaction; + +import org.apache.jdo.tck.JDO_Test; +import org.apache.jdo.tck.pc.company.CompanyModelReader; +import org.apache.jdo.tck.pc.company.Employee; +import org.apache.jdo.tck.query.QueryTest; +import org.apache.jdo.tck.util.BatchTestRunner; + +/** + *Title: Null Variable Declaration in addSubquery + *
+ *Keywords: query + *
+ *Assertion ID: A14.6.2-53. + *
+ *Assertion Description: + * If the trimmed value is the empty String, or the parameter is null, + * then JDOUserException is thrown. + */ +public class NullVariableDeclaration extends SubqueriesTest { + + /** */ + private static final String ASSERTION_FAILED = + "Assertion A14.6.2-53 (NullVariableDeclaration) failed: "; + + /** + * The main is called when the class + * is directly executed from the command line. + * @param args The arguments passed to the program. + */ + public static void main(String[] args) { + BatchTestRunner.run(NullVariableDeclaration.class); + } + + /** */ + public void testNegative() throws Exception { + PersistenceManager pm = getPM(); + runTestNullVariable(pm); + runTestEmptyVariable(pm); + } + + /** */ + void runTestNullVariable(PersistenceManager pm) { + Query apiQuery = pm.newQuery(Employee.class); + try { + apiQuery.addSubquery(null, null, null); + apiQuery.compile(); + fail(ASSERTION_FAILED, + "addSubquery called with a null varible declaration must throw a JDOUserException."); + } catch (JDOException ex) { + // expected JDOException + } + } + + /** */ + void runTestEmptyVariable(PersistenceManager pm) { + Query apiQuery = pm.newQuery(Employee.class); + try { + apiQuery.addSubquery(null, " ", null); + apiQuery.compile(); + fail(ASSERTION_FAILED, + "addSubquery called with an empty varible declaration must throw a JDOUserException."); + } catch (JDOException ex) { + // expected JDOException + } + } + +} Index: src/java/org/apache/jdo/tck/query/jdoql/subqueries/NonCorrelatedSubqueries.java =================================================================== --- src/java/org/apache/jdo/tck/query/jdoql/subqueries/NonCorrelatedSubqueries.java (Revision 0) +++ src/java/org/apache/jdo/tck/query/jdoql/subqueries/NonCorrelatedSubqueries.java (Revision 0) @@ -0,0 +1,147 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.jdo.tck.query.jdoql.subqueries; + +import java.util.Calendar; +import java.util.Date; +import java.util.List; +import java.util.Locale; +import java.util.TimeZone; + +import javax.jdo.PersistenceManager; +import javax.jdo.Query; +import javax.jdo.Transaction; + +import org.apache.jdo.tck.JDO_Test; +import org.apache.jdo.tck.pc.company.CompanyModelReader; +import org.apache.jdo.tck.pc.company.Employee; +import org.apache.jdo.tck.query.QueryTest; +import org.apache.jdo.tck.util.BatchTestRunner; + +/** + *Title: Non-correlated Subqueries + *
+ *Keywords: query + *
+ *Assertion ID: A14.6.2-55. + *
+ *Assertion Description: + * If the subquery has no references to expressions in the outer query + * the subquery is noncorrelated. + */ +public class NonCorrelatedSubqueries extends SubqueriesTest { + + /** */ + private static final String ASSERTION_FAILED = + "Assertion A14.6.2-55 (NonCorrelatedSubqueries) failed: "; + + /** + * The main is called when the class + * is directly executed from the command line. + * @param args The arguments passed to the program. + */ + public static void main(String[] args) { + BatchTestRunner.run(NonCorrelatedSubqueries.class); + } + + /** */ + public void testPositive() throws Exception { + PersistenceManager pm = getPM(); + runTestSubqueries01(pm); + runTestSubqueries02(pm); + } + + /** */ + void runTestSubqueries01(PersistenceManager pm) { + List expectedResult = getTransientCompanyModelInstancesAsList( + new String[]{"emp1","emp2","emp4","emp5","emp6","emp7","emp10"}); + + // select employees who work more than the average of all employees + String singleStringJDOQL = + "SELECT FROM Employee WHERE this.weeklyhours > " + + "(SELECT AVG(e.weeklyhours) FROM Employee e)"; + + // API query + Query sub = pm.newQuery(Employee.class); + sub.setResult("avg(this.weeklyhours)"); + Query apiQuery = pm.newQuery(Employee.class); + apiQuery.setFilter("this.weeklyhours> averageWeeklyhours"); + apiQuery.addSubquery(sub, "double averageWeeklyhours", null); + executeJDOQuery(ASSERTION_FAILED, apiQuery, singleStringJDOQL, + false, null, expectedResult, true); + + // API query against memory model + List allEmployees = (List)pm.newQuery(Employee.class).execute(); + apiQuery.setCandidates(allEmployees); + executeJDOQuery(ASSERTION_FAILED, apiQuery, singleStringJDOQL, + false, null, expectedResult, true); + + // single String JDOQL + Query singleStringQuery = pm.newQuery(singleStringJDOQL); + executeJDOQuery(ASSERTION_FAILED, singleStringQuery, singleStringJDOQL, + false, null, expectedResult, true); + } + + /** */ + void runTestSubqueries02(PersistenceManager pm) { + List expectedResult = getTransientCompanyModelInstancesAsList( + new String[]{"emp2", "emp5", "emp10"}); + + // Select employees hired after a particular date who work more + // than the average of all employees + String singleStringJDOQL = + "SELECT FROM Employee WHERE this.hiredate > :hired && " + + "this.weeklyhours> (SELECT AVG(e.weeklyhours) FROM Employee e)"; + + Calendar cal = Calendar.getInstance( + TimeZone.getTimeZone("America/New_York"), Locale.US); + cal.set(2002, Calendar.SEPTEMBER, 1, 0, 0, 0); + Date hired = cal.getTime(); + + // API query + Query sub = pm.newQuery(Employee.class); + sub.setResult("avg(this.weeklyhours)"); + Query apiQuery = pm.newQuery(Employee.class); + apiQuery.setFilter("this.hiredate > :hired && this.weeklyhours > averageWeeklyhours"); + apiQuery.addSubquery(sub, "double averageWeeklyhours", null); + executeJDOQuery(ASSERTION_FAILED, apiQuery, singleStringJDOQL, + false, new Object[]{hired}, expectedResult, true); + + // API query against memory model + List allEmployees = (List)pm.newQuery(Employee.class).execute(); + apiQuery.setCandidates(allEmployees); + executeJDOQuery(ASSERTION_FAILED, apiQuery, singleStringJDOQL, + false, null, expectedResult, true); + + // single String JDOQL + Query singleStringQuery = pm.newQuery(singleStringJDOQL); + executeJDOQuery(ASSERTION_FAILED, singleStringQuery, singleStringJDOQL, + false, new Object[]{hired}, expectedResult, true); + } + + /** + * @see JDO_Test#localSetUp() + */ + protected void localSetUp() { + addTearDownClass(CompanyModelReader.getTearDownClasses()); + loadAndPersistCompanyModel(getPM()); + } + +} + + Index: src/java/org/apache/jdo/tck/query/jdoql/subqueries/SubqueriesTest.java =================================================================== --- src/java/org/apache/jdo/tck/query/jdoql/subqueries/SubqueriesTest.java (Revision 0) +++ src/java/org/apache/jdo/tck/query/jdoql/subqueries/SubqueriesTest.java (Revision 0) @@ -0,0 +1,38 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.jdo.tck.query.jdoql.subqueries; + +import org.apache.jdo.tck.query.QueryTest; + +/** + * Superclass for all subquery test classes. + */ +public abstract class SubqueriesTest extends QueryTest { + + /** */ + public static final String SUBQUERIES_TEST_COMPANY_TESTDATA = + "org/apache/jdo/tck/pc/company/companyForSubqueriesTests.xml"; + + /** + * Returns the name of the company test data resource. + * @return name of the company test data resource. + */ + protected String getCompanyTestDataResource() { + return SUBQUERIES_TEST_COMPANY_TESTDATA; + } +} Index: src/java/org/apache/jdo/tck/query/jdoql/subqueries/UnmodifiedSubqueryInstance.java =================================================================== --- src/java/org/apache/jdo/tck/query/jdoql/subqueries/UnmodifiedSubqueryInstance.java (Revision 0) +++ src/java/org/apache/jdo/tck/query/jdoql/subqueries/UnmodifiedSubqueryInstance.java (Revision 0) @@ -0,0 +1,132 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.jdo.tck.query.jdoql.subqueries; + +import java.util.List; + +import javax.jdo.PersistenceManager; +import javax.jdo.Query; +import javax.jdo.Transaction; + +import org.apache.jdo.tck.JDO_Test; +import org.apache.jdo.tck.pc.company.CompanyModelReader; +import org.apache.jdo.tck.pc.company.Employee; +import org.apache.jdo.tck.query.QueryTest; +import org.apache.jdo.tck.util.BatchTestRunner; + +/** + *Title: Unmodified Subquery Instance. + *
+ *Keywords: query + *
+ *Assertion ID: A14.6.2-50. + *
+ *Assertion Description: + * The Query parameter instance is unmodified as a result of the addSubquery + * or subsequent execution of the outer Query. Only some of the parameter query + * parts are copied for use as the subquery. The parts copied include the + * candidate class, filter, parameter declarations, variable declarations, + * imports, ordering specification, uniqueness, result specification, and + * grouping specification. The association with a PersistenceManager, the + * candidate collection or extent, result class, and range limits are not used. + */ +public class UnmodifiedSubqueryInstance extends SubqueriesTest { + + /** */ + private static final String ASSERTION_FAILED = + "Assertion A14.6.2-50 (UnmodifiedSubqueryInstance) failed: "; + + /** + * The main is called when the class + * is directly executed from the command line. + * @param args The arguments passed to the program. + */ + public static void main(String[] args) { + BatchTestRunner.run(UnmodifiedSubqueryInstance.class); + } + + /** */ + public void testPositive() throws Exception { + PersistenceManager pm = getPM(); + runTestUnmodifiedSubquery(pm); + runTestDifferentPM(pm); + } + + /** */ + void runTestUnmodifiedSubquery(PersistenceManager pm) { + List expectedResult = getTransientCompanyModelInstancesAsList( + new String[]{"emp1","emp2","emp4","emp5","emp6","emp7","emp10"}); + Double averageWeeklyHours = new Double(33.5); + + // select average weeklyhours of all employees + String singleStringJDOQLSubquery = + "SELECT AVG(e.weeklyhours) FROM Employee e"; + // select employees who work more than the average of all employees + String singleStringJDOQL = + "SELECT FROM Employee WHERE this.weeklyhours > " + + "(" + singleStringJDOQLSubquery + ")"; + + // execute subquery + Query sub = pm.newQuery(Employee.class); + sub.setResult("avg(this.weeklyhours)"); + executeJDOQuery(ASSERTION_FAILED, sub, singleStringJDOQLSubquery, + false, null, averageWeeklyHours, true); + + // execute API query + Query apiQuery = pm.newQuery(Employee.class); + apiQuery.setFilter("this.weeklyhours> averageWeeklyhours"); + apiQuery.addSubquery(sub, "double averageWeeklyhours", null); + executeJDOQuery(ASSERTION_FAILED, apiQuery, singleStringJDOQL, + false, null, expectedResult, true); + + // execute subquery again + executeJDOQuery(ASSERTION_FAILED, sub, singleStringJDOQLSubquery, + false, null, averageWeeklyHours, true); + } + + /** */ + void runTestDifferentPM(PersistenceManager pm) { + List expectedResult = getTransientCompanyModelInstancesAsList( + new String[]{"emp1","emp2","emp4","emp5","emp6","emp7","emp10"}); + + // select employees who work more than the average of all employees + String singleStringJDOQL = + "SELECT FROM Employee WHERE this.weeklyhours > " + + "(SELECT AVG(e.weeklyhours) FROM Employee e)"; + + // create subquery instance using different pm + PersistenceManager newPM = + pm.getPersistenceManagerFactory().getPersistenceManager(); + Query sub = newPM.newQuery(Employee.class); + sub.setResult("avg(this.weeklyhours)"); + + Query apiQuery = pm.newQuery(Employee.class); + apiQuery.setFilter("this.weeklyhours> averageWeeklyhours"); + apiQuery.addSubquery(sub, "double averageWeeklyhours", null); + executeJDOQuery(ASSERTION_FAILED, apiQuery, singleStringJDOQL, + false, null, expectedResult, true); + } + + /** + * @see JDO_Test#localSetUp() + */ + protected void localSetUp() { + addTearDownClass(CompanyModelReader.getTearDownClasses()); + loadAndPersistCompanyModel(getPM()); + } +} Index: src/java/org/apache/jdo/tck/query/jdoql/subqueries/NullSubqueryParameter.java =================================================================== --- src/java/org/apache/jdo/tck/query/jdoql/subqueries/NullSubqueryParameter.java (Revision 0) +++ src/java/org/apache/jdo/tck/query/jdoql/subqueries/NullSubqueryParameter.java (Revision 0) @@ -0,0 +1,91 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.jdo.tck.query.jdoql.subqueries; + +import java.util.List; + +import javax.jdo.PersistenceManager; +import javax.jdo.Query; +import javax.jdo.Transaction; + +import org.apache.jdo.tck.JDO_Test; +import org.apache.jdo.tck.pc.company.CompanyModelReader; +import org.apache.jdo.tck.pc.company.Employee; +import org.apache.jdo.tck.query.QueryTest; +import org.apache.jdo.tck.util.BatchTestRunner; + +/** + *Title: Null Subquery Parameter. + *
+ *Keywords: query + *
+ *Assertion ID: A14.6.2-52. + *
+ *Assertion Description: + * If the subquery parameter is null, the variable is unset, effectively + * making the variable named in the variableDeclaration unbound. + */ +public class NullSubqueryParameter extends SubqueriesTest { + + /** */ + private static final String ASSERTION_FAILED = + "Assertion A14.6.2-52 (NullSubqueryParameter) failed: "; + + /** + * The main is called when the class + * is directly executed from the command line. + * @param args The arguments passed to the program. + */ + public static void main(String[] args) { + BatchTestRunner.run(NullSubqueryParameter.class); + } + + /** */ + public void testPositive() throws Exception { + PersistenceManager pm = getPM(); + + List expectedResult = getTransientCompanyModelInstancesAsList( + new String[]{"emp1", "emp2", "emp4", "emp6", "emp7", "emp10"}); + + String singleStringJDOQL = + "SELECT FROM Employee WHERE this.weeklyhours = emp.weeklyhours && " + + "emp.firstName = 'emp1First' VARIABLES Employee emp"; + + // API query + Query apiQuery = pm.newQuery(Employee.class); + apiQuery.setFilter("this.weeklyhours > emp.weeklyhours && emp.firstName = 'emp1First'"); + // null subquery parameter + apiQuery.addSubquery(null, "Employee emp", null); + executeJDOQuery(ASSERTION_FAILED, apiQuery, singleStringJDOQL, + false, null, expectedResult, true); + + // single String JDOQL + Query singleStringQuery = pm.newQuery(singleStringJDOQL); + executeJDOQuery(ASSERTION_FAILED, singleStringQuery, singleStringJDOQL, + false, null, expectedResult, true); + } + + /** + * @see JDO_Test#localSetUp() + */ + protected void localSetUp() { + addTearDownClass(CompanyModelReader.getTearDownClasses()); + loadAndPersistCompanyModel(getPM()); + } + +} Index: src/java/org/apache/jdo/tck/query/jdoql/subqueries/CorrelatedSubqueries.java =================================================================== --- src/java/org/apache/jdo/tck/query/jdoql/subqueries/CorrelatedSubqueries.java (Revision 0) +++ src/java/org/apache/jdo/tck/query/jdoql/subqueries/CorrelatedSubqueries.java (Revision 0) @@ -0,0 +1,100 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.jdo.tck.query.jdoql.subqueries; + +import java.util.List; + +import javax.jdo.PersistenceManager; +import javax.jdo.Query; + +import org.apache.jdo.tck.JDO_Test; +import org.apache.jdo.tck.pc.company.CompanyModelReader; +import org.apache.jdo.tck.pc.company.Employee; +import org.apache.jdo.tck.util.BatchTestRunner; + +/** + *Title: Correlated Subqueries Without Parameters + *
+ *Keywords: query + *
+ *Assertion ID: A14.6.2-56 + *
+ *Assertion Description: + * A correlated subquery is a subquery which contains references to expressions + * in the outer query. If the correlation can be expressed as a restriction of + * the candidate collection of the subquery, no parameters are needed. + */ +public class CorrelatedSubqueries extends SubqueriesTest { + + /** */ + private static final String ASSERTION_FAILED = + "Assertion A14.6.2-56 (CorrelatedSubqueries) failed: "; + + /** + * The main is called when the class + * is directly executed from the command line. + * @param args The arguments passed to the program. + */ + public static void main(String[] args) { + BatchTestRunner.run(CorrelatedSubqueries.class); + } + + /** */ + public void testPositive() throws Exception { + PersistenceManager pm = getPM(); + + List expectedResult = getTransientCompanyModelInstancesAsList( + new String[]{"emp1", "emp2", "emp4", "emp6", "emp7", "emp10"}); + + // Select employees who work more than the average of + // their department employees. + String singleStringJDOQL = + "SELECT FROM Employee WHERE this.weeklyhours > " + + "(SELECT AVG(e.weeklyhours) FROM this.department.employees e)"; + + // API query + Query sub = pm.newQuery(Employee.class); + sub.setResult("avg(this.weeklyhours)"); + Query apiQuery = pm.newQuery(Employee.class); + apiQuery.setFilter("this.weeklyhours> averageWeeklyhours"); + apiQuery.addSubquery(sub, "double averageWeeklyhours", + "this.department.employees"); + executeJDOQuery(ASSERTION_FAILED, apiQuery, singleStringJDOQL, + false, null, expectedResult, true); + + // API query against memory model + List allEmployees = (List)pm.newQuery(Employee.class).execute(); + apiQuery.setCandidates(allEmployees); + executeJDOQuery(ASSERTION_FAILED, apiQuery, singleStringJDOQL, + false, null, expectedResult, true); + + // single String JDOQL + Query singleStringQuery = pm.newQuery(singleStringJDOQL); + executeJDOQuery(ASSERTION_FAILED, singleStringQuery, singleStringJDOQL, + false, null, expectedResult, true); + } + + /** + * @see JDO_Test#localSetUp() + */ + protected void localSetUp() { + addTearDownClass(CompanyModelReader.getTearDownClasses()); + loadAndPersistCompanyModel(getPM()); + } + +} Index: src/java/org/apache/jdo/tck/query/jdoql/subqueries/CorrelatedSubqueriesWithParameters.java =================================================================== --- src/java/org/apache/jdo/tck/query/jdoql/subqueries/CorrelatedSubqueriesWithParameters.java (Revision 0) +++ src/java/org/apache/jdo/tck/query/jdoql/subqueries/CorrelatedSubqueriesWithParameters.java (Revision 0) @@ -0,0 +1,187 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.jdo.tck.query.jdoql.subqueries; + +import java.util.Calendar; +import java.util.Date; +import java.util.List; +import java.util.Locale; +import java.util.TimeZone; + +import javax.jdo.PersistenceManager; +import javax.jdo.Query; + +import org.apache.jdo.tck.JDO_Test; +import org.apache.jdo.tck.pc.company.CompanyModelReader; +import org.apache.jdo.tck.pc.company.Employee; +import org.apache.jdo.tck.util.BatchTestRunner; + +/** + *Title: Support for subqueries in JDOQL + *
+ *Keywords: query + *
+ *Assertion ID: A14.6.2-57. + *
+ *Assertion Description: + * If the correlation cannot be expressed as a restriction of the candidate + * collection, the correlation is expressed as one or more parameters in the + * subquery which are bound to expressions of the outer query. + */ +public class CorrelatedSubqueriesWithParameters extends SubqueriesTest { + + /** */ + private static final String ASSERTION_FAILED = + "Assertion A14.6.2-57 (CorrelatedSubqueriesWithParameters) failed: "; + + /** + * The main is called when the class + * is directly executed from the command line. + * @param args The arguments passed to the program. + */ + public static void main(String[] args) { + BatchTestRunner.run(CorrelatedSubqueriesWithParameters.class); + } + + /** */ + public void testPositive() throws Exception { + PersistenceManager pm = getPM(); + runTestSubqueries01(pm); + runTestSubqueries02(pm); + runTestSubqueries03(pm); + } + + /** + * Test subquery: + */ + void runTestSubqueries01(PersistenceManager pm) { + List expectedResult = getTransientCompanyModelInstancesAsList( + new String[]{"emp2", "emp6"}); + + // Select employees who work more than the average of the employees + // in their department having the same manager + String singleStringJDOQL = + "SELECT FROM Employee WHERE this.weeklyhours > " + + "(SELECT AVG(e.weeklyhours) FROM this.department.employees e " + + " WHERE e.manager == this.manager)"; + + // API query + Query sub = pm.newQuery(Employee.class); + sub.setResult("avg(this.weeklyhours)"); + sub.setFilter("this.manager == :manager"); + Query apiQuery = pm.newQuery(Employee.class); + apiQuery.setFilter("this.weeklyhours> averageWeeklyhours"); + apiQuery.addSubquery(sub, "double averageWeeklyhours", + "this.department.employees", "this.manager"); + executeJDOQuery(ASSERTION_FAILED, apiQuery, singleStringJDOQL, + false, null, expectedResult, true); + + // API query against memory model + List allEmployees = (List)pm.newQuery(Employee.class).execute(); + apiQuery.setCandidates(allEmployees); + executeJDOQuery(ASSERTION_FAILED, apiQuery, singleStringJDOQL, + false, null, expectedResult, true); + + // single String JDOQL + Query singleStringQuery = pm.newQuery(singleStringJDOQL); + executeJDOQuery(ASSERTION_FAILED, singleStringQuery, singleStringJDOQL, + false, null, expectedResult, true); + } + + /** */ + void runTestSubqueries02(PersistenceManager pm) { + List expectedResult = getTransientCompanyModelInstancesAsList( + new String[]{"emp2", "emp10"}); + + // Select employees hired after a particular date who work more + // than the average of all employees of the same manager + String singleStringJDOQL = + "SELECT FROM Employee WHERE this.hiredate > :hired && this.weeklyhours > " + + "(SELECT AVG(e.weeklyhours) FROM Employee e WHERE e.manager == this.manager)"; + + Calendar cal = Calendar.getInstance( + TimeZone.getTimeZone("America/New_York"), Locale.US); + cal.set(2002, Calendar.SEPTEMBER, 1, 0, 0, 0); + Date hired = cal.getTime(); + + // API query + Query sub = pm.newQuery(Employee.class); + sub.setResult("avg(this.weeklyhours)"); + sub.setFilter("this.manager == :manager"); + Query apiQuery = pm.newQuery(Employee.class); + apiQuery.setFilter("this.hiredate > :hired && this.weeklyhours> averageWeeklyhours"); + apiQuery.addSubquery(sub, "double averageWeeklyhours", null, "this.manager"); + executeJDOQuery(ASSERTION_FAILED, apiQuery, singleStringJDOQL, + false, new Object[] {hired}, expectedResult, true); + + // API query against memory model + List allEmployees = (List)pm.newQuery(Employee.class).execute(); + apiQuery.setCandidates(allEmployees); + executeJDOQuery(ASSERTION_FAILED, apiQuery, singleStringJDOQL, + false, null, expectedResult, true); + + // single String JDOQL + Query singleStringQuery = pm.newQuery(singleStringJDOQL); + executeJDOQuery(ASSERTION_FAILED, singleStringQuery, singleStringJDOQL, + false, new Object[]{hired}, expectedResult, true); + } + + /** */ + void runTestSubqueries03(PersistenceManager pm) { + List expectedResult = getTransientCompanyModelInstancesAsList( + new String[]{"emp2", "emp6", "emp10"}); + + // Select employees who work more than the average of all + // employees of the same manager + String singleStringJDOQL = + "SELECT FROM Employee WHERE this.weeklyhours > " + + "(SELECT AVG(e.weeklyhours) FROM Employee e WHERE e.manager == this.manager)"; + + // API query + Query sub = pm.newQuery(Employee.class); + sub.setResult("avg(this.weeklyhours)"); + sub.setFilter("this.manager == :manager"); + Query apiQuery = pm.newQuery(Employee.class); + apiQuery.setFilter("this.weeklyHours > averageWeeklyhours"); + apiQuery.addSubquery(sub, "double averageWeeklyhours", null, "this.manager"); + executeJDOQuery(ASSERTION_FAILED, apiQuery, singleStringJDOQL, + false, null, expectedResult, true); + + // API query against memory model + List allEmployees = (List)pm.newQuery(Employee.class).execute(); + apiQuery.setCandidates(allEmployees); + executeJDOQuery(ASSERTION_FAILED, apiQuery, singleStringJDOQL, + false, null, expectedResult, true); + + // single String JDOQL + Query singleStringQuery = pm.newQuery(singleStringJDOQL); + executeJDOQuery(ASSERTION_FAILED, singleStringQuery, singleStringJDOQL, + false, null, expectedResult, true); + } + + /** + * @see JDO_Test#localSetUp() + */ + protected void localSetUp() { + addTearDownClass(CompanyModelReader.getTearDownClasses()); + loadAndPersistCompanyModel(getPM()); + } + +} + + Index: src/testdata/org/apache/jdo/tck/pc/company/companyForSubqueriesTests.xml =================================================================== --- src/testdata/org/apache/jdo/tck/pc/company/companyForSubqueriesTests.xml (Revision 0) +++ src/testdata/org/apache/jdo/tck/pc/company/companyForSubqueriesTests.xml (Revision 0) @@ -0,0 +1,256 @@ + + + + + + Company instances for query testing + + + + + + + + + + + 1 + Sun Microsystems, Inc. + 11/Apr/1952 + + + + + + + + + + + 1 + Development + + + + + + + + + + + + + + + 2 + Human Resources + + + + + + + + + + + + + 1 + emp1First + emp1Last + emp1Middle + 10/Jun/1970 + + 1/Jan/1999 + 30000 + 40 + + + + + + + + + + + + 2 + emp2First + emp2Last + emp2Middle + 22/Dec/1975 + + 1/Jul/2003 + 20000 + 40 + + + + + + 3 + emp3First + emp3Last + emp3Middle + 5/Sep/1972 + + 15/Aug/2002 + 10000 + 25 + + + + + + 4 + emp4First + emp4Last + emp4Middle + 6/Sep/1973 + + 15/Apr/2001 + 25000 + 40 + + + + + + + + + + + 5 + emp5First + emp5Last + emp5Middle + 5/Jul/1962 + + 1/Nov/2002 + 18000 + 35 + + + + + + 6 + emp6First + emp6Last + emp6Middle + 10/Jun/1969 + + 1/Jun/2002 + 22000 + 40 + + + + + + 7 + emp7First + emp7Last + emp7Middle + 10/Jun/1970 + + 1/Jan/2000 + 40000 + 40 + + + + + + + + + + + 8 + emp8First + emp8Last + emp8Middle + 22/Dec/1975 + + 1/Aug/2003 + 10000 + 15 + + + + + + 9 + emp9First + emp9Last + emp9Middle + 5/Sep/1972 + + 1/May/2002 + 12000 + 20 + + + + + + 10 + emp10First + emp10Last + emp10Middle + 5/Sep/1972 + + 1/Oct/2002 + 24000 + 40 + + + + + + + 1 + Unter den Linden 1 + Berlin + + 12345 + Germany + + + 2 + Broadway 1 + New York + NY + 10000 + USA + + + 3 + Market St. + San Francisco + CA + 94102 + USA + + +