From 14cba2a57ec78cd1bb8e664474f0db1e6f2799b9 Mon Sep 17 00:00:00 2001 From: Mark Payne Date: Wed, 7 Jan 2015 14:16:51 -0500 Subject: [PATCH] NIFI-22: fixed issues with newly added join and count functions --- .../attribute/expression/language/Query.java | 50 +++++++++++-------- .../evaluation/reduce/JoinEvaluator.java | 4 +- .../selection/MappingEvaluator.java | 2 +- .../expression/language/TestQuery.java | 6 +-- 4 files changed, 35 insertions(+), 27 deletions(-) diff --git a/commons/nifi-expression-language/src/main/java/org/apache/nifi/attribute/expression/language/Query.java b/commons/nifi-expression-language/src/main/java/org/apache/nifi/attribute/expression/language/Query.java index 9a5fe0a746..420a8e21c7 100644 --- a/commons/nifi-expression-language/src/main/java/org/apache/nifi/attribute/expression/language/Query.java +++ b/commons/nifi-expression-language/src/main/java/org/apache/nifi/attribute/expression/language/Query.java @@ -116,6 +116,7 @@ import org.antlr.runtime.ANTLRStringStream; import org.antlr.runtime.CharStream; import org.antlr.runtime.CommonTokenStream; import org.antlr.runtime.tree.Tree; +import org.apache.nifi.attribute.expression.language.evaluation.selection.MappingEvaluator; /** * Class used for creating and evaluating NiFi Expression Language. Once a Query @@ -515,26 +516,26 @@ public class Query { try { final List substrings = new ArrayList<>(); final Map trees = new HashMap<>(); - + int lastIndex = 0; for (final Range range : ranges) { if (range.getStart() > lastIndex) { substrings.add(query.substring(lastIndex, range.getStart()).replace("$$", "$")); lastIndex = range.getEnd() + 1; } - + final String treeText = query.substring(range.getStart(), range.getEnd() + 1).replace("$$", "$"); substrings.add(treeText); trees.put(treeText, Query.compileTree(treeText)); lastIndex = range.getEnd() + 1; } - + final Range lastRange = ranges.get(ranges.size() - 1); if (lastRange.getEnd() + 1 < query.length()) { final String treeText = query.substring(lastRange.getEnd() + 1).replace("$$", "$"); substrings.add(treeText); } - + return new StandardPreparedQuery(substrings, trees); } catch (final AttributeExpressionLanguageParsingException e) { return new InvalidPreparedQuery(query, e.getMessage()); @@ -550,7 +551,7 @@ public class Query { final Evaluator evaluator = buildEvaluator(tree); verifyMappingEvaluatorReduced(evaluator); - + return new Query(query, tree, evaluator); } catch (final AttributeExpressionLanguageParsingException e) { throw e; @@ -559,7 +560,6 @@ public class Query { } } - private static void verifyMappingEvaluatorReduced(final Evaluator evaluator) { // if the result type of the evaluator is BOOLEAN, then it will always // be reduced when evaluator. @@ -572,20 +572,20 @@ public class Query { if (rootEvaluator != null && rootEvaluator instanceof MultiAttributeEvaluator) { final MultiAttributeEvaluator multiAttrEval = (MultiAttributeEvaluator) rootEvaluator; switch (multiAttrEval.getEvaluationType()) { - case ALL_ATTRIBUTES: - case ALL_MATCHING_ATTRIBUTES: - case ALL_DELINEATED_VALUES: { - if (!(evaluator instanceof ReduceEvaluator)) { - throw new AttributeExpressionLanguageParsingException("Cannot evaluate expression because it attempts to reference multiple attributes but does not use a reducing function"); + case ALL_ATTRIBUTES: + case ALL_MATCHING_ATTRIBUTES: + case ALL_DELINEATED_VALUES: { + if (!(evaluator instanceof ReduceEvaluator)) { + throw new AttributeExpressionLanguageParsingException("Cannot evaluate expression because it attempts to reference multiple attributes but does not use a reducing function"); + } + break; } - break; - } - default: - throw new AttributeExpressionLanguageParsingException("Cannot evaluate expression because it attempts to reference multiple attributes but does not use a reducing function"); + default: + throw new AttributeExpressionLanguageParsingException("Cannot evaluate expression because it attempts to reference multiple attributes but does not use a reducing function"); } } } - + private static CommonTokenStream createTokenStream(final String expression) throws AttributeExpressionLanguageParsingException { final CharStream input = new ANTLRStringStream(expression); final AttributeExpressionLexer lexer = new AttributeExpressionLexer(input); @@ -791,7 +791,7 @@ public class Query { if (tree.getChildCount() == 0) { throw new AttributeExpressionLanguageParsingException("EXPRESSION tree node has no children"); } - + final Evaluator evaluator; if (tree.getChildCount() == 1) { evaluator = buildEvaluator(tree.getChild(0)); @@ -804,7 +804,7 @@ public class Query { // tree from the right-most child going left-ward. evaluator = buildFunctionExpressionEvaluator(tree, 0); } - + Evaluator chosenEvaluator = evaluator; final Evaluator rootEvaluator = getRootSubjectEvaluator(evaluator); if (rootEvaluator != null) { @@ -819,13 +819,21 @@ public class Query { break; case ALL_ATTRIBUTES: case ALL_MATCHING_ATTRIBUTES: - case ALL_DELINEATED_VALUES: - chosenEvaluator = new AllAttributesEvaluator((BooleanEvaluator) evaluator, multiAttrEval); + case ALL_DELINEATED_VALUES: { + final ResultType resultType = evaluator.getResultType(); + if (resultType == ResultType.BOOLEAN) { + chosenEvaluator = new AllAttributesEvaluator((BooleanEvaluator) evaluator, multiAttrEval); + } else if (evaluator instanceof ReduceEvaluator) { + chosenEvaluator = new MappingEvaluator((ReduceEvaluator) evaluator, multiAttrEval); + } else { + throw new AttributeExpressionLanguageException("Cannot evaluate Expression because it attempts to reference multiple attributes but does not use a reducing function"); + } break; + } } } } - + return chosenEvaluator; } diff --git a/commons/nifi-expression-language/src/main/java/org/apache/nifi/attribute/expression/language/evaluation/reduce/JoinEvaluator.java b/commons/nifi-expression-language/src/main/java/org/apache/nifi/attribute/expression/language/evaluation/reduce/JoinEvaluator.java index 6fab871887..eefdadad19 100644 --- a/commons/nifi-expression-language/src/main/java/org/apache/nifi/attribute/expression/language/evaluation/reduce/JoinEvaluator.java +++ b/commons/nifi-expression-language/src/main/java/org/apache/nifi/attribute/expression/language/evaluation/reduce/JoinEvaluator.java @@ -37,9 +37,9 @@ public class JoinEvaluator extends StringEvaluator implements ReduceEvaluator evaluate(final Map attributes) { - final String subject = subjectEvaluator.evaluate(attributes).getValue(); + String subject = subjectEvaluator.evaluate(attributes).getValue(); if ( subject == null ) { - return new StringQueryResult(""); + subject = ""; } final String delimiter = delimiterEvaluator.evaluate(attributes).getValue(); diff --git a/commons/nifi-expression-language/src/main/java/org/apache/nifi/attribute/expression/language/evaluation/selection/MappingEvaluator.java b/commons/nifi-expression-language/src/main/java/org/apache/nifi/attribute/expression/language/evaluation/selection/MappingEvaluator.java index 61ff2af1a4..d872b6e4c2 100644 --- a/commons/nifi-expression-language/src/main/java/org/apache/nifi/attribute/expression/language/evaluation/selection/MappingEvaluator.java +++ b/commons/nifi-expression-language/src/main/java/org/apache/nifi/attribute/expression/language/evaluation/selection/MappingEvaluator.java @@ -55,7 +55,7 @@ public class MappingEvaluator implements Evaluator { @Override public Evaluator getSubjectEvaluator() { - return mappingEvaluator; + return null; } } diff --git a/commons/nifi-expression-language/src/test/java/org/apache/nifi/attribute/expression/language/TestQuery.java b/commons/nifi-expression-language/src/test/java/org/apache/nifi/attribute/expression/language/TestQuery.java index 824249ba79..ad0065cf38 100644 --- a/commons/nifi-expression-language/src/test/java/org/apache/nifi/attribute/expression/language/TestQuery.java +++ b/commons/nifi-expression-language/src/test/java/org/apache/nifi/attribute/expression/language/TestQuery.java @@ -235,8 +235,8 @@ public class TestQuery { public void testJoin() { final Map attributes = new HashMap<>(); attributes.put("a.a", "a"); - attributes.put("b.b", "b"); - attributes.put("c.c", "c"); + attributes.put("a.b", "b"); + attributes.put("a.c", "c"); verifyEquals("${allAttributes( 'a.a', 'a.b', 'a.c' ):join(', ')}", attributes, "a, b, c"); verifyEquals("${x:join(', ')}", attributes, ""); verifyEquals("${a.a:join(', ')}", attributes, "a"); @@ -282,7 +282,7 @@ public class TestQuery { public void testCount() { final Map attributes = new HashMap<>(); attributes.put("a", "a"); - attributes.put("b", ""); + attributes.put("b", "abc"); attributes.put("c", " \n"); attributes.put("n1", "111"); attributes.put("n2", "222");