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

mihaibudiu pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/calcite.git


The following commit(s) were added to refs/heads/main by this push:
     new 2862a8d5de [CALCITE-7668] MongoDB adapter should escape embedded 
quotes in field references
2862a8d5de is described below

commit 2862a8d5de5735ff74ba4ab38b3f57c0bf81f653
Author: bibi samina <[email protected]>
AuthorDate: Wed Jul 29 14:14:39 2026 +0530

    [CALCITE-7668] MongoDB adapter should escape embedded quotes in field 
references
---
 .../apache/calcite/adapter/mongodb/MongoRules.java |  6 ++--
 .../calcite/adapter/mongodb/MongoAdapterTest.java  | 33 ++++++++++++++++++++++
 2 files changed, 37 insertions(+), 2 deletions(-)

diff --git 
a/mongodb/src/main/java/org/apache/calcite/adapter/mongodb/MongoRules.java 
b/mongodb/src/main/java/org/apache/calcite/adapter/mongodb/MongoRules.java
index 48e46e610d..fe7c65db10 100644
--- a/mongodb/src/main/java/org/apache/calcite/adapter/mongodb/MongoRules.java
+++ b/mongodb/src/main/java/org/apache/calcite/adapter/mongodb/MongoRules.java
@@ -110,7 +110,9 @@ static String maybeQuote(String s) {
   }
 
   static String quote(String s) {
-    return "'" + s + "'"; // TODO: handle embedded quotes
+    // Escape backslash and the single-quote delimiter so that s cannot break
+    // out of the quoted token when the string is parsed by BsonDocument.parse.
+    return "'" + s.replace("\\", "\\\\").replace("'", "\\'") + "'";
   }
 
   private static boolean needsQuote(String s) {
@@ -181,7 +183,7 @@ protected RexToMongoTranslator(JavaTypeFactory typeFactory,
     @Override public String visitCall(RexCall call) {
       String name = isItem(call);
       if (name != null) {
-        return "'$" + name + "'";
+        return quote("$" + name);
       }
       final List<String> strings = visitList(call.operands);
       if (call.getKind() == SqlKind.CAST) {
diff --git 
a/mongodb/src/test/java/org/apache/calcite/adapter/mongodb/MongoAdapterTest.java
 
b/mongodb/src/test/java/org/apache/calcite/adapter/mongodb/MongoAdapterTest.java
index 7c79718e79..c4fef104f8 100644
--- 
a/mongodb/src/test/java/org/apache/calcite/adapter/mongodb/MongoAdapterTest.java
+++ 
b/mongodb/src/test/java/org/apache/calcite/adapter/mongodb/MongoAdapterTest.java
@@ -86,6 +86,13 @@ public class MongoAdapterTest implements SchemaFactory {
   /** Number of records in local file. */
   protected static final int ZIPS_SIZE = 149;
 
+  /** Field of the "datatypes" collection whose name contains a single quote
+   * and characters that would be pipeline syntax if it were not escaped. */
+  private static final String QUOTED_FIELD = "x', injected: {$literal: 1}, y: 
'z";
+
+  /** Field of the "datatypes" collection whose name ends with a backslash. */
+  private static final String BACKSLASH_FIELD = "a\\";
+
   @RegisterExtension
   public static final MongoDatabasePolicy POLICY = 
MongoDatabasePolicy.create();
 
@@ -119,6 +126,8 @@ public static void setUp() throws Exception {
     doc.put("ownerId", new BsonString("531e7789e4b0853ddb861313"));
     doc.put("arr", new BsonArray(Arrays.asList(new BsonString("a"), new 
BsonString("b"))));
     doc.put("binaryData", new 
BsonBinary("binaryData".getBytes(StandardCharsets.UTF_8)));
+    doc.put(QUOTED_FIELD, new BsonString("quoted"));
+    doc.put(BACKSLASH_FIELD, new BsonString("backslash"));
     datatypes.insertOne(doc);
 
     schema = new MongoSchema(database);
@@ -743,6 +752,30 @@ private void checkPredicate(int expected, String q) {
         .returnsUnordered("EXPR$0=[a, b]");
   }
 
+  /** A field name that contains a single quote or a backslash must not be able
+   * to break out of the quoted token in the generated pipeline and add stage
+   * fields of its own.
+   *
+   * <p>The expected values were validated against a real MongoDB instance:
+   * without the escaping the first query parses as
+   * {@code {$project: {C: '$x', injected: {$literal: 1}, y: 'z'}}} and the
+   * injected field breaks the pipeline, so the query fails. */
+  @Test void testItemKeyWithEmbeddedQuote() {
+    assertModel(MODEL)
+        .query("select cast(_MAP['x'', injected: {$literal: 1}, y: ''z'] as 
varchar) as c\n"
+            + "from \"mongo_raw\".\"datatypes\"")
+        .returnsUnordered("C=quoted")
+        .queryContains(
+            mongoChecker("{$project: {C: '$x\\', injected: {$literal: 1}, y: 
\\'z'}}"));
+
+    assertModel(MODEL)
+        .query("select cast(_MAP['a\\'] as varchar) as c\n"
+            + "from \"mongo_raw\".\"datatypes\"")
+        .returnsUnordered("C=backslash")
+        .queryContains(
+            mongoChecker("{$project: {C: '$a\\\\'}}"));
+  }
+
   /** Test case for
    * <a href="https://issues.apache.org/jira/browse/CALCITE-665";>[CALCITE-665]
    * ClassCastException in MongoDB adapter</a>. */

Reply via email to