db-jdo-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Craig Russell (JIRA)" <j...@apache.org>
Subject [jira] Commented: (JDO-246) JPOX eliminates duplicates in the query result although DISTINCT is not specified.
Date Mon, 06 Feb 2006 20:34:01 GMT
    [ http://issues.apache.org/jira/browse/JDO-246?page=comments#action_12365343 ] 

Craig Russell commented on JDO-246:
-----------------------------------

The relevant parts of the specification are these:

14.6.5 A variable that is not constrained with an explicit contains clause is constrained
by the extent of the persistence capable class (including subclasses).
...
The semantics of contains is "exists", where the contains clause is used to filter instances.
The meaning of the expression "emps.contains(e) && e.salary < param" is "there
exists an e in the emps collection such that e.salary is less than param". This is the natural
meaning of contains in the Java language, except where the expression is negated. If the variable
is used in the result, then it need not be constrained.
...
A portable query will constrain all variables with a contains clause in each side of an "OR"
expression of the filter where the variable is used. Further, each variable must either be
used in the query result or its contains clause must be the left expression of an "AND" expression
where the variable is used in the right expression. That is, for each occurrence of an expression
in the filter using the variable, there is a contains clause "ANDed" with the expression that
constrains the possible values by the elements of a collection.

14.6.9 If a variable or a field of a variable is included in the result, either directly or
via navigation through the variable, then the semantics of the "contains" clause that include
the variable change. In this case, all values of the variable that satisfy the filter are
included in the result.
...
If any result is a navigational expression, and a non-terminal field or variable has a null
value for a particular set of conditions (the result calculation would throw NullPointerException),
then the result is null for that result expression.

Using the sample query data provided in the TCK in companyForQueryTests.xml and applying these
to the cases at hand:

SELECT this.name from org.apache.jdo.tck.pc.company.Department WHERE name.matches(".*e.*")

The candidate tuples are {dept1, dept2}. Both satisfy the condition. The projection results
in:
{"Development"}, {Human Resources"}

SELECT this.name, e.lastname from org.apache.jdo.tck.pc.company.Department WHERE name.matches(".*e.*")
VARIABLES Employee e

This query is not portable because the variable employee is not constrained. This is not so
useful because the relationship between department and employee is not constrained. Therefore
the extent of department and the extent of employee are used.The candidate tuples are the
cartesian product of {this, e}. There are two departments and five employees, so the cartesian
product contains 10 tuples. The projection then is {{"Development", "emp1Last"}, {"Development",
"emp2Last"}, {"Development", "emp3Last"},  {"Development", "emp4Last"},  {"Development", "emp5Last"},
{"Human Resouces", "emp1Last"}, {"Human Resouces", "emp2Last"}, {"Human Resouces", "emp3Last"},
{"Human Resouces", "emp4Last"}, {"Human Resouces", "emp5Last"}}.

SELECT this.name, e.lastname from org.apache.jdo.tck.pc.company.Department WHERE name.matches(".*e.*")
&& this.employees.contains(Employee e)

The candidate tuples are the cartesian product of {this, e}. There are two departments and
five employees, so the cartesian product contains 10 tuples. Of these 10, only 5 satisfy the
filter because of the emps.contains clause. These are {{dept1, emp1}, {dept1, emp2}, {dept1,
emp3}, {dept2, emp4}, {dept2, emp5}}. The projection then is {{"Development", "emp1Last"},
{"Development", "emp2Last"}, {"Development", "emp3Last"}, {"Human Resouces", "emp4Last"},
{"Human Resouces", "emp5Last"}}

SELECT employee.id, employee.manager.lastname FROM org.apache.jdo.tck.pc.company.Department
WHERE employees.contains(employee) VARIABLES Employee employee 

The candidate tuples are this.employee. These are {{emp1}, {emp2}, {emp3}, {emp4}, {emp5}}.
The projection then is {{1", "emp2Last"}, {2, "emp2Last"}, {3, "emp2Last"}, {4, null}, {5,
null}}

SELECT employee.manager.lastname FROM org.apache.jdo.tck.pc.company.Department WHERE employees.contains(employee)
VARIABLES Employee employee 

The candidate tuples are this.employee. These are {{emp1}, {emp2}, {emp3}, {emp4}, {emp5}}.
The projection then is {{"emp2Last"}, {"emp2Last"}, {"emp2Last"}, {null}, {null}}

SELECT employee.lastname, project.name FROM org.apache.jdo.tck.pc.company.Department  VARIABLES
Employee employee; Project project

This query is not portable because the variable employee is not constrained. The candidate
tuples are the cartesian product of department, employee, and project. Two departments, five
employees, and three projects result in 30 tuples. The result will contain 30 projections
with each combination of employee.lastname and project.name repeated twice (one for each department).

SELECT employee.lastname, project.name FROM org.apache.jdo.tck.pc.company.Department  WHERE
employees.contains(Employee employee)VARIABLES Employee employee; Project project;

This query is not portable because the variable project is not constrained. The candidate
tuples are the cartesian product of department, employee, and project. Two departments, five
employees, and three projects result in 30 tuples. The filter reduces the results to 15 (the
cartesian product of the {department, employee-who-works-in-the-department} and {project}.
The result will contain 15 projections with each combination of employee.lastname and project.name.

SELECT employee.lastname, project.name FROM org.apache.jdo.tck.pc.company.Department  WHERE
employees.contains(Employee employee) && employees.projects.contains(project) VARIABLES
Employee employee; Project project

This query is portable because all variables are constrained. The candidate tuples are the
cartesian product of department, employee, and project. Two departments, five employees, and
three projects result in 30 tuples. The filter reduces the result tuples to 7 {{dept1, emp1,
proj3}, {dept1, emp2, proj1}, {dept1, emp2, proj2}, {dept1, emp3, proj1}, {dept1, emp3, proj2},
{dept2, emp4, proj3}, {dept2, emp5, proj3}, }. The result will contain 7 projections {{"emp1Last",
"green"}, {"emp2Last", "orange"}, {"emp2Last", "blue"}, {"emp3Last", "orange"}, {"emp3Last",
"blue"}, {"emp4Last", "green"}, {"emp5Last", "green"}}


> JPOX eliminates duplicates in the query result although DISTINCT is not specified.
> ----------------------------------------------------------------------------------
>
>          Key: JDO-246
>          URL: http://issues.apache.org/jira/browse/JDO-246
>      Project: JDO
>         Type: Bug
>   Components: tck20
>     Versions: JDO 2 beta
>     Reporter: Michael Watzek
>     Assignee: Erik Bengtson
>      Fix For: JDO 2 rc1

>
> Test case NPEInResultExpr fails because the result of the query below is expected to
contain duplicates. JPOX eliminates the duplicates.
> 14:22:55,046 (main) DEBUG [org.apache.jdo.tck] - Executing API query: SELECT employee.manager.lastname
FROM org.apache.jdo.tck.pc.company.Department WHERE employees.contains(employee) VARIABLES
Employee employee 
> 14:22:55,078 (main) DEBUG [org.apache.jdo.tck] - Query result: [emp2Last, null]
> 14:22:55,078 (main) DEBUG [org.apache.jdo.tck] - Wrong query result: 
> expected: [emp2Last, null, emp2Last, emp2Last, emp2Last]
> got:      [emp2Last, null]
> 14:22:55,078 (main) INFO  [org.apache.jdo.tck] - Exception during setUp or runtest: 
> junit.framework.AssertionFailedError: Assertion A14.6.9-4 (NPEInResultExpr) failed: 
> Wrong query result: 
> expected: [emp2Last, null, emp2Last, emp2Last, emp2Last]
> got:      [emp2Last, null]
> 	at junit.framework.Assert.fail(Assert.java:47)
> 	at org.apache.jdo.tck.JDO_Test.fail(JDO_Test.java:546)
> 	at org.apache.jdo.tck.query.QueryTest.queryFailed(QueryTest.java:500)
> 	at org.apache.jdo.tck.query.QueryTest.checkQueryResultWithoutOrder(QueryTest.java:485)
> 	at org.apache.jdo.tck.query.QueryTest.execute(QueryTest.java:1189)
> 	at org.apache.jdo.tck.query.QueryTest.execute(QueryTest.java:1029)
> 	at org.apache.jdo.tck.query.QueryTest.executeAPIQuery(QueryTest.java:966)
> 	at org.apache.jdo.tck.query.QueryTest.executeAPIQuery(QueryTest.java:946)
> 	at org.apache.jdo.tck.query.result.NPEInResultExpr.testPositive(NPEInResultExpr.java:106)
> 	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
> 	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
> 	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
> 	at java.lang.reflect.Method.invoke(Method.java:324)
> 	at junit.framework.TestCase.runTest(TestCase.java:154)
> 	at org.apache.jdo.tck.JDO_Test.runBare(JDO_Test.java:204)
> 	at junit.framework.TestResult$1.protect(TestResult.java:106)
> 	at junit.framework.TestResult.runProtected(TestResult.java:124)
> 	at junit.framework.TestResult.run(TestResult.java:109)
> 	at junit.framework.TestCase.run(TestCase.java:118)
> 	at junit.framework.TestSuite.runTest(TestSuite.java:208)
> 	at junit.framework.TestSuite.run(TestSuite.java:203)
> 	at junit.framework.TestSuite.runTest(TestSuite.java:208)
> 	at junit.framework.TestSuite.run(TestSuite.java:203)
> 	at junit.textui.TestRunner.doRun(TestRunner.java:116)
> 	at junit.textui.TestRunner.doRun(TestRunner.java:109)
> 	at org.apache.jdo.tck.util.BatchTestRunner.start(BatchTestRunner.java:120)
> 	at org.apache.jdo.tck.util.BatchTestRunner.main(BatchTestRunner.java:95)

-- 
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators:
   http://issues.apache.org/jira/secure/Administrators.jspa
-
For more information on JIRA, see:
   http://www.atlassian.com/software/jira


Mime
View raw message