Uploaded image for project: 'Core Server'
  1. Core Server
  2. SERVER-79488

[CQF] Different behavior with empty-array equality (discovered by fuzzer)

    • Type: Icon: Bug Bug
    • Resolution: Won't Fix
    • Priority: Icon: Major - P3 Major - P3
    • None
    • Affects Version/s: None
    • Component/s: None
    • None
    • Query Optimization
    • ALL
    • QO 2023-12-11, QO 2023-12-25, QO 2024-01-08

      The fuzzer found another bug. Here's a repro:

      const pipeline = [
          // Variations on this predicate seem to not matter much.
          {$match: {"num": 3}},
      
          {
              $match: {
                  $or: [
                      {"array1": {$eq: []}},
      
                      // Although this predicate is always false, when I comment it out
                      // then the test does not reproduce the bug.
                      {"array2": {$eq: [false]}},
                  ]
              }
          },
      ];
      
      const docs = [
          {
              _id: 1,
              "num": 3,
      
              // This has to be empty array:
              // Changing the query to {$eq: [5]} and doc to 'array1: [5]'
              // does not repro.
              "array1": [],
      
              // This field's value and presence doesn't matter.
              // "array2": [123]
          },
      ];
      
      const coll = db.cqf_fuzzer_bug;
      
      coll.drop();
      assert.commandWorked(coll.insert(docs));
      
      // The first stage matches.
      assert.eq(1, coll.aggregate([pipeline[0]]).itcount());
      // The second stage matches.
      assert.eq(1, coll.aggregate([pipeline[1]]).itcount());
      
      // Their composition should also match.
      assert.eq(1, coll.aggregate(pipeline).itcount());
      

      This passes on the default configuration, but the last assertion fails on Bonsai. Each $match individually matches the document, but when put together in one query it doesn't match. So it must be a rewrite combining the predicates incorrectly.

      These {$eq: <array>} predicates are interesting because they check the whole array (in addition to checking in element): we generate a disjunction where one branch doesn't use traverse.

            Assignee:
            backlog-query-optimization [DO NOT USE] Backlog - Query Optimization
            Reporter:
            david.percy@mongodb.com David Percy
            Votes:
            0 Vote for this issue
            Watchers:
            7 Start watching this issue

              Created:
              Updated:
              Resolved: