================================================================================ Merge Diffs: /ade/ailitche_toplink_main/tldev/source/essentials/oracle/toplink/essentials/expressions/ExpressionOperator.java vs. /net/stottnfs2.ca.oracle.com/vol/vol1/ade_ottawa_txn/ailitche/ailitche_ri_gf672_060801/ade_storage/000001/AB0952363AC40CBFE034080020E8C54E.16 Report generated at Tue Aug 1 15:57:32 2006 -------------------------------------------------------------------------------- *** /net/stottnfs2.ca.oracle.com/vol/vol1/ade_ottawa_txn/ailitche/ailitche_ri_gf672_060801/ade_storage/000001/AB0952363AC40CBFE034080020E8C54E.16 Tue Aug 1 15:41:45 2006 --- /ade/ailitche_toplink_main/tldev/source/essentials/oracle/toplink/essentials/expressions/ExpressionOperator.java Tue Aug 1 15:57:32 2006 *************** *** 2638,2641 **** --- 2638,2664 ---- exOperator.setNodeClass(ClassConstants.FunctionExpression_Class); return exOperator; } + + /** + * INTERNAL: + * Indicates whether operator has selector Any or Some + */ + public boolean isAny() { + return selector == ExpressionOperator.Any || + selector == ExpressionOperator.Some; + } + /** + * INTERNAL: + * Indicates whether operator has selector All + */ + public boolean isAll() { + return selector == ExpressionOperator.All; + } + /** + * INTERNAL: + * Indicates whether operator has selector Any, Some or All + */ + public boolean isAnyOrAll() { + return isAny() || isAll(); + } } ================================================================================ Merge Diffs: /ade/ailitche_toplink_main/tldev/source/essentials/oracle/toplink/essentials/internal/expressions/RelationExpression.java vs. /net/stottnfs2.ca.oracle.com/vol/vol1/ade_ottawa_txn/ailitche/ailitche_ri_gf672_060801/ade_storage/000002/AB0952363AC40CBFE034080020E8C54E.11 Report generated at Tue Aug 1 15:57:32 2006 -------------------------------------------------------------------------------- *** /net/stottnfs2.ca.oracle.com/vol/vol1/ade_ottawa_txn/ailitche/ailitche_ri_gf672_060801/ade_storage/000002/AB0952363AC40CBFE034080020E8C54E.11 Tue Aug 1 15:42:13 2006 --- /ade/ailitche_toplink_main/tldev/source/essentials/oracle/toplink/essentials/internal/expressions/RelationExpression.java Tue Aug 1 15:57:32 2006 *************** *** 350,356 **** return false; } ! return getSecondChild().isObjectExpression() || getSecondChild().isValueExpression(); } /** --- 350,356 ---- return false; } ! return getSecondChild().isObjectExpression() || (getSecondChild().isValueExpression() || (getSecondChild().isFunctionExpression() && ((FunctionExpression)getSecondChild()).getOperator().isAnyOrAll())); } /** *************** *** 377,382 **** --- 377,416 ---- throw QueryException.invalidOperatorForObjectComparison(this); } + if(getSecondChild().isFunctionExpression()) { + FunctionExpression funcExp = (FunctionExpression)getSecondChild(); + if(funcExp.getOperator().isAnyOrAll()) { + SubSelectExpression subSelectExp = (SubSelectExpression)funcExp.getChildren().elementAt(1); + ReportQuery subQuery = subSelectExp.getSubQuery(); + Expression subSelectCriteria = subQuery.getSelectionCriteria(); + ExpressionBuilder subBuilder = subQuery.getExpressionBuilder(); + + ExpressionBuilder builder = getFirstChild().getBuilder(); + + Expression newExp; + if(funcExp.getOperator().isAny()) { + // Any or Some + if(getOperator().getSelector() == ExpressionOperator.Equal) { + subSelectCriteria = subBuilder.equal(getFirstChild()).and(subSelectCriteria); + } else { + subSelectCriteria = subBuilder.notEqual(getFirstChild()).and(subSelectCriteria); + } + subQuery.setSelectionCriteria(subSelectCriteria); + newExp = builder.exists(subQuery); + } else { + // All + if(getOperator().getSelector() == ExpressionOperator.Equal) { + subSelectCriteria = subBuilder.notEqual(getFirstChild()).and(subSelectCriteria); + } else { + subSelectCriteria = subBuilder.equal(getFirstChild()).and(subSelectCriteria); + } + subQuery.setSelectionCriteria(subSelectCriteria); + newExp = builder.notExists(subQuery); + } + return newExp.normalize(normalizer); + } + } + // This can either be comparison to another object, null or another expression reference. // Object comparisons can be done on other object builders, 1:1 or 1:m m:m mappings, // 1:m/m:m must twist the primary key expression, ================================================================================ Merge Diffs: /ade/ailitche_toplink_main/tltest/source/entity-persistence-tests/src/java/oracle/toplink/essentials/testing/tests/cmp3/advanced/compositepk/AdvancedCompositePKJunitTest.java vs. /net/stottnfs2.ca.oracle.com/vol/vol1/ade_ottawa_txn/ailitche/ailitche_ri_gf672_060801/ade_storage/000003/AB0952363AC40CBFE034080020E8C54E.6 Report generated at Tue Aug 1 15:57:32 2006 -------------------------------------------------------------------------------- *** /net/stottnfs2.ca.oracle.com/vol/vol1/ade_ottawa_txn/ailitche/ailitche_ri_gf672_060801/ade_storage/000003/AB0952363AC40CBFE034080020E8C54E.6 Tue Aug 1 15:46:58 2006 --- /ade/ailitche_toplink_main/tltest/source/entity-persistence-tests/src/java/oracle/toplink/essentials/testing/tests/cmp3/advanced/compositepk/AdvancedCompositePKJunitTest.java Tue Aug 1 15:57:32 2006 *************** *** 21,26 **** --- 21,30 ---- // Copyright (c) 1998, 2006, Oracle. All rights reserved. package oracle.toplink.essentials.testing.tests.cmp3.advanced.compositepk; + import java.util.List; + import java.util.ArrayList; + import javax.persistence.Query; + import javax.persistence.EntityManager; import junit.framework.*; *************** *** 63,68 **** --- 67,73 ---- suite.addTest(new AdvancedCompositePKJunitTest("testCreateScientists")); suite.addTest(new AdvancedCompositePKJunitTest("testReadDepartment")); suite.addTest(new AdvancedCompositePKJunitTest("testReadJuniorScientist")); + suite.addTest(new AdvancedCompositePKJunitTest("testAnyAndAll")); return new TestSetup(suite) { protected void setUp() { *************** *** 187,190 **** --- 192,251 ---- jScientist = (JuniorScientist) createEntityManager().find(JuniorScientist.class, m_jScientistPK); assertTrue("Error on reading back the junior scientist.", jScientist != null); } + + //bug gf672 - JBQL Select query with IN/ANY in WHERE clause and subselect fails. + public void testAnyAndAll() { + EntityManager em = createEntityManager(); + + // queries to test + + Query query1 = em.createQuery("SELECT s FROM Scientist s WHERE s = ANY (SELECT s2 FROM Scientist s2)"); + List results1 = query1.getResultList(); + + Query query2 = em.createQuery("SELECT s FROM Scientist s WHERE s = ALL (SELECT s2 FROM Scientist s2)"); + List results2 = query2.getResultList(); + + Query query3 = em.createQuery("SELECT s FROM Scientist s WHERE s.department = ALL (SELECT DISTINCT d FROM Department d WHERE d.name = 'DEPT A' AND d.role = 'ROLE A' AND d.location = 'LOCATION A')"); + List results3 = query3.getResultList(); + + Query query4 = em.createQuery("SELECT s FROM Scientist s WHERE s.department = ANY (SELECT DISTINCT d FROM Department d JOIN d.scientists ds JOIN ds.cubicle c WHERE c.code = 'G')"); + List results4 = query4.getResultList(); + + // control queries + + Query controlQuery1 = em.createQuery("SELECT s FROM Scientist s"); + List controlResults1 = controlQuery1.getResultList(); + + List controlResults2; + if(controlResults1.size() == 1) { + controlResults2 = controlResults1; + } else { + controlResults2 = new ArrayList(); + } + + Query controlQuery3 = em.createQuery("SELECT s FROM Scientist s JOIN s.department d WHERE d.name = 'DEPT A' AND d.role = 'ROLE A' AND d.location = 'LOCATION A'"); + List controlResults3 = controlQuery3.getResultList(); + + Query controlQuery4 = em.createQuery("SELECT s FROM Scientist s WHERE EXISTS (SELECT DISTINCT d FROM Department d JOIN d.scientists ds JOIN ds.cubicle c WHERE c.code = 'G' AND d = s.department)"); + List controlResults4 = controlQuery4.getResultList(); + + em.close(); + + // compare results - they should be the same + compareResults(results1, controlResults1, "query1"); + compareResults(results2, controlResults2, "query2"); + compareResults(results3, controlResults3, "query3"); + compareResults(results4, controlResults4, "query4"); + } + + protected void compareResults(List results, List controlResults, String testName) { + if(results.size() != controlResults.size()) { + fail(testName + ": results.size() = " + results.size() + "; controlResults.size() = " + controlResults.size()); + } + for (Object s : results) { + if(!controlResults.contains(s)) { + fail(testName + ": " + s + "contained in results but not in controlResults"); + } + } + } } ================================================================================ Merge Diffs: /ade/ailitche_toplink_main/tldev/source/essentials/oracle/toplink/essentials/expressions/ExpressionOperator.java vs. /net/stottnfs2.ca.oracle.com/vol/vol1/ade_ottawa_txn/ailitche/ailitche_ri_gf672_060801/ade_storage/000001/AB0952363AC40CBFE034080020E8C54E.16 Report generated at Tue Aug 1 15:58:05 2006 -------------------------------------------------------------------------------- *** /net/stottnfs2.ca.oracle.com/vol/vol1/ade_ottawa_txn/ailitche/ailitche_ri_gf672_060801/ade_storage/000001/AB0952363AC40CBFE034080020E8C54E.16 Tue Aug 1 15:41:45 2006 --- /ade/ailitche_toplink_main/tldev/source/essentials/oracle/toplink/essentials/expressions/ExpressionOperator.java Tue Aug 1 15:57:32 2006 *************** *** 2638,2641 **** --- 2638,2664 ---- exOperator.setNodeClass(ClassConstants.FunctionExpression_Class); return exOperator; } + + /** + * INTERNAL: + * Indicates whether operator has selector Any or Some + */ + public boolean isAny() { + return selector == ExpressionOperator.Any || + selector == ExpressionOperator.Some; + } + /** + * INTERNAL: + * Indicates whether operator has selector All + */ + public boolean isAll() { + return selector == ExpressionOperator.All; + } + /** + * INTERNAL: + * Indicates whether operator has selector Any, Some or All + */ + public boolean isAnyOrAll() { + return isAny() || isAll(); + } } ================================================================================ Merge Diffs: /ade/ailitche_toplink_main/tldev/source/essentials/oracle/toplink/essentials/internal/expressions/RelationExpression.java vs. /net/stottnfs2.ca.oracle.com/vol/vol1/ade_ottawa_txn/ailitche/ailitche_ri_gf672_060801/ade_storage/000002/AB0952363AC40CBFE034080020E8C54E.11 Report generated at Tue Aug 1 15:58:05 2006 -------------------------------------------------------------------------------- *** /net/stottnfs2.ca.oracle.com/vol/vol1/ade_ottawa_txn/ailitche/ailitche_ri_gf672_060801/ade_storage/000002/AB0952363AC40CBFE034080020E8C54E.11 Tue Aug 1 15:42:13 2006 --- /ade/ailitche_toplink_main/tldev/source/essentials/oracle/toplink/essentials/internal/expressions/RelationExpression.java Tue Aug 1 15:57:32 2006 *************** *** 350,356 **** return false; } ! return getSecondChild().isObjectExpression() || getSecondChild().isValueExpression(); } /** --- 350,356 ---- return false; } ! return getSecondChild().isObjectExpression() || (getSecondChild().isValueExpression() || (getSecondChild().isFunctionExpression() && ((FunctionExpression)getSecondChild()).getOperator().isAnyOrAll())); } /** *************** *** 377,382 **** --- 377,416 ---- throw QueryException.invalidOperatorForObjectComparison(this); } + if(getSecondChild().isFunctionExpression()) { + FunctionExpression funcExp = (FunctionExpression)getSecondChild(); + if(funcExp.getOperator().isAnyOrAll()) { + SubSelectExpression subSelectExp = (SubSelectExpression)funcExp.getChildren().elementAt(1); + ReportQuery subQuery = subSelectExp.getSubQuery(); + Expression subSelectCriteria = subQuery.getSelectionCriteria(); + ExpressionBuilder subBuilder = subQuery.getExpressionBuilder(); + + ExpressionBuilder builder = getFirstChild().getBuilder(); + + Expression newExp; + if(funcExp.getOperator().isAny()) { + // Any or Some + if(getOperator().getSelector() == ExpressionOperator.Equal) { + subSelectCriteria = subBuilder.equal(getFirstChild()).and(subSelectCriteria); + } else { + subSelectCriteria = subBuilder.notEqual(getFirstChild()).and(subSelectCriteria); + } + subQuery.setSelectionCriteria(subSelectCriteria); + newExp = builder.exists(subQuery); + } else { + // All + if(getOperator().getSelector() == ExpressionOperator.Equal) { + subSelectCriteria = subBuilder.notEqual(getFirstChild()).and(subSelectCriteria); + } else { + subSelectCriteria = subBuilder.equal(getFirstChild()).and(subSelectCriteria); + } + subQuery.setSelectionCriteria(subSelectCriteria); + newExp = builder.notExists(subQuery); + } + return newExp.normalize(normalizer); + } + } + // This can either be comparison to another object, null or another expression reference. // Object comparisons can be done on other object builders, 1:1 or 1:m m:m mappings, // 1:m/m:m must twist the primary key expression, ================================================================================ Merge Diffs: /ade/ailitche_toplink_main/tltest/source/entity-persistence-tests/src/java/oracle/toplink/essentials/testing/tests/cmp3/advanced/compositepk/AdvancedCompositePKJunitTest.java vs. /net/stottnfs2.ca.oracle.com/vol/vol1/ade_ottawa_txn/ailitche/ailitche_ri_gf672_060801/ade_storage/000003/AB0952363AC40CBFE034080020E8C54E.6 Report generated at Tue Aug 1 15:58:05 2006 -------------------------------------------------------------------------------- *** /net/stottnfs2.ca.oracle.com/vol/vol1/ade_ottawa_txn/ailitche/ailitche_ri_gf672_060801/ade_storage/000003/AB0952363AC40CBFE034080020E8C54E.6 Tue Aug 1 15:46:58 2006 --- /ade/ailitche_toplink_main/tltest/source/entity-persistence-tests/src/java/oracle/toplink/essentials/testing/tests/cmp3/advanced/compositepk/AdvancedCompositePKJunitTest.java Tue Aug 1 15:57:32 2006 *************** *** 21,26 **** --- 21,30 ---- // Copyright (c) 1998, 2006, Oracle. All rights reserved. package oracle.toplink.essentials.testing.tests.cmp3.advanced.compositepk; + import java.util.List; + import java.util.ArrayList; + import javax.persistence.Query; + import javax.persistence.EntityManager; import junit.framework.*; *************** *** 63,68 **** --- 67,73 ---- suite.addTest(new AdvancedCompositePKJunitTest("testCreateScientists")); suite.addTest(new AdvancedCompositePKJunitTest("testReadDepartment")); suite.addTest(new AdvancedCompositePKJunitTest("testReadJuniorScientist")); + suite.addTest(new AdvancedCompositePKJunitTest("testAnyAndAll")); return new TestSetup(suite) { protected void setUp() { *************** *** 187,190 **** --- 192,251 ---- jScientist = (JuniorScientist) createEntityManager().find(JuniorScientist.class, m_jScientistPK); assertTrue("Error on reading back the junior scientist.", jScientist != null); } + + //bug gf672 - JBQL Select query with IN/ANY in WHERE clause and subselect fails. + public void testAnyAndAll() { + EntityManager em = createEntityManager(); + + // queries to test + + Query query1 = em.createQuery("SELECT s FROM Scientist s WHERE s = ANY (SELECT s2 FROM Scientist s2)"); + List results1 = query1.getResultList(); + + Query query2 = em.createQuery("SELECT s FROM Scientist s WHERE s = ALL (SELECT s2 FROM Scientist s2)"); + List results2 = query2.getResultList(); + + Query query3 = em.createQuery("SELECT s FROM Scientist s WHERE s.department = ALL (SELECT DISTINCT d FROM Department d WHERE d.name = 'DEPT A' AND d.role = 'ROLE A' AND d.location = 'LOCATION A')"); + List results3 = query3.getResultList(); + + Query query4 = em.createQuery("SELECT s FROM Scientist s WHERE s.department = ANY (SELECT DISTINCT d FROM Department d JOIN d.scientists ds JOIN ds.cubicle c WHERE c.code = 'G')"); + List results4 = query4.getResultList(); + + // control queries + + Query controlQuery1 = em.createQuery("SELECT s FROM Scientist s"); + List controlResults1 = controlQuery1.getResultList(); + + List controlResults2; + if(controlResults1.size() == 1) { + controlResults2 = controlResults1; + } else { + controlResults2 = new ArrayList(); + } + + Query controlQuery3 = em.createQuery("SELECT s FROM Scientist s JOIN s.department d WHERE d.name = 'DEPT A' AND d.role = 'ROLE A' AND d.location = 'LOCATION A'"); + List controlResults3 = controlQuery3.getResultList(); + + Query controlQuery4 = em.createQuery("SELECT s FROM Scientist s WHERE EXISTS (SELECT DISTINCT d FROM Department d JOIN d.scientists ds JOIN ds.cubicle c WHERE c.code = 'G' AND d = s.department)"); + List controlResults4 = controlQuery4.getResultList(); + + em.close(); + + // compare results - they should be the same + compareResults(results1, controlResults1, "query1"); + compareResults(results2, controlResults2, "query2"); + compareResults(results3, controlResults3, "query3"); + compareResults(results4, controlResults4, "query4"); + } + + protected void compareResults(List results, List controlResults, String testName) { + if(results.size() != controlResults.size()) { + fail(testName + ": results.size() = " + results.size() + "; controlResults.size() = " + controlResults.size()); + } + for (Object s : results) { + if(!controlResults.contains(s)) { + fail(testName + ": " + s + "contained in results but not in controlResults"); + } + } + } }