changeset 845:441a73af4626 pg-next-1099 tip

test: do not filter against resourceType when a publicId is provided
author Alain Mazy <am@orthanc.team>
date Mon, 14 Sep 2026 19:19:36 +0200
parents e76a0b1763dc
children
files Framework/Plugins/ISqlLookupFormatter.cpp Framework/Plugins/IndexBackend.cpp
diffstat 2 files changed, 45 insertions(+), 13 deletions(-) [+]
line wrap: on
line diff
--- a/Framework/Plugins/ISqlLookupFormatter.cpp	Mon Sep 14 15:02:52 2026 +0200
+++ b/Framework/Plugins/ISqlLookupFormatter.cpp	Mon Sep 14 19:19:36 2026 +0200
@@ -884,11 +884,13 @@
     sql = ("SELECT " +
            strQueryLevel + ".publicId, " +
            strQueryLevel + ".internalId, " +
+           strQueryLevel + ".resourceType, " +
            orderingSql +
            " FROM Resources AS " + strQueryLevel);
 
 
-    std::string joins, comparisons;
+    std::string joins; //, comparisons;
+    std::vector<std::string> comparisons;
 
     const bool isOrthancIdentifiersDefined = (!request.orthanc_id_patient().empty() ||
                                               !request.orthanc_id_study().empty() ||
@@ -902,11 +904,11 @@
 
       if (topParentLevel == queryLevel)
       {
-        comparisons += " AND " + FormatLevel(topParentLevel) + ".publicId = " + formatter.GenerateParameter(GetOrthancIdentifier(request, topParentLevel));
+        comparisons.push_back(FormatLevel(topParentLevel) + ".publicId = " + formatter.GenerateParameter(GetOrthancIdentifier(request, topParentLevel)));
       }
       else
       {
-        comparisons += " AND " + FormatLevel("parent", topParentLevel) + ".publicId = " + formatter.GenerateParameter(GetOrthancIdentifier(request, topParentLevel));
+        comparisons.push_back(FormatLevel("parent", topParentLevel) + ".publicId = " + formatter.GenerateParameter(GetOrthancIdentifier(request, topParentLevel)));
 
         for (int level = queryLevel; level > topParentLevel; level--)
         {
@@ -954,7 +956,7 @@
 
         if (!comparison.empty())
         {
-          comparisons += " AND " + comparison;
+          comparisons.push_back(comparison);
         }
 
         count ++;
@@ -973,7 +975,7 @@
 
         if (!comparison.empty())
         {
-          comparisons += " AND " + comparison;
+          comparisons.push_back(comparison);
         }
         
         count ++;
@@ -999,9 +1001,28 @@
     // }
 
     std::list<std::string> where;
-    where.push_back(strQueryLevel + ".resourceType = " +
-                    formatter.FormatResourceType(queryLevel) + comparisons);
+    std::string comparisonsStr;
+    if (comparisons.size() > 0)
+    {
+      Orthanc::Toolbox::JoinStrings(comparisonsStr, comparisons, " AND ");
+    }
 
+    if (isOrthancIdentifiersDefined)
+    {
+      // if there is a filter on the publicId, there is no need to filter on the resourceType.  Filtering for resourceType=X AND publicId=Y 
+      // would return the same result as publicId=Y since publicIds are unique.
+      assert(comparisons.size() > 0); // at least "publicId=Y"
+      where.push_back(comparisonsStr);
+    }
+    else
+    {
+      if (comparisonsStr.size() > 0)
+      {
+        comparisonsStr = " AND " + comparisonsStr;
+      }
+      where.push_back(strQueryLevel + ".resourceType = " +
+                      formatter.FormatResourceType(queryLevel) + comparisonsStr);
+    }
 
     if (!request.labels().empty())
     {
--- a/Framework/Plugins/IndexBackend.cpp	Mon Sep 14 15:02:52 2026 +0200
+++ b/Framework/Plugins/IndexBackend.cpp	Mon Sep 14 19:19:36 2026 +0200
@@ -3565,7 +3565,7 @@
           "  " + formatter.FormatNull("TEXT") + " AS c4_string2, "
           "  " + formatter.FormatNull("TEXT") + " AS c5_string3, "
           "  " + formatter.FormatNull("BYTEA") + " AS c6_string4, "
-          "  " + formatter.FormatNull("INT") + " AS c7_int1, "
+          "  Lookup.resourceType AS c7_int1, "
           "  " + formatter.FormatNull("INT") + " AS c8_int2, "
           "  " + formatter.FormatNull("INT") + " AS c9_int3, "
           "  " + formatter.FormatNull("BIGINT") + " AS c10_big_int1, "
@@ -4236,17 +4236,28 @@
       int32_t queryId = statement->ReadInteger32(C0_QUERY_ID);
       int64_t internalId = statement->ReadInteger64(C1_INTERNAL_ID);
       
-      assert(queryId == QUERY_LOOKUP || responses.find(internalId) != responses.end()); // the QUERY_LOOKUP must be read first and must create the response before any other query tries to populate the fields
+      // assert(queryId == QUERY_LOOKUP); // the QUERY_LOOKUP must be read first and must create the response before any other query tries to populate the fields
+
+      if (queryId != QUERY_LOOKUP && responses.find(internalId) == responses.end()) // this happens when e.g, accessing an instance level with a series id
+      {
+        statement->Next();
+        continue;
+      }
 
       // LOG(INFO) << queryId << "  " << statement->ReadString(C3_STRING_1);
 
       switch (queryId)
       {
         case QUERY_LOOKUP:
-          responses[internalId] = response.add_find();
-          responses[internalId]->set_public_id(statement->ReadString(C3_STRING_1));
-          responses[internalId]->set_internal_id(internalId);
-          break;
+        {
+          int64_t resourceType = statement->ReadInteger32(C7_INT_1);
+          if (resourceType == request.level()) // this happens when e.g, accessing an instance level with a series id
+          {
+            responses[internalId] = response.add_find();
+            responses[internalId]->set_public_id(statement->ReadString(C3_STRING_1));
+            responses[internalId]->set_internal_id(internalId);
+          }
+          }; break;
 
         case QUERY_LABELS:
           responses[internalId]->add_labels(statement->ReadString(C3_STRING_1));