From d5601723b40f627c5257181259d7618fdf7e9d03 Mon Sep 17 00:00:00 2001
From: Case Nelson <case@metabase.com>
Date: Mon, 5 Aug 2024 13:15:16 -0600
Subject: [PATCH] fix: mongo ObjectId should be orderable (#46501)

* fix: mongo ObjectId should be orderable

Fixes #46259

Mongo ObjectId derive :type/TextLike but that can't be an orderable
type, so we mark the specific Mongo type as orderable for malli schemas.

* Fix test
---
 .../mongo/test/metabase/driver/mongo_test.clj | 33 ++++++++++++++++---
 src/metabase/lib/schema/expression.cljc       |  2 +-
 2 files changed, 30 insertions(+), 5 deletions(-)

diff --git a/modules/drivers/mongo/test/metabase/driver/mongo_test.clj b/modules/drivers/mongo/test/metabase/driver/mongo_test.clj
index 82a7f3dbfb2..76b42be63ed 100644
--- a/modules/drivers/mongo/test/metabase/driver/mongo_test.clj
+++ b/modules/drivers/mongo/test/metabase/driver/mongo_test.clj
@@ -537,15 +537,27 @@
           (is (= [[3 "Unlucky Raven" nil]]
                  (mt/rows (mt/run-mbql-query birds
                             {:filter [:is-empty $bird_id]
-                             :fields [$id $name $bird_id]})))))
+                             :fields [$id $name $bird_id]}))))))
 
         (testing "treat non-null ObjectId as not-empty (#15801)"
           (is (= [[1 "Rasta Toucan" (ObjectId. "012345678901234567890123")]
                   [2 "Lucky Pigeon" (ObjectId. "abcdefabcdefabcdefabcdef")]]
                  (mt/rows (mt/run-mbql-query birds
                             {:filter [:not-empty $bird_id]
-                             :fields [$id $name $bird_id]}))))))
-
+                             :fields [$id $name $bird_id]})))))
+        (testing "can order by ObjectId (#46259)"
+          (is (= [[3 nil]
+                  [1 (ObjectId. "012345678901234567890123")]
+                  [2 (ObjectId. "abcdefabcdefabcdefabcdef")]]
+                 (mt/rows (mt/run-mbql-query birds
+                            {:fields [$id $bird_id]
+                             :order-by [[:asc $bird_id]]}))))
+          (is (= [[2 (ObjectId. "abcdefabcdefabcdefabcdef")]
+                  [1 (ObjectId. "012345678901234567890123")]
+                  [3 nil]]
+                 (mt/rows (mt/run-mbql-query birds
+                            {:fields [$id $bird_id]
+                             :order-by [[:desc $bird_id]]})))))
       (testing "BSON UUIDs"
         (testing "Check that we support Mongo BSON UUID and can filter by it"
           (is (= [[2 "Lucky Pigeon" "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"]]
@@ -570,7 +582,20 @@
                 [2 "Lucky Pigeon" "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"]]
                (mt/rows (mt/run-mbql-query birds
                           {:filter [:not-empty $bird_uuid]
-                           :fields [$id $name $bird_uuid]}))))))))
+                           :fields [$id $name $bird_uuid]})))))
+      (testing "can order by UUID (#46259)"
+          (is (= [[3 nil]
+                  [1 "11111111-1111-1111-1111-111111111111"]
+                  [2 "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"]]
+                 (mt/rows (mt/run-mbql-query birds
+                            {:fields [$id $bird_uuid]
+                             :order-by [[:asc $bird_uuid]]}))))
+          (is (= [[2 "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"]
+                  [1 "11111111-1111-1111-1111-111111111111"]
+                  [3 nil]]
+                 (mt/rows (mt/run-mbql-query birds
+                            {:fields [$id $bird_uuid]
+                             :order-by [[:desc $bird_uuid]]}))))))))
 
 
 (deftest ^:parallel bson-fn-call-forms-test
diff --git a/src/metabase/lib/schema/expression.cljc b/src/metabase/lib/schema/expression.cljc
index 8b01e218053..268f56c7eb1 100644
--- a/src/metabase/lib/schema/expression.cljc
+++ b/src/metabase/lib/schema/expression.cljc
@@ -136,7 +136,7 @@
 
 (def orderable-types
   "Set of base types that are orderable."
-  #{:type/Text :type/Number :type/Temporal :type/Boolean})
+  #{:type/Text :type/Number :type/Temporal :type/Boolean :type/MongoBSONID})
 
 (mr/def ::orderable
   (expression-schema orderable-types
-- 
GitLab