Skip to content

Commit 99259f4

Browse files
authored
fix: domains over array types now correctly apply "tweaks" (#672)
1 parent ea8480e commit 99259f4

37 files changed

Lines changed: 724 additions & 119 deletions

packages/graphile-build-pg/src/plugins/PgTypesPlugin.js

Lines changed: 63 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -255,9 +255,13 @@ export default (function PgTypesPlugin(
255255
];
256256

257257
const tweakToJson = fragment => fragment; // Since everything is to_json'd now, just pass through
258+
const tweakToJsonArray = fragment => fragment;
258259
const tweakToText = fragment => sql.fragment`(${fragment})::text`;
260+
const tweakToTextArray = fragment => sql.fragment`(${fragment})::text[]`;
259261
const tweakToNumericText = fragment =>
260262
sql.fragment`(${fragment})::numeric::text`;
263+
const tweakToNumericTextArray = fragment =>
264+
sql.fragment`(${fragment})::numeric[]::text[]`;
261265
const pgTweaksByTypeIdAndModifer = {};
262266
const pgTweaksByTypeId = {
263267
// '::text' rawTypes
@@ -292,13 +296,65 @@ export default (function PgTypesPlugin(
292296
if (tweaker) {
293297
return tweaker(fragment, resolveData);
294298
} else if (type.domainBaseType) {
295-
// TODO: check that domains don't support atttypemod
296-
return pgTweakFragmentForTypeAndModifier(
297-
fragment,
298-
type.domainBaseType,
299-
type.domainBaseTypeModifier,
300-
resolveData
301-
);
299+
if (type.domainBaseType.isPgArray) {
300+
// If we have a domain that's for example an `int8[]`, we must
301+
// process it into a `text[]` otherwise we risk loss of accuracy
302+
// when taking PostgreSQL's JSON into Node.js.
303+
const arrayItemType = type.domainBaseType.arrayItemType;
304+
305+
const domainBaseTypeModifierKey =
306+
type.domainBaseTypeModifier != null
307+
? type.domainBaseTypeModifier
308+
: -1;
309+
const arrayItemTweaker =
310+
(pgTweaksByTypeIdAndModifer[arrayItemType.id] &&
311+
pgTweaksByTypeIdAndModifer[arrayItemType.id][
312+
domainBaseTypeModifierKey
313+
]) ||
314+
pgTweaksByTypeId[arrayItemType.id];
315+
316+
// If it's a domain over a known type array (e.g. `bigint[]`), use
317+
// the Array version of the tweaker.
318+
switch (arrayItemTweaker) {
319+
case tweakToText:
320+
return tweakToTextArray(fragment);
321+
case tweakToNumericText:
322+
return tweakToNumericTextArray(fragment);
323+
case tweakToJson:
324+
return tweakToJsonArray(fragment);
325+
}
326+
327+
// If we get here, it's not a simple type, so use our
328+
// infrastructure to figure out what tweaks to apply to the array
329+
// item.
330+
331+
const sqlVal = sql.fragment`val`;
332+
const innerFragment = pgTweakFragmentForTypeAndModifier(
333+
sqlVal,
334+
arrayItemType,
335+
type.domainBaseTypeModifier,
336+
resolveData
337+
);
338+
339+
if (innerFragment === sqlVal) {
340+
// There was no tweak applied to the fragment, no change
341+
// necessary.
342+
return fragment;
343+
} else {
344+
// Tweaking was necessary, process each item in the array in this
345+
// way, and then return the resulting array, being careful that
346+
// nulls are preserved.
347+
return sql.fragment`(case when ${fragment} is null then null else array(select ${innerFragment} from unnest(${fragment}) as unnest(${sqlVal})) end)`;
348+
}
349+
} else {
350+
// TODO: check that domains don't support atttypemod
351+
return pgTweakFragmentForTypeAndModifier(
352+
fragment,
353+
type.domainBaseType,
354+
type.domainBaseTypeModifier,
355+
resolveData
356+
);
357+
}
302358
} else if (type.isPgArray) {
303359
const error = new Error(
304360
`Internal graphile-build-pg error: should not attempt to tweak an array, please process array before tweaking (type: "${type.namespaceName}.${type.name}")`

packages/postgraphile-core/__tests__/fixtures/mutations/mutation-create.graphql

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,16 @@ mutation CreateMutation($config: KeyValueHash!) {
102102
},
103103
cidr: "192.168.0.0/16",
104104
macaddr: "0cafec0ffee0"
105+
textArrayDomain: [
106+
"TEXT 2098288669218571759"
107+
"TEXT 2098288669218571760"
108+
"TEXT 2098288669218571761"
109+
]
110+
int8ArrayDomain: [
111+
"2098288669218571759"
112+
"2098288669218571760"
113+
"2098288669218571761"
114+
]
105115
}
106116
}) {
107117
clientMutationId
@@ -149,6 +159,11 @@ mutation CreateMutation($config: KeyValueHash!) {
149159
}
150160
point { x y }
151161
nullablePoint { x y }
162+
inet
163+
cidr
164+
macaddr
165+
textArrayDomain
166+
int8ArrayDomain
152167
}
153168
query { nodeId }
154169
}

packages/postgraphile-core/__tests__/fixtures/mutations/pg10.identity.graphql renamed to packages/postgraphile-core/__tests__/fixtures/mutations/pg11.identity.graphql

File renamed without changes.

packages/postgraphile-core/__tests__/fixtures/mutations/pg10.network_types.createNetwork.graphql renamed to packages/postgraphile-core/__tests__/fixtures/mutations/pg11.network_types.createNetwork.graphql

File renamed without changes.

packages/postgraphile-core/__tests__/fixtures/mutations/pg10.types.graphql renamed to packages/postgraphile-core/__tests__/fixtures/mutations/pg11.types.graphql

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,12 @@ mutation {
55
id: 12
66
typePatch: {
77
regrole: "postgraphile_test_authenticator"
8-
regnamespace: "pg10"
8+
regnamespace: "pg11"
9+
bigintDomainArrayDomain: [
10+
"2098288669218571759"
11+
"2098288669218571760"
12+
"2098288669218571761"
13+
]
914
}
1015
}
1116
) {
@@ -19,6 +24,11 @@ mutation {
1924
type: {
2025
regrole: "postgraphile_test_visitor"
2126
regnamespace: "c"
27+
bigintDomainArrayDomain: [
28+
"2098288669218571759"
29+
"2098288669218571760"
30+
"2098288669218571761"
31+
]
2232
}
2333
}
2434
) {
@@ -32,4 +42,5 @@ fragment type on Type {
3242
id
3343
regrole
3444
regnamespace
45+
bigintDomainArrayDomain
3546
}

packages/postgraphile-core/__tests__/fixtures/mutations/types.graphql

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -55,14 +55,24 @@ mutation {
5555
money: 27
5656
compoundType: { a: 1 }
5757
nestedCompoundType: { a: { a: 1 } }
58-
regproc: "b.type_function"
59-
regprocedure: "b.type_function(int)"
58+
nullablePoint: { x: 0, y: 42 }
59+
inet: "192.168.0.0"
60+
cidr: "192.168.0.0/16"
61+
macaddr: "08:00:2b:01:02:03"
62+
regproc: "b.type_function"
63+
regprocedure: "b.type_function(int)"
6064
regoper: "*<>"
6165
regoperator: "+(integer, integer)"
62-
regclass: "c.person"
63-
regtype: "numeric"
66+
regclass: "c.person"
67+
regtype: "numeric"
6468
regconfig: "dutch"
6569
regdictionary: "dutch_stem"
70+
textArrayDomain: ["T1", "T2", "T3"]
71+
int8ArrayDomain: [
72+
"2098288669218571759"
73+
"2098288669218571760"
74+
"2098288669218571761"
75+
]
6676
}
6777
}
6878
) {
@@ -110,12 +120,12 @@ mutation {
110120
money: 27
111121
compoundType: { a: 1 }
112122
nestedCompoundType: { a: { a: 1 } }
113-
regproc: "b.type_function"
114-
regprocedure: "b.type_function(int)"
123+
regproc: "b.type_function"
124+
regprocedure: "b.type_function(int)"
115125
regoper: "*<>"
116126
regoperator: "+(integer, integer)"
117-
regclass: "c.person"
118-
regtype: "numeric"
127+
regclass: "c.person"
128+
regtype: "numeric"
119129
regconfig: "dutch"
120130
regdictionary: "dutch_stem"
121131
}
@@ -212,6 +222,9 @@ fragment type on Type {
212222
x
213223
y
214224
}
225+
inet
226+
cidr
227+
macaddr
215228
regproc
216229
regprocedure
217230
regoper
@@ -220,4 +233,6 @@ fragment type on Type {
220233
regtype
221234
regconfig
222235
regdictionary
236+
textArrayDomain
237+
int8ArrayDomain
223238
}

packages/postgraphile-core/__tests__/fixtures/queries/pg10.network_types.graphql renamed to packages/postgraphile-core/__tests__/fixtures/queries/pg11.network_types.graphql

File renamed without changes.

packages/postgraphile-core/__tests__/fixtures/queries/pg10.types.graphql renamed to packages/postgraphile-core/__tests__/fixtures/queries/pg11.types.graphql

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ fragment type on Type {
88
id
99
regrole
1010
regnamespace
11+
bigintDomainArrayDomain
1112
}
1213

1314
fragment typesConnection on TypesConnection {

packages/postgraphile-core/__tests__/fixtures/queries/types.graphql

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,11 @@ fragment type on Type {
131131
x
132132
y
133133
}
134+
inet
135+
cidr
136+
macaddr
137+
textArrayDomain
138+
int8ArrayDomain
134139
postBySmallint {
135140
id
136141
headline

0 commit comments

Comments
 (0)