Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Proposed fix for #3624 NPE at RangeQueryRewriter.rewriteLocationStep #3625

Conversation

dizzzz
Copy link
Member

@dizzzz dizzzz commented Nov 22, 2020

Proposed fix for #3624 NPE at org.exist.xquery.modules.range.RangeQueryRewriter.rewriteLocationStep
Handle all operators

Help needed for tests

…RangeQueryRewriter.rewriteLocationStep

Handle all operators
@joewiz
Copy link
Member

joewiz commented Nov 22, 2020

I can confirm that this fixes the issue I reported in #3624. Thank you, @dizzzz!

@adamretter
Copy link
Member

adamretter commented Nov 23, 2020

@dizzzz Interesting stuff... I have some questions ;-)

  1. Previously this was limited to fn:matches but now it is only restricted to a Function that implements Lookup. Joe mentioned he did not see the problem in 5.2.0 - but this code would not have changed between 5.3.0 and 5.2.0, so I wonder where your insight for this fix came from?

  2. What was the expression that was causing the issue?

  3. This code can still cause an NPE:

Lookup func = Lookup.create(function.getContext(), operator, path);
func.setArguments(eqArgs);

The Lookup.Create function can return null. So the value of func should probably be checked/logged before it is used or not.

@dizzzz
Copy link
Member Author

dizzzz commented Nov 23, 2020

eq came in as option instead of matches, then I realized that only one item (eq) was handled. In other cases than matches NULL was returned, yielding in the NPE that @joewiz reported;

Instead of preventing the eq NPE, I thought it would make sense just to handle all enum options 👍 That should be OK as all options should accept 2 parameters,

Hmmm did I miss a potential NPE? I thought I covered it all....

@adamretter
Copy link
Member

Hmmm, shouldn't eq be handled just above in the if (expression instanceof GeneralComparison) { branch?

@dizzzz
Copy link
Member Author

dizzzz commented Nov 23, 2020

Hmmmm you are right on this I guess. good spot. hmmmm

@dizzzz dizzzz marked this pull request as draft November 23, 2020 17:18
@dizzzz
Copy link
Member Author

dizzzz commented Jan 3, 2021

What shall I do? close PR?

Copy link
Member

@wolfgangmm wolfgangmm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I debugged the original issue myself and came to the conclusion that Dannes' proposed fix is basically correct. What we have here is an expression which has already been partially rewritten (the GeneralComparison was replaced by range:eq). I'm not sure where this partial optimization was applied - probably an earlier traversal of the expression (we would need a much more reduced test case to know), but it is certainly a possible case which should not lead to an exception.

As Dannes pointed out, RangeQueryRewriter.rewrite only handled matches (stupid me!). It should handle all functions implementing Lookup.

…proposal_fix_npe_rangequeryrewriter

* 'develop' of github.com:eXist-db/exist: (109 commits)
  Bump dependency-check-maven from 6.0.3 to 6.0.4
  Wrong merge.... file needs to be deleted
  Fix for  eXist-db#3688
  Read buffer
  wrap file stream writes into BufferedOutputStreams.
  Remove old (unfinished?) code
  Bump rsyntaxtextarea from 3.1.1 to 3.1.2
  Feedback from review: use explicit services file
  Feedback from Adam
  Bump bcprov-jdk15on from 1.67 to 1.68
  Bump xmlunit.version from 2.8.1 to 2.8.2
  Feedback from Codacy
  Feedback from Codacy
  Setting the dot.
  Improved text a bit
  Handle potential (and real) NPE; allow issue to be ignored.
  Only delete (overwrite) file if user explicitly agrees
  Bump jansi from 2.1.0 to 2.1.1
  Reported by codacy
  Improve startup logging
  ...
@sonarcloud
Copy link

sonarcloud bot commented Jan 4, 2021

Kudos, SonarCloud Quality Gate passed!

Bug A 0 Bugs
Vulnerability A 0 Vulnerabilities
Security Hotspot A 0 Security Hotspots
Code Smell A 0 Code Smells

No Coverage information No Coverage information
0.0% 0.0% Duplication

@dizzzz
Copy link
Member Author

dizzzz commented Jan 4, 2021

@wolfgangmm @adamretter ready to go

@dizzzz dizzzz added the bug issue confirmed as bug label Jan 4, 2021
@dizzzz dizzzz marked this pull request as ready for review January 4, 2021 21:59
@dizzzz dizzzz added this to the eXist-5.3.0 milestone Jan 4, 2021
Copy link
Member

@joewiz joewiz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dizzzz I can confirm that the updated PR still fixes the issue I reported in #3624. Thank you!

@dizzzz dizzzz requested a review from wolfgangmm January 7, 2021 19:09
@dizzzz dizzzz merged commit 8dcefe0 into eXist-db:develop Jan 7, 2021
@dizzzz dizzzz deleted the bugfix/3624_proposal_fix_npe_rangequeryrewriter branch January 7, 2021 19:42
@joewiz
Copy link
Member

joewiz commented Jan 7, 2021

@dizzzz Thank you so much for this fix! And thanks to @adamretter and @wolfgangmm for your reviews.

@adamretter
Copy link
Member

I just dug into this further to try and understand why this fix works. I reduced Dannes's changes to the absolute minimum to pass Joe's reported issue #3624, and was left with just this patch:

diff --git a/extensions/indexes/range/src/main/java/org/exist/xquery/modules/range/RangeQueryRewriter.java b/extensions/indexes/range/src/main/java/org/exist/xquery/modules/range/RangeQueryRewriter.java
index 04f3db1f89..f7d47facce 100644
--- a/extensions/indexes/range/src/main/java/org/exist/xquery/modules/range/RangeQueryRewriter.java
+++ b/extensions/indexes/range/src/main/java/org/exist/xquery/modules/range/RangeQueryRewriter.java
@@ -139,13 +139,12 @@ public class RangeQueryRewriter extends QueryRewriter {
             InternalFunctionCall fcall = (InternalFunctionCall) expression;
             Function function = fcall.getFunction();
             if (function instanceof Lookup) {
-                if (function.isCalledAs("matches")) {
                     eqArgs.add(function.getArgument(0));
                     eqArgs.add(function.getArgument(1));
-                    Lookup func = Lookup.create(function.getContext(), RangeIndex.Operator.MATCH, path);
+                    final RangeIndex.Operator operator = RangeIndex.Operator.getByName(function.getName().getLocalPart());
+                    Lookup func = Lookup.create(function.getContext(), operator, path);
                     func.setArguments(eqArgs);
                     return func;
-                }
             }
         }
         return null;

As @wolfgangmm hinted at previously, the statement if (function.isCalledAs("matches")) { meant that RangeQueryRewriter#rewrite(Expression, NodePath) would return null, if it was presented with an instance of the Lookup class (which is an expression that is optimized for the Range Index) that was not range:matches#2.

The more I think about this, the less sense the current code makes. If we already have an instance of Lookup then it is already optimized and so it doesn't need to be passed to RangeQueryRewriter#rewrite to be rewritten as a Lookup function, because it is already a Lookup function!

With that in mind I still think it likely that the current fix is addressing a symptom rather than the root cause of the problem, and that eXist-db is doing more work than necessary by replacing one optimized Lookup expression with exactly the same optimized Lookup expression. I will keep digging...

@adamretter
Copy link
Member

If we already have an instance of Lookup then it is already optimized and so it doesn't need to be passed to RangeQueryRewriter#rewrite to be rewritten as a Lookup function, because it is already a Lookup function!

We (Evolved Binary) have provided an updated PR that takes a more efficient path in - #4882

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug issue confirmed as bug
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants