From f111141e3f9627b154a9132f6f1a9cfe02afc559 Mon Sep 17 00:00:00 2001 From: ymc9 <104139426+ymc9@users.noreply.github.com> Date: Sat, 30 Sep 2023 23:09:11 -0700 Subject: [PATCH 1/2] fix: report validation error when binary expressions have arrays --- .../validator/expression-validator.ts | 15 +++++++ .../validation/attribute-validation.test.ts | 44 +++++++++++++++++++ 2 files changed, 59 insertions(+) diff --git a/packages/schema/src/language-server/validator/expression-validator.ts b/packages/schema/src/language-server/validator/expression-validator.ts index 21548c89f..d3ef26cb5 100644 --- a/packages/schema/src/language-server/validator/expression-validator.ts +++ b/packages/schema/src/language-server/validator/expression-validator.ts @@ -64,6 +64,16 @@ export default class ExpressionValidator implements AstValidator { case '<=': case '&&': case '||': { + if (expr.left.$resolvedType?.array) { + accept('error', 'operand cannot be an array', { node: expr.left }); + break; + } + + if (expr.right.$resolvedType?.array) { + accept('error', 'operand cannot be an array', { node: expr.right }); + break; + } + let supportedShapes: ExpressionType[]; if (['>', '>=', '<', '<='].includes(expr.operator)) { supportedShapes = ['Int', 'Float', 'DateTime', 'Any']; @@ -105,6 +115,11 @@ export default class ExpressionValidator implements AstValidator { case '==': case '!=': { + if (expr.left.$resolvedType?.array !== expr.right.$resolvedType?.array) { + accept('error', 'incompatible operand types', { node: expr }); + break; + } + // disallow comparing model type with scalar type or comparison between // incompatible model types const leftType = expr.left.$resolvedType?.decl; diff --git a/packages/schema/tests/schema/validation/attribute-validation.test.ts b/packages/schema/tests/schema/validation/attribute-validation.test.ts index cc908898b..5c638a841 100644 --- a/packages/schema/tests/schema/validation/attribute-validation.test.ts +++ b/packages/schema/tests/schema/validation/attribute-validation.test.ts @@ -553,6 +553,50 @@ describe('Attribute tests', () => { `) ).toContain('incompatible operand types'); + expect( + await loadModelWithError(` + ${prelude} + model A { + id String @id + x Int + y Int[] + + @@allow(true, x == y) + } + `) + ).toContain('incompatible operand types'); + + expect( + await loadModelWithError(` + ${prelude} + model A { + id String @id + x Int + y Int[] + + @@allow(true, x > y) + } + `) + ).toContain('operand cannot be an array'); + + expect( + await loadModelWithError(` + ${prelude} + model User { + id Int @id + foo Foo @relation(fields: [fooId], references: [id]) + fooId Int + } + + model Foo { + id Int @id + users User[] + + @@allow('all', users == auth()) + } + `) + ).toContain('incompatible operand types'); + expect( await loadModelWithError(` ${prelude} From fc525160f2cd51299169672126f98d923707445c Mon Sep 17 00:00:00 2001 From: ymc9 <104139426+ymc9@users.noreply.github.com> Date: Sun, 1 Oct 2023 16:27:28 -0700 Subject: [PATCH 2/2] fix comparison --- .../src/language-server/validator/expression-validator.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/schema/src/language-server/validator/expression-validator.ts b/packages/schema/src/language-server/validator/expression-validator.ts index d3ef26cb5..557b0f338 100644 --- a/packages/schema/src/language-server/validator/expression-validator.ts +++ b/packages/schema/src/language-server/validator/expression-validator.ts @@ -115,7 +115,7 @@ export default class ExpressionValidator implements AstValidator { case '==': case '!=': { - if (expr.left.$resolvedType?.array !== expr.right.$resolvedType?.array) { + if (!!expr.left.$resolvedType?.array !== !!expr.right.$resolvedType?.array) { accept('error', 'incompatible operand types', { node: expr }); break; }