This is an automated email from the ASF dual-hosted git repository.

cwylie pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/druid.git


The following commit(s) were added to refs/heads/master by this push:
     new f8645de3413 Remove incorrect utf8 conversion of ResultCache keys 
(#16569)
f8645de3413 is described below

commit f8645de341397356cc643e7d76ade7874181214d
Author: Zoltan Haindrich <[email protected]>
AuthorDate: Wed Jun 12 22:12:05 2024 +0200

    Remove incorrect utf8 conversion of ResultCache keys (#16569)
---
 extensions-contrib/redis-cache/pom.xml             |  6 ++++
 .../druid/client/cache/RedisClusterCacheTest.java  |  3 +-
 .../client/cache/RedisStandaloneCacheTest.java     |  3 +-
 .../java/org/apache/druid/client/CacheUtil.java    | 15 +++-----
 .../druid/query/ResultLevelCachingQueryRunner.java | 25 +++++++-------
 .../apache/druid/client/cache/CacheTestBase.java   | 40 ++++++++++++++++++++++
 .../druid/client/cache/CaffeineCacheTest.java      |  3 +-
 .../apache/druid/client/cache/MapCacheTest.java    |  3 +-
 .../druid/client/cache/MemcachedCacheTest.java     |  4 +--
 .../druid/sql/calcite/CalciteSelectQueryTest.java  | 28 +++++++++++++++
 10 files changed, 96 insertions(+), 34 deletions(-)

diff --git a/extensions-contrib/redis-cache/pom.xml 
b/extensions-contrib/redis-cache/pom.xml
index d98d61f0579..281f5372345 100644
--- a/extensions-contrib/redis-cache/pom.xml
+++ b/extensions-contrib/redis-cache/pom.xml
@@ -115,6 +115,12 @@
             <version>1.3</version>
             <scope>test</scope>
         </dependency>
+        <dependency>
+            <groupId>org.apache.druid</groupId>
+            <artifactId>druid-server</artifactId>
+            <version>${project.parent.version}</version>
+            <type>test-jar</type>
+        </dependency>
     </dependencies>
 
     <build>
diff --git 
a/extensions-contrib/redis-cache/src/test/java/org/apache/druid/client/cache/RedisClusterCacheTest.java
 
b/extensions-contrib/redis-cache/src/test/java/org/apache/druid/client/cache/RedisClusterCacheTest.java
index 3a7f9bb04ab..d2ab17d08bf 100644
--- 
a/extensions-contrib/redis-cache/src/test/java/org/apache/druid/client/cache/RedisClusterCacheTest.java
+++ 
b/extensions-contrib/redis-cache/src/test/java/org/apache/druid/client/cache/RedisClusterCacheTest.java
@@ -36,7 +36,7 @@ import redis.clients.jedis.JedisCluster;
 import java.io.IOException;
 import java.util.Map;
 
-public class RedisClusterCacheTest
+public class RedisClusterCacheTest extends CacheTestBase<RedisClusterCache>
 {
   private static final byte[] HI = StringUtils.toUtf8("hiiiiiiiiiiiiiiiiiii");
   private static final byte[] HO = StringUtils.toUtf8("hooooooooooooooooooo");
@@ -57,7 +57,6 @@ public class RedisClusterCacheTest
   };
 
   private RedisServer server;
-  private RedisClusterCache cache;
 
   @Before
   public void setUp() throws IOException
diff --git 
a/extensions-contrib/redis-cache/src/test/java/org/apache/druid/client/cache/RedisStandaloneCacheTest.java
 
b/extensions-contrib/redis-cache/src/test/java/org/apache/druid/client/cache/RedisStandaloneCacheTest.java
index d980dfa5f6d..de0e8233674 100644
--- 
a/extensions-contrib/redis-cache/src/test/java/org/apache/druid/client/cache/RedisStandaloneCacheTest.java
+++ 
b/extensions-contrib/redis-cache/src/test/java/org/apache/druid/client/cache/RedisStandaloneCacheTest.java
@@ -43,13 +43,12 @@ import java.io.IOException;
 import java.util.Map;
 import java.util.UUID;
 
-public class RedisStandaloneCacheTest
+public class RedisStandaloneCacheTest extends 
CacheTestBase<RedisStandaloneCache>
 {
   private static final byte[] HI = StringUtils.toUtf8("hiiiiiiiiiiiiiiiiiii");
   private static final byte[] HO = StringUtils.toUtf8("hooooooooooooooooooo");
 
   private RedisServer server;
-  private RedisStandaloneCache cache;
   private final RedisCacheConfig cacheConfig = new RedisCacheConfig()
   {
     @Override
diff --git a/server/src/main/java/org/apache/druid/client/CacheUtil.java 
b/server/src/main/java/org/apache/druid/client/CacheUtil.java
index a8d65e4effa..53f6a178024 100644
--- a/server/src/main/java/org/apache/druid/client/CacheUtil.java
+++ b/server/src/main/java/org/apache/druid/client/CacheUtil.java
@@ -34,6 +34,8 @@ import java.nio.ByteBuffer;
 
 public class CacheUtil
 {
+  private static final String RESULT_CACHE_NS = "RES";
+
   public enum ServerType
   {
     BROKER {
@@ -57,18 +59,9 @@ public class CacheUtil
     abstract boolean willMergeRunners();
   }
 
-  public static Cache.NamedKey computeResultLevelCacheKey(String 
resultLevelCacheIdentifier)
-  {
-    return new Cache.NamedKey(resultLevelCacheIdentifier, 
StringUtils.toUtf8(resultLevelCacheIdentifier));
-  }
-
-  public static void populateResultCache(
-      Cache cache,
-      Cache.NamedKey key,
-      byte[] resultBytes
-  )
+  public static Cache.NamedKey computeResultLevelCacheKey(byte[] 
resultLevelCacheIdentifier)
   {
-    cache.put(key, resultBytes);
+    return new Cache.NamedKey(RESULT_CACHE_NS, resultLevelCacheIdentifier);
   }
 
   public static Cache.NamedKey computeSegmentCacheKey(
diff --git 
a/server/src/main/java/org/apache/druid/query/ResultLevelCachingQueryRunner.java
 
b/server/src/main/java/org/apache/druid/query/ResultLevelCachingQueryRunner.java
index 2b8efbc3308..182faba7a09 100644
--- 
a/server/src/main/java/org/apache/druid/query/ResultLevelCachingQueryRunner.java
+++ 
b/server/src/main/java/org/apache/druid/query/ResultLevelCachingQueryRunner.java
@@ -28,6 +28,7 @@ import com.google.common.base.Preconditions;
 import com.google.common.collect.ImmutableMap;
 import org.apache.druid.client.CacheUtil;
 import org.apache.druid.client.cache.Cache;
+import org.apache.druid.client.cache.Cache.NamedKey;
 import org.apache.druid.client.cache.CacheConfig;
 import org.apache.druid.java.util.common.RE;
 import org.apache.druid.java.util.common.StringUtils;
@@ -87,8 +88,9 @@ public class ResultLevelCachingQueryRunner<T> implements 
QueryRunner<T>
   {
     if (useResultCache || populateResultCache) {
 
-      final String cacheKeyStr = 
StringUtils.fromUtf8(strategy.computeResultLevelCacheKey(query));
-      final byte[] cachedResultSet = 
fetchResultsFromResultLevelCache(cacheKeyStr);
+      final byte[] queryCacheKey = strategy.computeResultLevelCacheKey(query);
+      final Cache.NamedKey cacheKey = 
CacheUtil.computeResultLevelCacheKey(queryCacheKey);
+      final byte[] cachedResultSet = 
fetchResultsFromResultLevelCache(cacheKey);
       String existingResultSetId = extractEtagFromResults(cachedResultSet);
 
       existingResultSetId = existingResultSetId == null ? "" : 
existingResultSetId;
@@ -107,7 +109,7 @@ public class ResultLevelCachingQueryRunner<T> implements 
QueryRunner<T>
       } else {
         @Nullable
         ResultLevelCachePopulator resultLevelCachePopulator = 
createResultLevelCachePopulator(
-            cacheKeyStr,
+            cacheKey,
             newResultSetId
         );
         if (resultLevelCachePopulator == null) {
@@ -166,11 +168,11 @@ public class ResultLevelCachingQueryRunner<T> implements 
QueryRunner<T>
 
   @Nullable
   private byte[] fetchResultsFromResultLevelCache(
-      final String queryCacheKey
+      final NamedKey cacheKey
   )
   {
-    if (useResultCache && queryCacheKey != null) {
-      return cache.get(CacheUtil.computeResultLevelCacheKey(queryCacheKey));
+    if (useResultCache && cacheKey != null) {
+      return cache.get(cacheKey);
     }
     return null;
   }
@@ -216,7 +218,7 @@ public class ResultLevelCachingQueryRunner<T> implements 
QueryRunner<T>
   }
 
   private ResultLevelCachePopulator createResultLevelCachePopulator(
-      String cacheKeyStr,
+      NamedKey cacheKey,
       String resultSetId
   )
   {
@@ -224,7 +226,7 @@ public class ResultLevelCachingQueryRunner<T> implements 
QueryRunner<T>
       ResultLevelCachePopulator resultLevelCachePopulator = new 
ResultLevelCachePopulator(
           cache,
           objectMapper,
-          CacheUtil.computeResultLevelCacheKey(cacheKeyStr),
+          cacheKey,
           cacheConfig,
           true
       );
@@ -302,11 +304,8 @@ public class ResultLevelCachingQueryRunner<T> implements 
QueryRunner<T>
 
     public void populateResults()
     {
-      CacheUtil.populateResultCache(
-          cache,
-          key,
-          Preconditions.checkNotNull(cacheObjectStream, 
"cacheObjectStream").toByteArray()
-      );
+      byte[] cachedResults = Preconditions.checkNotNull(cacheObjectStream, 
"cacheObjectStream").toByteArray();
+      cache.put(key, cachedResults);
     }
   }
 }
diff --git 
a/server/src/test/java/org/apache/druid/client/cache/CacheTestBase.java 
b/server/src/test/java/org/apache/druid/client/cache/CacheTestBase.java
new file mode 100644
index 00000000000..056339ff3b8
--- /dev/null
+++ b/server/src/test/java/org/apache/druid/client/cache/CacheTestBase.java
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.druid.client.cache;
+
+import org.apache.druid.client.CacheUtil;
+import org.apache.druid.client.cache.Cache.NamedKey;
+import org.junit.Test;
+
+import static org.junit.Assert.assertArrayEquals;
+
+public class CacheTestBase<T extends Cache>
+{
+  T cache;
+
+  @Test
+  public void testKeyContainingNegativeBytes()
+  {
+    byte[] value = new byte[] {1, 0, -10, -55, 111};
+    NamedKey key = CacheUtil.computeResultLevelCacheKey(new byte[] {1, 0, -10, 
0});
+    cache.put(key, value);
+    assertArrayEquals(value, cache.get(key));
+  }
+}
diff --git 
a/server/src/test/java/org/apache/druid/client/cache/CaffeineCacheTest.java 
b/server/src/test/java/org/apache/druid/client/cache/CaffeineCacheTest.java
index 2352661b6d0..b34fcbdd830 100644
--- a/server/src/test/java/org/apache/druid/client/cache/CaffeineCacheTest.java
+++ b/server/src/test/java/org/apache/druid/client/cache/CaffeineCacheTest.java
@@ -44,12 +44,11 @@ import java.util.Random;
 import java.util.UUID;
 import java.util.concurrent.ForkJoinPool;
 
-public class CaffeineCacheTest
+public class CaffeineCacheTest extends CacheTestBase<CaffeineCache>
 {
   private static final byte[] HI = StringUtils.toUtf8("hiiiiiiiiiiiiiiiiiii");
   private static final byte[] HO = StringUtils.toUtf8("hooooooooooooooooooo");
 
-  private CaffeineCache cache;
   private final CaffeineCacheConfig cacheConfig = new CaffeineCacheConfig()
   {
     @Override
diff --git 
a/server/src/test/java/org/apache/druid/client/cache/MapCacheTest.java 
b/server/src/test/java/org/apache/druid/client/cache/MapCacheTest.java
index 67315fff825..9abafac99fb 100644
--- a/server/src/test/java/org/apache/druid/client/cache/MapCacheTest.java
+++ b/server/src/test/java/org/apache/druid/client/cache/MapCacheTest.java
@@ -27,12 +27,11 @@ import org.junit.Test;
 
 /**
  */
-public class MapCacheTest
+public class MapCacheTest extends CacheTestBase<MapCache>
 {
   private static final byte[] HI = StringUtils.toUtf8("hi");
   private static final byte[] HO = StringUtils.toUtf8("ho");
   private ByteCountingLRUMap baseMap;
-  private MapCache cache;
 
   @Before
   public void setUp()
diff --git 
a/server/src/test/java/org/apache/druid/client/cache/MemcachedCacheTest.java 
b/server/src/test/java/org/apache/druid/client/cache/MemcachedCacheTest.java
index d7748c7e48f..7c1cfebae97 100644
--- a/server/src/test/java/org/apache/druid/client/cache/MemcachedCacheTest.java
+++ b/server/src/test/java/org/apache/druid/client/cache/MemcachedCacheTest.java
@@ -80,7 +80,7 @@ import java.util.concurrent.TimeUnit;
 
 /**
  */
-public class MemcachedCacheTest
+public class MemcachedCacheTest extends CacheTestBase<MemcachedCache>
 {
   private static final Logger log = new Logger(MemcachedCacheTest.class);
   private static final byte[] HI = StringUtils.toUtf8("hiiiiiiiiiiiiiiiiiii");
@@ -93,7 +93,7 @@ public class MemcachedCacheTest
       return false;
     }
   };
-  private MemcachedCache cache;
+
   private final MemcachedCacheConfig memcachedCacheConfig = new 
MemcachedCacheConfig()
   {
     @Override
diff --git 
a/sql/src/test/java/org/apache/druid/sql/calcite/CalciteSelectQueryTest.java 
b/sql/src/test/java/org/apache/druid/sql/calcite/CalciteSelectQueryTest.java
index d6d53481bbf..9f81962d1a0 100644
--- a/sql/src/test/java/org/apache/druid/sql/calcite/CalciteSelectQueryTest.java
+++ b/sql/src/test/java/org/apache/druid/sql/calcite/CalciteSelectQueryTest.java
@@ -49,6 +49,7 @@ import 
org.apache.druid.segment.virtual.ExpressionVirtualColumn;
 import org.apache.druid.sql.calcite.filtration.Filtration;
 import org.apache.druid.sql.calcite.planner.PlannerConfig;
 import org.apache.druid.sql.calcite.planner.PlannerContext;
+import org.apache.druid.sql.calcite.util.CacheTestHelperModule.ResultCacheMode;
 import org.apache.druid.sql.calcite.util.CalciteTests;
 import org.joda.time.DateTime;
 import org.joda.time.DateTimeZone;
@@ -2133,4 +2134,31 @@ public class CalciteSelectQueryTest extends 
BaseCalciteQueryTest
         ),
         ImmutableList.of());
   }
+
+  @SqlTestFrameworkConfig.ResultCache(ResultCacheMode.ENABLED)
+  @Test
+  public void testCacheKeyConsistency()
+  {
+    skipVectorize();
+    // possibly pollute the cache
+    // https://github.com/apache/druid/issues/16552
+    testBuilder()
+        .sql("select dim1,d1 from numfoo where 0.0 < d1 and d1 < 1.25 group by 
dim1,d1")
+        .expectedResults(
+            ImmutableList.of(
+                new Object[] {"", 1.0D}
+            )
+        )
+        .run();
+
+    testBuilder()
+        .sql("select dim1,d1 from numfoo where 0.0 < d1 and d1 < 1.75 group by 
dim1,d1")
+        .expectedResults(
+            ImmutableList.of(
+                new Object[] {"", 1.0D},
+                new Object[] {"10.1", 1.7D}
+            )
+        )
+        .run();
+  }
 }


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to