From b2cb0f6000eddc017f8c89a3c2801c71e694f2ba Mon Sep 17 00:00:00 2001 From: Simon Binder Date: Sun, 31 Jul 2022 23:26:00 +0200 Subject: [PATCH] Forbid whereSamePrimaryKey for null values (#1956) --- .../runtime/query_builder/statements/query.dart | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/drift/lib/src/runtime/query_builder/statements/query.dart b/drift/lib/src/runtime/query_builder/statements/query.dart index b1b339a9..c50772df 100644 --- a/drift/lib/src/runtime/query_builder/statements/query.dart +++ b/drift/lib/src/runtime/query_builder/statements/query.dart @@ -356,6 +356,13 @@ extension QueryTableExtensions /// Applies a [where] statement so that the row with the same primary key as /// [d] will be matched. + /// + /// Note that, as far as primary key equality is concerned, `NULL` values are + /// considered distinct from all values (including other `NULL`s). + /// This matches sqlite3's behavior of not counting duplicate `NULL`s as a + /// uniqueness constraint violation for primary keys, but makes it impossible + /// to find other rows with [whereSamePrimaryKey] if nullable primary keys are + /// used. void whereSamePrimaryKey(Insertable d) { final source = _sourceTable; assert( @@ -384,6 +391,16 @@ extension QueryTableExtensions return MapEntry(primaryKeyColumns[columnName]!, value); }); + assert( + primaryKeyValues.values + .every((value) => value is! Variable || value.value != null), + 'Tried to find a row with a matching primary key that has a null value, ' + 'which is not supported. In sqlite3, `NULL` values in a primary key are ' + 'considered distinct from all other values (including other `NULL`s), so ' + "drift can't find a matching row for this query. \n" + 'For details, see https://github.com/simolus3/drift/issues/1956#issuecomment-1200502026', + ); + Expression? predicate; for (final entry in primaryKeyValues.entries) { final comparison =