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

Disallow the empty string as an index key type

    XMLWordPrintable

    Details

    • Backwards Compatibility:
      Minor Change
    • Operating System:
      ALL
    • Backport Requested:
      v4.2
    • Steps To Reproduce:
      Hide

      db.repro.createIndex({x:""})
      

      Outputs:

      > db.repro.createIndex({x:""})
      {
      	"createdCollectionAutomatically" : true,
      	"numIndexesBefore" : 1,
      	"numIndexesAfter" : 2,
      	"ok" : 1
      }
      

      A few additional lines from 4.1.10:

      > db.version()
      4.1.10
      > db.repro.createIndex({x:""})
      {
      	"createdCollectionAutomatically" : true,
      	"numIndexesBefore" : 1,
      	"numIndexesAfter" : 2,
      	"ok" : 1
      }
      > db.repro.createIndex({x:1})
      {
      	"createdCollectionAutomatically" : false,
      	"numIndexesBefore" : 2,
      	"numIndexesAfter" : 3,
      	"ok" : 1
      }
      > db.repro.getIndices()
      [
      	{
      		"v" : 2,
      		"key" : {
      			"_id" : 1
      		},
      		"name" : "_id_",
      		"ns" : "repo.repro"
      	},
      	{
      		"v" : 2,
      		"key" : {
      			"x" : ""
      		},
      		"name" : "x_",
      		"ns" : "repo.repro"
      	},
      	{
      		"v" : 2,
      		"key" : {
      			"x" : 1
      		},
      		"name" : "x_1",
      		"ns" : "repo.repro"
      	}
      ]
      

      Show
      db.repro.createIndex({x:""}) Outputs: > db.repro.createIndex({x:""}) { "createdCollectionAutomatically" : true, "numIndexesBefore" : 1, "numIndexesAfter" : 2, "ok" : 1 } A few additional lines from 4.1.10 : > db.version() 4.1.10 > db.repro.createIndex({x:""}) { "createdCollectionAutomatically" : true, "numIndexesBefore" : 1, "numIndexesAfter" : 2, "ok" : 1 } > db.repro.createIndex({x:1}) { "createdCollectionAutomatically" : false, "numIndexesBefore" : 2, "numIndexesAfter" : 3, "ok" : 1 } > db.repro.getIndices() [ { "v" : 2, "key" : { "_id" : 1 }, "name" : "_id_", "ns" : "repo.repro" }, { "v" : 2, "key" : { "x" : "" }, "name" : "x_", "ns" : "repo.repro" }, { "v" : 2, "key" : { "x" : 1 }, "name" : "x_1", "ns" : "repo.repro" } ]
    • Sprint:
      Query 2019-06-17
    • Case:

      Description

      At present it is possible to generate an index with an empty string as the key type (eg a definition of {x:""}).  The optimizer seems to be able to use this index when the key is a predicate in the query:

       

      > db.repro.find({x:123}).explain()
      {
      	"queryPlanner" : {
      		"plannerVersion" : 1,
      		"namespace" : "repro.repro",
      		"indexFilterSet" : false,
      		"parsedQuery" : {
      			"x" : {
      				"$eq" : 123
      			}
      		},
      		"queryHash" : "716F281A",
      		"planCacheKey" : "0FA0E5FD",
      		"winningPlan" : {
      			"stage" : "FETCH",
      			"inputStage" : {
      				"stage" : "IXSCAN",
      				"keyPattern" : {
      					"x" : ""
      				},
      				"indexName" : "x_",
      				"isMultiKey" : false,
      				"multiKeyPaths" : {
      					"x" : [ ]
      				},
      				"isUnique" : false,
      				"isSparse" : false,
      				"isPartial" : false,
      				"indexVersion" : 2,
      				"direction" : "forward",
      				"indexBounds" : {
      					"x" : [
      						"[123.0, 123.0]"
      					]
      				}
      			}
      		},
      		"rejectedPlans" : [ ]
      	},
      	"serverInfo" : {
      		"host" : "Chriss-MacBook-Pro.local",
      		"port" : 27017,
      		"version" : "4.1.10",
      		"gitVersion" : "8cdc51e7810f7fd8898a4c60b935e389f04659ee"
      	},
      	"ok" : 1
      } 

      However it is unable to use the index to sort:

      > db.repro.find({x:123}).sort({x:1}).explain()
      {
      	"queryPlanner" : {
      		"plannerVersion" : 1,
      		"namespace" : "repro.repro",
      		"indexFilterSet" : false,
      		"parsedQuery" : {
      			"x" : {
      				"$eq" : 123
      			}
      		},
      		"queryHash" : "87B348CE",
      		"planCacheKey" : "F46EA305",
      		"winningPlan" : {
      			"stage" : "FETCH",
      			"inputStage" : {
      				"stage" : "SORT",
      				"sortPattern" : {
      					"x" : 1
      				},
      				"inputStage" : {
      					"stage" : "SORT_KEY_GENERATOR",
      					"inputStage" : {
      						"stage" : "IXSCAN",
      						"keyPattern" : {
      							"x" : ""
      						},
      						"indexName" : "x_",
      						"isMultiKey" : false,
      						"multiKeyPaths" : {
      							"x" : [ ]
      						},
      						"isUnique" : false,
      						"isSparse" : false,
      						"isPartial" : false,
      						"indexVersion" : 2,
      						"direction" : "forward",
      						"indexBounds" : {
      							"x" : [
      								"[123.0, 123.0]"
      							]
      						}
      					}
      				}
      			}
      		},
      		"rejectedPlans" : [ ]
      	},
      	"serverInfo" : {
      		"host" : "Chriss-MacBook-Pro.local",
      		"port" : 27017,
      		"version" : "4.1.10",
      		"gitVersion" : "8cdc51e7810f7fd8898a4c60b935e389f04659ee"
      	},
      	"ok" : 1
      }
      > db.repro.find().sort({x:1}).explain()
      {
      	"queryPlanner" : {
      		"plannerVersion" : 1,
      		"namespace" : "repro.repro",
      		"indexFilterSet" : false,
      		"parsedQuery" : {
      			
      		},
      		"queryHash" : "B7791BAD",
      		"planCacheKey" : "B7791BAD",
      		"winningPlan" : {
      			"stage" : "SORT",
      			"sortPattern" : {
      				"x" : 1
      			},
      			"inputStage" : {
      				"stage" : "SORT_KEY_GENERATOR",
      				"inputStage" : {
      					"stage" : "COLLSCAN",
      					"direction" : "forward"
      				}
      			}
      		},
      		"rejectedPlans" : [ ]
      	},
      	"serverInfo" : {
      		"host" : "Chriss-MacBook-Pro.local",
      		"port" : 27017,
      		"version" : "4.1.10",
      		"gitVersion" : "8cdc51e7810f7fd8898a4c60b935e389f04659ee"
      	},
      	"ok" : 1
      } 

      This type of index should fail validation and not be created.

        Attachments

          Activity

            People

            Assignee:
            xinhao.zhang Xin Hao Zhang (Inactive)
            Reporter:
            christopher.harris Christopher Harris
            Participants:
            Votes:
            0 Vote for this issue
            Watchers:
            6 Start watching this issue

              Dates

              Created:
              Updated:
              Resolved: