changeset 6560:ca3056469cea

tools/find: filtering against 'LabelsConstraint': 'None' with an empty list of 'Labels' now returns all resources that do not have any labels attached instead of returning all resources
author Alain Mazy <am@orthanc.team>
date Wed, 14 Jan 2026 18:24:29 +0100
parents daf168bb0927
children f2de0250584c
files NEWS OrthancServer/Sources/Search/ISqlLookupFormatter.cpp
diffstat 2 files changed, 14 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/NEWS	Tue Jan 13 17:31:17 2026 +0100
+++ b/NEWS	Wed Jan 14 18:24:29 2026 +0100
@@ -13,6 +13,10 @@
   - "orthanc_logged_warnings_count"
 * Fixed a security issue where one could hijack HTTP headers in the response
   through the `filename` argument of "/.../file" or "/.../archive" routes.
+* In tools/find, filtering against "LabelsConstraint": "None" with an empty "Labels" list
+  now returns all resources that do not have any labels attached instead of returning all resources.
+  This applies to the default SQLite DB and will apply to the next PostgreSQL plugin (vXXX)
+
 
 Maintenance
 -----------
--- a/OrthancServer/Sources/Search/ISqlLookupFormatter.cpp	Tue Jan 13 17:31:17 2026 +0100
+++ b/OrthancServer/Sources/Search/ISqlLookupFormatter.cpp	Wed Jan 14 18:24:29 2026 +0100
@@ -958,6 +958,10 @@
       where.push_back("(SELECT COUNT(1) FROM Labels AS selectedLabels WHERE selectedLabels.id = " + strQueryLevel +
                       ".internalId AND selectedLabels.label IN (" + Join(formattedLabels, "", ", ") + ")) " + condition);
     }
+    else if (request.GetLabelsConstraint() == LabelsConstraint_None) // from 1.12.11, 'None' with an empty labels list means "list all resources without any labels"
+    {
+      where.push_back("(SELECT COUNT(1) FROM Labels WHERE id = " + strQueryLevel + ".internalId) = 0");
+    }
 
     sql += joins + orderingJoins + Join(where, " WHERE ", " AND ");
 
@@ -968,6 +972,7 @@
   }
 
 
+  // this function is not used in SQLite but is used in the Database plugins
   void ISqlLookupFormatter::ApplySingleLevel(std::string& sql,
                                              ISqlLookupFormatter& formatter,
                                              const DatabaseDicomTagConstraints& lookup,
@@ -1075,6 +1080,11 @@
                                         ") AS temp "
                                  " WHERE labelsCount " + condition + ")");
     }
+    else if (labelsConstraint == LabelsConstraint_None) // from 1.12.11, 'None' with an empty labels list means "list all resources without any labels"
+    {
+      sql += (" AND (SELECT COUNT(1) FROM Labels WHERE id = internalId) = 0");
+    }
+
 
     if (limit != 0)
     {