Skip to content

Commit

Permalink
fix: domains over array types now correctly apply "tweaks" (#672)
Browse files Browse the repository at this point in the history
  • Loading branch information
benjie committed Sep 29, 2020
1 parent ea8480e commit 99259f4
Show file tree
Hide file tree
Showing 37 changed files with 724 additions and 119 deletions.
70 changes: 63 additions & 7 deletions packages/graphile-build-pg/src/plugins/PgTypesPlugin.js
Expand Up @@ -255,9 +255,13 @@ export default (function PgTypesPlugin(
];

const tweakToJson = fragment => fragment; // Since everything is to_json'd now, just pass through
const tweakToJsonArray = fragment => fragment;
const tweakToText = fragment => sql.fragment`(${fragment})::text`;
const tweakToTextArray = fragment => sql.fragment`(${fragment})::text[]`;
const tweakToNumericText = fragment =>
sql.fragment`(${fragment})::numeric::text`;
const tweakToNumericTextArray = fragment =>
sql.fragment`(${fragment})::numeric[]::text[]`;
const pgTweaksByTypeIdAndModifer = {};
const pgTweaksByTypeId = {
// '::text' rawTypes
Expand Down Expand Up @@ -292,13 +296,65 @@ export default (function PgTypesPlugin(
if (tweaker) {
return tweaker(fragment, resolveData);
} else if (type.domainBaseType) {
// TODO: check that domains don't support atttypemod
return pgTweakFragmentForTypeAndModifier(
fragment,
type.domainBaseType,
type.domainBaseTypeModifier,
resolveData
);
if (type.domainBaseType.isPgArray) {
// If we have a domain that's for example an `int8[]`, we must
// process it into a `text[]` otherwise we risk loss of accuracy
// when taking PostgreSQL's JSON into Node.js.
const arrayItemType = type.domainBaseType.arrayItemType;

const domainBaseTypeModifierKey =
type.domainBaseTypeModifier != null
? type.domainBaseTypeModifier
: -1;
const arrayItemTweaker =
(pgTweaksByTypeIdAndModifer[arrayItemType.id] &&
pgTweaksByTypeIdAndModifer[arrayItemType.id][
domainBaseTypeModifierKey
]) ||
pgTweaksByTypeId[arrayItemType.id];

// If it's a domain over a known type array (e.g. `bigint[]`), use
// the Array version of the tweaker.
switch (arrayItemTweaker) {
case tweakToText:
return tweakToTextArray(fragment);
case tweakToNumericText:
return tweakToNumericTextArray(fragment);
case tweakToJson:
return tweakToJsonArray(fragment);
}

// If we get here, it's not a simple type, so use our
// infrastructure to figure out what tweaks to apply to the array
// item.

const sqlVal = sql.fragment`val`;
const innerFragment = pgTweakFragmentForTypeAndModifier(
sqlVal,
arrayItemType,
type.domainBaseTypeModifier,
resolveData
);

if (innerFragment === sqlVal) {
// There was no tweak applied to the fragment, no change
// necessary.
return fragment;
} else {
// Tweaking was necessary, process each item in the array in this
// way, and then return the resulting array, being careful that
// nulls are preserved.
return sql.fragment`(case when ${fragment} is null then null else array(select ${innerFragment} from unnest(${fragment}) as unnest(${sqlVal})) end)`;
}
} else {
// TODO: check that domains don't support atttypemod
return pgTweakFragmentForTypeAndModifier(
fragment,
type.domainBaseType,
type.domainBaseTypeModifier,
resolveData
);
}
} else if (type.isPgArray) {
const error = new Error(
`Internal graphile-build-pg error: should not attempt to tweak an array, please process array before tweaking (type: "${type.namespaceName}.${type.name}")`
Expand Down
Expand Up @@ -102,6 +102,16 @@ mutation CreateMutation($config: KeyValueHash!) {
},
cidr: "192.168.0.0/16",
macaddr: "0cafec0ffee0"
textArrayDomain: [
"TEXT 2098288669218571759"
"TEXT 2098288669218571760"
"TEXT 2098288669218571761"
]
int8ArrayDomain: [
"2098288669218571759"
"2098288669218571760"
"2098288669218571761"
]
}
}) {
clientMutationId
Expand Down Expand Up @@ -149,6 +159,11 @@ mutation CreateMutation($config: KeyValueHash!) {
}
point { x y }
nullablePoint { x y }
inet
cidr
macaddr
textArrayDomain
int8ArrayDomain
}
query { nodeId }
}
Expand Down
Expand Up @@ -5,7 +5,12 @@ mutation {
id: 12
typePatch: {
regrole: "postgraphile_test_authenticator"
regnamespace: "pg10"
regnamespace: "pg11"
bigintDomainArrayDomain: [
"2098288669218571759"
"2098288669218571760"
"2098288669218571761"
]
}
}
) {
Expand All @@ -19,6 +24,11 @@ mutation {
type: {
regrole: "postgraphile_test_visitor"
regnamespace: "c"
bigintDomainArrayDomain: [
"2098288669218571759"
"2098288669218571760"
"2098288669218571761"
]
}
}
) {
Expand All @@ -32,4 +42,5 @@ fragment type on Type {
id
regrole
regnamespace
bigintDomainArrayDomain
}
Expand Up @@ -55,14 +55,24 @@ mutation {
money: 27
compoundType: { a: 1 }
nestedCompoundType: { a: { a: 1 } }
regproc: "b.type_function"
regprocedure: "b.type_function(int)"
nullablePoint: { x: 0, y: 42 }
inet: "192.168.0.0"
cidr: "192.168.0.0/16"
macaddr: "08:00:2b:01:02:03"
regproc: "b.type_function"
regprocedure: "b.type_function(int)"
regoper: "*<>"
regoperator: "+(integer, integer)"
regclass: "c.person"
regtype: "numeric"
regclass: "c.person"
regtype: "numeric"
regconfig: "dutch"
regdictionary: "dutch_stem"
textArrayDomain: ["T1", "T2", "T3"]
int8ArrayDomain: [
"2098288669218571759"
"2098288669218571760"
"2098288669218571761"
]
}
}
) {
Expand Down Expand Up @@ -110,12 +120,12 @@ mutation {
money: 27
compoundType: { a: 1 }
nestedCompoundType: { a: { a: 1 } }
regproc: "b.type_function"
regprocedure: "b.type_function(int)"
regproc: "b.type_function"
regprocedure: "b.type_function(int)"
regoper: "*<>"
regoperator: "+(integer, integer)"
regclass: "c.person"
regtype: "numeric"
regclass: "c.person"
regtype: "numeric"
regconfig: "dutch"
regdictionary: "dutch_stem"
}
Expand Down Expand Up @@ -212,6 +222,9 @@ fragment type on Type {
x
y
}
inet
cidr
macaddr
regproc
regprocedure
regoper
Expand All @@ -220,4 +233,6 @@ fragment type on Type {
regtype
regconfig
regdictionary
textArrayDomain
int8ArrayDomain
}
Expand Up @@ -8,6 +8,7 @@ fragment type on Type {
id
regrole
regnamespace
bigintDomainArrayDomain
}

fragment typesConnection on TypesConnection {
Expand Down
Expand Up @@ -131,6 +131,11 @@ fragment type on Type {
x
y
}
inet
cidr
macaddr
textArrayDomain
int8ArrayDomain
postBySmallint {
id
headline
Expand Down

0 comments on commit 99259f4

Please sign in to comment.