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

Regex containing an escaped | pipe symbol are not handled correctly

    • Type: Icon: Bug Bug
    • Resolution: Duplicate
    • Priority: Icon: Major - P3 Major - P3
    • None
    • Affects Version/s: None
    • Component/s: Querying
    • Labels:
      None
    • ALL
    • Hide

      Setup test data:

      for(var i=0; i < 100; i++) { db.regexTest.insertOne({name:"test|"+i})}
      

      The follwoing query should only return a single document, but instead it returns all:

      db.regexTest.find({name: { $regex: "^test\|18"}})
      

      If a double escape is being used, then it matches only a single document:

      db.regexTest.find({name: { $regex: "^test\\|18"}})
      

      The results are the same if an index is being used.

      However because of the related bug SERVER-16622 in the classification of the regex, the regex is classified as complex and the wrong index bounds are being used:

      db.regexTest.createIndex({name:1})
      db.regexTest.find({name: { $regex: "^test\\|18"}}).explain()
      {
        "queryPlanner": {
          "plannerVersion": 1,
          "namespace": "test.regexTest",
          "indexFilterSet": false,
          "parsedQuery": {
            "name": /^test\|18/
          },
          "winningPlan": {
            "stage": "FETCH",
            "inputStage": {
              "stage": "IXSCAN",
              "filter": {
                "name": /^test\|18/
              },
              "keyPattern": {
                "name": 1
              },
              "indexName": "name_1",
              "isMultiKey": false,
              "multiKeyPaths": {
                "name": [ ]
              },
              "isUnique": false,
              "isSparse": false,
              "isPartial": false,
              "indexVersion": 2,
              "direction": "forward",
              "indexBounds": {
                "name": [
                  "[\"\", {})",
                  "[/^test\\|18/, /^test\\|18/]"
                ]
              }
            }
          },
          "rejectedPlans": [ ]
        },
      
      Show
      Setup test data: for(var i=0; i < 100; i++) { db.regexTest.insertOne({name:"test|"+i})} The follwoing query should only return a single document, but instead it returns all: db.regexTest.find({name: { $regex: "^test\|18"}}) If a double escape is being used, then it matches only a single document: db.regexTest.find({name: { $regex: "^test\\|18"}}) The results are the same if an index is being used. However because of the related bug SERVER-16622 in the classification of the regex, the regex is classified as complex and the wrong index bounds are being used: db.regexTest.createIndex({name:1}) db.regexTest.find({name: { $regex: "^test\\|18"}}).explain() { "queryPlanner": { "plannerVersion": 1, "namespace": "test.regexTest", "indexFilterSet": false, "parsedQuery": { "name": /^test\|18/ }, "winningPlan": { "stage": "FETCH", "inputStage": { "stage": "IXSCAN", "filter": { "name": /^test\|18/ }, "keyPattern": { "name": 1 }, "indexName": "name_1", "isMultiKey": false, "multiKeyPaths": { "name": [ ] }, "isUnique": false, "isSparse": false, "isPartial": false, "indexVersion": 2, "direction": "forward", "indexBounds": { "name": [ "[\"\", {})", "[/^test\\|18/, /^test\\|18/]" ] } } }, "rejectedPlans": [ ] },

      If a regex query contains an escaped pipe symbol it is not handled as an escaped | but as an OR. Only if the pipe is double escaped ( \ \ | ) it is being handle as an escaped |.

            Assignee:
            kelsey.schubert@mongodb.com Kelsey Schubert
            Reporter:
            kai.orend@mongodb.com Kai Orend
            Votes:
            0 Vote for this issue
            Watchers:
            5 Start watching this issue

              Created:
              Updated:
              Resolved: