Hashed index spec hints on timeseries logical namespace bypass hint translation and match bucket-level indexes

XMLWordPrintableJSON

    • Query Integration
    • ALL
    • Hide
      db.repro.drop();
        db.createCollection("repro", {timeseries: {timeField: "t", metaField: "m"}});
        db.repro.insertMany([
            {t: new Date(), m: "a", x: 1},
            {t: new Date(), m: "b", x: 2},
        ]);
      
        // Create a hashed index on the bucket collection via rawData.
        db.runCommand({
            createIndexes: "repro",
            indexes: [{key: {"control.min.x": "hashed"}, name: "hashed_min_x"}],
            rawData: true,
        });
      
        // Btree bucket-level spec hint: correctly rejected.
        db.runCommand({find: "repro", filter: {}, hint: {"control.min.x": 1}});
        // => BadValue: "hint provided does not correspond to an existing index"
      
        // Hashed bucket-level spec hint: incorrectly accepted.
        db.runCommand({find: "repro", filter: {}, hint: {"control.min.x": "hashed"}});
        // => Succeeds (should be rejected like the btree case)
      
      Show
      db.repro.drop(); db.createCollection( "repro" , {timeseries: {timeField: "t" , metaField: "m" }}); db.repro.insertMany([ {t: new Date(), m: "a" , x: 1}, {t: new Date(), m: "b" , x: 2}, ]); // Create a hashed index on the bucket collection via rawData. db.runCommand({ createIndexes: "repro" , indexes: [{key: { "control.min.x" : "hashed" }, name: "hashed_min_x" }], rawData: true , }); // Btree bucket-level spec hint: correctly rejected. db.runCommand({find: "repro" , filter: {}, hint: { "control.min.x" : 1}}); // => BadValue: "hint provided does not correspond to an existing index" // Hashed bucket-level spec hint: incorrectly accepted. db.runCommand({find: "repro" , filter: {}, hint: { "control.min.x" : "hashed" }}); // => Succeeds (should be rejected like the btree case )
    • None
    • None
    • None
    • None
    • None
    • None
    • None

      When a user provides a spec-based index hint on a viewless timeseries collection, translateIndexHintIfRequiredImpl attempts to translate the hint from logical to bucket format via createBucketsIndexSpecFromTimeseriesIndexSpec. For btree specs (numeric values like 1/-1), the translation proceeds and the
        resulting double-prefixed spec (control.min.control.min.x) doesn't match any index, so the hint is correctly rejected with BadValue.

        However, for non-numeric index types like "hashed", the translation fails with BadValue at the !elem.isNumber() check in createBucketsIndexSpecFromTimeseriesIndexSpec. The calling code in translateIndexHintIfRequiredImpl silently passes the hint through unchanged when translation fails. This allows the
        untranslated bucket-level spec to reach the planner, where it matches the bucket-level index directly.

        This is inconsistent: {"control.min.x": 1} is rejected as a hint, but {"control.min.x": "hashed"} is accepted. Both are bucket-level specs that shouldn't be usable as hints on the logical namespace. The same issue would apply to any non-numeric index type string (e.g., "text", "2d").

            Assignee:
            Unassigned
            Reporter:
            Chris Wolff
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

              Created:
              Updated: