Skip to content

Commit

Permalink
Merge 40b3270 into be7f890
Browse files Browse the repository at this point in the history
  • Loading branch information
obi1kenobi committed Oct 8, 2018
2 parents be7f890 + 40b3270 commit 53c368c
Showing 1 changed file with 19 additions and 46 deletions.
65 changes: 19 additions & 46 deletions graphql_compiler/compiler/compiler_frontend.py
Expand Up @@ -393,15 +393,8 @@ def _compile_vertex_ast(schema, current_schema_type, ast,
inner_location, context)
basic_blocks.extend(inner_basic_blocks)

# The length of the stack should be the same before exiting this function
initial_marked_location_stack_size = len(context['marked_location_stack'])

# step V-3: mark the graph position, and process output_source directive
basic_blocks.append(_mark_location(location))
if not is_in_fold_scope(context):
# The following append is the Location corresponding to the initial MarkLocation
# for the current vertex and the `num_traverses` counter set to 0.
context['marked_location_stack'].append(_construct_location_stack_entry(location, 0))

output_source = _process_output_source_directive(schema, current_schema_type, ast,
location, context, unique_local_directives)
Expand Down Expand Up @@ -436,17 +429,27 @@ def _compile_vertex_ast(schema, current_schema_type, ast,
within_optional_scope = 'optional' in context

if edge_traversal_is_optional:
# Entering an optional block!
# Make sure there's a marked location right before it for the optional Backtrack
# to jump back to. Otherwise, the traversal could rewind to an old marked location
# and might ignore entire stretches of applied filtering.
if context['marked_location_stack'][-1].num_traverses > 0:
# Invariant: There must always be a marked location corresponding to the query position
# immediately before any optional Traverse.
#
# This invariant is verified in the IR sanity checks module (ir_sanity_checks.py),
# in the function named _sanity_check_mark_location_preceding_optional_traverse().
#
# This marked location is the one that the @optional directive's corresponding
# optional Backtrack will jump back to. If such a marked location isn't present,
# the backtrack could rewind to an old marked location and might ignore
# entire stretches of applied filtering.
#
# Assumption: The only way there might not be a marked location here is
# if the current location already traversed into child locations, not including folds.
non_fold_child_locations = {
child_location
for child_location in query_metadata_table.get_child_locations(location)
if not isinstance(child_location, FoldScopeLocation)
}
if non_fold_child_locations:
location = query_metadata_table.revisit_location(location)

basic_blocks.append(_mark_location(location))
context['marked_location_stack'].pop()
new_stack_entry = _construct_location_stack_entry(location, 0)
context['marked_location_stack'].append(new_stack_entry)

if fold_directive:
inner_location = location.navigate_to_fold(field_name)
Expand Down Expand Up @@ -490,14 +493,6 @@ def _compile_vertex_ast(schema, current_schema_type, ast,
optional=edge_traversal_is_optional,
within_optional_scope=within_optional_scope))

if not edge_traversal_is_folded and not is_in_fold_scope(context):
# Current block is either a Traverse or a Recurse that is not within any fold context.
# Increment the `num_traverses` counter.
old_location_stack_entry = context['marked_location_stack'][-1]
new_location_stack_entry = _construct_location_stack_entry(
old_location_stack_entry.location, old_location_stack_entry.num_traverses + 1)
context['marked_location_stack'][-1] = new_location_stack_entry

inner_basic_blocks = _compile_ast_node_to_ir(schema, field_schema_type, field_ast,
inner_location, context)
basic_blocks.extend(inner_basic_blocks)
Expand Down Expand Up @@ -535,25 +530,9 @@ def _compile_vertex_ast(schema, current_schema_type, ast,
location = query_metadata_table.revisit_location(location)

basic_blocks.append(_mark_location(location))
context['marked_location_stack'].pop()
new_stack_entry = _construct_location_stack_entry(location, 0)
context['marked_location_stack'].append(new_stack_entry)
else:
basic_blocks.append(blocks.Backtrack(location))

# Pop off the initial Location for the current vertex.
if not is_in_fold_scope(context):
context['marked_location_stack'].pop()

# Check that the length of the stack remains the same as when control entered this function.
final_marked_location_stack_size = len(context['marked_location_stack'])
if initial_marked_location_stack_size != final_marked_location_stack_size:
raise AssertionError(u'Size of stack changed from {} to {} after executing this function.'
u'This should never happen : {}'
.format(initial_marked_location_stack_size,
final_marked_location_stack_size,
context['marked_location_stack']))

return basic_blocks


Expand Down Expand Up @@ -755,12 +734,6 @@ def _compile_root_ast_to_ir(schema, ast, type_equivalence_hints=None):
# 'type_equivalence_hints_inverse' is the inverse of type_equivalence_hints,
# which is always invertible.
'type_equivalence_hints_inverse': invert_dict(type_equivalence_hints),
# The marked_location_stack explicitly maintains a stack (implemented as list)
# of namedtuples (each corresponding to a MarkLocation) containing:
# - location: the location within the corresponding MarkLocation object
# - num_traverses: the number of Recurse and Traverse blocks created
# after the corresponding MarkLocation
'marked_location_stack': []
}

# Add the query root basic block to the output.
Expand Down

0 comments on commit 53c368c

Please sign in to comment.