From d116a15965a677eaf7e95fb04107a7788487a906 Mon Sep 17 00:00:00 2001 From: Predrag Gruevski Date: Fri, 8 Nov 2024 15:54:21 +0000 Subject: [PATCH 1/2] Add test data that reproduces incorrect query evaluation. --- ...l_with_immediate_filter.graphql-parsed.ron | 79 +++++ ...optional_with_immediate_filter.graphql.ron | 16 + ...tent_optional_with_immediate_filter.ir.ron | 55 +++ ..._optional_with_immediate_filter.output.ron | 16 + ...t_optional_with_immediate_filter.trace.ron | 209 +++++++++++ ...iate_is_not_null_filter.graphql-parsed.ron | 76 ++++ ...h_immediate_is_not_null_filter.graphql.ron | 14 + ...l_with_immediate_is_not_null_filter.ir.ron | 46 +++ ...th_immediate_is_not_null_filter.output.ron | 16 + ...ith_immediate_is_not_null_filter.trace.ron | 200 +++++++++++ ...onal_with_nested_filter.graphql-parsed.ron | 94 +++++ ...nt_optional_with_nested_filter.graphql.ron | 18 + ...xistent_optional_with_nested_filter.ir.ron | 65 ++++ ...ent_optional_with_nested_filter.output.ron | 16 + ...tent_optional_with_nested_filter.trace.ron | 273 +++++++++++++++ ...sted_is_not_null_filter.graphql-parsed.ron | 91 +++++ ...with_nested_is_not_null_filter.graphql.ron | 16 + ...onal_with_nested_is_not_null_filter.ir.ron | 56 +++ ..._with_nested_is_not_null_filter.output.ron | 16 + ...l_with_nested_is_not_null_filter.trace.ron | 264 ++++++++++++++ ...tagged_immediate_filter.graphql-parsed.ron | 79 +++++ ...l_with_tagged_immediate_filter.graphql.ron | 14 + ...tional_with_tagged_immediate_filter.ir.ron | 50 +++ ...al_with_tagged_immediate_filter.output.ron | 16 + ...nal_with_tagged_immediate_filter.trace.ron | 261 ++++++++++++++ ...th_tagged_nested_filter.graphql-parsed.ron | 94 +++++ ...onal_with_tagged_nested_filter.graphql.ron | 16 + ..._optional_with_tagged_nested_filter.ir.ron | 60 ++++ ...ional_with_tagged_nested_filter.output.ron | 16 + ...tional_with_tagged_nested_filter.trace.ron | 327 ++++++++++++++++++ 30 files changed, 2569 insertions(+) create mode 100644 trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_immediate_filter.graphql-parsed.ron create mode 100644 trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_immediate_filter.graphql.ron create mode 100644 trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_immediate_filter.ir.ron create mode 100644 trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_immediate_filter.output.ron create mode 100644 trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_immediate_filter.trace.ron create mode 100644 trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_immediate_is_not_null_filter.graphql-parsed.ron create mode 100644 trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_immediate_is_not_null_filter.graphql.ron create mode 100644 trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_immediate_is_not_null_filter.ir.ron create mode 100644 trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_immediate_is_not_null_filter.output.ron create mode 100644 trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_immediate_is_not_null_filter.trace.ron create mode 100644 trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_nested_filter.graphql-parsed.ron create mode 100644 trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_nested_filter.graphql.ron create mode 100644 trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_nested_filter.ir.ron create mode 100644 trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_nested_filter.output.ron create mode 100644 trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_nested_filter.trace.ron create mode 100644 trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_nested_is_not_null_filter.graphql-parsed.ron create mode 100644 trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_nested_is_not_null_filter.graphql.ron create mode 100644 trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_nested_is_not_null_filter.ir.ron create mode 100644 trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_nested_is_not_null_filter.output.ron create mode 100644 trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_nested_is_not_null_filter.trace.ron create mode 100644 trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_tagged_immediate_filter.graphql-parsed.ron create mode 100644 trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_tagged_immediate_filter.graphql.ron create mode 100644 trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_tagged_immediate_filter.ir.ron create mode 100644 trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_tagged_immediate_filter.output.ron create mode 100644 trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_tagged_immediate_filter.trace.ron create mode 100644 trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_tagged_nested_filter.graphql-parsed.ron create mode 100644 trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_tagged_nested_filter.graphql.ron create mode 100644 trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_tagged_nested_filter.ir.ron create mode 100644 trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_tagged_nested_filter.output.ron create mode 100644 trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_tagged_nested_filter.trace.ron diff --git a/trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_immediate_filter.graphql-parsed.ron b/trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_immediate_filter.graphql-parsed.ron new file mode 100644 index 00000000..c3ee128c --- /dev/null +++ b/trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_immediate_filter.graphql-parsed.ron @@ -0,0 +1,79 @@ +Ok(TestParsedGraphQLQuery( + schema_name: "numbers", + query: Query( + root_connection: FieldConnection( + position: Pos( + line: 3, + column: 5, + ), + name: "Zero", + ), + root_field: FieldNode( + position: Pos( + line: 3, + column: 5, + ), + name: "Zero", + connections: [ + (FieldConnection( + position: Pos( + line: 4, + column: 9, + ), + name: "value", + alias: Some("zero"), + ), FieldNode( + position: Pos( + line: 4, + column: 9, + ), + name: "value", + alias: Some("zero"), + output: [ + OutputDirective(), + ], + )), + (FieldConnection( + position: Pos( + line: 6, + column: 9, + ), + name: "predecessor", + optional: Some(OptionalDirective()), + ), FieldNode( + position: Pos( + line: 6, + column: 9, + ), + name: "predecessor", + connections: [ + (FieldConnection( + position: Pos( + line: 7, + column: 13, + ), + name: "value", + ), FieldNode( + position: Pos( + line: 7, + column: 13, + ), + name: "value", + filter: [ + FilterDirective( + operation: LessThan((), VariableRef("zero")), + ), + ], + output: [ + OutputDirective(), + ], + )), + ], + )), + ], + ), + ), + arguments: { + "zero": Int64(0), + }, +)) diff --git a/trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_immediate_filter.graphql.ron b/trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_immediate_filter.graphql.ron new file mode 100644 index 00000000..2a8798f4 --- /dev/null +++ b/trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_immediate_filter.graphql.ron @@ -0,0 +1,16 @@ +TestGraphQLQuery ( + schema_name: "numbers", + query: r#" +{ + Zero { + zero: value @output + + predecessor @optional { + value @output @filter(op: "<", value: ["$zero"]) + } + } +}"#, + arguments: { + "zero": Int64(0), + }, +) diff --git a/trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_immediate_filter.ir.ron b/trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_immediate_filter.ir.ron new file mode 100644 index 00000000..94f95a19 --- /dev/null +++ b/trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_immediate_filter.ir.ron @@ -0,0 +1,55 @@ +Ok(TestIRQuery( + schema_name: "numbers", + ir_query: IRQuery( + root_name: "Zero", + root_component: IRQueryComponent( + root: Vid(1), + vertices: { + Vid(1): IRVertex( + vid: Vid(1), + type_name: "Number", + ), + Vid(2): IRVertex( + vid: Vid(2), + type_name: "Number", + filters: [ + LessThan(LocalField( + field_name: "value", + field_type: "Int", + ), Variable(VariableRef( + variable_name: "zero", + variable_type: "Int!", + ))), + ], + ), + }, + edges: { + Eid(1): IREdge( + eid: Eid(1), + from_vid: Vid(1), + to_vid: Vid(2), + edge_name: "predecessor", + optional: true, + ), + }, + outputs: { + "value": ContextField( + vertex_id: Vid(2), + field_name: "value", + field_type: "Int", + ), + "zero": ContextField( + vertex_id: Vid(1), + field_name: "value", + field_type: "Int", + ), + }, + ), + variables: { + "zero": "Int!", + }, + ), + arguments: { + "zero": Int64(0), + }, +)) diff --git a/trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_immediate_filter.output.ron b/trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_immediate_filter.output.ron new file mode 100644 index 00000000..2a673cbb --- /dev/null +++ b/trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_immediate_filter.output.ron @@ -0,0 +1,16 @@ +TestInterpreterOutputData( + schema_name: "numbers", + outputs: { + "value": Output( + name: "value", + value_type: "Int", + vid: Vid(2), + ), + "zero": Output( + name: "zero", + value_type: "Int", + vid: Vid(1), + ), + }, + results: [], +) diff --git a/trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_immediate_filter.trace.ron b/trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_immediate_filter.trace.ron new file mode 100644 index 00000000..343ee549 --- /dev/null +++ b/trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_immediate_filter.trace.ron @@ -0,0 +1,209 @@ +TestInterpreterOutputTrace( + schema_name: "numbers", + trace: Trace( + ops: { + Opid(1): TraceOp( + opid: Opid(1), + parent_opid: None, + content: Call(ResolveStartingVertices(Vid(1))), + ), + Opid(2): TraceOp( + opid: Opid(2), + parent_opid: None, + content: Call(ResolveNeighbors(Vid(1), "Number", Eid(1))), + ), + Opid(3): TraceOp( + opid: Opid(3), + parent_opid: None, + content: Call(ResolveProperty(Vid(2), "Number", "value")), + ), + Opid(4): TraceOp( + opid: Opid(4), + parent_opid: None, + content: Call(ResolveProperty(Vid(2), "Number", "value")), + ), + Opid(5): TraceOp( + opid: Opid(5), + parent_opid: None, + content: Call(ResolveProperty(Vid(1), "Number", "value")), + ), + Opid(6): TraceOp( + opid: Opid(6), + parent_opid: Some(Opid(5)), + content: AdvanceInputIterator, + ), + Opid(7): TraceOp( + opid: Opid(7), + parent_opid: Some(Opid(4)), + content: AdvanceInputIterator, + ), + Opid(8): TraceOp( + opid: Opid(8), + parent_opid: Some(Opid(3)), + content: AdvanceInputIterator, + ), + Opid(9): TraceOp( + opid: Opid(9), + parent_opid: Some(Opid(2)), + content: AdvanceInputIterator, + ), + Opid(10): TraceOp( + opid: Opid(10), + parent_opid: Some(Opid(1)), + content: YieldFrom(ResolveStartingVertices(Neither(NeitherNumber(0)))), + ), + Opid(11): TraceOp( + opid: Opid(11), + parent_opid: Some(Opid(2)), + content: YieldInto(SerializableContext( + active_vertex: Some(Neither(NeitherNumber(0))), + vertices: { + Vid(1): Some(Neither(NeitherNumber(0))), + }, + )), + ), + Opid(12): TraceOp( + opid: Opid(12), + parent_opid: Some(Opid(2)), + content: YieldFrom(ResolveNeighborsOuter(SerializableContext( + active_vertex: Some(Neither(NeitherNumber(0))), + vertices: { + Vid(1): Some(Neither(NeitherNumber(0))), + }, + ))), + ), + Opid(13): TraceOp( + opid: Opid(13), + parent_opid: Some(Opid(12)), + content: OutputIteratorExhausted, + ), + Opid(14): TraceOp( + opid: Opid(14), + parent_opid: Some(Opid(3)), + content: YieldInto(SerializableContext( + active_vertex: None, + vertices: { + Vid(1): Some(Neither(NeitherNumber(0))), + }, + )), + ), + Opid(15): TraceOp( + opid: Opid(15), + parent_opid: Some(Opid(3)), + content: YieldFrom(ResolveProperty(SerializableContext( + active_vertex: None, + vertices: { + Vid(1): Some(Neither(NeitherNumber(0))), + }, + ), Null)), + ), + Opid(16): TraceOp( + opid: Opid(16), + parent_opid: Some(Opid(3)), + content: AdvanceInputIterator, + ), + Opid(17): TraceOp( + opid: Opid(17), + parent_opid: Some(Opid(2)), + content: AdvanceInputIterator, + ), + Opid(18): TraceOp( + opid: Opid(18), + parent_opid: Some(Opid(1)), + content: OutputIteratorExhausted, + ), + Opid(19): TraceOp( + opid: Opid(19), + parent_opid: Some(Opid(2)), + content: InputIteratorExhausted, + ), + Opid(20): TraceOp( + opid: Opid(20), + parent_opid: Some(Opid(2)), + content: OutputIteratorExhausted, + ), + Opid(21): TraceOp( + opid: Opid(21), + parent_opid: Some(Opid(3)), + content: InputIteratorExhausted, + ), + Opid(22): TraceOp( + opid: Opid(22), + parent_opid: Some(Opid(3)), + content: OutputIteratorExhausted, + ), + Opid(23): TraceOp( + opid: Opid(23), + parent_opid: Some(Opid(4)), + content: InputIteratorExhausted, + ), + Opid(24): TraceOp( + opid: Opid(24), + parent_opid: Some(Opid(4)), + content: OutputIteratorExhausted, + ), + Opid(25): TraceOp( + opid: Opid(25), + parent_opid: Some(Opid(5)), + content: InputIteratorExhausted, + ), + Opid(26): TraceOp( + opid: Opid(26), + parent_opid: Some(Opid(5)), + content: OutputIteratorExhausted, + ), + }, + ir_query: IRQuery( + root_name: "Zero", + root_component: IRQueryComponent( + root: Vid(1), + vertices: { + Vid(1): IRVertex( + vid: Vid(1), + type_name: "Number", + ), + Vid(2): IRVertex( + vid: Vid(2), + type_name: "Number", + filters: [ + LessThan(LocalField( + field_name: "value", + field_type: "Int", + ), Variable(VariableRef( + variable_name: "zero", + variable_type: "Int!", + ))), + ], + ), + }, + edges: { + Eid(1): IREdge( + eid: Eid(1), + from_vid: Vid(1), + to_vid: Vid(2), + edge_name: "predecessor", + optional: true, + ), + }, + outputs: { + "value": ContextField( + vertex_id: Vid(2), + field_name: "value", + field_type: "Int", + ), + "zero": ContextField( + vertex_id: Vid(1), + field_name: "value", + field_type: "Int", + ), + }, + ), + variables: { + "zero": "Int!", + }, + ), + arguments: { + "zero": Int64(0), + }, + ), +) diff --git a/trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_immediate_is_not_null_filter.graphql-parsed.ron b/trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_immediate_is_not_null_filter.graphql-parsed.ron new file mode 100644 index 00000000..22c92d47 --- /dev/null +++ b/trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_immediate_is_not_null_filter.graphql-parsed.ron @@ -0,0 +1,76 @@ +Ok(TestParsedGraphQLQuery( + schema_name: "numbers", + query: Query( + root_connection: FieldConnection( + position: Pos( + line: 3, + column: 5, + ), + name: "Zero", + ), + root_field: FieldNode( + position: Pos( + line: 3, + column: 5, + ), + name: "Zero", + connections: [ + (FieldConnection( + position: Pos( + line: 4, + column: 9, + ), + name: "value", + alias: Some("zero"), + ), FieldNode( + position: Pos( + line: 4, + column: 9, + ), + name: "value", + alias: Some("zero"), + output: [ + OutputDirective(), + ], + )), + (FieldConnection( + position: Pos( + line: 6, + column: 9, + ), + name: "predecessor", + optional: Some(OptionalDirective()), + ), FieldNode( + position: Pos( + line: 6, + column: 9, + ), + name: "predecessor", + connections: [ + (FieldConnection( + position: Pos( + line: 7, + column: 13, + ), + name: "value", + ), FieldNode( + position: Pos( + line: 7, + column: 13, + ), + name: "value", + filter: [ + FilterDirective( + operation: IsNotNull(()), + ), + ], + output: [ + OutputDirective(), + ], + )), + ], + )), + ], + ), + ), +)) diff --git a/trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_immediate_is_not_null_filter.graphql.ron b/trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_immediate_is_not_null_filter.graphql.ron new file mode 100644 index 00000000..ae1eaa41 --- /dev/null +++ b/trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_immediate_is_not_null_filter.graphql.ron @@ -0,0 +1,14 @@ +TestGraphQLQuery ( + schema_name: "numbers", + query: r#" +{ + Zero { + zero: value @output + + predecessor @optional { + value @output @filter(op: "is_not_null") + } + } +}"#, + arguments: {}, +) diff --git a/trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_immediate_is_not_null_filter.ir.ron b/trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_immediate_is_not_null_filter.ir.ron new file mode 100644 index 00000000..8acc61d8 --- /dev/null +++ b/trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_immediate_is_not_null_filter.ir.ron @@ -0,0 +1,46 @@ +Ok(TestIRQuery( + schema_name: "numbers", + ir_query: IRQuery( + root_name: "Zero", + root_component: IRQueryComponent( + root: Vid(1), + vertices: { + Vid(1): IRVertex( + vid: Vid(1), + type_name: "Number", + ), + Vid(2): IRVertex( + vid: Vid(2), + type_name: "Number", + filters: [ + IsNotNull(LocalField( + field_name: "value", + field_type: "Int", + )), + ], + ), + }, + edges: { + Eid(1): IREdge( + eid: Eid(1), + from_vid: Vid(1), + to_vid: Vid(2), + edge_name: "predecessor", + optional: true, + ), + }, + outputs: { + "value": ContextField( + vertex_id: Vid(2), + field_name: "value", + field_type: "Int", + ), + "zero": ContextField( + vertex_id: Vid(1), + field_name: "value", + field_type: "Int", + ), + }, + ), + ), +)) diff --git a/trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_immediate_is_not_null_filter.output.ron b/trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_immediate_is_not_null_filter.output.ron new file mode 100644 index 00000000..2a673cbb --- /dev/null +++ b/trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_immediate_is_not_null_filter.output.ron @@ -0,0 +1,16 @@ +TestInterpreterOutputData( + schema_name: "numbers", + outputs: { + "value": Output( + name: "value", + value_type: "Int", + vid: Vid(2), + ), + "zero": Output( + name: "zero", + value_type: "Int", + vid: Vid(1), + ), + }, + results: [], +) diff --git a/trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_immediate_is_not_null_filter.trace.ron b/trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_immediate_is_not_null_filter.trace.ron new file mode 100644 index 00000000..ddd05eeb --- /dev/null +++ b/trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_immediate_is_not_null_filter.trace.ron @@ -0,0 +1,200 @@ +TestInterpreterOutputTrace( + schema_name: "numbers", + trace: Trace( + ops: { + Opid(1): TraceOp( + opid: Opid(1), + parent_opid: None, + content: Call(ResolveStartingVertices(Vid(1))), + ), + Opid(2): TraceOp( + opid: Opid(2), + parent_opid: None, + content: Call(ResolveNeighbors(Vid(1), "Number", Eid(1))), + ), + Opid(3): TraceOp( + opid: Opid(3), + parent_opid: None, + content: Call(ResolveProperty(Vid(2), "Number", "value")), + ), + Opid(4): TraceOp( + opid: Opid(4), + parent_opid: None, + content: Call(ResolveProperty(Vid(2), "Number", "value")), + ), + Opid(5): TraceOp( + opid: Opid(5), + parent_opid: None, + content: Call(ResolveProperty(Vid(1), "Number", "value")), + ), + Opid(6): TraceOp( + opid: Opid(6), + parent_opid: Some(Opid(5)), + content: AdvanceInputIterator, + ), + Opid(7): TraceOp( + opid: Opid(7), + parent_opid: Some(Opid(4)), + content: AdvanceInputIterator, + ), + Opid(8): TraceOp( + opid: Opid(8), + parent_opid: Some(Opid(3)), + content: AdvanceInputIterator, + ), + Opid(9): TraceOp( + opid: Opid(9), + parent_opid: Some(Opid(2)), + content: AdvanceInputIterator, + ), + Opid(10): TraceOp( + opid: Opid(10), + parent_opid: Some(Opid(1)), + content: YieldFrom(ResolveStartingVertices(Neither(NeitherNumber(0)))), + ), + Opid(11): TraceOp( + opid: Opid(11), + parent_opid: Some(Opid(2)), + content: YieldInto(SerializableContext( + active_vertex: Some(Neither(NeitherNumber(0))), + vertices: { + Vid(1): Some(Neither(NeitherNumber(0))), + }, + )), + ), + Opid(12): TraceOp( + opid: Opid(12), + parent_opid: Some(Opid(2)), + content: YieldFrom(ResolveNeighborsOuter(SerializableContext( + active_vertex: Some(Neither(NeitherNumber(0))), + vertices: { + Vid(1): Some(Neither(NeitherNumber(0))), + }, + ))), + ), + Opid(13): TraceOp( + opid: Opid(13), + parent_opid: Some(Opid(12)), + content: OutputIteratorExhausted, + ), + Opid(14): TraceOp( + opid: Opid(14), + parent_opid: Some(Opid(3)), + content: YieldInto(SerializableContext( + active_vertex: None, + vertices: { + Vid(1): Some(Neither(NeitherNumber(0))), + }, + )), + ), + Opid(15): TraceOp( + opid: Opid(15), + parent_opid: Some(Opid(3)), + content: YieldFrom(ResolveProperty(SerializableContext( + active_vertex: None, + vertices: { + Vid(1): Some(Neither(NeitherNumber(0))), + }, + ), Null)), + ), + Opid(16): TraceOp( + opid: Opid(16), + parent_opid: Some(Opid(3)), + content: AdvanceInputIterator, + ), + Opid(17): TraceOp( + opid: Opid(17), + parent_opid: Some(Opid(2)), + content: AdvanceInputIterator, + ), + Opid(18): TraceOp( + opid: Opid(18), + parent_opid: Some(Opid(1)), + content: OutputIteratorExhausted, + ), + Opid(19): TraceOp( + opid: Opid(19), + parent_opid: Some(Opid(2)), + content: InputIteratorExhausted, + ), + Opid(20): TraceOp( + opid: Opid(20), + parent_opid: Some(Opid(2)), + content: OutputIteratorExhausted, + ), + Opid(21): TraceOp( + opid: Opid(21), + parent_opid: Some(Opid(3)), + content: InputIteratorExhausted, + ), + Opid(22): TraceOp( + opid: Opid(22), + parent_opid: Some(Opid(3)), + content: OutputIteratorExhausted, + ), + Opid(23): TraceOp( + opid: Opid(23), + parent_opid: Some(Opid(4)), + content: InputIteratorExhausted, + ), + Opid(24): TraceOp( + opid: Opid(24), + parent_opid: Some(Opid(4)), + content: OutputIteratorExhausted, + ), + Opid(25): TraceOp( + opid: Opid(25), + parent_opid: Some(Opid(5)), + content: InputIteratorExhausted, + ), + Opid(26): TraceOp( + opid: Opid(26), + parent_opid: Some(Opid(5)), + content: OutputIteratorExhausted, + ), + }, + ir_query: IRQuery( + root_name: "Zero", + root_component: IRQueryComponent( + root: Vid(1), + vertices: { + Vid(1): IRVertex( + vid: Vid(1), + type_name: "Number", + ), + Vid(2): IRVertex( + vid: Vid(2), + type_name: "Number", + filters: [ + IsNotNull(LocalField( + field_name: "value", + field_type: "Int", + )), + ], + ), + }, + edges: { + Eid(1): IREdge( + eid: Eid(1), + from_vid: Vid(1), + to_vid: Vid(2), + edge_name: "predecessor", + optional: true, + ), + }, + outputs: { + "value": ContextField( + vertex_id: Vid(2), + field_name: "value", + field_type: "Int", + ), + "zero": ContextField( + vertex_id: Vid(1), + field_name: "value", + field_type: "Int", + ), + }, + ), + ), + ), +) diff --git a/trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_nested_filter.graphql-parsed.ron b/trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_nested_filter.graphql-parsed.ron new file mode 100644 index 00000000..9b64fbaa --- /dev/null +++ b/trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_nested_filter.graphql-parsed.ron @@ -0,0 +1,94 @@ +Ok(TestParsedGraphQLQuery( + schema_name: "numbers", + query: Query( + root_connection: FieldConnection( + position: Pos( + line: 3, + column: 5, + ), + name: "Zero", + ), + root_field: FieldNode( + position: Pos( + line: 3, + column: 5, + ), + name: "Zero", + connections: [ + (FieldConnection( + position: Pos( + line: 4, + column: 9, + ), + name: "value", + alias: Some("zero"), + ), FieldNode( + position: Pos( + line: 4, + column: 9, + ), + name: "value", + alias: Some("zero"), + output: [ + OutputDirective(), + ], + )), + (FieldConnection( + position: Pos( + line: 6, + column: 9, + ), + name: "predecessor", + optional: Some(OptionalDirective()), + ), FieldNode( + position: Pos( + line: 6, + column: 9, + ), + name: "predecessor", + connections: [ + (FieldConnection( + position: Pos( + line: 7, + column: 13, + ), + name: "successor", + ), FieldNode( + position: Pos( + line: 7, + column: 13, + ), + name: "successor", + connections: [ + (FieldConnection( + position: Pos( + line: 8, + column: 17, + ), + name: "value", + ), FieldNode( + position: Pos( + line: 8, + column: 17, + ), + name: "value", + filter: [ + FilterDirective( + operation: Equals((), VariableRef("zero")), + ), + ], + output: [ + OutputDirective(), + ], + )), + ], + )), + ], + )), + ], + ), + ), + arguments: { + "zero": Int64(0), + }, +)) diff --git a/trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_nested_filter.graphql.ron b/trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_nested_filter.graphql.ron new file mode 100644 index 00000000..8b65b0a2 --- /dev/null +++ b/trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_nested_filter.graphql.ron @@ -0,0 +1,18 @@ +TestGraphQLQuery ( + schema_name: "numbers", + query: r#" +{ + Zero { + zero: value @output + + predecessor @optional { + successor { + value @output @filter(op: "=", value: ["$zero"]) + } + } + } +}"#, + arguments: { + "zero": Int64(0), + }, +) diff --git a/trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_nested_filter.ir.ron b/trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_nested_filter.ir.ron new file mode 100644 index 00000000..584c1757 --- /dev/null +++ b/trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_nested_filter.ir.ron @@ -0,0 +1,65 @@ +Ok(TestIRQuery( + schema_name: "numbers", + ir_query: IRQuery( + root_name: "Zero", + root_component: IRQueryComponent( + root: Vid(1), + vertices: { + Vid(1): IRVertex( + vid: Vid(1), + type_name: "Number", + ), + Vid(2): IRVertex( + vid: Vid(2), + type_name: "Number", + ), + Vid(3): IRVertex( + vid: Vid(3), + type_name: "Number", + filters: [ + Equals(LocalField( + field_name: "value", + field_type: "Int", + ), Variable(VariableRef( + variable_name: "zero", + variable_type: "Int", + ))), + ], + ), + }, + edges: { + Eid(1): IREdge( + eid: Eid(1), + from_vid: Vid(1), + to_vid: Vid(2), + edge_name: "predecessor", + optional: true, + ), + Eid(2): IREdge( + eid: Eid(2), + from_vid: Vid(2), + to_vid: Vid(3), + edge_name: "successor", + ), + }, + outputs: { + "value": ContextField( + vertex_id: Vid(3), + field_name: "value", + field_type: "Int", + ), + "zero": ContextField( + vertex_id: Vid(1), + field_name: "value", + field_type: "Int", + ), + }, + ), + variables: { + "zero": "Int", + }, + ), + arguments: { + "zero": Int64(0), + }, +)) diff --git a/trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_nested_filter.output.ron b/trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_nested_filter.output.ron new file mode 100644 index 00000000..2d5221b6 --- /dev/null +++ b/trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_nested_filter.output.ron @@ -0,0 +1,16 @@ +TestInterpreterOutputData( + schema_name: "numbers", + outputs: { + "value": Output( + name: "value", + value_type: "Int", + vid: Vid(3), + ), + "zero": Output( + name: "zero", + value_type: "Int", + vid: Vid(1), + ), + }, + results: [], +) diff --git a/trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_nested_filter.trace.ron b/trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_nested_filter.trace.ron new file mode 100644 index 00000000..8e5a2f2a --- /dev/null +++ b/trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_nested_filter.trace.ron @@ -0,0 +1,273 @@ +TestInterpreterOutputTrace( + schema_name: "numbers", + trace: Trace( + ops: { + Opid(1): TraceOp( + opid: Opid(1), + parent_opid: None, + content: Call(ResolveStartingVertices(Vid(1))), + ), + Opid(2): TraceOp( + opid: Opid(2), + parent_opid: None, + content: Call(ResolveNeighbors(Vid(1), "Number", Eid(1))), + ), + Opid(3): TraceOp( + opid: Opid(3), + parent_opid: None, + content: Call(ResolveNeighbors(Vid(2), "Number", Eid(2))), + ), + Opid(4): TraceOp( + opid: Opid(4), + parent_opid: None, + content: Call(ResolveProperty(Vid(3), "Number", "value")), + ), + Opid(5): TraceOp( + opid: Opid(5), + parent_opid: None, + content: Call(ResolveProperty(Vid(3), "Number", "value")), + ), + Opid(6): TraceOp( + opid: Opid(6), + parent_opid: None, + content: Call(ResolveProperty(Vid(1), "Number", "value")), + ), + Opid(7): TraceOp( + opid: Opid(7), + parent_opid: Some(Opid(6)), + content: AdvanceInputIterator, + ), + Opid(8): TraceOp( + opid: Opid(8), + parent_opid: Some(Opid(5)), + content: AdvanceInputIterator, + ), + Opid(9): TraceOp( + opid: Opid(9), + parent_opid: Some(Opid(4)), + content: AdvanceInputIterator, + ), + Opid(10): TraceOp( + opid: Opid(10), + parent_opid: Some(Opid(3)), + content: AdvanceInputIterator, + ), + Opid(11): TraceOp( + opid: Opid(11), + parent_opid: Some(Opid(2)), + content: AdvanceInputIterator, + ), + Opid(12): TraceOp( + opid: Opid(12), + parent_opid: Some(Opid(1)), + content: YieldFrom(ResolveStartingVertices(Neither(NeitherNumber(0)))), + ), + Opid(13): TraceOp( + opid: Opid(13), + parent_opid: Some(Opid(2)), + content: YieldInto(SerializableContext( + active_vertex: Some(Neither(NeitherNumber(0))), + vertices: { + Vid(1): Some(Neither(NeitherNumber(0))), + }, + )), + ), + Opid(14): TraceOp( + opid: Opid(14), + parent_opid: Some(Opid(2)), + content: YieldFrom(ResolveNeighborsOuter(SerializableContext( + active_vertex: Some(Neither(NeitherNumber(0))), + vertices: { + Vid(1): Some(Neither(NeitherNumber(0))), + }, + ))), + ), + Opid(15): TraceOp( + opid: Opid(15), + parent_opid: Some(Opid(14)), + content: OutputIteratorExhausted, + ), + Opid(16): TraceOp( + opid: Opid(16), + parent_opid: Some(Opid(3)), + content: YieldInto(SerializableContext( + active_vertex: None, + vertices: { + Vid(1): Some(Neither(NeitherNumber(0))), + Vid(2): None, + }, + )), + ), + Opid(17): TraceOp( + opid: Opid(17), + parent_opid: Some(Opid(3)), + content: YieldFrom(ResolveNeighborsOuter(SerializableContext( + active_vertex: None, + vertices: { + Vid(1): Some(Neither(NeitherNumber(0))), + Vid(2): None, + }, + ))), + ), + Opid(18): TraceOp( + opid: Opid(18), + parent_opid: Some(Opid(17)), + content: OutputIteratorExhausted, + ), + Opid(19): TraceOp( + opid: Opid(19), + parent_opid: Some(Opid(4)), + content: YieldInto(SerializableContext( + active_vertex: None, + vertices: { + Vid(1): Some(Neither(NeitherNumber(0))), + Vid(2): None, + }, + )), + ), + Opid(20): TraceOp( + opid: Opid(20), + parent_opid: Some(Opid(4)), + content: YieldFrom(ResolveProperty(SerializableContext( + active_vertex: None, + vertices: { + Vid(1): Some(Neither(NeitherNumber(0))), + Vid(2): None, + }, + ), Null)), + ), + Opid(21): TraceOp( + opid: Opid(21), + parent_opid: Some(Opid(4)), + content: AdvanceInputIterator, + ), + Opid(22): TraceOp( + opid: Opid(22), + parent_opid: Some(Opid(3)), + content: AdvanceInputIterator, + ), + Opid(23): TraceOp( + opid: Opid(23), + parent_opid: Some(Opid(2)), + content: AdvanceInputIterator, + ), + Opid(24): TraceOp( + opid: Opid(24), + parent_opid: Some(Opid(1)), + content: OutputIteratorExhausted, + ), + Opid(25): TraceOp( + opid: Opid(25), + parent_opid: Some(Opid(2)), + content: InputIteratorExhausted, + ), + Opid(26): TraceOp( + opid: Opid(26), + parent_opid: Some(Opid(2)), + content: OutputIteratorExhausted, + ), + Opid(27): TraceOp( + opid: Opid(27), + parent_opid: Some(Opid(3)), + content: InputIteratorExhausted, + ), + Opid(28): TraceOp( + opid: Opid(28), + parent_opid: Some(Opid(3)), + content: OutputIteratorExhausted, + ), + Opid(29): TraceOp( + opid: Opid(29), + parent_opid: Some(Opid(4)), + content: InputIteratorExhausted, + ), + Opid(30): TraceOp( + opid: Opid(30), + parent_opid: Some(Opid(4)), + content: OutputIteratorExhausted, + ), + Opid(31): TraceOp( + opid: Opid(31), + parent_opid: Some(Opid(5)), + content: InputIteratorExhausted, + ), + Opid(32): TraceOp( + opid: Opid(32), + parent_opid: Some(Opid(5)), + content: OutputIteratorExhausted, + ), + Opid(33): TraceOp( + opid: Opid(33), + parent_opid: Some(Opid(6)), + content: InputIteratorExhausted, + ), + Opid(34): TraceOp( + opid: Opid(34), + parent_opid: Some(Opid(6)), + content: OutputIteratorExhausted, + ), + }, + ir_query: IRQuery( + root_name: "Zero", + root_component: IRQueryComponent( + root: Vid(1), + vertices: { + Vid(1): IRVertex( + vid: Vid(1), + type_name: "Number", + ), + Vid(2): IRVertex( + vid: Vid(2), + type_name: "Number", + ), + Vid(3): IRVertex( + vid: Vid(3), + type_name: "Number", + filters: [ + Equals(LocalField( + field_name: "value", + field_type: "Int", + ), Variable(VariableRef( + variable_name: "zero", + variable_type: "Int", + ))), + ], + ), + }, + edges: { + Eid(1): IREdge( + eid: Eid(1), + from_vid: Vid(1), + to_vid: Vid(2), + edge_name: "predecessor", + optional: true, + ), + Eid(2): IREdge( + eid: Eid(2), + from_vid: Vid(2), + to_vid: Vid(3), + edge_name: "successor", + ), + }, + outputs: { + "value": ContextField( + vertex_id: Vid(3), + field_name: "value", + field_type: "Int", + ), + "zero": ContextField( + vertex_id: Vid(1), + field_name: "value", + field_type: "Int", + ), + }, + ), + variables: { + "zero": "Int", + }, + ), + arguments: { + "zero": Int64(0), + }, + ), +) diff --git a/trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_nested_is_not_null_filter.graphql-parsed.ron b/trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_nested_is_not_null_filter.graphql-parsed.ron new file mode 100644 index 00000000..113b50cd --- /dev/null +++ b/trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_nested_is_not_null_filter.graphql-parsed.ron @@ -0,0 +1,91 @@ +Ok(TestParsedGraphQLQuery( + schema_name: "numbers", + query: Query( + root_connection: FieldConnection( + position: Pos( + line: 3, + column: 5, + ), + name: "Zero", + ), + root_field: FieldNode( + position: Pos( + line: 3, + column: 5, + ), + name: "Zero", + connections: [ + (FieldConnection( + position: Pos( + line: 4, + column: 9, + ), + name: "value", + alias: Some("zero"), + ), FieldNode( + position: Pos( + line: 4, + column: 9, + ), + name: "value", + alias: Some("zero"), + output: [ + OutputDirective(), + ], + )), + (FieldConnection( + position: Pos( + line: 6, + column: 9, + ), + name: "predecessor", + optional: Some(OptionalDirective()), + ), FieldNode( + position: Pos( + line: 6, + column: 9, + ), + name: "predecessor", + connections: [ + (FieldConnection( + position: Pos( + line: 7, + column: 13, + ), + name: "successor", + ), FieldNode( + position: Pos( + line: 7, + column: 13, + ), + name: "successor", + connections: [ + (FieldConnection( + position: Pos( + line: 8, + column: 17, + ), + name: "value", + ), FieldNode( + position: Pos( + line: 8, + column: 17, + ), + name: "value", + filter: [ + FilterDirective( + operation: IsNotNull(()), + ), + ], + output: [ + OutputDirective(), + ], + )), + ], + )), + ], + )), + ], + ), + ), +)) diff --git a/trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_nested_is_not_null_filter.graphql.ron b/trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_nested_is_not_null_filter.graphql.ron new file mode 100644 index 00000000..ae71a0a2 --- /dev/null +++ b/trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_nested_is_not_null_filter.graphql.ron @@ -0,0 +1,16 @@ +TestGraphQLQuery ( + schema_name: "numbers", + query: r#" +{ + Zero { + zero: value @output + + predecessor @optional { + successor { + value @output @filter(op: "is_not_null") + } + } + } +}"#, + arguments: {}, +) diff --git a/trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_nested_is_not_null_filter.ir.ron b/trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_nested_is_not_null_filter.ir.ron new file mode 100644 index 00000000..13969f73 --- /dev/null +++ b/trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_nested_is_not_null_filter.ir.ron @@ -0,0 +1,56 @@ +Ok(TestIRQuery( + schema_name: "numbers", + ir_query: IRQuery( + root_name: "Zero", + root_component: IRQueryComponent( + root: Vid(1), + vertices: { + Vid(1): IRVertex( + vid: Vid(1), + type_name: "Number", + ), + Vid(2): IRVertex( + vid: Vid(2), + type_name: "Number", + ), + Vid(3): IRVertex( + vid: Vid(3), + type_name: "Number", + filters: [ + IsNotNull(LocalField( + field_name: "value", + field_type: "Int", + )), + ], + ), + }, + edges: { + Eid(1): IREdge( + eid: Eid(1), + from_vid: Vid(1), + to_vid: Vid(2), + edge_name: "predecessor", + optional: true, + ), + Eid(2): IREdge( + eid: Eid(2), + from_vid: Vid(2), + to_vid: Vid(3), + edge_name: "successor", + ), + }, + outputs: { + "value": ContextField( + vertex_id: Vid(3), + field_name: "value", + field_type: "Int", + ), + "zero": ContextField( + vertex_id: Vid(1), + field_name: "value", + field_type: "Int", + ), + }, + ), + ), +)) diff --git a/trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_nested_is_not_null_filter.output.ron b/trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_nested_is_not_null_filter.output.ron new file mode 100644 index 00000000..2d5221b6 --- /dev/null +++ b/trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_nested_is_not_null_filter.output.ron @@ -0,0 +1,16 @@ +TestInterpreterOutputData( + schema_name: "numbers", + outputs: { + "value": Output( + name: "value", + value_type: "Int", + vid: Vid(3), + ), + "zero": Output( + name: "zero", + value_type: "Int", + vid: Vid(1), + ), + }, + results: [], +) diff --git a/trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_nested_is_not_null_filter.trace.ron b/trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_nested_is_not_null_filter.trace.ron new file mode 100644 index 00000000..1f212a3d --- /dev/null +++ b/trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_nested_is_not_null_filter.trace.ron @@ -0,0 +1,264 @@ +TestInterpreterOutputTrace( + schema_name: "numbers", + trace: Trace( + ops: { + Opid(1): TraceOp( + opid: Opid(1), + parent_opid: None, + content: Call(ResolveStartingVertices(Vid(1))), + ), + Opid(2): TraceOp( + opid: Opid(2), + parent_opid: None, + content: Call(ResolveNeighbors(Vid(1), "Number", Eid(1))), + ), + Opid(3): TraceOp( + opid: Opid(3), + parent_opid: None, + content: Call(ResolveNeighbors(Vid(2), "Number", Eid(2))), + ), + Opid(4): TraceOp( + opid: Opid(4), + parent_opid: None, + content: Call(ResolveProperty(Vid(3), "Number", "value")), + ), + Opid(5): TraceOp( + opid: Opid(5), + parent_opid: None, + content: Call(ResolveProperty(Vid(3), "Number", "value")), + ), + Opid(6): TraceOp( + opid: Opid(6), + parent_opid: None, + content: Call(ResolveProperty(Vid(1), "Number", "value")), + ), + Opid(7): TraceOp( + opid: Opid(7), + parent_opid: Some(Opid(6)), + content: AdvanceInputIterator, + ), + Opid(8): TraceOp( + opid: Opid(8), + parent_opid: Some(Opid(5)), + content: AdvanceInputIterator, + ), + Opid(9): TraceOp( + opid: Opid(9), + parent_opid: Some(Opid(4)), + content: AdvanceInputIterator, + ), + Opid(10): TraceOp( + opid: Opid(10), + parent_opid: Some(Opid(3)), + content: AdvanceInputIterator, + ), + Opid(11): TraceOp( + opid: Opid(11), + parent_opid: Some(Opid(2)), + content: AdvanceInputIterator, + ), + Opid(12): TraceOp( + opid: Opid(12), + parent_opid: Some(Opid(1)), + content: YieldFrom(ResolveStartingVertices(Neither(NeitherNumber(0)))), + ), + Opid(13): TraceOp( + opid: Opid(13), + parent_opid: Some(Opid(2)), + content: YieldInto(SerializableContext( + active_vertex: Some(Neither(NeitherNumber(0))), + vertices: { + Vid(1): Some(Neither(NeitherNumber(0))), + }, + )), + ), + Opid(14): TraceOp( + opid: Opid(14), + parent_opid: Some(Opid(2)), + content: YieldFrom(ResolveNeighborsOuter(SerializableContext( + active_vertex: Some(Neither(NeitherNumber(0))), + vertices: { + Vid(1): Some(Neither(NeitherNumber(0))), + }, + ))), + ), + Opid(15): TraceOp( + opid: Opid(15), + parent_opid: Some(Opid(14)), + content: OutputIteratorExhausted, + ), + Opid(16): TraceOp( + opid: Opid(16), + parent_opid: Some(Opid(3)), + content: YieldInto(SerializableContext( + active_vertex: None, + vertices: { + Vid(1): Some(Neither(NeitherNumber(0))), + Vid(2): None, + }, + )), + ), + Opid(17): TraceOp( + opid: Opid(17), + parent_opid: Some(Opid(3)), + content: YieldFrom(ResolveNeighborsOuter(SerializableContext( + active_vertex: None, + vertices: { + Vid(1): Some(Neither(NeitherNumber(0))), + Vid(2): None, + }, + ))), + ), + Opid(18): TraceOp( + opid: Opid(18), + parent_opid: Some(Opid(17)), + content: OutputIteratorExhausted, + ), + Opid(19): TraceOp( + opid: Opid(19), + parent_opid: Some(Opid(4)), + content: YieldInto(SerializableContext( + active_vertex: None, + vertices: { + Vid(1): Some(Neither(NeitherNumber(0))), + Vid(2): None, + }, + )), + ), + Opid(20): TraceOp( + opid: Opid(20), + parent_opid: Some(Opid(4)), + content: YieldFrom(ResolveProperty(SerializableContext( + active_vertex: None, + vertices: { + Vid(1): Some(Neither(NeitherNumber(0))), + Vid(2): None, + }, + ), Null)), + ), + Opid(21): TraceOp( + opid: Opid(21), + parent_opid: Some(Opid(4)), + content: AdvanceInputIterator, + ), + Opid(22): TraceOp( + opid: Opid(22), + parent_opid: Some(Opid(3)), + content: AdvanceInputIterator, + ), + Opid(23): TraceOp( + opid: Opid(23), + parent_opid: Some(Opid(2)), + content: AdvanceInputIterator, + ), + Opid(24): TraceOp( + opid: Opid(24), + parent_opid: Some(Opid(1)), + content: OutputIteratorExhausted, + ), + Opid(25): TraceOp( + opid: Opid(25), + parent_opid: Some(Opid(2)), + content: InputIteratorExhausted, + ), + Opid(26): TraceOp( + opid: Opid(26), + parent_opid: Some(Opid(2)), + content: OutputIteratorExhausted, + ), + Opid(27): TraceOp( + opid: Opid(27), + parent_opid: Some(Opid(3)), + content: InputIteratorExhausted, + ), + Opid(28): TraceOp( + opid: Opid(28), + parent_opid: Some(Opid(3)), + content: OutputIteratorExhausted, + ), + Opid(29): TraceOp( + opid: Opid(29), + parent_opid: Some(Opid(4)), + content: InputIteratorExhausted, + ), + Opid(30): TraceOp( + opid: Opid(30), + parent_opid: Some(Opid(4)), + content: OutputIteratorExhausted, + ), + Opid(31): TraceOp( + opid: Opid(31), + parent_opid: Some(Opid(5)), + content: InputIteratorExhausted, + ), + Opid(32): TraceOp( + opid: Opid(32), + parent_opid: Some(Opid(5)), + content: OutputIteratorExhausted, + ), + Opid(33): TraceOp( + opid: Opid(33), + parent_opid: Some(Opid(6)), + content: InputIteratorExhausted, + ), + Opid(34): TraceOp( + opid: Opid(34), + parent_opid: Some(Opid(6)), + content: OutputIteratorExhausted, + ), + }, + ir_query: IRQuery( + root_name: "Zero", + root_component: IRQueryComponent( + root: Vid(1), + vertices: { + Vid(1): IRVertex( + vid: Vid(1), + type_name: "Number", + ), + Vid(2): IRVertex( + vid: Vid(2), + type_name: "Number", + ), + Vid(3): IRVertex( + vid: Vid(3), + type_name: "Number", + filters: [ + IsNotNull(LocalField( + field_name: "value", + field_type: "Int", + )), + ], + ), + }, + edges: { + Eid(1): IREdge( + eid: Eid(1), + from_vid: Vid(1), + to_vid: Vid(2), + edge_name: "predecessor", + optional: true, + ), + Eid(2): IREdge( + eid: Eid(2), + from_vid: Vid(2), + to_vid: Vid(3), + edge_name: "successor", + ), + }, + outputs: { + "value": ContextField( + vertex_id: Vid(3), + field_name: "value", + field_type: "Int", + ), + "zero": ContextField( + vertex_id: Vid(1), + field_name: "value", + field_type: "Int", + ), + }, + ), + ), + ), +) diff --git a/trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_tagged_immediate_filter.graphql-parsed.ron b/trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_tagged_immediate_filter.graphql-parsed.ron new file mode 100644 index 00000000..58fc39bb --- /dev/null +++ b/trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_tagged_immediate_filter.graphql-parsed.ron @@ -0,0 +1,79 @@ +Ok(TestParsedGraphQLQuery( + schema_name: "numbers", + query: Query( + root_connection: FieldConnection( + position: Pos( + line: 3, + column: 5, + ), + name: "Zero", + ), + root_field: FieldNode( + position: Pos( + line: 3, + column: 5, + ), + name: "Zero", + connections: [ + (FieldConnection( + position: Pos( + line: 4, + column: 9, + ), + name: "value", + alias: Some("zero"), + ), FieldNode( + position: Pos( + line: 4, + column: 9, + ), + name: "value", + alias: Some("zero"), + output: [ + OutputDirective(), + ], + tag: [ + TagDirective(), + ], + )), + (FieldConnection( + position: Pos( + line: 6, + column: 9, + ), + name: "predecessor", + optional: Some(OptionalDirective()), + ), FieldNode( + position: Pos( + line: 6, + column: 9, + ), + name: "predecessor", + connections: [ + (FieldConnection( + position: Pos( + line: 7, + column: 13, + ), + name: "value", + ), FieldNode( + position: Pos( + line: 7, + column: 13, + ), + name: "value", + filter: [ + FilterDirective( + operation: LessThan((), TagRef("zero")), + ), + ], + output: [ + OutputDirective(), + ], + )), + ], + )), + ], + ), + ), +)) diff --git a/trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_tagged_immediate_filter.graphql.ron b/trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_tagged_immediate_filter.graphql.ron new file mode 100644 index 00000000..d6a61c3f --- /dev/null +++ b/trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_tagged_immediate_filter.graphql.ron @@ -0,0 +1,14 @@ +TestGraphQLQuery ( + schema_name: "numbers", + query: r#" +{ + Zero { + zero: value @output @tag + + predecessor @optional { + value @output @filter(op: "<", value: ["%zero"]) + } + } +}"#, + arguments: {}, +) diff --git a/trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_tagged_immediate_filter.ir.ron b/trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_tagged_immediate_filter.ir.ron new file mode 100644 index 00000000..1a83b230 --- /dev/null +++ b/trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_tagged_immediate_filter.ir.ron @@ -0,0 +1,50 @@ +Ok(TestIRQuery( + schema_name: "numbers", + ir_query: IRQuery( + root_name: "Zero", + root_component: IRQueryComponent( + root: Vid(1), + vertices: { + Vid(1): IRVertex( + vid: Vid(1), + type_name: "Number", + ), + Vid(2): IRVertex( + vid: Vid(2), + type_name: "Number", + filters: [ + LessThan(LocalField( + field_name: "value", + field_type: "Int", + ), Tag(ContextField(ContextField( + vertex_id: Vid(1), + field_name: "value", + field_type: "Int", + )))), + ], + ), + }, + edges: { + Eid(1): IREdge( + eid: Eid(1), + from_vid: Vid(1), + to_vid: Vid(2), + edge_name: "predecessor", + optional: true, + ), + }, + outputs: { + "value": ContextField( + vertex_id: Vid(2), + field_name: "value", + field_type: "Int", + ), + "zero": ContextField( + vertex_id: Vid(1), + field_name: "value", + field_type: "Int", + ), + }, + ), + ), +)) diff --git a/trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_tagged_immediate_filter.output.ron b/trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_tagged_immediate_filter.output.ron new file mode 100644 index 00000000..2a673cbb --- /dev/null +++ b/trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_tagged_immediate_filter.output.ron @@ -0,0 +1,16 @@ +TestInterpreterOutputData( + schema_name: "numbers", + outputs: { + "value": Output( + name: "value", + value_type: "Int", + vid: Vid(2), + ), + "zero": Output( + name: "zero", + value_type: "Int", + vid: Vid(1), + ), + }, + results: [], +) diff --git a/trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_tagged_immediate_filter.trace.ron b/trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_tagged_immediate_filter.trace.ron new file mode 100644 index 00000000..a9fd9ca0 --- /dev/null +++ b/trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_tagged_immediate_filter.trace.ron @@ -0,0 +1,261 @@ +TestInterpreterOutputTrace( + schema_name: "numbers", + trace: Trace( + ops: { + Opid(1): TraceOp( + opid: Opid(1), + parent_opid: None, + content: Call(ResolveStartingVertices(Vid(1))), + ), + Opid(2): TraceOp( + opid: Opid(2), + parent_opid: None, + content: Call(ResolveNeighbors(Vid(1), "Number", Eid(1))), + ), + Opid(3): TraceOp( + opid: Opid(3), + parent_opid: None, + content: Call(ResolveProperty(Vid(2), "Number", "value")), + ), + Opid(4): TraceOp( + opid: Opid(4), + parent_opid: None, + content: Call(ResolveProperty(Vid(1), "Number", "value")), + ), + Opid(5): TraceOp( + opid: Opid(5), + parent_opid: None, + content: Call(ResolveProperty(Vid(2), "Number", "value")), + ), + Opid(6): TraceOp( + opid: Opid(6), + parent_opid: None, + content: Call(ResolveProperty(Vid(1), "Number", "value")), + ), + Opid(7): TraceOp( + opid: Opid(7), + parent_opid: Some(Opid(6)), + content: AdvanceInputIterator, + ), + Opid(8): TraceOp( + opid: Opid(8), + parent_opid: Some(Opid(5)), + content: AdvanceInputIterator, + ), + Opid(9): TraceOp( + opid: Opid(9), + parent_opid: Some(Opid(4)), + content: AdvanceInputIterator, + ), + Opid(10): TraceOp( + opid: Opid(10), + parent_opid: Some(Opid(3)), + content: AdvanceInputIterator, + ), + Opid(11): TraceOp( + opid: Opid(11), + parent_opid: Some(Opid(2)), + content: AdvanceInputIterator, + ), + Opid(12): TraceOp( + opid: Opid(12), + parent_opid: Some(Opid(1)), + content: YieldFrom(ResolveStartingVertices(Neither(NeitherNumber(0)))), + ), + Opid(13): TraceOp( + opid: Opid(13), + parent_opid: Some(Opid(2)), + content: YieldInto(SerializableContext( + active_vertex: Some(Neither(NeitherNumber(0))), + vertices: { + Vid(1): Some(Neither(NeitherNumber(0))), + }, + )), + ), + Opid(14): TraceOp( + opid: Opid(14), + parent_opid: Some(Opid(2)), + content: YieldFrom(ResolveNeighborsOuter(SerializableContext( + active_vertex: Some(Neither(NeitherNumber(0))), + vertices: { + Vid(1): Some(Neither(NeitherNumber(0))), + }, + ))), + ), + Opid(15): TraceOp( + opid: Opid(15), + parent_opid: Some(Opid(14)), + content: OutputIteratorExhausted, + ), + Opid(16): TraceOp( + opid: Opid(16), + parent_opid: Some(Opid(3)), + content: YieldInto(SerializableContext( + active_vertex: None, + vertices: { + Vid(1): Some(Neither(NeitherNumber(0))), + }, + )), + ), + Opid(17): TraceOp( + opid: Opid(17), + parent_opid: Some(Opid(3)), + content: YieldFrom(ResolveProperty(SerializableContext( + active_vertex: None, + vertices: { + Vid(1): Some(Neither(NeitherNumber(0))), + }, + ), Null)), + ), + Opid(18): TraceOp( + opid: Opid(18), + parent_opid: Some(Opid(4)), + content: YieldInto(SerializableContext( + active_vertex: Some(Neither(NeitherNumber(0))), + vertices: { + Vid(1): Some(Neither(NeitherNumber(0))), + }, + values: [ + Null, + ], + suspended_vertices: [ + None, + ], + )), + ), + Opid(19): TraceOp( + opid: Opid(19), + parent_opid: Some(Opid(4)), + content: YieldFrom(ResolveProperty(SerializableContext( + active_vertex: Some(Neither(NeitherNumber(0))), + vertices: { + Vid(1): Some(Neither(NeitherNumber(0))), + }, + values: [ + Null, + ], + suspended_vertices: [ + None, + ], + ), Int64(0))), + ), + Opid(20): TraceOp( + opid: Opid(20), + parent_opid: Some(Opid(4)), + content: AdvanceInputIterator, + ), + Opid(21): TraceOp( + opid: Opid(21), + parent_opid: Some(Opid(3)), + content: AdvanceInputIterator, + ), + Opid(22): TraceOp( + opid: Opid(22), + parent_opid: Some(Opid(2)), + content: AdvanceInputIterator, + ), + Opid(23): TraceOp( + opid: Opid(23), + parent_opid: Some(Opid(1)), + content: OutputIteratorExhausted, + ), + Opid(24): TraceOp( + opid: Opid(24), + parent_opid: Some(Opid(2)), + content: InputIteratorExhausted, + ), + Opid(25): TraceOp( + opid: Opid(25), + parent_opid: Some(Opid(2)), + content: OutputIteratorExhausted, + ), + Opid(26): TraceOp( + opid: Opid(26), + parent_opid: Some(Opid(3)), + content: InputIteratorExhausted, + ), + Opid(27): TraceOp( + opid: Opid(27), + parent_opid: Some(Opid(3)), + content: OutputIteratorExhausted, + ), + Opid(28): TraceOp( + opid: Opid(28), + parent_opid: Some(Opid(4)), + content: InputIteratorExhausted, + ), + Opid(29): TraceOp( + opid: Opid(29), + parent_opid: Some(Opid(4)), + content: OutputIteratorExhausted, + ), + Opid(30): TraceOp( + opid: Opid(30), + parent_opid: Some(Opid(5)), + content: InputIteratorExhausted, + ), + Opid(31): TraceOp( + opid: Opid(31), + parent_opid: Some(Opid(5)), + content: OutputIteratorExhausted, + ), + Opid(32): TraceOp( + opid: Opid(32), + parent_opid: Some(Opid(6)), + content: InputIteratorExhausted, + ), + Opid(33): TraceOp( + opid: Opid(33), + parent_opid: Some(Opid(6)), + content: OutputIteratorExhausted, + ), + }, + ir_query: IRQuery( + root_name: "Zero", + root_component: IRQueryComponent( + root: Vid(1), + vertices: { + Vid(1): IRVertex( + vid: Vid(1), + type_name: "Number", + ), + Vid(2): IRVertex( + vid: Vid(2), + type_name: "Number", + filters: [ + LessThan(LocalField( + field_name: "value", + field_type: "Int", + ), Tag(ContextField(ContextField( + vertex_id: Vid(1), + field_name: "value", + field_type: "Int", + )))), + ], + ), + }, + edges: { + Eid(1): IREdge( + eid: Eid(1), + from_vid: Vid(1), + to_vid: Vid(2), + edge_name: "predecessor", + optional: true, + ), + }, + outputs: { + "value": ContextField( + vertex_id: Vid(2), + field_name: "value", + field_type: "Int", + ), + "zero": ContextField( + vertex_id: Vid(1), + field_name: "value", + field_type: "Int", + ), + }, + ), + ), + ), +) diff --git a/trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_tagged_nested_filter.graphql-parsed.ron b/trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_tagged_nested_filter.graphql-parsed.ron new file mode 100644 index 00000000..97eec012 --- /dev/null +++ b/trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_tagged_nested_filter.graphql-parsed.ron @@ -0,0 +1,94 @@ +Ok(TestParsedGraphQLQuery( + schema_name: "numbers", + query: Query( + root_connection: FieldConnection( + position: Pos( + line: 3, + column: 5, + ), + name: "Zero", + ), + root_field: FieldNode( + position: Pos( + line: 3, + column: 5, + ), + name: "Zero", + connections: [ + (FieldConnection( + position: Pos( + line: 4, + column: 9, + ), + name: "value", + alias: Some("zero"), + ), FieldNode( + position: Pos( + line: 4, + column: 9, + ), + name: "value", + alias: Some("zero"), + output: [ + OutputDirective(), + ], + tag: [ + TagDirective(), + ], + )), + (FieldConnection( + position: Pos( + line: 6, + column: 9, + ), + name: "predecessor", + optional: Some(OptionalDirective()), + ), FieldNode( + position: Pos( + line: 6, + column: 9, + ), + name: "predecessor", + connections: [ + (FieldConnection( + position: Pos( + line: 7, + column: 13, + ), + name: "successor", + ), FieldNode( + position: Pos( + line: 7, + column: 13, + ), + name: "successor", + connections: [ + (FieldConnection( + position: Pos( + line: 8, + column: 17, + ), + name: "value", + ), FieldNode( + position: Pos( + line: 8, + column: 17, + ), + name: "value", + filter: [ + FilterDirective( + operation: Equals((), TagRef("zero")), + ), + ], + output: [ + OutputDirective(), + ], + )), + ], + )), + ], + )), + ], + ), + ), +)) diff --git a/trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_tagged_nested_filter.graphql.ron b/trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_tagged_nested_filter.graphql.ron new file mode 100644 index 00000000..f8e5ebd9 --- /dev/null +++ b/trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_tagged_nested_filter.graphql.ron @@ -0,0 +1,16 @@ +TestGraphQLQuery ( + schema_name: "numbers", + query: r#" +{ + Zero { + zero: value @output @tag + + predecessor @optional { + successor { + value @output @filter(op: "=", value: ["%zero"]) + } + } + } +}"#, + arguments: {}, +) diff --git a/trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_tagged_nested_filter.ir.ron b/trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_tagged_nested_filter.ir.ron new file mode 100644 index 00000000..4077fcbe --- /dev/null +++ b/trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_tagged_nested_filter.ir.ron @@ -0,0 +1,60 @@ +Ok(TestIRQuery( + schema_name: "numbers", + ir_query: IRQuery( + root_name: "Zero", + root_component: IRQueryComponent( + root: Vid(1), + vertices: { + Vid(1): IRVertex( + vid: Vid(1), + type_name: "Number", + ), + Vid(2): IRVertex( + vid: Vid(2), + type_name: "Number", + ), + Vid(3): IRVertex( + vid: Vid(3), + type_name: "Number", + filters: [ + Equals(LocalField( + field_name: "value", + field_type: "Int", + ), Tag(ContextField(ContextField( + vertex_id: Vid(1), + field_name: "value", + field_type: "Int", + )))), + ], + ), + }, + edges: { + Eid(1): IREdge( + eid: Eid(1), + from_vid: Vid(1), + to_vid: Vid(2), + edge_name: "predecessor", + optional: true, + ), + Eid(2): IREdge( + eid: Eid(2), + from_vid: Vid(2), + to_vid: Vid(3), + edge_name: "successor", + ), + }, + outputs: { + "value": ContextField( + vertex_id: Vid(3), + field_name: "value", + field_type: "Int", + ), + "zero": ContextField( + vertex_id: Vid(1), + field_name: "value", + field_type: "Int", + ), + }, + ), + ), +)) diff --git a/trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_tagged_nested_filter.output.ron b/trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_tagged_nested_filter.output.ron new file mode 100644 index 00000000..2d5221b6 --- /dev/null +++ b/trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_tagged_nested_filter.output.ron @@ -0,0 +1,16 @@ +TestInterpreterOutputData( + schema_name: "numbers", + outputs: { + "value": Output( + name: "value", + value_type: "Int", + vid: Vid(3), + ), + "zero": Output( + name: "zero", + value_type: "Int", + vid: Vid(1), + ), + }, + results: [], +) diff --git a/trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_tagged_nested_filter.trace.ron b/trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_tagged_nested_filter.trace.ron new file mode 100644 index 00000000..fa2ef14d --- /dev/null +++ b/trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_tagged_nested_filter.trace.ron @@ -0,0 +1,327 @@ +TestInterpreterOutputTrace( + schema_name: "numbers", + trace: Trace( + ops: { + Opid(1): TraceOp( + opid: Opid(1), + parent_opid: None, + content: Call(ResolveStartingVertices(Vid(1))), + ), + Opid(2): TraceOp( + opid: Opid(2), + parent_opid: None, + content: Call(ResolveNeighbors(Vid(1), "Number", Eid(1))), + ), + Opid(3): TraceOp( + opid: Opid(3), + parent_opid: None, + content: Call(ResolveNeighbors(Vid(2), "Number", Eid(2))), + ), + Opid(4): TraceOp( + opid: Opid(4), + parent_opid: None, + content: Call(ResolveProperty(Vid(3), "Number", "value")), + ), + Opid(5): TraceOp( + opid: Opid(5), + parent_opid: None, + content: Call(ResolveProperty(Vid(1), "Number", "value")), + ), + Opid(6): TraceOp( + opid: Opid(6), + parent_opid: None, + content: Call(ResolveProperty(Vid(3), "Number", "value")), + ), + Opid(7): TraceOp( + opid: Opid(7), + parent_opid: None, + content: Call(ResolveProperty(Vid(1), "Number", "value")), + ), + Opid(8): TraceOp( + opid: Opid(8), + parent_opid: Some(Opid(7)), + content: AdvanceInputIterator, + ), + Opid(9): TraceOp( + opid: Opid(9), + parent_opid: Some(Opid(6)), + content: AdvanceInputIterator, + ), + Opid(10): TraceOp( + opid: Opid(10), + parent_opid: Some(Opid(5)), + content: AdvanceInputIterator, + ), + Opid(11): TraceOp( + opid: Opid(11), + parent_opid: Some(Opid(4)), + content: AdvanceInputIterator, + ), + Opid(12): TraceOp( + opid: Opid(12), + parent_opid: Some(Opid(3)), + content: AdvanceInputIterator, + ), + Opid(13): TraceOp( + opid: Opid(13), + parent_opid: Some(Opid(2)), + content: AdvanceInputIterator, + ), + Opid(14): TraceOp( + opid: Opid(14), + parent_opid: Some(Opid(1)), + content: YieldFrom(ResolveStartingVertices(Neither(NeitherNumber(0)))), + ), + Opid(15): TraceOp( + opid: Opid(15), + parent_opid: Some(Opid(2)), + content: YieldInto(SerializableContext( + active_vertex: Some(Neither(NeitherNumber(0))), + vertices: { + Vid(1): Some(Neither(NeitherNumber(0))), + }, + )), + ), + Opid(16): TraceOp( + opid: Opid(16), + parent_opid: Some(Opid(2)), + content: YieldFrom(ResolveNeighborsOuter(SerializableContext( + active_vertex: Some(Neither(NeitherNumber(0))), + vertices: { + Vid(1): Some(Neither(NeitherNumber(0))), + }, + ))), + ), + Opid(17): TraceOp( + opid: Opid(17), + parent_opid: Some(Opid(16)), + content: OutputIteratorExhausted, + ), + Opid(18): TraceOp( + opid: Opid(18), + parent_opid: Some(Opid(3)), + content: YieldInto(SerializableContext( + active_vertex: None, + vertices: { + Vid(1): Some(Neither(NeitherNumber(0))), + Vid(2): None, + }, + )), + ), + Opid(19): TraceOp( + opid: Opid(19), + parent_opid: Some(Opid(3)), + content: YieldFrom(ResolveNeighborsOuter(SerializableContext( + active_vertex: None, + vertices: { + Vid(1): Some(Neither(NeitherNumber(0))), + Vid(2): None, + }, + ))), + ), + Opid(20): TraceOp( + opid: Opid(20), + parent_opid: Some(Opid(19)), + content: OutputIteratorExhausted, + ), + Opid(21): TraceOp( + opid: Opid(21), + parent_opid: Some(Opid(4)), + content: YieldInto(SerializableContext( + active_vertex: None, + vertices: { + Vid(1): Some(Neither(NeitherNumber(0))), + Vid(2): None, + }, + )), + ), + Opid(22): TraceOp( + opid: Opid(22), + parent_opid: Some(Opid(4)), + content: YieldFrom(ResolveProperty(SerializableContext( + active_vertex: None, + vertices: { + Vid(1): Some(Neither(NeitherNumber(0))), + Vid(2): None, + }, + ), Null)), + ), + Opid(23): TraceOp( + opid: Opid(23), + parent_opid: Some(Opid(5)), + content: YieldInto(SerializableContext( + active_vertex: Some(Neither(NeitherNumber(0))), + vertices: { + Vid(1): Some(Neither(NeitherNumber(0))), + Vid(2): None, + }, + values: [ + Null, + ], + suspended_vertices: [ + None, + ], + )), + ), + Opid(24): TraceOp( + opid: Opid(24), + parent_opid: Some(Opid(5)), + content: YieldFrom(ResolveProperty(SerializableContext( + active_vertex: Some(Neither(NeitherNumber(0))), + vertices: { + Vid(1): Some(Neither(NeitherNumber(0))), + Vid(2): None, + }, + values: [ + Null, + ], + suspended_vertices: [ + None, + ], + ), Int64(0))), + ), + Opid(25): TraceOp( + opid: Opid(25), + parent_opid: Some(Opid(5)), + content: AdvanceInputIterator, + ), + Opid(26): TraceOp( + opid: Opid(26), + parent_opid: Some(Opid(4)), + content: AdvanceInputIterator, + ), + Opid(27): TraceOp( + opid: Opid(27), + parent_opid: Some(Opid(3)), + content: AdvanceInputIterator, + ), + Opid(28): TraceOp( + opid: Opid(28), + parent_opid: Some(Opid(2)), + content: AdvanceInputIterator, + ), + Opid(29): TraceOp( + opid: Opid(29), + parent_opid: Some(Opid(1)), + content: OutputIteratorExhausted, + ), + Opid(30): TraceOp( + opid: Opid(30), + parent_opid: Some(Opid(2)), + content: InputIteratorExhausted, + ), + Opid(31): TraceOp( + opid: Opid(31), + parent_opid: Some(Opid(2)), + content: OutputIteratorExhausted, + ), + Opid(32): TraceOp( + opid: Opid(32), + parent_opid: Some(Opid(3)), + content: InputIteratorExhausted, + ), + Opid(33): TraceOp( + opid: Opid(33), + parent_opid: Some(Opid(3)), + content: OutputIteratorExhausted, + ), + Opid(34): TraceOp( + opid: Opid(34), + parent_opid: Some(Opid(4)), + content: InputIteratorExhausted, + ), + Opid(35): TraceOp( + opid: Opid(35), + parent_opid: Some(Opid(4)), + content: OutputIteratorExhausted, + ), + Opid(36): TraceOp( + opid: Opid(36), + parent_opid: Some(Opid(5)), + content: InputIteratorExhausted, + ), + Opid(37): TraceOp( + opid: Opid(37), + parent_opid: Some(Opid(5)), + content: OutputIteratorExhausted, + ), + Opid(38): TraceOp( + opid: Opid(38), + parent_opid: Some(Opid(6)), + content: InputIteratorExhausted, + ), + Opid(39): TraceOp( + opid: Opid(39), + parent_opid: Some(Opid(6)), + content: OutputIteratorExhausted, + ), + Opid(40): TraceOp( + opid: Opid(40), + parent_opid: Some(Opid(7)), + content: InputIteratorExhausted, + ), + Opid(41): TraceOp( + opid: Opid(41), + parent_opid: Some(Opid(7)), + content: OutputIteratorExhausted, + ), + }, + ir_query: IRQuery( + root_name: "Zero", + root_component: IRQueryComponent( + root: Vid(1), + vertices: { + Vid(1): IRVertex( + vid: Vid(1), + type_name: "Number", + ), + Vid(2): IRVertex( + vid: Vid(2), + type_name: "Number", + ), + Vid(3): IRVertex( + vid: Vid(3), + type_name: "Number", + filters: [ + Equals(LocalField( + field_name: "value", + field_type: "Int", + ), Tag(ContextField(ContextField( + vertex_id: Vid(1), + field_name: "value", + field_type: "Int", + )))), + ], + ), + }, + edges: { + Eid(1): IREdge( + eid: Eid(1), + from_vid: Vid(1), + to_vid: Vid(2), + edge_name: "predecessor", + optional: true, + ), + Eid(2): IREdge( + eid: Eid(2), + from_vid: Vid(2), + to_vid: Vid(3), + edge_name: "successor", + ), + }, + outputs: { + "value": ContextField( + vertex_id: Vid(3), + field_name: "value", + field_type: "Int", + ), + "zero": ContextField( + vertex_id: Vid(1), + field_name: "value", + field_type: "Int", + ), + }, + ), + ), + ), +) From a6d9154de58ab5d2d86aad10e96587abe98387db Mon Sep 17 00:00:00 2001 From: Predrag Gruevski Date: Fri, 8 Nov 2024 16:06:05 +0000 Subject: [PATCH 2/2] Add filtering fix and update test cases. --- trustfall_core/src/interpreter/filtering.rs | 4 +- trustfall_core/src/interpreter/mod.rs | 14 ++ ..._optional_with_immediate_filter.output.ron | 7 +- ...t_optional_with_immediate_filter.trace.ron | 108 +++++++++++--- ...th_immediate_is_not_null_filter.output.ron | 7 +- ...ith_immediate_is_not_null_filter.trace.ron | 108 +++++++++++--- ...ent_optional_with_nested_filter.output.ron | 7 +- ...tent_optional_with_nested_filter.trace.ron | 124 ++++++++++++---- ..._with_nested_is_not_null_filter.output.ron | 7 +- ...l_with_nested_is_not_null_filter.trace.ron | 124 ++++++++++++---- ...al_with_tagged_immediate_filter.output.ron | 7 +- ...nal_with_tagged_immediate_filter.trace.ron | 120 ++++++++++++---- ...ional_with_tagged_nested_filter.output.ron | 7 +- ...tional_with_tagged_nested_filter.trace.ron | 136 +++++++++++++----- 14 files changed, 622 insertions(+), 158 deletions(-) diff --git a/trustfall_core/src/interpreter/filtering.rs b/trustfall_core/src/interpreter/filtering.rs index 61d15f2c..02afb22a 100644 --- a/trustfall_core/src/interpreter/filtering.rs +++ b/trustfall_core/src/interpreter/filtering.rs @@ -233,7 +233,7 @@ fn apply_unary_filter< ) -> ContextIterator<'query, Vertex> { Box::new(iterator.filter_map(move |mut context| { let last_value = context.values.pop().expect("no value present"); - filter_op(&last_value).then_some(context) + (context.within_nonexistent_optional() || filter_op(&last_value)).then_some(context) })) } @@ -391,7 +391,7 @@ fn apply_filter_op< left: &FieldValue, right: &RightValue, ) -> Option> { - filter_op(left, right).then_some(ctx) + (ctx.within_nonexistent_optional() || filter_op(left, right)).then_some(ctx) } fn apply_filter_with_static_argument_value<'query, Vertex: Debug + Clone + 'query>( diff --git a/trustfall_core/src/interpreter/mod.rs b/trustfall_core/src/interpreter/mod.rs index 0679af3c..c4e4d43b 100644 --- a/trustfall_core/src/interpreter/mod.rs +++ b/trustfall_core/src/interpreter/mod.rs @@ -99,6 +99,20 @@ impl DataContext { self.active_vertex.as_ref().and_then(AsVertex::as_vertex) } + /// Whether this context is currently inside an `@optional` block with no values. + /// + /// Let's unpack that: + /// - At this point in the query execution, we're within an `@optional` block of the query. + /// - An `@optional` edge in the evaluation of this context did not exist. It might not be + /// the innermost `@optional` one — it might be a prior one if we're several `@optional` deep. + /// + /// This is relevant, for example, for situations where we have filters or type coercions + /// to apply within the `@optional` block and need to know if there's anything to filter/coerce. + #[inline] + pub(crate) fn within_nonexistent_optional(&self) -> bool { + self.active_vertex.is_none() + } + /// Converts `DataContext` to `DataContext` by mapping each `Vertex` to `Other`. /// /// If you are implementing an [`Adapter`] for a data source, diff --git a/trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_immediate_filter.output.ron b/trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_immediate_filter.output.ron index 2a673cbb..644fc1d7 100644 --- a/trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_immediate_filter.output.ron +++ b/trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_immediate_filter.output.ron @@ -12,5 +12,10 @@ TestInterpreterOutputData( vid: Vid(1), ), }, - results: [], + results: [ + { + "value": Null, + "zero": Int64(0), + }, + ], ) diff --git a/trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_immediate_filter.trace.ron b/trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_immediate_filter.trace.ron index 343ee549..6ad61296 100644 --- a/trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_immediate_filter.trace.ron +++ b/trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_immediate_filter.trace.ron @@ -99,56 +99,124 @@ TestInterpreterOutputTrace( ), Opid(16): TraceOp( opid: Opid(16), - parent_opid: Some(Opid(3)), - content: AdvanceInputIterator, + parent_opid: Some(Opid(4)), + content: YieldInto(SerializableContext( + active_vertex: None, + vertices: { + Vid(1): Some(Neither(NeitherNumber(0))), + Vid(2): None, + }, + )), ), Opid(17): TraceOp( opid: Opid(17), - parent_opid: Some(Opid(2)), - content: AdvanceInputIterator, + parent_opid: Some(Opid(4)), + content: YieldFrom(ResolveProperty(SerializableContext( + active_vertex: None, + vertices: { + Vid(1): Some(Neither(NeitherNumber(0))), + Vid(2): None, + }, + ), Null)), ), Opid(18): TraceOp( opid: Opid(18), - parent_opid: Some(Opid(1)), - content: OutputIteratorExhausted, + parent_opid: Some(Opid(5)), + content: YieldInto(SerializableContext( + active_vertex: Some(Neither(NeitherNumber(0))), + vertices: { + Vid(1): Some(Neither(NeitherNumber(0))), + Vid(2): None, + }, + values: [ + Null, + ], + )), ), Opid(19): TraceOp( opid: Opid(19), - parent_opid: Some(Opid(2)), - content: InputIteratorExhausted, + parent_opid: Some(Opid(5)), + content: YieldFrom(ResolveProperty(SerializableContext( + active_vertex: Some(Neither(NeitherNumber(0))), + vertices: { + Vid(1): Some(Neither(NeitherNumber(0))), + Vid(2): None, + }, + values: [ + Null, + ], + ), Int64(0))), ), Opid(20): TraceOp( opid: Opid(20), - parent_opid: Some(Opid(2)), - content: OutputIteratorExhausted, + parent_opid: None, + content: ProduceQueryResult({ + "value": Null, + "zero": Int64(0), + }), ), Opid(21): TraceOp( opid: Opid(21), - parent_opid: Some(Opid(3)), - content: InputIteratorExhausted, + parent_opid: Some(Opid(5)), + content: AdvanceInputIterator, ), Opid(22): TraceOp( opid: Opid(22), - parent_opid: Some(Opid(3)), - content: OutputIteratorExhausted, + parent_opid: Some(Opid(4)), + content: AdvanceInputIterator, ), Opid(23): TraceOp( opid: Opid(23), - parent_opid: Some(Opid(4)), - content: InputIteratorExhausted, + parent_opid: Some(Opid(3)), + content: AdvanceInputIterator, ), Opid(24): TraceOp( opid: Opid(24), - parent_opid: Some(Opid(4)), - content: OutputIteratorExhausted, + parent_opid: Some(Opid(2)), + content: AdvanceInputIterator, ), Opid(25): TraceOp( opid: Opid(25), - parent_opid: Some(Opid(5)), - content: InputIteratorExhausted, + parent_opid: Some(Opid(1)), + content: OutputIteratorExhausted, ), Opid(26): TraceOp( opid: Opid(26), + parent_opid: Some(Opid(2)), + content: InputIteratorExhausted, + ), + Opid(27): TraceOp( + opid: Opid(27), + parent_opid: Some(Opid(2)), + content: OutputIteratorExhausted, + ), + Opid(28): TraceOp( + opid: Opid(28), + parent_opid: Some(Opid(3)), + content: InputIteratorExhausted, + ), + Opid(29): TraceOp( + opid: Opid(29), + parent_opid: Some(Opid(3)), + content: OutputIteratorExhausted, + ), + Opid(30): TraceOp( + opid: Opid(30), + parent_opid: Some(Opid(4)), + content: InputIteratorExhausted, + ), + Opid(31): TraceOp( + opid: Opid(31), + parent_opid: Some(Opid(4)), + content: OutputIteratorExhausted, + ), + Opid(32): TraceOp( + opid: Opid(32), + parent_opid: Some(Opid(5)), + content: InputIteratorExhausted, + ), + Opid(33): TraceOp( + opid: Opid(33), parent_opid: Some(Opid(5)), content: OutputIteratorExhausted, ), diff --git a/trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_immediate_is_not_null_filter.output.ron b/trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_immediate_is_not_null_filter.output.ron index 2a673cbb..644fc1d7 100644 --- a/trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_immediate_is_not_null_filter.output.ron +++ b/trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_immediate_is_not_null_filter.output.ron @@ -12,5 +12,10 @@ TestInterpreterOutputData( vid: Vid(1), ), }, - results: [], + results: [ + { + "value": Null, + "zero": Int64(0), + }, + ], ) diff --git a/trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_immediate_is_not_null_filter.trace.ron b/trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_immediate_is_not_null_filter.trace.ron index ddd05eeb..c2601199 100644 --- a/trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_immediate_is_not_null_filter.trace.ron +++ b/trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_immediate_is_not_null_filter.trace.ron @@ -99,56 +99,124 @@ TestInterpreterOutputTrace( ), Opid(16): TraceOp( opid: Opid(16), - parent_opid: Some(Opid(3)), - content: AdvanceInputIterator, + parent_opid: Some(Opid(4)), + content: YieldInto(SerializableContext( + active_vertex: None, + vertices: { + Vid(1): Some(Neither(NeitherNumber(0))), + Vid(2): None, + }, + )), ), Opid(17): TraceOp( opid: Opid(17), - parent_opid: Some(Opid(2)), - content: AdvanceInputIterator, + parent_opid: Some(Opid(4)), + content: YieldFrom(ResolveProperty(SerializableContext( + active_vertex: None, + vertices: { + Vid(1): Some(Neither(NeitherNumber(0))), + Vid(2): None, + }, + ), Null)), ), Opid(18): TraceOp( opid: Opid(18), - parent_opid: Some(Opid(1)), - content: OutputIteratorExhausted, + parent_opid: Some(Opid(5)), + content: YieldInto(SerializableContext( + active_vertex: Some(Neither(NeitherNumber(0))), + vertices: { + Vid(1): Some(Neither(NeitherNumber(0))), + Vid(2): None, + }, + values: [ + Null, + ], + )), ), Opid(19): TraceOp( opid: Opid(19), - parent_opid: Some(Opid(2)), - content: InputIteratorExhausted, + parent_opid: Some(Opid(5)), + content: YieldFrom(ResolveProperty(SerializableContext( + active_vertex: Some(Neither(NeitherNumber(0))), + vertices: { + Vid(1): Some(Neither(NeitherNumber(0))), + Vid(2): None, + }, + values: [ + Null, + ], + ), Int64(0))), ), Opid(20): TraceOp( opid: Opid(20), - parent_opid: Some(Opid(2)), - content: OutputIteratorExhausted, + parent_opid: None, + content: ProduceQueryResult({ + "value": Null, + "zero": Int64(0), + }), ), Opid(21): TraceOp( opid: Opid(21), - parent_opid: Some(Opid(3)), - content: InputIteratorExhausted, + parent_opid: Some(Opid(5)), + content: AdvanceInputIterator, ), Opid(22): TraceOp( opid: Opid(22), - parent_opid: Some(Opid(3)), - content: OutputIteratorExhausted, + parent_opid: Some(Opid(4)), + content: AdvanceInputIterator, ), Opid(23): TraceOp( opid: Opid(23), - parent_opid: Some(Opid(4)), - content: InputIteratorExhausted, + parent_opid: Some(Opid(3)), + content: AdvanceInputIterator, ), Opid(24): TraceOp( opid: Opid(24), - parent_opid: Some(Opid(4)), - content: OutputIteratorExhausted, + parent_opid: Some(Opid(2)), + content: AdvanceInputIterator, ), Opid(25): TraceOp( opid: Opid(25), - parent_opid: Some(Opid(5)), - content: InputIteratorExhausted, + parent_opid: Some(Opid(1)), + content: OutputIteratorExhausted, ), Opid(26): TraceOp( opid: Opid(26), + parent_opid: Some(Opid(2)), + content: InputIteratorExhausted, + ), + Opid(27): TraceOp( + opid: Opid(27), + parent_opid: Some(Opid(2)), + content: OutputIteratorExhausted, + ), + Opid(28): TraceOp( + opid: Opid(28), + parent_opid: Some(Opid(3)), + content: InputIteratorExhausted, + ), + Opid(29): TraceOp( + opid: Opid(29), + parent_opid: Some(Opid(3)), + content: OutputIteratorExhausted, + ), + Opid(30): TraceOp( + opid: Opid(30), + parent_opid: Some(Opid(4)), + content: InputIteratorExhausted, + ), + Opid(31): TraceOp( + opid: Opid(31), + parent_opid: Some(Opid(4)), + content: OutputIteratorExhausted, + ), + Opid(32): TraceOp( + opid: Opid(32), + parent_opid: Some(Opid(5)), + content: InputIteratorExhausted, + ), + Opid(33): TraceOp( + opid: Opid(33), parent_opid: Some(Opid(5)), content: OutputIteratorExhausted, ), diff --git a/trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_nested_filter.output.ron b/trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_nested_filter.output.ron index 2d5221b6..cd79bd45 100644 --- a/trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_nested_filter.output.ron +++ b/trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_nested_filter.output.ron @@ -12,5 +12,10 @@ TestInterpreterOutputData( vid: Vid(1), ), }, - results: [], + results: [ + { + "value": Null, + "zero": Int64(0), + }, + ], ) diff --git a/trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_nested_filter.trace.ron b/trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_nested_filter.trace.ron index 8e5a2f2a..0f9a2e91 100644 --- a/trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_nested_filter.trace.ron +++ b/trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_nested_filter.trace.ron @@ -138,71 +138,143 @@ TestInterpreterOutputTrace( ), Opid(21): TraceOp( opid: Opid(21), - parent_opid: Some(Opid(4)), - content: AdvanceInputIterator, + parent_opid: Some(Opid(5)), + content: YieldInto(SerializableContext( + active_vertex: None, + vertices: { + Vid(1): Some(Neither(NeitherNumber(0))), + Vid(2): None, + Vid(3): None, + }, + )), ), Opid(22): TraceOp( opid: Opid(22), - parent_opid: Some(Opid(3)), - content: AdvanceInputIterator, + parent_opid: Some(Opid(5)), + content: YieldFrom(ResolveProperty(SerializableContext( + active_vertex: None, + vertices: { + Vid(1): Some(Neither(NeitherNumber(0))), + Vid(2): None, + Vid(3): None, + }, + ), Null)), ), Opid(23): TraceOp( opid: Opid(23), - parent_opid: Some(Opid(2)), - content: AdvanceInputIterator, + parent_opid: Some(Opid(6)), + content: YieldInto(SerializableContext( + active_vertex: Some(Neither(NeitherNumber(0))), + vertices: { + Vid(1): Some(Neither(NeitherNumber(0))), + Vid(2): None, + Vid(3): None, + }, + values: [ + Null, + ], + )), ), Opid(24): TraceOp( opid: Opid(24), - parent_opid: Some(Opid(1)), - content: OutputIteratorExhausted, + parent_opid: Some(Opid(6)), + content: YieldFrom(ResolveProperty(SerializableContext( + active_vertex: Some(Neither(NeitherNumber(0))), + vertices: { + Vid(1): Some(Neither(NeitherNumber(0))), + Vid(2): None, + Vid(3): None, + }, + values: [ + Null, + ], + ), Int64(0))), ), Opid(25): TraceOp( opid: Opid(25), - parent_opid: Some(Opid(2)), - content: InputIteratorExhausted, + parent_opid: None, + content: ProduceQueryResult({ + "value": Null, + "zero": Int64(0), + }), ), Opid(26): TraceOp( opid: Opid(26), - parent_opid: Some(Opid(2)), - content: OutputIteratorExhausted, + parent_opid: Some(Opid(6)), + content: AdvanceInputIterator, ), Opid(27): TraceOp( opid: Opid(27), - parent_opid: Some(Opid(3)), - content: InputIteratorExhausted, + parent_opid: Some(Opid(5)), + content: AdvanceInputIterator, ), Opid(28): TraceOp( opid: Opid(28), - parent_opid: Some(Opid(3)), - content: OutputIteratorExhausted, + parent_opid: Some(Opid(4)), + content: AdvanceInputIterator, ), Opid(29): TraceOp( opid: Opid(29), - parent_opid: Some(Opid(4)), - content: InputIteratorExhausted, + parent_opid: Some(Opid(3)), + content: AdvanceInputIterator, ), Opid(30): TraceOp( opid: Opid(30), - parent_opid: Some(Opid(4)), - content: OutputIteratorExhausted, + parent_opid: Some(Opid(2)), + content: AdvanceInputIterator, ), Opid(31): TraceOp( opid: Opid(31), - parent_opid: Some(Opid(5)), - content: InputIteratorExhausted, + parent_opid: Some(Opid(1)), + content: OutputIteratorExhausted, ), Opid(32): TraceOp( opid: Opid(32), - parent_opid: Some(Opid(5)), - content: OutputIteratorExhausted, + parent_opid: Some(Opid(2)), + content: InputIteratorExhausted, ), Opid(33): TraceOp( opid: Opid(33), - parent_opid: Some(Opid(6)), - content: InputIteratorExhausted, + parent_opid: Some(Opid(2)), + content: OutputIteratorExhausted, ), Opid(34): TraceOp( opid: Opid(34), + parent_opid: Some(Opid(3)), + content: InputIteratorExhausted, + ), + Opid(35): TraceOp( + opid: Opid(35), + parent_opid: Some(Opid(3)), + content: OutputIteratorExhausted, + ), + Opid(36): TraceOp( + opid: Opid(36), + parent_opid: Some(Opid(4)), + content: InputIteratorExhausted, + ), + Opid(37): TraceOp( + opid: Opid(37), + parent_opid: Some(Opid(4)), + content: OutputIteratorExhausted, + ), + Opid(38): TraceOp( + opid: Opid(38), + parent_opid: Some(Opid(5)), + content: InputIteratorExhausted, + ), + Opid(39): TraceOp( + opid: Opid(39), + parent_opid: Some(Opid(5)), + content: OutputIteratorExhausted, + ), + Opid(40): TraceOp( + opid: Opid(40), + parent_opid: Some(Opid(6)), + content: InputIteratorExhausted, + ), + Opid(41): TraceOp( + opid: Opid(41), parent_opid: Some(Opid(6)), content: OutputIteratorExhausted, ), diff --git a/trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_nested_is_not_null_filter.output.ron b/trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_nested_is_not_null_filter.output.ron index 2d5221b6..cd79bd45 100644 --- a/trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_nested_is_not_null_filter.output.ron +++ b/trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_nested_is_not_null_filter.output.ron @@ -12,5 +12,10 @@ TestInterpreterOutputData( vid: Vid(1), ), }, - results: [], + results: [ + { + "value": Null, + "zero": Int64(0), + }, + ], ) diff --git a/trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_nested_is_not_null_filter.trace.ron b/trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_nested_is_not_null_filter.trace.ron index 1f212a3d..af91df88 100644 --- a/trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_nested_is_not_null_filter.trace.ron +++ b/trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_nested_is_not_null_filter.trace.ron @@ -138,71 +138,143 @@ TestInterpreterOutputTrace( ), Opid(21): TraceOp( opid: Opid(21), - parent_opid: Some(Opid(4)), - content: AdvanceInputIterator, + parent_opid: Some(Opid(5)), + content: YieldInto(SerializableContext( + active_vertex: None, + vertices: { + Vid(1): Some(Neither(NeitherNumber(0))), + Vid(2): None, + Vid(3): None, + }, + )), ), Opid(22): TraceOp( opid: Opid(22), - parent_opid: Some(Opid(3)), - content: AdvanceInputIterator, + parent_opid: Some(Opid(5)), + content: YieldFrom(ResolveProperty(SerializableContext( + active_vertex: None, + vertices: { + Vid(1): Some(Neither(NeitherNumber(0))), + Vid(2): None, + Vid(3): None, + }, + ), Null)), ), Opid(23): TraceOp( opid: Opid(23), - parent_opid: Some(Opid(2)), - content: AdvanceInputIterator, + parent_opid: Some(Opid(6)), + content: YieldInto(SerializableContext( + active_vertex: Some(Neither(NeitherNumber(0))), + vertices: { + Vid(1): Some(Neither(NeitherNumber(0))), + Vid(2): None, + Vid(3): None, + }, + values: [ + Null, + ], + )), ), Opid(24): TraceOp( opid: Opid(24), - parent_opid: Some(Opid(1)), - content: OutputIteratorExhausted, + parent_opid: Some(Opid(6)), + content: YieldFrom(ResolveProperty(SerializableContext( + active_vertex: Some(Neither(NeitherNumber(0))), + vertices: { + Vid(1): Some(Neither(NeitherNumber(0))), + Vid(2): None, + Vid(3): None, + }, + values: [ + Null, + ], + ), Int64(0))), ), Opid(25): TraceOp( opid: Opid(25), - parent_opid: Some(Opid(2)), - content: InputIteratorExhausted, + parent_opid: None, + content: ProduceQueryResult({ + "value": Null, + "zero": Int64(0), + }), ), Opid(26): TraceOp( opid: Opid(26), - parent_opid: Some(Opid(2)), - content: OutputIteratorExhausted, + parent_opid: Some(Opid(6)), + content: AdvanceInputIterator, ), Opid(27): TraceOp( opid: Opid(27), - parent_opid: Some(Opid(3)), - content: InputIteratorExhausted, + parent_opid: Some(Opid(5)), + content: AdvanceInputIterator, ), Opid(28): TraceOp( opid: Opid(28), - parent_opid: Some(Opid(3)), - content: OutputIteratorExhausted, + parent_opid: Some(Opid(4)), + content: AdvanceInputIterator, ), Opid(29): TraceOp( opid: Opid(29), - parent_opid: Some(Opid(4)), - content: InputIteratorExhausted, + parent_opid: Some(Opid(3)), + content: AdvanceInputIterator, ), Opid(30): TraceOp( opid: Opid(30), - parent_opid: Some(Opid(4)), - content: OutputIteratorExhausted, + parent_opid: Some(Opid(2)), + content: AdvanceInputIterator, ), Opid(31): TraceOp( opid: Opid(31), - parent_opid: Some(Opid(5)), - content: InputIteratorExhausted, + parent_opid: Some(Opid(1)), + content: OutputIteratorExhausted, ), Opid(32): TraceOp( opid: Opid(32), - parent_opid: Some(Opid(5)), - content: OutputIteratorExhausted, + parent_opid: Some(Opid(2)), + content: InputIteratorExhausted, ), Opid(33): TraceOp( opid: Opid(33), - parent_opid: Some(Opid(6)), - content: InputIteratorExhausted, + parent_opid: Some(Opid(2)), + content: OutputIteratorExhausted, ), Opid(34): TraceOp( opid: Opid(34), + parent_opid: Some(Opid(3)), + content: InputIteratorExhausted, + ), + Opid(35): TraceOp( + opid: Opid(35), + parent_opid: Some(Opid(3)), + content: OutputIteratorExhausted, + ), + Opid(36): TraceOp( + opid: Opid(36), + parent_opid: Some(Opid(4)), + content: InputIteratorExhausted, + ), + Opid(37): TraceOp( + opid: Opid(37), + parent_opid: Some(Opid(4)), + content: OutputIteratorExhausted, + ), + Opid(38): TraceOp( + opid: Opid(38), + parent_opid: Some(Opid(5)), + content: InputIteratorExhausted, + ), + Opid(39): TraceOp( + opid: Opid(39), + parent_opid: Some(Opid(5)), + content: OutputIteratorExhausted, + ), + Opid(40): TraceOp( + opid: Opid(40), + parent_opid: Some(Opid(6)), + content: InputIteratorExhausted, + ), + Opid(41): TraceOp( + opid: Opid(41), parent_opid: Some(Opid(6)), content: OutputIteratorExhausted, ), diff --git a/trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_tagged_immediate_filter.output.ron b/trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_tagged_immediate_filter.output.ron index 2a673cbb..644fc1d7 100644 --- a/trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_tagged_immediate_filter.output.ron +++ b/trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_tagged_immediate_filter.output.ron @@ -12,5 +12,10 @@ TestInterpreterOutputData( vid: Vid(1), ), }, - results: [], + results: [ + { + "value": Null, + "zero": Int64(0), + }, + ], ) diff --git a/trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_tagged_immediate_filter.trace.ron b/trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_tagged_immediate_filter.trace.ron index a9fd9ca0..997cc4dd 100644 --- a/trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_tagged_immediate_filter.trace.ron +++ b/trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_tagged_immediate_filter.trace.ron @@ -141,71 +141,139 @@ TestInterpreterOutputTrace( ), Opid(20): TraceOp( opid: Opid(20), - parent_opid: Some(Opid(4)), - content: AdvanceInputIterator, + parent_opid: Some(Opid(5)), + content: YieldInto(SerializableContext( + active_vertex: None, + vertices: { + Vid(1): Some(Neither(NeitherNumber(0))), + Vid(2): None, + }, + )), ), Opid(21): TraceOp( opid: Opid(21), - parent_opid: Some(Opid(3)), - content: AdvanceInputIterator, + parent_opid: Some(Opid(5)), + content: YieldFrom(ResolveProperty(SerializableContext( + active_vertex: None, + vertices: { + Vid(1): Some(Neither(NeitherNumber(0))), + Vid(2): None, + }, + ), Null)), ), Opid(22): TraceOp( opid: Opid(22), - parent_opid: Some(Opid(2)), - content: AdvanceInputIterator, + parent_opid: Some(Opid(6)), + content: YieldInto(SerializableContext( + active_vertex: Some(Neither(NeitherNumber(0))), + vertices: { + Vid(1): Some(Neither(NeitherNumber(0))), + Vid(2): None, + }, + values: [ + Null, + ], + )), ), Opid(23): TraceOp( opid: Opid(23), - parent_opid: Some(Opid(1)), - content: OutputIteratorExhausted, + parent_opid: Some(Opid(6)), + content: YieldFrom(ResolveProperty(SerializableContext( + active_vertex: Some(Neither(NeitherNumber(0))), + vertices: { + Vid(1): Some(Neither(NeitherNumber(0))), + Vid(2): None, + }, + values: [ + Null, + ], + ), Int64(0))), ), Opid(24): TraceOp( opid: Opid(24), - parent_opid: Some(Opid(2)), - content: InputIteratorExhausted, + parent_opid: None, + content: ProduceQueryResult({ + "value": Null, + "zero": Int64(0), + }), ), Opid(25): TraceOp( opid: Opid(25), - parent_opid: Some(Opid(2)), - content: OutputIteratorExhausted, + parent_opid: Some(Opid(6)), + content: AdvanceInputIterator, ), Opid(26): TraceOp( opid: Opid(26), - parent_opid: Some(Opid(3)), - content: InputIteratorExhausted, + parent_opid: Some(Opid(5)), + content: AdvanceInputIterator, ), Opid(27): TraceOp( opid: Opid(27), - parent_opid: Some(Opid(3)), - content: OutputIteratorExhausted, + parent_opid: Some(Opid(4)), + content: AdvanceInputIterator, ), Opid(28): TraceOp( opid: Opid(28), - parent_opid: Some(Opid(4)), - content: InputIteratorExhausted, + parent_opid: Some(Opid(3)), + content: AdvanceInputIterator, ), Opid(29): TraceOp( opid: Opid(29), - parent_opid: Some(Opid(4)), - content: OutputIteratorExhausted, + parent_opid: Some(Opid(2)), + content: AdvanceInputIterator, ), Opid(30): TraceOp( opid: Opid(30), - parent_opid: Some(Opid(5)), - content: InputIteratorExhausted, + parent_opid: Some(Opid(1)), + content: OutputIteratorExhausted, ), Opid(31): TraceOp( opid: Opid(31), - parent_opid: Some(Opid(5)), - content: OutputIteratorExhausted, + parent_opid: Some(Opid(2)), + content: InputIteratorExhausted, ), Opid(32): TraceOp( opid: Opid(32), - parent_opid: Some(Opid(6)), - content: InputIteratorExhausted, + parent_opid: Some(Opid(2)), + content: OutputIteratorExhausted, ), Opid(33): TraceOp( opid: Opid(33), + parent_opid: Some(Opid(3)), + content: InputIteratorExhausted, + ), + Opid(34): TraceOp( + opid: Opid(34), + parent_opid: Some(Opid(3)), + content: OutputIteratorExhausted, + ), + Opid(35): TraceOp( + opid: Opid(35), + parent_opid: Some(Opid(4)), + content: InputIteratorExhausted, + ), + Opid(36): TraceOp( + opid: Opid(36), + parent_opid: Some(Opid(4)), + content: OutputIteratorExhausted, + ), + Opid(37): TraceOp( + opid: Opid(37), + parent_opid: Some(Opid(5)), + content: InputIteratorExhausted, + ), + Opid(38): TraceOp( + opid: Opid(38), + parent_opid: Some(Opid(5)), + content: OutputIteratorExhausted, + ), + Opid(39): TraceOp( + opid: Opid(39), + parent_opid: Some(Opid(6)), + content: InputIteratorExhausted, + ), + Opid(40): TraceOp( + opid: Opid(40), parent_opid: Some(Opid(6)), content: OutputIteratorExhausted, ), diff --git a/trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_tagged_nested_filter.output.ron b/trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_tagged_nested_filter.output.ron index 2d5221b6..cd79bd45 100644 --- a/trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_tagged_nested_filter.output.ron +++ b/trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_tagged_nested_filter.output.ron @@ -12,5 +12,10 @@ TestInterpreterOutputData( vid: Vid(1), ), }, - results: [], + results: [ + { + "value": Null, + "zero": Int64(0), + }, + ], ) diff --git a/trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_tagged_nested_filter.trace.ron b/trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_tagged_nested_filter.trace.ron index fa2ef14d..9d9de7ec 100644 --- a/trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_tagged_nested_filter.trace.ron +++ b/trustfall_core/test_data/tests/valid_queries/nonexistent_optional_with_tagged_nested_filter.trace.ron @@ -182,86 +182,158 @@ TestInterpreterOutputTrace( ), Opid(25): TraceOp( opid: Opid(25), - parent_opid: Some(Opid(5)), - content: AdvanceInputIterator, + parent_opid: Some(Opid(6)), + content: YieldInto(SerializableContext( + active_vertex: None, + vertices: { + Vid(1): Some(Neither(NeitherNumber(0))), + Vid(2): None, + Vid(3): None, + }, + )), ), Opid(26): TraceOp( opid: Opid(26), - parent_opid: Some(Opid(4)), - content: AdvanceInputIterator, + parent_opid: Some(Opid(6)), + content: YieldFrom(ResolveProperty(SerializableContext( + active_vertex: None, + vertices: { + Vid(1): Some(Neither(NeitherNumber(0))), + Vid(2): None, + Vid(3): None, + }, + ), Null)), ), Opid(27): TraceOp( opid: Opid(27), - parent_opid: Some(Opid(3)), - content: AdvanceInputIterator, + parent_opid: Some(Opid(7)), + content: YieldInto(SerializableContext( + active_vertex: Some(Neither(NeitherNumber(0))), + vertices: { + Vid(1): Some(Neither(NeitherNumber(0))), + Vid(2): None, + Vid(3): None, + }, + values: [ + Null, + ], + )), ), Opid(28): TraceOp( opid: Opid(28), - parent_opid: Some(Opid(2)), - content: AdvanceInputIterator, + parent_opid: Some(Opid(7)), + content: YieldFrom(ResolveProperty(SerializableContext( + active_vertex: Some(Neither(NeitherNumber(0))), + vertices: { + Vid(1): Some(Neither(NeitherNumber(0))), + Vid(2): None, + Vid(3): None, + }, + values: [ + Null, + ], + ), Int64(0))), ), Opid(29): TraceOp( opid: Opid(29), - parent_opid: Some(Opid(1)), - content: OutputIteratorExhausted, + parent_opid: None, + content: ProduceQueryResult({ + "value": Null, + "zero": Int64(0), + }), ), Opid(30): TraceOp( opid: Opid(30), - parent_opid: Some(Opid(2)), - content: InputIteratorExhausted, + parent_opid: Some(Opid(7)), + content: AdvanceInputIterator, ), Opid(31): TraceOp( opid: Opid(31), - parent_opid: Some(Opid(2)), - content: OutputIteratorExhausted, + parent_opid: Some(Opid(6)), + content: AdvanceInputIterator, ), Opid(32): TraceOp( opid: Opid(32), - parent_opid: Some(Opid(3)), - content: InputIteratorExhausted, + parent_opid: Some(Opid(5)), + content: AdvanceInputIterator, ), Opid(33): TraceOp( opid: Opid(33), - parent_opid: Some(Opid(3)), - content: OutputIteratorExhausted, + parent_opid: Some(Opid(4)), + content: AdvanceInputIterator, ), Opid(34): TraceOp( opid: Opid(34), - parent_opid: Some(Opid(4)), - content: InputIteratorExhausted, + parent_opid: Some(Opid(3)), + content: AdvanceInputIterator, ), Opid(35): TraceOp( opid: Opid(35), - parent_opid: Some(Opid(4)), - content: OutputIteratorExhausted, + parent_opid: Some(Opid(2)), + content: AdvanceInputIterator, ), Opid(36): TraceOp( opid: Opid(36), - parent_opid: Some(Opid(5)), - content: InputIteratorExhausted, + parent_opid: Some(Opid(1)), + content: OutputIteratorExhausted, ), Opid(37): TraceOp( opid: Opid(37), - parent_opid: Some(Opid(5)), - content: OutputIteratorExhausted, + parent_opid: Some(Opid(2)), + content: InputIteratorExhausted, ), Opid(38): TraceOp( opid: Opid(38), - parent_opid: Some(Opid(6)), - content: InputIteratorExhausted, + parent_opid: Some(Opid(2)), + content: OutputIteratorExhausted, ), Opid(39): TraceOp( opid: Opid(39), - parent_opid: Some(Opid(6)), - content: OutputIteratorExhausted, + parent_opid: Some(Opid(3)), + content: InputIteratorExhausted, ), Opid(40): TraceOp( opid: Opid(40), - parent_opid: Some(Opid(7)), - content: InputIteratorExhausted, + parent_opid: Some(Opid(3)), + content: OutputIteratorExhausted, ), Opid(41): TraceOp( opid: Opid(41), + parent_opid: Some(Opid(4)), + content: InputIteratorExhausted, + ), + Opid(42): TraceOp( + opid: Opid(42), + parent_opid: Some(Opid(4)), + content: OutputIteratorExhausted, + ), + Opid(43): TraceOp( + opid: Opid(43), + parent_opid: Some(Opid(5)), + content: InputIteratorExhausted, + ), + Opid(44): TraceOp( + opid: Opid(44), + parent_opid: Some(Opid(5)), + content: OutputIteratorExhausted, + ), + Opid(45): TraceOp( + opid: Opid(45), + parent_opid: Some(Opid(6)), + content: InputIteratorExhausted, + ), + Opid(46): TraceOp( + opid: Opid(46), + parent_opid: Some(Opid(6)), + content: OutputIteratorExhausted, + ), + Opid(47): TraceOp( + opid: Opid(47), + parent_opid: Some(Opid(7)), + content: InputIteratorExhausted, + ), + Opid(48): TraceOp( + opid: Opid(48), parent_opid: Some(Opid(7)), content: OutputIteratorExhausted, ),