Skip to content
This repository was archived by the owner on Apr 14, 2022. It is now read-only.

Commit 87df8fd

Browse files
committed
Fix problem with multihead connections with nulls
Close #200
1 parent 038c1eb commit 87df8fd

File tree

4 files changed

+512
-2
lines changed

4 files changed

+512
-2
lines changed

README.md

+9
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,15 @@ local compiled_query = graphql_lib.compile(query)
124124
local result = compiled_query:execute(variables)
125125
```
126126

127+
### Multi-head connections
128+
A parent object is matching against a multi-head connection variants in the
129+
order of the variants. The parent object should match with a determinant of
130+
at least one variant except the following case. When source fields of all
131+
variants are null the multi-head connection obligated to give null object as
132+
the result. In this case the parent object is allowed to don’t match any variant.
133+
One can use this feature to avoid to set any specific determinant value when a
134+
multi-head connection is known to have no connected object.
135+
127136
### Mutations
128137

129138
Mutations are disabled for avro-schema-2\*, because it can work incorrectly for

graphql/convert_schema/resolve.lua

+20-2
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ end
3333
---
3434
--- Note that connection key parts can be prefix of index key parts. Zero parts
3535
--- count considered as ok by this check.
36-
local function are_all_parts_null(parent, connection_parts)
36+
local function are_all_parts_null(parent, connection_parts, opts)
3737
local are_all_parts_null = true
3838
local are_all_parts_non_null = true
3939
for _, part in ipairs(connection_parts) do
@@ -47,7 +47,9 @@ local function are_all_parts_null(parent, connection_parts)
4747
end
4848

4949
local ok = are_all_parts_null or are_all_parts_non_null
50-
if not ok then -- avoid extra json.encode()
50+
local opts = opts or {}
51+
local no_assert = opts.no_assert or false
52+
if not ok and not no_assert then -- avoid extra json.encode()
5153
assert(ok,
5254
'FULL MATCH constraint was failed: connection ' ..
5355
'key parts must be all non-nulls or all nulls; ' ..
@@ -190,6 +192,22 @@ function resolve.gen_resolve_function_multihead(collection_name, connection,
190192
end
191193

192194
return function(parent, _, info)
195+
-- If a parent object does not have all source fields (for any of
196+
-- variants) non-null then we do not resolve variant and just return
197+
-- box.NULL.
198+
local is_source_fields_found = false
199+
for _, variant in ipairs(c.variants) do
200+
is_source_fields_found =
201+
not are_all_parts_null(parent, variant.parts, {no_assert = true})
202+
if is_source_fields_found then
203+
break
204+
end
205+
end
206+
207+
if not is_source_fields_found then
208+
return box.NULL, nil
209+
end
210+
193211
local v, variant_num, box_field_name = resolve_variant(parent)
194212
local destination_type = union_types[variant_num]
195213

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
#!/usr/bin/env tarantool
2+
3+
local fio = require('fio')
4+
5+
-- require in-repo version of graphql/ sources despite current working directory
6+
package.path = fio.abspath(debug.getinfo(1).source:match("@?(.*/)")
7+
:gsub('/./', '/'):gsub('/+$', '')) .. '/../../?.lua' .. ';' .. package.path
8+
9+
local test_utils = require('test.test_utils')
10+
local testdata = require('test.testdata.multihead_conn_with_nulls_testdata')
11+
12+
box.cfg({})
13+
14+
test_utils.run_testdata(testdata)
15+
16+
os.exit()

0 commit comments

Comments
 (0)