Jelajahi Sumber

HPCC-21860 Keyed limit not always correctly triggered on INDEX COUNT

Should match the processing on an index read.

Signed-off-by: Richard Chapman <rchapman@hpccsystems.com>
Richard Chapman 6 tahun lalu
induk
melakukan
ababdec221
2 mengubah file dengan 25 tambahan dan 3 penghapusan
  1. 11 2
      roxie/ccd/ccdactivities.cpp
  2. 14 1
      roxie/ccd/ccdserver.cpp

+ 11 - 2
roxie/ccd/ccdactivities.cpp

@@ -3226,6 +3226,15 @@ public:
 
         unsigned processedBefore = processed;
         unsigned __int64 count = 0;
+        if (!resent && (keyedLimit != (unsigned __int64) -1) && ((keyedLimit > preabortIndexReadsThreshold) || (indexHelper->getFlags() & TIRcountkeyedlimit) != 0)) // Don't recheck the limit every time!
+        {
+            if (!checkLimit(keyedLimit))
+            {
+                limitExceeded(true);
+                return NULL;
+            }
+
+        }
         ScopedAtomic<unsigned> indexRecordsRead(::indexRecordsRead);
         while (!aborted && inputsDone < inputCount && count < choosenLimit)
         {
@@ -3244,7 +3253,7 @@ public:
                         count += countHelper->numValid(tlk->queryKeyBuffer());
                         if (count > rowLimit)
                             limitExceeded(false);
-                        else if (count > keyedLimit)
+                        else if (keyprocessed > keyedLimit)
                             limitExceeded(true);
                         callback.finishedRow();
                     }
@@ -3258,7 +3267,7 @@ public:
                     if (count > rowLimit)
                         limitExceeded(false);
                     else if (count > keyedLimit)
-                        limitExceeded(true); // MORE - is this right?
+                        limitExceeded(true);
                 }
             }
             inputsDone++;

+ 14 - 1
roxie/ccd/ccdserver.cpp

@@ -24188,6 +24188,9 @@ public:
         if (done) return NULL;
         done = true;
         unsigned __int64 totalCount = 0;
+        // Checking keyed limit on server is a bit odd - we only know the counts after postfiltering by the time we are on the server
+        // The count needs to behave the same as the output, which will regard a keyed limit as exceeded if the sum of the postfiltered outputs exceeds the keyed limit
+        bool hasKeyedLimit =  (keyedLimit != (unsigned __int64) -1);
         bool hasLimit = rowLimit != (unsigned __int64) -1;
 
         try
@@ -24202,7 +24205,7 @@ public:
                 else
                     totalCount += *(unsigned __int64 *) next;
                 ReleaseRoxieRow(next);
-                if (totalCount > rowLimit || (totalCount > choosenLimit && !hasLimit)) // can't break out early if there is a possibility of later slave throwing limit exception
+                if (totalCount > rowLimit || (totalCount > choosenLimit && !hasLimit && !hasKeyedLimit)) // can't break out early if there is a possibility of later slave throwing limit exception
                     break;
             }
             if (totalCount > rowLimit)
@@ -24215,6 +24218,16 @@ public:
                 else
                     countHelper.onLimitExceeded();
             }
+            else if (totalCount > keyedLimit)
+            {
+                unsigned flags = indexHelper.getFlags();
+                if (flags & TIRkeyedlimitskips)
+                    totalCount = 0;
+                else if (flags & TIRkeyedlimitcreates)
+                    totalCount = 1;
+                else
+                    countHelper.onLimitExceeded();
+            }
             else if (totalCount > choosenLimit)
                 totalCount = choosenLimit;
         }