@@ -6,6 +6,7 @@ pub mod operators;
66
77use boolean_expression:: Expr ;
88use graphannis_core:: annostorage:: MatchGroup ;
9+ use itertools:: Itertools ;
910lalrpop_mod ! (
1011 #[ allow( clippy:: all) ]
1112 #[ allow( clippy:: panic) ]
@@ -77,7 +78,28 @@ pub fn execute_query_on_graph<'a>(
7778 let timeout = TimeoutCheck :: new ( timeout) ;
7879
7980 let config = Config { use_parallel_joins } ;
80- let it = ExecutionPlan :: from_disjunction ( query, graph, & config, timeout) ?;
81+ let it = ExecutionPlan :: from_disjunction ( query, graph, & config, timeout) ?
82+ . map_ok ( |mg| {
83+ // Rewrite match group to only include nodes that are included in the query
84+ // check if query node actually should be included
85+ let mut new_match_group = MatchGroup :: with_capacity ( mg. len ( ) ) ;
86+ for ( node_nr, m) in mg. into_iter ( ) . enumerate ( ) {
87+ let include_in_output = query
88+ . get_variable_by_node_nr ( node_nr)
89+ . is_some_and ( |var| query. is_included_in_output ( & var) ) ;
90+ if include_in_output {
91+ new_match_group. push ( m) ;
92+ }
93+ }
94+ new_match_group
95+ } )
96+ . unique_by ( move |mg| {
97+ // Map an error to an empty match group
98+ match mg {
99+ Ok ( mg) => mg. clone ( ) ,
100+ Err ( _) => MatchGroup :: new ( ) ,
101+ }
102+ } ) ;
81103
82104 Ok ( Box :: from ( it) )
83105}
@@ -663,4 +685,25 @@ mod tests {
663685 let it = execute_query_on_graph ( & graph, & query, true , None ) . unwrap ( ) ;
664686 assert_eq ! ( 11 , it. count( ) ) ;
665687 }
688+
689+ #[ test]
690+ fn query_on_annotation_graph_with_negation ( ) {
691+ let cargo_dir = PathBuf :: from ( env ! ( "CARGO_MANIFEST_DIR" ) ) ;
692+ let input_file = File :: open ( & cargo_dir. join ( "tests/SaltSampleCorpus.graphml" ) ) . unwrap ( ) ;
693+ let ( graph, _config_str) : ( AnnotationGraph , _ ) =
694+ graphannis_core:: graph:: serialization:: graphml:: import ( input_file, false , |_status| { } )
695+ . unwrap ( ) ;
696+
697+ let query = parse ( "tok? !. tok" , false ) . unwrap ( ) ;
698+ let it = execute_query_on_graph ( & graph, & query, true , None ) . unwrap ( ) ;
699+
700+ let matches: Result < Vec < _ > > = it. collect ( ) ;
701+ let matches = matches. unwrap ( ) ;
702+ assert_eq ! ( 4 , matches. len( ) ) ;
703+ // The match should not have 2 two nodes, but only one nde
704+ assert_eq ! ( 1 , matches[ 0 ] . len( ) ) ;
705+ assert_eq ! ( 1 , matches[ 1 ] . len( ) ) ;
706+ assert_eq ! ( 1 , matches[ 2 ] . len( ) ) ;
707+ assert_eq ! ( 1 , matches[ 3 ] . len( ) ) ;
708+ }
666709}
0 commit comments