Skip to content

Commit 7913a58

Browse files
committed
Use a single results array to simplify and speed up authorized fields
1 parent a96c899 commit 7913a58

1 file changed

Lines changed: 22 additions & 36 deletions

File tree

lib/graphql/execution/field_resolve_step.rb

Lines changed: 22 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ def initialize(parent_type:, runner:, key:, selections_step:)
1717
@all_next_results = nil
1818
@static_type = nil
1919
@next_selections = nil
20-
@object_is_authorized = nil
20+
@results = nil
2121
@finish_extension_idx = nil
2222
@was_scoped = nil
2323
@pending_steps = nil
@@ -103,12 +103,6 @@ def add_graphql_error(err)
103103
err
104104
end
105105

106-
module AlwaysAuthorized
107-
def self.[](_key)
108-
true
109-
end
110-
end
111-
112106
def build_arguments
113107
query = @selections_step.query
114108
field_name = @ast_node.name
@@ -124,10 +118,10 @@ def build_arguments
124118

125119
def execute_field
126120
objects = @selections_step.objects
121+
@results = @selections_step.results
127122
# TODO not as good because only one error?
128123
if @arguments.is_a?(GraphQL::RuntimeError)
129124
@field_results = Array.new(objects.size, @arguments)
130-
@object_is_authorized = AlwaysAuthorized
131125
build_results
132126
return
133127
end
@@ -139,7 +133,6 @@ def execute_field
139133
Schema::Validator.validate!(v, nil, ctx, @arguments)
140134
rescue GraphQL::RuntimeError => err
141135
@field_results = Array.new(objects.size, err)
142-
@object_is_authorized = AlwaysAuthorized
143136
build_results
144137
return
145138
end
@@ -170,30 +163,37 @@ def execute_field
170163
# TODO break this backwards compat somehow?
171164
objects = @selections_step.graphql_objects
172165
end
166+
173167
if @runner.authorization && @runner.authorizes?(@field_definition, ctx)
174168
authorized_objects = []
175-
@object_is_authorized = objects.map { |o|
176-
is_authed = @field_definition.authorized?(o, @arguments, ctx)
177-
if is_authed
169+
authorized_results = []
170+
l = objects.size
171+
i = 0
172+
while i < l
173+
o = objects[i]
174+
if @field_definition.authorized?(o, @arguments, ctx)
175+
authorized_results << @results[i]
178176
authorized_objects << o
179177
else
180178
begin
181179
err = GraphQL::UnauthorizedFieldError.new(object: o, type: @parent_type, context: ctx, field: @field_definition)
182180
authorized_objects << query.schema.unauthorized_object(err)
183-
is_authed = true
181+
authorized_results << @results[i]
184182
rescue GraphQL::ExecutionError => exec_err
185183
add_graphql_error(exec_err)
186184
end
187185
end
188-
is_authed
189-
}
186+
i += 1
187+
end
188+
190189
if authorized_objects.size == 0
191190
return
192191
end
192+
@results = authorized_results
193193
else
194194
authorized_objects = objects
195-
@object_is_authorized = AlwaysAuthorized
196195
end
196+
197197
if @parent_type.default_relay? && authorized_objects.all? { |o| o.respond_to?(:was_authorized_by_scope_items?) && o.was_authorized_by_scope_items? }
198198
@was_scoped = true
199199
end
@@ -361,18 +361,11 @@ def build_results
361361

362362
is_list = return_type.list?
363363
is_non_null = return_type.non_null?
364-
results = @selections_step.results
365-
field_result_idx = 0
366364
i = 0
367-
s = results.size
365+
s = @results.size
368366
while i < s do
369-
result_h = results[i]
370-
if @object_is_authorized[i]
371-
result = @field_results[field_result_idx]
372-
field_result_idx += 1
373-
else
374-
result = nil
375-
end
367+
result_h = @results[i]
368+
result = @field_results[i]
376369
i += 1
377370
build_graphql_result(result_h, @key, result, return_type, is_non_null, is_list, false)
378371
end
@@ -385,18 +378,11 @@ def build_results
385378
end
386379
else
387380
ctx = @selections_step.query.context
388-
results = @selections_step.results
389-
field_result_idx = 0
390381
i = 0
391-
s = results.size
382+
s = @results.size
392383
while i < s do
393-
result_h = results[i]
394-
if @object_is_authorized[i]
395-
field_result = @field_results[field_result_idx]
396-
field_result_idx += 1
397-
else
398-
field_result = nil
399-
end
384+
result_h = @results[i]
385+
field_result = @field_results[i]
400386
i += 1
401387
finish_leaf_result(result_h, @key, field_result, return_type, ctx)
402388
end

0 commit comments

Comments
 (0)