[ 
https://issues.apache.org/jira/browse/GEODE-6806?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Juan José Ramos Cassella reopened GEODE-6806:
---------------------------------------------

The new test added seems to be 
[flaky|https://concourse.apachegeode-ci.info/teams/main/pipelines/apache-develop-main/jobs/WindowsCoreIntegrationTestOpenJDK8/builds/13]
 and shows that the changes didn't completely fix the issue, only reduced the 
likely of it happening.


> Wrong Results in multi OQL joins + Indexes + LIMIT clause
> ---------------------------------------------------------
>
>                 Key: GEODE-6806
>                 URL: https://issues.apache.org/jira/browse/GEODE-6806
>             Project: Geode
>          Issue Type: Bug
>          Components: querying
>            Reporter: Juan José Ramos Cassella
>            Assignee: Juan José Ramos Cassella
>            Priority: Major
>              Labels: GeodeCommons
>             Fix For: 1.10.0
>
>          Time Spent: 40m
>  Remaining Estimate: 0h
>
> When joining multiple regions with indexes defined on them, the results of 
> the query might be wrong if the {{LIMIT}} keyword is used in the {{OQL}} and 
> the intermediate result size of the query is greater than the actual 
> {{LIMIT}} used.
> Internally we get the _partial_ results from the {{indexes}} and _cut down_ 
> these intermediate results during the actual execution. With the goal of 
> speeding things up, we use the {{LIMIT}} value to stop the iteration sooner 
> but we do not know if the first X results (governed by the {{LIMIT}} value) 
> might or might not fulfil the rest of the operands.
> The {{LIMIT}} clause is _disabled_ at the {{index}} level but still enabled 
> in this intermediate step, which is causing the final result to not contain 
> certain rows that should be included.
> The following example reproduces the issue (doesn't matter whether {{PDX}} is 
> used or not):
> {code:java}
>   private void populateTripleJointRegions(int expectedMatches, int 
> extraEntitiesPerRegion, Cache cache, Region<String, Object> orderRegion, 
> Region<String, Object> validationIssueRegion, Region<String, Object> 
> validationIssueXRefRegion) {
>     for (int i = 0; i < expectedMatches; i++) {
>       PdxInstance orderPdx = cache
>           .createPdxInstanceFactory("org.apache.geode.test.Order")
>           .writeString("orderId", "orderId_" + i)
>           .writeInt("version", i)
>           .create();
>       PdxInstance validationIssuePdx = cache
>           .createPdxInstanceFactory("org.apache.geode.test.ValidationIssue")
>           .writeString("issueId", "issueId_" + i)
>           .writeDate("createdTime", Calendar.getInstance().getTime())
>           .create();
>       PdxInstance validationIssueXRefPdx = cache
>           
> .createPdxInstanceFactory("org.apache.geode.test.OrderValidationIssueXRef")
>           .writeString("validationIssueXRefID", "validationIssueXRefID_" + i)
>           .writeString("referenceIssueId", "issueId_" + i)
>           .writeString("referenceOrderId", "orderId_" + i)
>           .writeInt("referenceOrderVersion", i)
>           .create();
>       orderRegion.put("orderId_" + i, orderPdx);
>       validationIssueRegion.put("issueId_" + i , validationIssuePdx);
>       validationIssueXRefRegion.put("validationIssueXRefID_" + i, 
> validationIssueXRefPdx);
>     }
>     for (int i = 0; i < extraEntitiesPerRegion; i++) {
>       PdxInstance orderPdx = cache
>           .createPdxInstanceFactory("org.apache.geode.test.Order")
>           .writeString("orderId", "orderId#" + i)
>           .writeInt("version", i)
>           .create();
>       PdxInstance validationIssuePdx = cache
>           .createPdxInstanceFactory("org.apache.geode.test.ValidationIssue")
>           .writeString("referenceIssueId", "referenceIssueId#" + i)
>           .writeDate("createdTime", Calendar.getInstance().getTime())
>           .create();
>       PdxInstance validationIssueXRefPdx = cache
>           
> .createPdxInstanceFactory("org.apache.geode.test.OrderValidationIssueXRef")
>           .writeString("validationIssueXRefID", "validationIssueXRefID#" + i)
>           .writeString("referenceIssueId", "validationIssueID2#" + i)
>           .writeString("referenceOrderId", "orderId#2" + i)
>           .writeInt("referenceOrderVersion", i)
>           .create();
>       orderRegion.put("orderId#" + i, orderPdx);
>       validationIssueRegion.put("issueId#" + i , validationIssuePdx );
>       validationIssueXRefRegion.put("validationIssueXRefID#" + i, 
> validationIssueXRefPdx);
>     }
>   }
>   @Test
>   public void 
> joiningThreeRegionsWhenIntermediateResultSizeIsHigherThanLimitClauseShouldNotTrimResults()
>  throws Exception {
>     int matches = 10;
>     int extraEntitiesPerRegion = 25;
>     Cache cache = CacheUtils.getCache();
>     QueryService queryService = cache.getQueryService();
>     String queryString = "SELECT issue.issueId, issue.createdTime, o.orderId, 
> o.version "
>         + "FROM /ValidationIssue issue, /OrderValidationIssueXRef xRef, 
> /Order o "
>         + "WHERE "
>         + "issue.issueId = xRef.referenceIssueId "
>         + "AND "
>         + "xRef.referenceOrderId = o.orderId "
>         + "AND "
>         + "xRef.referenceOrderVersion = o.version ";
>     try {
>       Region<String, Object> orderRegion = cache.<String, 
> Object>createRegionFactory()
>           .setDataPolicy(DataPolicy.REPLICATE).create("Order");
>       Region<String, Object> validationIssueRegion = cache.<String, 
> Object>createRegionFactory()
>           .setDataPolicy(DataPolicy.REPLICATE).create("ValidationIssue");
>       Region<String, Object> validationIssueXRefRegion = cache.<String, 
> Object>createRegionFactory()
>           
> .setDataPolicy(DataPolicy.REPLICATE).create("OrderValidationIssueXRef");
>         populateTripleJointRegions(matches, extraEntitiesPerRegion, 
> orderRegion, validationIssueRegion, validationIssueXRefRegion);
>       SelectResults baseResults = (SelectResults) 
> queryService.newQuery(queryString).execute();
>       SelectResults resultsWithLimitOne = (SelectResults) 
> queryService.newQuery(queryString + "LIMIT 2").execute();
>       SelectResults resultsWithLimitTwo = (SelectResults) 
> queryService.newQuery(queryString  + "LIMIT 5").execute();
>       assertThat(baseResults.size()).isEqualTo(matches);
>       assertThat(resultsWithLimitOne.size()).isEqualTo(2);
>       assertThat(resultsWithLimitTwo.size()).isEqualTo(5);
>       // Add Indexes and test again
>       cache.getQueryService().createIndex("order_orderID", "orderId", 
> "/Order", null);
>       cache.getQueryService().createIndex("validationIssue_issueID", 
> "issueId", "/ValidationIssue", null);
>       
> cache.getQueryService().createIndex("orderValidationIssueXRef_referenceOrderId",
>  "referenceOrderId", "/OrderValidationIssueXRef", null);
>       
> cache.getQueryService().createIndex("orderValidationIssueXRef_referenceIssueId",
>  "referenceIssueId", "/OrderValidationIssueXRef", null);
>       SelectResults baseResultsWithIndexes = (SelectResults) 
> queryService.newQuery(queryString).execute();
>       SelectResults resultsWithLimitOneWithIndexes = (SelectResults) 
> queryService.newQuery(queryString + "LIMIT 2").execute();
>       SelectResults resultsWithLimitTwoWithIndexes = (SelectResults) 
> queryService.newQuery(queryString  + "LIMIT 5").execute();
>       assertThat(baseResultsWithIndexes.size()).isEqualTo(matches);
>      // FAIL: the actual size will be 0 in both cases.
>       assertThat(resultsWithLimitOneWithIndexes.size()).isEqualTo(2);
>       assertThat(resultsWithLimitTwoWithIndexes.size()).isEqualTo(5);
>     } finally {
>       cache.getRegion("Order").destroyRegion();
>       cache.getRegion("ValidationIssue").destroyRegion();
>       cache.getRegion("OrderValidationIssueXRef").destroyRegion();
>     }
>   }
> {code}



--
This message was sent by Atlassian JIRA
(v7.6.3#76005)

Reply via email to