Skip to content

Commit

Permalink
Add null checks to validations, only add division rule if needed
Browse files Browse the repository at this point in the history
  • Loading branch information
darrellwarde committed Jul 18, 2023
1 parent 7d048a3 commit 150f9e3
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 13 deletions.
16 changes: 10 additions & 6 deletions packages/graphql/src/translate/utils/math.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,17 +114,21 @@ export function buildMathStatements(
const bitSize = mathDescriptor.graphQLType === "Int" ? 32 : 64;
// Avoid overflows, for 64 bit overflows, a long overflow is raised anyway by Neo4j
validatePredicates.push(
`apoc.util.validatePredicate(${scope}.${mathDescriptor.dbName} ${
mathDescriptor.operationSymbol
} $${param} > 2^${bitSize - 1}-1, 'Overflow: Value returned from operator %s is larger than %s bit', ["${
`apoc.util.validatePredicate(${scope}.${mathDescriptor.dbName} IS NOT NULL AND ${scope}.${
mathDescriptor.dbName
} ${mathDescriptor.operationSymbol} $${param} > 2^${
bitSize - 1
}-1, 'Overflow: Value returned from operator %s is larger than %s bit', ["${
mathDescriptor.operationName
}", "${bitSize}"])`
);

// Avoid type coercion where dividing an integer would result in a float value
validatePredicates.push(
`apoc.util.validatePredicate((${scope}.${mathDescriptor.dbName} ${mathDescriptor.operationSymbol} $${param}) % 1 <> 0, 'Type Mismatch: Value returned from operator %s does not match: %s', ["${mathDescriptor.operationName}", "${mathDescriptor.graphQLType}"])`
);
if (mathDescriptor.operationSymbol === "/" && mathDescriptor.graphQLType.includes("Int")) {
validatePredicates.push(
`apoc.util.validatePredicate(${scope}.${mathDescriptor.dbName} IS NOT NULL AND (${scope}.${mathDescriptor.dbName} ${mathDescriptor.operationSymbol} $${param}) % 1 <> 0, 'Type Mismatch: Value returned from operator %s does not match: %s', ["${mathDescriptor.operationName}", "${mathDescriptor.graphQLType}"])`
);
}

const statements: string[] = [];
const mathScope = Array.from(new Set([scope, ...withVars]));
Expand Down
3 changes: 2 additions & 1 deletion packages/graphql/tests/integration/math.int.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,7 @@ describe("Mathematical operations tests", () => {
variableValues: { id, value },
contextValue: neo4j.getContextValues(),
});
console.log(gqlResult.errors);
expect(gqlResult.errors).toBeDefined();
expect(
(gqlResult.errors as GraphQLError[]).some((el) => el.message.toLowerCase().includes(expectedError))
Expand Down Expand Up @@ -618,7 +619,7 @@ describe("Mathematical operations tests", () => {
schema: await neoSchema.getSchema(),
source: query,
variableValues: { id, value: increment },
contextValue: neo4j.getContextValues({ executionContext: session }),
contextValue: neo4j.getContextValues(),
});

expect(gqlResult.errors).toBeDefined();
Expand Down
12 changes: 6 additions & 6 deletions packages/graphql/tests/tck/math.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ describe("Math operators", () => {
CALL {
WITH this
WITH this
WHERE apoc.util.validatePredicate(this.viewers IS NULL, 'Cannot %s %s to Nan', [\\"_INCREMENT\\", $this_update_viewers_INCREMENT]) AND apoc.util.validatePredicate(this.viewers + $this_update_viewers_INCREMENT > 2^31-1, 'Overflow: Value returned from operator %s is larger than %s bit', [\\"_INCREMENT\\", \\"32\\"]) AND apoc.util.validatePredicate((this.viewers + $this_update_viewers_INCREMENT) % 1 <> 0, 'Type Mismatch: Value returned from operator %s does not match: %s', [\\"_INCREMENT\\", \\"Int\\"])
WHERE apoc.util.validatePredicate(this.viewers IS NULL, 'Cannot %s %s to Nan', [\\"_INCREMENT\\", $this_update_viewers_INCREMENT]) AND apoc.util.validatePredicate(this.viewers IS NOT NULL AND this.viewers + $this_update_viewers_INCREMENT > 2^31-1, 'Overflow: Value returned from operator %s is larger than %s bit', [\\"_INCREMENT\\", \\"32\\"])
SET this.viewers = this.viewers + $this_update_viewers_INCREMENT
RETURN this as this_viewers__INCREMENT
}
Expand Down Expand Up @@ -118,7 +118,7 @@ describe("Math operators", () => {
CALL {
WITH this
WITH this
WHERE apoc.util.validatePredicate(this.revenue IS NULL, 'Cannot %s %s to Nan', [\\"_MULTIPLY\\", $this_update_revenue_MULTIPLY]) AND apoc.util.validatePredicate(this.revenue * $this_update_revenue_MULTIPLY > 2^63-1, 'Overflow: Value returned from operator %s is larger than %s bit', [\\"_MULTIPLY\\", \\"64\\"]) AND apoc.util.validatePredicate((this.revenue * $this_update_revenue_MULTIPLY) % 1 <> 0, 'Type Mismatch: Value returned from operator %s does not match: %s', [\\"_MULTIPLY\\", \\"Float\\"])
WHERE apoc.util.validatePredicate(this.revenue IS NULL, 'Cannot %s %s to Nan', [\\"_MULTIPLY\\", $this_update_revenue_MULTIPLY]) AND apoc.util.validatePredicate(this.revenue IS NOT NULL AND this.revenue * $this_update_revenue_MULTIPLY > 2^63-1, 'Overflow: Value returned from operator %s is larger than %s bit', [\\"_MULTIPLY\\", \\"64\\"])
SET this.revenue = this.revenue * $this_update_revenue_MULTIPLY
RETURN this as this_revenue__MULTIPLY
}
Expand Down Expand Up @@ -158,7 +158,7 @@ describe("Math operators", () => {
CALL {
WITH this_actedIn0
WITH this_actedIn0
WHERE apoc.util.validatePredicate(this_actedIn0.viewers IS NULL, 'Cannot %s %s to Nan', [\\"_INCREMENT\\", $this_update_actedIn0_viewers_INCREMENT]) AND apoc.util.validatePredicate(this_actedIn0.viewers + $this_update_actedIn0_viewers_INCREMENT > 2^31-1, 'Overflow: Value returned from operator %s is larger than %s bit', [\\"_INCREMENT\\", \\"32\\"]) AND apoc.util.validatePredicate((this_actedIn0.viewers + $this_update_actedIn0_viewers_INCREMENT) % 1 <> 0, 'Type Mismatch: Value returned from operator %s does not match: %s', [\\"_INCREMENT\\", \\"Int\\"])
WHERE apoc.util.validatePredicate(this_actedIn0.viewers IS NULL, 'Cannot %s %s to Nan', [\\"_INCREMENT\\", $this_update_actedIn0_viewers_INCREMENT]) AND apoc.util.validatePredicate(this_actedIn0.viewers IS NOT NULL AND this_actedIn0.viewers + $this_update_actedIn0_viewers_INCREMENT > 2^31-1, 'Overflow: Value returned from operator %s is larger than %s bit', [\\"_INCREMENT\\", \\"32\\"])
SET this_actedIn0.viewers = this_actedIn0.viewers + $this_update_actedIn0_viewers_INCREMENT
RETURN this_actedIn0 as this_actedIn0_viewers__INCREMENT
}
Expand Down Expand Up @@ -215,7 +215,7 @@ describe("Math operators", () => {
CALL {
WITH this_acted_in0_relationship
WITH this_acted_in0_relationship
WHERE apoc.util.validatePredicate(this_acted_in0_relationship.pay IS NULL, 'Cannot %s %s to Nan', [\\"_ADD\\", $updateActors.args.update.actedIn[0].update.edge.pay_ADD]) AND apoc.util.validatePredicate(this_acted_in0_relationship.pay + $updateActors.args.update.actedIn[0].update.edge.pay_ADD > 2^63-1, 'Overflow: Value returned from operator %s is larger than %s bit', [\\"_ADD\\", \\"64\\"]) AND apoc.util.validatePredicate((this_acted_in0_relationship.pay + $updateActors.args.update.actedIn[0].update.edge.pay_ADD) % 1 <> 0, 'Type Mismatch: Value returned from operator %s does not match: %s', [\\"_ADD\\", \\"Float\\"])
WHERE apoc.util.validatePredicate(this_acted_in0_relationship.pay IS NULL, 'Cannot %s %s to Nan', [\\"_ADD\\", $updateActors.args.update.actedIn[0].update.edge.pay_ADD]) AND apoc.util.validatePredicate(this_acted_in0_relationship.pay IS NOT NULL AND this_acted_in0_relationship.pay + $updateActors.args.update.actedIn[0].update.edge.pay_ADD > 2^63-1, 'Overflow: Value returned from operator %s is larger than %s bit', [\\"_ADD\\", \\"64\\"])
SET this_acted_in0_relationship.pay = this_acted_in0_relationship.pay + $updateActors.args.update.actedIn[0].update.edge.pay_ADD
RETURN this_acted_in0_relationship as this_acted_in0_relationship_pay__ADD
}
Expand Down Expand Up @@ -289,7 +289,7 @@ describe("Math operators", () => {
CALL {
WITH this_marriedWith0
WITH this_marriedWith0
WHERE apoc.util.validatePredicate(this_marriedWith0.marriageLength IS NULL, 'Cannot %s %s to Nan', [\\"_INCREMENT\\", $this_update_marriedWith0_marriageLength_INCREMENT]) AND apoc.util.validatePredicate(this_marriedWith0.marriageLength + $this_update_marriedWith0_marriageLength_INCREMENT > 2^31-1, 'Overflow: Value returned from operator %s is larger than %s bit', [\\"_INCREMENT\\", \\"32\\"]) AND apoc.util.validatePredicate((this_marriedWith0.marriageLength + $this_update_marriedWith0_marriageLength_INCREMENT) % 1 <> 0, 'Type Mismatch: Value returned from operator %s does not match: %s', [\\"_INCREMENT\\", \\"Int\\"])
WHERE apoc.util.validatePredicate(this_marriedWith0.marriageLength IS NULL, 'Cannot %s %s to Nan', [\\"_INCREMENT\\", $this_update_marriedWith0_marriageLength_INCREMENT]) AND apoc.util.validatePredicate(this_marriedWith0.marriageLength IS NOT NULL AND this_marriedWith0.marriageLength + $this_update_marriedWith0_marriageLength_INCREMENT > 2^31-1, 'Overflow: Value returned from operator %s is larger than %s bit', [\\"_INCREMENT\\", \\"32\\"])
SET this_marriedWith0.marriageLength = this_marriedWith0.marriageLength + $this_update_marriedWith0_marriageLength_INCREMENT
RETURN this_marriedWith0 as this_marriedWith0_marriageLength__INCREMENT
}
Expand Down Expand Up @@ -369,7 +369,7 @@ describe("Math operators", () => {
CALL {
WITH this_marriedWith0
WITH this_marriedWith0
WHERE apoc.util.validatePredicate(this_marriedWith0.marriageLength IS NULL, 'Cannot %s %s to Nan', [\\"_INCREMENT\\", $this_update_marriedWith0_on_Star_marriageLength_INCREMENT]) AND apoc.util.validatePredicate(this_marriedWith0.marriageLength + $this_update_marriedWith0_on_Star_marriageLength_INCREMENT > 2^31-1, 'Overflow: Value returned from operator %s is larger than %s bit', [\\"_INCREMENT\\", \\"32\\"]) AND apoc.util.validatePredicate((this_marriedWith0.marriageLength + $this_update_marriedWith0_on_Star_marriageLength_INCREMENT) % 1 <> 0, 'Type Mismatch: Value returned from operator %s does not match: %s', [\\"_INCREMENT\\", \\"Int\\"])
WHERE apoc.util.validatePredicate(this_marriedWith0.marriageLength IS NULL, 'Cannot %s %s to Nan', [\\"_INCREMENT\\", $this_update_marriedWith0_on_Star_marriageLength_INCREMENT]) AND apoc.util.validatePredicate(this_marriedWith0.marriageLength IS NOT NULL AND this_marriedWith0.marriageLength + $this_update_marriedWith0_on_Star_marriageLength_INCREMENT > 2^31-1, 'Overflow: Value returned from operator %s is larger than %s bit', [\\"_INCREMENT\\", \\"32\\"])
SET this_marriedWith0.marriageLength = this_marriedWith0.marriageLength + $this_update_marriedWith0_on_Star_marriageLength_INCREMENT
RETURN this_marriedWith0 as this_marriedWith0_marriageLength__INCREMENT
}
Expand Down

0 comments on commit 150f9e3

Please sign in to comment.