[ 
https://issues.apache.org/jira/browse/FLINK-10470?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16639833#comment-16639833
 ] 

ASF GitHub Bot commented on FLINK-10470:
----------------------------------------

dawidwys closed pull request #6781: [FLINK-10470] Add method to check if 
pattern can produce empty matches
URL: https://github.com/apache/flink/pull/6781
 
 
   

This is a PR merged from a forked repository.
As GitHub hides the original diff on merge, it is displayed below for
the sake of provenance:

As this is a foreign pull request (from a fork), the diff is supplied
below (as it won't show otherwise due to GitHub magic):

diff --git 
a/flink-libraries/flink-cep/src/main/java/org/apache/flink/cep/nfa/compiler/NFACompiler.java
 
b/flink-libraries/flink-cep/src/main/java/org/apache/flink/cep/nfa/compiler/NFACompiler.java
index 8f49f68fe41..ed2ff2e7e59 100644
--- 
a/flink-libraries/flink-cep/src/main/java/org/apache/flink/cep/nfa/compiler/NFACompiler.java
+++ 
b/flink-libraries/flink-cep/src/main/java/org/apache/flink/cep/nfa/compiler/NFACompiler.java
@@ -40,8 +40,13 @@
 import java.util.Collection;
 import java.util.Collections;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
+import java.util.Stack;
+
+import static org.apache.flink.util.Preconditions.checkNotNull;
 
 /**
  * Compiler class containing methods to compile a {@link Pattern} into a 
{@link NFA} or a
@@ -74,6 +79,44 @@
                }
        }
 
+       /**
+        * Verifies if the provided pattern can possibly generate empty match. 
Example of patterns that can possibly
+        * generate empty matches are: A*, A?, A* B? etc.
+        *
+        * @param pattern pattern to check
+        * @return true if empty match could potentially match the pattern, 
false otherwise
+        */
+       public static boolean canProduceEmptyMatches(final Pattern<?, ?> 
pattern) {
+               NFAFactoryCompiler<?> compiler = new 
NFAFactoryCompiler<>(checkNotNull(pattern));
+               compiler.compileFactory();
+               State<?> startState = 
compiler.getStates().stream().filter(State::isStart).findFirst().orElseThrow(
+                       () -> new IllegalStateException("Compiler produced no 
start state. It is a bug. File a jira."));
+
+               Set<State<?>> visitedStates = new HashSet<>();
+               final Stack<State<?>> statesToCheck = new Stack<>();
+               statesToCheck.push(startState);
+               while (!statesToCheck.isEmpty()) {
+                       final State<?> currentState = statesToCheck.pop();
+                       if (visitedStates.contains(currentState)) {
+                               continue;
+                       } else {
+                               visitedStates.add(currentState);
+                       }
+
+                       for (StateTransition<?> transition : 
currentState.getStateTransitions()) {
+                               if (transition.getAction() == 
StateTransitionAction.PROCEED) {
+                                       if 
(transition.getTargetState().isFinal()) {
+                                               return true;
+                                       } else {
+                                               
statesToCheck.push(transition.getTargetState());
+                                       }
+                               }
+                       }
+               }
+
+               return false;
+       }
+
        /**
         * Converts a {@link Pattern} into graph of {@link State}. It enables 
sharing of
         * compilation state across methods.
diff --git 
a/flink-libraries/flink-cep/src/test/java/org/apache/flink/cep/nfa/compiler/NFACompilerTest.java
 
b/flink-libraries/flink-cep/src/test/java/org/apache/flink/cep/nfa/compiler/NFACompilerTest.java
index f39b17483cd..821da031c6d 100644
--- 
a/flink-libraries/flink-cep/src/test/java/org/apache/flink/cep/nfa/compiler/NFACompilerTest.java
+++ 
b/flink-libraries/flink-cep/src/test/java/org/apache/flink/cep/nfa/compiler/NFACompilerTest.java
@@ -44,7 +44,9 @@
 import java.util.Set;
 
 import static org.apache.flink.cep.utils.NFAUtils.compile;
+import static org.hamcrest.Matchers.is;
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertThat;
 import static org.junit.Assert.assertTrue;
 
 /**
@@ -226,4 +228,14 @@ public boolean filter(Event value) throws Exception {
                return transitions;
        }
 
+       @Test
+       public void testCheckingEmptyMatches() {
+               
assertThat(NFACompiler.canProduceEmptyMatches(Pattern.begin("a").optional()), 
is(true));
+               
assertThat(NFACompiler.canProduceEmptyMatches(Pattern.begin("a").oneOrMore().optional()),
 is(true));
+               
assertThat(NFACompiler.canProduceEmptyMatches(Pattern.begin("a").oneOrMore().optional().next("b").optional()),
 is(true));
+
+               
assertThat(NFACompiler.canProduceEmptyMatches(Pattern.begin("a")), is(false));
+               
assertThat(NFACompiler.canProduceEmptyMatches(Pattern.begin("a").oneOrMore()), 
is(false));
+               
assertThat(NFACompiler.canProduceEmptyMatches(Pattern.begin("a").oneOrMore().next("b").optional()),
 is(false));
+       }
 }


 

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
us...@infra.apache.org


> Add method to check if pattern can produce empty matches
> --------------------------------------------------------
>
>                 Key: FLINK-10470
>                 URL: https://issues.apache.org/jira/browse/FLINK-10470
>             Project: Flink
>          Issue Type: Sub-task
>          Components: CEP
>            Reporter: Dawid Wysakowicz
>            Assignee: Dawid Wysakowicz
>            Priority: Major
>              Labels: pull-request-available
>
> There is couple of inconsistencies how CEP library handles greedy and 
> reluctant operators at the beginning at end of pattern. This results in 
> subtle problems how empty matches should be generated for patterns like e.g. 
> A? or A*?, where one is greedy and the other one is reluctant. In order to 
> provide first version of MATCH_RECOGNIZE function we should have a 
> possibility to disable patterns which can produce empty matches.



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

Reply via email to