From 02ee791796852c4b7092131da193dd77780bfcb1 Mon Sep 17 00:00:00 2001
From: WithoutPants <53250216+WithoutPants@users.noreply.github.com>
Date: Tue, 29 Mar 2022 06:45:46 +1100
Subject: [PATCH] Fix missing date filter (#2434)

---
 pkg/sqlite/gallery.go                         |  2 +-
 pkg/sqlite/gallery_test.go                    | 23 +++++++++++++++++++
 pkg/sqlite/scene.go                           |  2 +-
 pkg/sqlite/scene_test.go                      |  4 +++-
 pkg/sqlite/setup_test.go                      |  5 ++--
 .../components/Changelog/versions/v0140.md    |  1 +
 6 files changed, 32 insertions(+), 5 deletions(-)

diff --git a/pkg/sqlite/gallery.go b/pkg/sqlite/gallery.go
index 18512d5f0..b7f9276ac 100644
--- a/pkg/sqlite/gallery.go
+++ b/pkg/sqlite/gallery.go
@@ -300,7 +300,7 @@ func galleryIsMissingCriterionHandler(qb *galleryQueryBuilder, isMissing *string
 				qb.performersRepository().join(f, "performers_join", "galleries.id")
 				f.addWhere("performers_join.gallery_id IS NULL")
 			case "date":
-				f.addWhere("galleries.date IS \"\" OR galleries.date IS \"0001-01-01\"")
+				f.addWhere("galleries.date IS NULL OR galleries.date IS \"\" OR galleries.date IS \"0001-01-01\"")
 			case "tags":
 				qb.tagsRepository().join(f, "tags_join", "galleries.id")
 				f.addWhere("tags_join.gallery_id IS NULL")
diff --git a/pkg/sqlite/gallery_test.go b/pkg/sqlite/gallery_test.go
index a121e4b5c..f9aa9ef5e 100644
--- a/pkg/sqlite/gallery_test.go
+++ b/pkg/sqlite/gallery_test.go
@@ -4,6 +4,7 @@
 package sqlite_test
 
 import (
+	"math"
 	"strconv"
 	"testing"
 
@@ -562,6 +563,28 @@ func TestGalleryQueryIsMissingTags(t *testing.T) {
 	})
 }
 
+func TestGalleryQueryIsMissingDate(t *testing.T) {
+	withTxn(func(r models.Repository) error {
+		sqb := r.Gallery()
+		isMissing := "date"
+		galleryFilter := models.GalleryFilterType{
+			IsMissing: &isMissing,
+		}
+
+		galleries := queryGallery(t, sqb, &galleryFilter, nil)
+
+		// three in four scenes have no date
+		assert.Len(t, galleries, int(math.Ceil(float64(totalGalleries)/4*3)))
+
+		// ensure date is null, empty or "0001-01-01"
+		for _, g := range galleries {
+			assert.True(t, !g.Date.Valid || g.Date.String == "" || g.Date.String == "0001-01-01")
+		}
+
+		return nil
+	})
+}
+
 func TestGalleryQueryPerformers(t *testing.T) {
 	withTxn(func(r models.Repository) error {
 		sqb := r.Gallery()
diff --git a/pkg/sqlite/scene.go b/pkg/sqlite/scene.go
index 054e82266..e6c0d7019 100644
--- a/pkg/sqlite/scene.go
+++ b/pkg/sqlite/scene.go
@@ -582,7 +582,7 @@ func sceneIsMissingCriterionHandler(qb *sceneQueryBuilder, isMissing *string) cr
 				qb.performersRepository().join(f, "performers_join", "scenes.id")
 				f.addWhere("performers_join.scene_id IS NULL")
 			case "date":
-				f.addWhere("scenes.date IS \"\" OR scenes.date IS \"0001-01-01\"")
+				f.addWhere(`scenes.date IS NULL OR scenes.date IS "" OR scenes.date IS "0001-01-01"`)
 			case "tags":
 				qb.tagsRepository().join(f, "tags_join", "scenes.id")
 				f.addWhere("tags_join.scene_id IS NULL")
diff --git a/pkg/sqlite/scene_test.go b/pkg/sqlite/scene_test.go
index 5541fdd95..dc70d7637 100644
--- a/pkg/sqlite/scene_test.go
+++ b/pkg/sqlite/scene_test.go
@@ -6,6 +6,7 @@ package sqlite_test
 import (
 	"database/sql"
 	"fmt"
+	"math"
 	"regexp"
 	"strconv"
 	"testing"
@@ -931,7 +932,8 @@ func TestSceneQueryIsMissingDate(t *testing.T) {
 
 		scenes := queryScene(t, sqb, &sceneFilter, nil)
 
-		assert.True(t, len(scenes) > 0)
+		// three in four scenes have no date
+		assert.Len(t, scenes, int(math.Ceil(float64(totalScenes)/4*3)))
 
 		// ensure date is null, empty or "0001-01-01"
 		for _, scene := range scenes {
diff --git a/pkg/sqlite/setup_test.go b/pkg/sqlite/setup_test.go
index 4a5377e0d..4e4189b6c 100644
--- a/pkg/sqlite/setup_test.go
+++ b/pkg/sqlite/setup_test.go
@@ -625,7 +625,7 @@ func getWidth(index int) sql.NullInt64 {
 	}
 }
 
-func getSceneDate(index int) models.SQLiteDate {
+func getObjectDate(index int) models.SQLiteDate {
 	dates := []string{"null", "", "0001-01-01", "2001-02-03"}
 	date := dates[index%len(dates)]
 	return models.SQLiteDate{
@@ -647,7 +647,7 @@ func createScenes(sqb models.SceneReaderWriter, n int) error {
 			Duration: getSceneDuration(i),
 			Height:   getHeight(i),
 			Width:    getWidth(i),
-			Date:     getSceneDate(i),
+			Date:     getObjectDate(i),
 		}
 
 		created, err := sqb.Create(scene)
@@ -715,6 +715,7 @@ func createGalleries(gqb models.GalleryReaderWriter, n int) error {
 			URL:      getGalleryNullStringValue(i, urlField),
 			Checksum: getGalleryStringValue(i, checksumField),
 			Rating:   getRating(i),
+			Date:     getObjectDate(i),
 		}
 
 		created, err := gqb.Create(gallery)
diff --git a/ui/v2.5/src/components/Changelog/versions/v0140.md b/ui/v2.5/src/components/Changelog/versions/v0140.md
index 89d4f9acd..3d24b2471 100644
--- a/ui/v2.5/src/components/Changelog/versions/v0140.md
+++ b/ui/v2.5/src/components/Changelog/versions/v0140.md
@@ -8,6 +8,7 @@
 * Improved autotag performance. ([#2368](https://github.com/stashapp/stash/pull/2368))
 
 ### 🐛 Bug fixes
+* Fix Is Missing Date filter not including null date values. ([#2434](https://github.com/stashapp/stash/pull/2434))
 * Fix Open Stash systray menu item not opening stash when Skip Opening Browser was enabled. ([#2418](https://github.com/stashapp/stash/pull/2418))
 * Fix error saving a scene from the tagger when the scene has stash ids. ([#2408](https://github.com/stashapp/stash/pull/2408))
 * Perform tag pattern exclusion on stash-box sources. ([#2391](https://github.com/stashapp/stash/pull/2391))