From aff000fd03b39ca083df1f6611a98f2f3db60962 Mon Sep 17 00:00:00 2001 From: Richard Haines Date: Wed, 17 Mar 2021 13:18:32 +0100 Subject: [PATCH 1/9] Added new section about null conditions --- .../080-null-and-undefined.mdx | 153 ++++++++++++++++++ 1 file changed, 153 insertions(+) diff --git a/content/200-concepts/100-components/02-prisma-client/080-null-and-undefined.mdx b/content/200-concepts/100-components/02-prisma-client/080-null-and-undefined.mdx index 414399f76f..6fa1ad0737 100644 --- a/content/200-concepts/100-components/02-prisma-client/080-null-and-undefined.mdx +++ b/content/200-concepts/100-components/02-prisma-client/080-null-and-undefined.mdx @@ -134,3 +134,156 @@ updateUser: (parent, args, ctx: Context) => { }) }, ``` + +## The effect of NULL on conditionals + +There are some caveats to filtering with conditionals which might produce unexpected results. When filtering with conditionals you might expect one result but receive another given how Prisma treats `nullable` values. + +### A high level overview + + +|Operator | 0 filters | 1 filter | n filters | +|-----------------------------|------------------------|------------------------|----------------------| +|OR | return empty list | validate single filter | validate all filters | +|AND | return all items | validate single filter | validate all filters | +|NOT | return all items | validate single filter | validate all filters | + + +### OR + +The `OR` operator states that one or more conditions must be true for the result to return any data. It is therefore logical to assume that using the `OR` +operator but supplying no filters, returns no results. + +```js +prisma.myTable.findMany({ + where: { + OR: [], + }, +}); +``` + +When supplying the operator with a single filter, that filter will be run and it's results returned. If multiple filters are supplied then `n` results will be returned dependant on the filters supplied. + +```js +// Single filter +prisma.myTable.findMany({ + where: { + OR: [{name: 'Emelie'}], + }, +}); + +// Multiple filters +prisma.myTable.findMany({ + where: { + OR: [{ + name: 'Emelie', + drivesCar: true + }], + }, +}); +``` + +See the `OR` section in the [Prisma Client reference](../../../reference/api-reference/prisma-client-reference#or) for more information about the operator. + +### AND + +The `AND` operator expects all conditions to be true, that is, all filters must return something for it to return anything if it is to return data. +As stated above, Prisma treats `null` values as having a value, where as `undefined` means do nothing. +To that end if the `AND` operator is used but no filters are supplied then it will return all items requested in the query because providing no filter is like providing no condition, +which means that the query will return it's default data. + +```js +// This is the same +prisma.myTable.findMany({ + where: { + AND: [], + }, +}); + +// As this +prisma.myTable.findMany(); +``` + +Prioviding a single filter to the `AND` operator works the same way as the `OR` condition except that the filter **must** return true for it to return the filtered data. +The same applies for multiple filters, where all filters must return true for the query to return any data. + +```js +// Single filter +prisma.myTable.findMany({ + where: { + AND: [ + { + name: { + contains: 'Emelie' + }, + } + ], + }, +}); + +// Multiple filters +prisma.myTable.findMany({ + where: { + AND: [ + { + name: { + contains: 'Emelie' + }, + }, + { + drivesCar: { + equals: true + }, + } + ], + }, +}); +``` + +See the `AND` section in the [Prisma Client reference](../../../reference/api-reference/prisma-client-reference#and) for more information about the operator. + +### NOT + +The `NOT` operator expects that all conditions are false before it will return any data. Much like the `AND` operator, `NOT` will return the queries default data if no filters are passed. + +```js +// This is the same +prisma.myTable.findMany({ + where: { + NOT: [], + }, +}); + +// As this +prisma.myTable.findMany(); +``` + +`NOT` is most often used in conjunction with other operators to form fluid conditions from which the data should be filtered through. Using all three conditional operators: + +```js +const result = await prisma.post.findMany({ + where: { + OR: [ + { + name: { + contains: 'Emelie', + }, + }, + ], + AND: [ + { + drivesCar: { + equals: true + }, + } + ], + NOT: { + name: { + contains: 'Mrs', + }, + }, + }, +}) +``` + +See the `NOT` section in the [Prisma Client reference](../../../reference/api-reference/prisma-client-reference#not) for more information about the operator. From 7e0c7edd9fe3fdef4a86b63e463506152b4ad1a6 Mon Sep 17 00:00:00 2001 From: Richard Haines Date: Wed, 17 Mar 2021 14:27:09 +0100 Subject: [PATCH 2/9] changed section title, added clarity to undefined --- .../02-prisma-client/080-null-and-undefined.mdx | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/content/200-concepts/100-components/02-prisma-client/080-null-and-undefined.mdx b/content/200-concepts/100-components/02-prisma-client/080-null-and-undefined.mdx index 6fa1ad0737..976271bc14 100644 --- a/content/200-concepts/100-components/02-prisma-client/080-null-and-undefined.mdx +++ b/content/200-concepts/100-components/02-prisma-client/080-null-and-undefined.mdx @@ -135,7 +135,7 @@ updateUser: (parent, args, ctx: Context) => { }, ``` -## The effect of NULL on conditionals +## The effect of null and undefined on conditionals There are some caveats to filtering with conditionals which might produce unexpected results. When filtering with conditionals you might expect one result but receive another given how Prisma treats `nullable` values. @@ -162,6 +162,8 @@ prisma.myTable.findMany({ }); ``` +> This is the same as passing `null`, which maps to `null` in the database. If you were to pass `undefined` that would represent no value at all and so would be the same as passing no conditions to the query. + When supplying the operator with a single filter, that filter will be run and it's results returned. If multiple filters are supplied then `n` results will be returned dependant on the filters supplied. ```js @@ -193,15 +195,15 @@ To that end if the `AND` operator is used but no filters are supplied then it wi which means that the query will return it's default data. ```js -// This is the same +// This has the same effect prisma.myTable.findMany({ where: { - AND: [], + AND: [], // The same as passing null }, }); // As this -prisma.myTable.findMany(); +prisma.myTable.findMany(); // The same as passing undefined ``` Prioviding a single filter to the `AND` operator works the same way as the `OR` condition except that the filter **must** return true for it to return the filtered data. @@ -247,15 +249,15 @@ See the `AND` section in the [Prisma Client reference](../../../reference/api-re The `NOT` operator expects that all conditions are false before it will return any data. Much like the `AND` operator, `NOT` will return the queries default data if no filters are passed. ```js -// This is the same +// This has the same effect prisma.myTable.findMany({ where: { - NOT: [], + NOT: [], // The same as passing null }, }); // As this -prisma.myTable.findMany(); +prisma.myTable.findMany(); // The same as passing undefined ``` `NOT` is most often used in conjunction with other operators to form fluid conditions from which the data should be filtered through. Using all three conditional operators: From 2c0f98d8cde1882a804a6637d2db18fb2a832e4e Mon Sep 17 00:00:00 2001 From: Richard Haines Date: Thu, 18 Mar 2021 10:09:50 +0100 Subject: [PATCH 3/9] refactoring to simplify --- .../02-prisma-client/080-null-and-undefined.mdx | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/content/200-concepts/100-components/02-prisma-client/080-null-and-undefined.mdx b/content/200-concepts/100-components/02-prisma-client/080-null-and-undefined.mdx index 976271bc14..d3a5ba6a27 100644 --- a/content/200-concepts/100-components/02-prisma-client/080-null-and-undefined.mdx +++ b/content/200-concepts/100-components/02-prisma-client/080-null-and-undefined.mdx @@ -142,11 +142,11 @@ There are some caveats to filtering with conditionals which might produce unexpe ### A high level overview -|Operator | 0 filters | 1 filter | n filters | -|-----------------------------|------------------------|------------------------|----------------------| -|OR | return empty list | validate single filter | validate all filters | -|AND | return all items | validate single filter | validate all filters | -|NOT | return all items | validate single filter | validate all filters | +|Operator | 0 filters | 1 filter | n filters | +|-----------|------------------------|------------------------|----------------------| +|`OR` | return empty list | validate single filter | validate all filters | +|`AND` | return all items | validate single filter | validate all filters | +|`NOT` | return all items | validate single filter | validate all filters | ### OR @@ -162,8 +162,7 @@ prisma.myTable.findMany({ }); ``` -> This is the same as passing `null`, which maps to `null` in the database. If you were to pass `undefined` that would represent no value at all and so would be the same as passing no conditions to the query. - +> This is the same as passing `null`, which maps to `null` in the database. When supplying the operator with a single filter, that filter will be run and it's results returned. If multiple filters are supplied then `n` results will be returned dependant on the filters supplied. ```js @@ -206,7 +205,7 @@ prisma.myTable.findMany({ prisma.myTable.findMany(); // The same as passing undefined ``` -Prioviding a single filter to the `AND` operator works the same way as the `OR` condition except that the filter **must** return true for it to return the filtered data. +Providing a single filter to the `AND` operator works the same way as the `OR` condition except that the filter **must** return true for it to return the filtered data. The same applies for multiple filters, where all filters must return true for the query to return any data. ```js From 468abcaadf4e316888ceeade2e1f5b01f17700cc Mon Sep 17 00:00:00 2001 From: Richard Haines Date: Thu, 18 Mar 2021 10:53:52 +0100 Subject: [PATCH 4/9] feedback --- .../02-prisma-client/080-null-and-undefined.mdx | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/content/200-concepts/100-components/02-prisma-client/080-null-and-undefined.mdx b/content/200-concepts/100-components/02-prisma-client/080-null-and-undefined.mdx index d3a5ba6a27..584e691672 100644 --- a/content/200-concepts/100-components/02-prisma-client/080-null-and-undefined.mdx +++ b/content/200-concepts/100-components/02-prisma-client/080-null-and-undefined.mdx @@ -137,7 +137,7 @@ updateUser: (parent, args, ctx: Context) => { ## The effect of null and undefined on conditionals -There are some caveats to filtering with conditionals which might produce unexpected results. When filtering with conditionals you might expect one result but receive another given how Prisma treats `nullable` values. +There are some caveats to filtering with conditionals which might produce unexpected results. When filtering with conditionals you might expect one result but receive another given how Prisma treats nullable values. ### A high level overview @@ -151,7 +151,7 @@ There are some caveats to filtering with conditionals which might produce unexpe ### OR -The `OR` operator states that one or more conditions must be true for the result to return any data. It is therefore logical to assume that using the `OR` +The [`OR`](../../../reference/api-reference/prisma-client-reference#or) operator states that one or more conditions must be true for the result to return any data. It is therefore logical to assume that using the `OR` operator but supplying no filters, returns no results. ```js @@ -163,6 +163,7 @@ prisma.myTable.findMany({ ``` > This is the same as passing `null`, which maps to `null` in the database. + When supplying the operator with a single filter, that filter will be run and it's results returned. If multiple filters are supplied then `n` results will be returned dependant on the filters supplied. ```js @@ -184,11 +185,9 @@ prisma.myTable.findMany({ }); ``` -See the `OR` section in the [Prisma Client reference](../../../reference/api-reference/prisma-client-reference#or) for more information about the operator. - ### AND -The `AND` operator expects all conditions to be true, that is, all filters must return something for it to return anything if it is to return data. +The [`AND`](../../../reference/api-reference/prisma-client-reference#and) operator expects all conditions to be true, that is, all filters must return something for it to return anything if it is to return data. As stated above, Prisma treats `null` values as having a value, where as `undefined` means do nothing. To that end if the `AND` operator is used but no filters are supplied then it will return all items requested in the query because providing no filter is like providing no condition, which means that the query will return it's default data. @@ -241,11 +240,9 @@ prisma.myTable.findMany({ }); ``` -See the `AND` section in the [Prisma Client reference](../../../reference/api-reference/prisma-client-reference#and) for more information about the operator. - ### NOT -The `NOT` operator expects that all conditions are false before it will return any data. Much like the `AND` operator, `NOT` will return the queries default data if no filters are passed. +The [`NOT`](../../../reference/api-reference/prisma-client-reference#not) operator expects that all conditions are false before it will return any data. Much like the `AND` operator, `NOT` will return the queries default data if no filters are passed. ```js // This has the same effect @@ -285,6 +282,4 @@ const result = await prisma.post.findMany({ }, }, }) -``` - -See the `NOT` section in the [Prisma Client reference](../../../reference/api-reference/prisma-client-reference#not) for more information about the operator. +``` \ No newline at end of file From 03c3ab5fd32c80a3092a3bd1925088ca1b42c488 Mon Sep 17 00:00:00 2001 From: Richard Haines Date: Fri, 19 Mar 2021 08:33:53 +0100 Subject: [PATCH 5/9] simplified --- .../080-null-and-undefined.mdx | 174 ++++++------------ 1 file changed, 56 insertions(+), 118 deletions(-) diff --git a/content/200-concepts/100-components/02-prisma-client/080-null-and-undefined.mdx b/content/200-concepts/100-components/02-prisma-client/080-null-and-undefined.mdx index 584e691672..5d5c0df8b2 100644 --- a/content/200-concepts/100-components/02-prisma-client/080-null-and-undefined.mdx +++ b/content/200-concepts/100-components/02-prisma-client/080-null-and-undefined.mdx @@ -148,138 +148,76 @@ There are some caveats to filtering with conditionals which might produce unexpe |`AND` | return all items | validate single filter | validate all filters | |`NOT` | return all items | validate single filter | validate all filters | +The following example shows how an `undefined` parameter can impact the expected return data when passed to a conditional operator such as [`OR`](../../../reference/api-reference/prisma-client-reference#or) . -### OR - -The [`OR`](../../../reference/api-reference/prisma-client-reference#or) operator states that one or more conditions must be true for the result to return any data. It is therefore logical to assume that using the `OR` -operator but supplying no filters, returns no results. - -```js -prisma.myTable.findMany({ - where: { - OR: [], - }, -}); -``` - -> This is the same as passing `null`, which maps to `null` in the database. +```ts +interface FormData { + name: string; + email?: string; +} -When supplying the operator with a single filter, that filter will be run and it's results returned. If multiple filters are supplied then `n` results will be returned dependant on the filters supplied. +const formData: FormData = { + name: 'Emelie' +} -```js -// Single filter -prisma.myTable.findMany({ - where: { - OR: [{name: 'Emelie'}], - }, -}); +const users = await prisma.user.findMany({ + where: { + OR: [ + { + email: { + contains: formData.email + } + } + ] + } +}) -// Multiple filters -prisma.myTable.findMany({ - where: { - OR: [{ - name: 'Emelie', - drivesCar: true - }], - }, -}); +// returns: [] ``` -### AND +The query is passed the form data which can optionally contain an email. In this instance the email field has been omitted from the form. When this query is run no data is returned. -The [`AND`](../../../reference/api-reference/prisma-client-reference#and) operator expects all conditions to be true, that is, all filters must return something for it to return anything if it is to return data. -As stated above, Prisma treats `null` values as having a value, where as `undefined` means do nothing. -To that end if the `AND` operator is used but no filters are supplied then it will return all items requested in the query because providing no filter is like providing no condition, -which means that the query will return it's default data. +This is in contrast to both the [`AND`](../../../reference/api-reference/prisma-client-reference#and) and [`NOT`](../../../reference/api-reference/prisma-client-reference#not) operators which will both return all the users +if an undefined value is used. -```js -// This has the same effect -prisma.myTable.findMany({ - where: { - AND: [], // The same as passing null - }, -}); +> This is because passing an `undefined` value to an `AND` or `NOT` operator is the same +as passing nothing at all, meaning the `findMany` query in the example will run without any filters and return all the users. -// As this -prisma.myTable.findMany(); // The same as passing undefined -``` - -Providing a single filter to the `AND` operator works the same way as the `OR` condition except that the filter **must** return true for it to return the filtered data. -The same applies for multiple filters, where all filters must return true for the query to return any data. - -```js -// Single filter -prisma.myTable.findMany({ - where: { - AND: [ - { - name: { - contains: 'Emelie' - }, - } - ], - }, -}); - -// Multiple filters -prisma.myTable.findMany({ - where: { - AND: [ - { - name: { - contains: 'Emelie' - }, - }, - { - drivesCar: { - equals: true - }, - } - ], - }, -}); -``` - -### NOT - -The [`NOT`](../../../reference/api-reference/prisma-client-reference#not) operator expects that all conditions are false before it will return any data. Much like the `AND` operator, `NOT` will return the queries default data if no filters are passed. +```ts +interface FormData { + name: string; + email?: string; +} -```js -// This has the same effect -prisma.myTable.findMany({ - where: { - NOT: [], // The same as passing null - }, -}); +const formData: FormData = { + name: 'Emelie' +} -// As this -prisma.myTable.findMany(); // The same as passing undefined -``` +const users = await prisma.user.findMany({ + where: { + AND: [ + { + email: { + contains: formData.email + } + } + ] + } +}) -`NOT` is most often used in conjunction with other operators to form fluid conditions from which the data should be filtered through. Using all three conditional operators: +// returns: { id: 1, email: 'ems@boop.com', name: 'Emelie' } -```js -const result = await prisma.post.findMany({ +const users = await prisma.user.findMany({ where: { - OR: [ - { - name: { - contains: 'Emelie', - }, - }, - ], - AND: [ + NOT: [ { - drivesCar: { - equals: true - }, + email: { + contains: formData.email + } } - ], - NOT: { - name: { - contains: 'Mrs', - }, - }, - }, + ] + } }) -``` \ No newline at end of file + +// returns: { id: 1, email: 'ems@boop.com', name: 'Emelie' } +``` From 81484e8efb293cec58ad69fc1749a9b3cee79829 Mon Sep 17 00:00:00 2001 From: Rich Haines Date: Fri, 19 Mar 2021 09:51:03 +0100 Subject: [PATCH 6/9] Update content/200-concepts/100-components/02-prisma-client/080-null-and-undefined.mdx Co-authored-by: Martina Welander --- .../100-components/02-prisma-client/080-null-and-undefined.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/200-concepts/100-components/02-prisma-client/080-null-and-undefined.mdx b/content/200-concepts/100-components/02-prisma-client/080-null-and-undefined.mdx index 5d5c0df8b2..33fbed12fa 100644 --- a/content/200-concepts/100-components/02-prisma-client/080-null-and-undefined.mdx +++ b/content/200-concepts/100-components/02-prisma-client/080-null-and-undefined.mdx @@ -148,7 +148,7 @@ There are some caveats to filtering with conditionals which might produce unexpe |`AND` | return all items | validate single filter | validate all filters | |`NOT` | return all items | validate single filter | validate all filters | -The following example shows how an `undefined` parameter can impact the expected return data when passed to a conditional operator such as [`OR`](../../../reference/api-reference/prisma-client-reference#or) . +The following example shows how an `undefined` parameter impacts the results returned by a query that uses the [`OR`](../../../reference/api-reference/prisma-client-reference#or) operator. ```ts interface FormData { From 38c82b2f1e65a28bf409c3c8bacb85114f87516f Mon Sep 17 00:00:00 2001 From: Rich Haines Date: Fri, 19 Mar 2021 10:03:02 +0100 Subject: [PATCH 7/9] Update content/200-concepts/100-components/02-prisma-client/080-null-and-undefined.mdx Co-authored-by: Martina Welander --- .../100-components/02-prisma-client/080-null-and-undefined.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/200-concepts/100-components/02-prisma-client/080-null-and-undefined.mdx b/content/200-concepts/100-components/02-prisma-client/080-null-and-undefined.mdx index 33fbed12fa..5f0027764d 100644 --- a/content/200-concepts/100-components/02-prisma-client/080-null-and-undefined.mdx +++ b/content/200-concepts/100-components/02-prisma-client/080-null-and-undefined.mdx @@ -177,7 +177,7 @@ const users = await prisma.user.findMany({ The query is passed the form data which can optionally contain an email. In this instance the email field has been omitted from the form. When this query is run no data is returned. -This is in contrast to both the [`AND`](../../../reference/api-reference/prisma-client-reference#and) and [`NOT`](../../../reference/api-reference/prisma-client-reference#not) operators which will both return all the users +This is in contrast to the [`AND`](../../../reference/api-reference/prisma-client-reference#and) and [`NOT`](../../../reference/api-reference/prisma-client-reference#not) operators, which will both return all the users if an undefined value is used. > This is because passing an `undefined` value to an `AND` or `NOT` operator is the same From bd10d6dafcbe0fe73cee846d9f395d5fe5bee3cb Mon Sep 17 00:00:00 2001 From: Rich Haines Date: Fri, 19 Mar 2021 10:03:27 +0100 Subject: [PATCH 8/9] Update content/200-concepts/100-components/02-prisma-client/080-null-and-undefined.mdx Co-authored-by: Martina Welander --- .../100-components/02-prisma-client/080-null-and-undefined.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/200-concepts/100-components/02-prisma-client/080-null-and-undefined.mdx b/content/200-concepts/100-components/02-prisma-client/080-null-and-undefined.mdx index 5f0027764d..3a90788daf 100644 --- a/content/200-concepts/100-components/02-prisma-client/080-null-and-undefined.mdx +++ b/content/200-concepts/100-components/02-prisma-client/080-null-and-undefined.mdx @@ -178,7 +178,7 @@ const users = await prisma.user.findMany({ The query is passed the form data which can optionally contain an email. In this instance the email field has been omitted from the form. When this query is run no data is returned. This is in contrast to the [`AND`](../../../reference/api-reference/prisma-client-reference#and) and [`NOT`](../../../reference/api-reference/prisma-client-reference#not) operators, which will both return all the users -if an undefined value is used. +if you pass in an `undefined` value. > This is because passing an `undefined` value to an `AND` or `NOT` operator is the same as passing nothing at all, meaning the `findMany` query in the example will run without any filters and return all the users. From 8dfb597e9f70425813a236b794f76fedd9c64a9b Mon Sep 17 00:00:00 2001 From: Richard Haines Date: Fri, 19 Mar 2021 10:14:52 +0100 Subject: [PATCH 9/9] feedback-changes --- .../02-prisma-client/080-null-and-undefined.mdx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/content/200-concepts/100-components/02-prisma-client/080-null-and-undefined.mdx b/content/200-concepts/100-components/02-prisma-client/080-null-and-undefined.mdx index 3a90788daf..dddb73989c 100644 --- a/content/200-concepts/100-components/02-prisma-client/080-null-and-undefined.mdx +++ b/content/200-concepts/100-components/02-prisma-client/080-null-and-undefined.mdx @@ -139,7 +139,7 @@ updateUser: (parent, args, ctx: Context) => { There are some caveats to filtering with conditionals which might produce unexpected results. When filtering with conditionals you might expect one result but receive another given how Prisma treats nullable values. -### A high level overview +The following table provides a high-level overview of how the different operators handle 0, 1 and `n` filters. |Operator | 0 filters | 1 filter | n filters | @@ -148,7 +148,7 @@ There are some caveats to filtering with conditionals which might produce unexpe |`AND` | return all items | validate single filter | validate all filters | |`NOT` | return all items | validate single filter | validate all filters | -The following example shows how an `undefined` parameter impacts the results returned by a query that uses the [`OR`](../../../reference/api-reference/prisma-client-reference#or) operator. +This example shows how an `undefined` parameter impacts the results returned by a query that uses the [`OR`](../../../reference/api-reference/prisma-client-reference#or) operator. ```ts interface FormData { @@ -175,7 +175,7 @@ const users = await prisma.user.findMany({ // returns: [] ``` -The query is passed the form data which can optionally contain an email. In this instance the email field has been omitted from the form. When this query is run no data is returned. +The query receives filters from a formData object, which includes an optional email property. In this instance, the value of the email property is `undefined`. When this query is run no data is returned. This is in contrast to the [`AND`](../../../reference/api-reference/prisma-client-reference#and) and [`NOT`](../../../reference/api-reference/prisma-client-reference#not) operators, which will both return all the users if you pass in an `undefined` value.