question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Compound unique with a nullable field should allow null

See original GitHub issue

Bug description

Consider the following schema:

model TelemetryMetric {
  action   String
  category String
  id       Int              @id @default(autoincrement())
  label    String?

  @@unique([category, action, label])
}

It would be expected to be able to pass null as a label when using the index. But the definition of the index is:

export type CategoryActionLabelUserIdCompoundUniqueInput = {
  category: string
  action: string
  label: string
}

Casting a null results in a runtime error.

Environment & setup

  • OS: All
  • Database: PostgreSQL
  • Node.js version: 12.X
  • Prisma version: 2.3.0

Issue Analytics

  • State:open
  • Created 3 years ago
  • Reactions:17
  • Comments:16 (11 by maintainers)

github_iconTop GitHub Comments

7reactions
dpetrickcommented, Aug 5, 2020

NULL != NULL in SQL. We can’t reliably query records that have nulls. Example:

2 rows: ID, category, action, label

  1. 1, 1, 2, null
  2. 1, 1, 2, null <- this works because SQL null != null, so no unique is violated.
SELECT * FROM TelemetryMetric WHERE category = "1" AND action = "2" AND label = NULL;
SELECT * FROM TelemetryMetric WHERE category = "1" AND action = "2" AND label IS NULL;

The first one doesn’t return anything, which isn’t a surprise if null != null. The practice for nulls is the second one, but that one returns 2 records. Since a unique cursor / where must pin a single record, we can’t allow nulls in the API.

3reactions
lstwncommented, Nov 3, 2020

Having stumbled upon the very same issue, I wanted to ask what the recommended workaround is in this case.

Is it what @Akxe mentioned? I.e. a dummy value instead of null?

I have solved this very same problem using a generated column that is part of the key (either unique or primary (our case))

CREATE TABLE `fotodoc` (
  `orderID` smallint(5) unsigned NOT NULL,
  `itemID` int(11) NOT NULL,
  `groupID` smallint(5) unsigned DEFAULT NULL,
  `groupIDNotNull` smallint(5) GENERATED ALWAYS AS (coalesce(`groupID`,0)) STORED NOT NULL,
  `name` varchar(200) NOT NULL,
  PRIMARY KEY (`orderID`,`itemID`,`groupIDNotNull`)
);

or rather an unique index (e. g. https://stackoverflow.com/questions/8289100/create-unique-constraint-with-null-columns/8289253#8289253)?

Also, do you guys plan to handle this natively with Prisma in the future or do we have to stick to these sql workarounds?

Thanks!

Read more comments on GitHub >

github_iconTop Results From Across the Web

How to allow nulls in unique fields - Simple Talk
The solution to allow nulls in unique fields is create a unique filtered index excluding the nulls of the index, due to that...
Read more >
Allow null in unique column - sql - Stack Overflow
This is a misunderstanding. The UNIQUE constraint does exactly what you want. NULL values can coexist in multiple rows in a column defined...
Read more >
How to write a composite unique constraint with one null value ...
Therefore Unique Constraint cannot be applied on “NULL”. It is advisable that the column which has a unique constraint should not allow NULL....
Read more >
postgresql - Compound unique constraint with NULL values
the coalesce() will turn all null values in the same "real" value, forcing a unique constraint violation when you try to insert another...
Read more >
PostgreSQL unique constraint null: Allowing only one Null - EDB
While the SQL standard allows multiple nulls in a unique column, and that is how Postgres behaves, some database systems (e.g. MS SQL)...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found