-
1. Re: CompoundCriteria.getCriteria().removeAll(...) leaving empty criteria ()
shawkins Sep 15, 2014 10:07 AM (in response to deveshmishra)You are directly manipulating the list under a CompoundCriteria, which is not expected to have less than 2 entries. You can instead use something like Criteria.combineCriteria on the manipulated list, which will check for the empty and single entry cases as well.
Out of curiosity is this manipulation part of a modification to the engine or with logic to form queries to submit to Teiid?
-
2. Re: Re: CompoundCriteria.getCriteria().removeAll(...) leaving empty criteria ()
deveshmishra Sep 16, 2014 3:18 AM (in response to shawkins)Thanks Steven, the Criteria.combineCriteria works when I use a separateCriteriaByAnd method. something like below.
q.setCriteria(CompoundCriteria.combineCriteria(CompoundCriteria.separateCriteriaByAnd(q.getCriteria())));
q is the final manipulated query (essentially a SELECT * FROM T, B WHERE (B.B = 10) AND ())
The challenge is, it does not work in case of an OR in the Compound criteria. example - SELECT * FROM T, B WHERE (B.B = 10) AND ((T.A < 10) OR(T.B = 10))
I reused (copy-pasted) the separateCriteriaByAnd method in my code and enabled it to work even with OR and it all works good. this looks like a hack, do you have a better approach. Thanks
The queries are manipulated and/or formed based on the logic and then submitted to teiid for processing.
-
3. Re: Re: CompoundCriteria.getCriteria().removeAll(...) leaving empty criteria ()
shawkins Sep 16, 2014 9:29 AM (in response to deveshmishra)> I reused (copy-pasted) the separateCriteriaByAnd method in my code and enabled it to work even with OR and it all works good. this looks like a hack, do you have a better approach.
When dealing with an AND, the conjuncts can be dealt with individually as their effect is cumulative. Removing just a single disjunct from OR may not logically be what you want to do.
-
4. Re: Re: CompoundCriteria.getCriteria().removeAll(...) leaving empty criteria ()
deveshmishra Sep 17, 2014 1:05 AM (in response to shawkins)Right, this probably will lead to other unknown issues. Any other approach you can suggest.? Thanks
-
5. Re: Re: CompoundCriteria.getCriteria().removeAll(...) leaving empty criteria ()
deveshmishra Sep 17, 2014 4:49 AM (in response to deveshmishra)I have found another solution (hack?) to this problem.
1) fix the orphan compound criteria. like below. if the criteriaCount is zero, i.e. orphan compound criteria. remove it. This solution works too.
private void fixOrphanCompoundCrits(final CompoundCriteria obj)
{
final List<Criteria> crits = new ArrayList<>();
for (final Criteria crit : obj.getCriteria())
{
if (crit instanceof CompoundCriteria)
{
if (((CompoundCriteria) crit).getCriteriaCount() == 0)
{
crits.add(crit);
}
}
}
obj.getCriteria().removeAll(crits);
}
Another approach will be to parse through the query and remove the orphan criteria. In this case we can visit through the CompoundCriteria and iterate through the Criteria. In case of an ExpressionCriteria, if it is empty we can remove it. Something like below.
private static void fixQuery(final Query q)
{
PostOrderNavigator.doVisit(q, new LanguageVisitor()
{
@Override
public void visit(final CompoundCriteria obj)
{
Criteria crTooRemove = null;
for (final Criteria crit : obj.getCriteria())
{
if (crit instanceof ExpressionCriteria)
{
final ExpressionCriteria exCrit = (ExpressionCriteria) crit;
if (exCrit.getExpression() instanceof Array)
{
final Array arr = (Array) exCrit.getExpression();
if (arr.getExpressions().size() == 0)
{
crTooRemove = crit;
}
}
}
}
obj.getCriteria().remove(crTooRemove);
}
});
}
-
6. Re: Re: CompoundCriteria.getCriteria().removeAll(...) leaving empty criteria ()
shawkins Sep 17, 2014 9:55 AM (in response to deveshmishra)1 of 1 people found this helpful> I have found another solution (hack?) to this problem.
It's really up to your logic (what expression/criteria is to be removed) as to what you'll need to do. You can also look at ExpressionMappingVisitor which is designed to modify expressions in place. For example a common thing to do is replace a predicate (with true/false/unknown) rather than remove it. Then it's up to the rewrite logic to simplify.
-
7. Re: CompoundCriteria.getCriteria().removeAll(...) leaving empty criteria ()
deveshmishra Sep 19, 2014 6:56 AM (in response to shawkins)Thanks Steven. I have another questions regarding the PostOrderNavigator behaviour. Consider the following code.
final Query q =
(Query) QueryParser.getQueryParser()
.parseCommand("SELECT * FROM T, B WHERE (B = 20) AND ((T.A = 10) AND (T.B = 20))");
PostOrderNavigator.doVisit(q, new LanguageVisitor()
{
@Override
public void visit(final CompoundCriteria obj)
{
System.out.println(obj);
}
});
The output it gives is...
(T.A = 10) AND (T.B = 20)
(B = 20) AND ((T.A = 10) AND (T.B = 20))
In this case, we are getting the repeated inner criteria. (T.A = 10) AND (T.B = 20) was already visited but again it appears in the second line where the entire criteria is visited. Any help is greatly appreciated. Thanks a lot.
-
8. Re: CompoundCriteria.getCriteria().removeAll(...) leaving empty criteria ()
shawkins Sep 19, 2014 8:50 AM (in response to deveshmishra)That is the expected output. Every parens () is a nesting level of compound criteria. They are not flattened by the engine until rewrite.
-
9. Re: CompoundCriteria.getCriteria().removeAll(...) leaving empty criteria ()
deveshmishra Sep 19, 2014 9:17 AM (in response to shawkins)Thanks Steven. Is there a way I can find out if it is a nesting level of Compound Criteria. The problem that I am facing is, I am traversing through the tree and for CompoundCriteria visitor - splitting it and populating another query. In my case, I am getting multiple criteria's added. Thank you.
-
10. Re: CompoundCriteria.getCriteria().removeAll(...) leaving empty criteria ()
shawkins Sep 19, 2014 10:00 AM (in response to deveshmishra)More than likely this just represents an issue with what you are going after. It's not any compoundcriteria there's something specific about some part of it in the where clause. For example just visiting the entire query will hit criteria in select clause case statements, join criteria, the having clause, etc.
-
11. Re: CompoundCriteria.getCriteria().removeAll(...) leaving empty criteria ()
deveshmishra Sep 21, 2014 9:34 AM (in response to shawkins)Was just wondering, if I could traverse a criteria (lets not consider the entire query). Just a Criteria with branching.and could filter and pull criteria to build another query.
Say below... SELECT * FROM T, B WHERE (B = 20) AND ((T.A = 10) AND (T.B = 20))
I want to filter out criteria of B.
so the resultant query is to be SELECT * FROM T, B WHERE ((T.A = 10) AND (T.B = 20))
but what I am getting is... SELECT * FROM T, B WHERE (T.A = 10) AND (T.B = 20) and (T.A = 10) AND (T.B = 20) and ((T.A = 10) AND (T.B = 20))
-
12. Re: CompoundCriteria.getCriteria().removeAll(...) leaving empty criteria ()
shawkins Sep 22, 2014 8:09 AM (in response to deveshmishra)> I want to filter out criteria of B.
As long as you are just considering the AND / conjunctive case, then you would first use separateCriteriaByAnd, then remove as needed and call combineCriteria. If you can have OR, then you need to consider what's the meaning of what copying/removing disjuncts. In any case you know that if one of the conjuncts returned by separateCriteriaByAnd is a CompoundCriteria, then it's an OR case. You could just put your handling there and recombine using an OR, or whatever is appropriate.
-
13. Re: CompoundCriteria.getCriteria().removeAll(...) leaving empty criteria ()
deveshmishra Sep 22, 2014 11:46 AM (in response to shawkins)Thanks Steven. Works like charm.