[SERVER-19642] createIndexes command allows duplicate element names in index spec Created: 28/Jul/15  Updated: 16/May/16  Resolved: 09/May/16

Status: Closed
Project: Core Server
Component/s: Index Maintenance
Affects Version/s: 2.6.10, 3.0.5, 3.1.6
Fix Version/s: 3.3.6

Type: Bug Priority: Major - P3
Reporter: Max Hirschhorn Assignee: Vincent Do
Resolution: Done Votes: 1
Labels: neweng
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Issue Links:
Related
is related to SERVER-24032 When processing createIndexes (on V2 ... Closed
is related to SERVER-6439 Duplicate fields at the same level sh... Backlog
Backwards Compatibility: Fully Compatible
Operating System: ALL
Steps To Reproduce:

Since there is no way to create an arbitrary BSONObj to send to the server from the mongo shell, used the mgo driver to create an index spec with a duplicate element name.

package main
 
import (
  "gopkg.in/mgo.v2"
  "log"
)
 
func main() {
  session, err := mgo.Dial("127.0.0.1:27017")
  if err != nil {
    log.Fatal(err)
  }
 
  err = session.DB("test").DropDatabase()
  if err != nil {
    log.Fatal(err)
  }
 
  coll := session.DB("test").C("coll")
 
  index := mgo.Index{
    Key: []string{"a", "a", "b"},
  }
  err = coll.EnsureIndex(index)
  if err != nil {
    log.Fatal(err)
  }
}

Sprint: Integrate+Tuning 14 (05/13/16)
Participants:

 Description   

An index with duplicate element names in the index spec can be created:

> db.coll.getIndexes()
[
  {
    "v" : 1,
    "key" : {
      "_id" : 1
    },
    "name" : "_id_",
    "ns" : "test.coll"
  },
  {
    "v" : 1,
    "key" : {
      "a" : 1,
      "a" : 1,
      "b" : 1
    },
    "name" : "a_1_a_1_b_1",
    "ns" : "test.coll"
  }
]



 Comments   
Comment by Githook User [ 09/May/16 ]

Author:

{u'username': u'vincentdo', u'name': u'Vincent Do', u'email': u'do.vincent@live.com'}

Message: SERVER-19642 Fix compile
Branch: master
https://github.com/mongodb/mongo/commit/e8bbaa64f492d93c082f67b99ffa04733235bd01

Comment by Githook User [ 09/May/16 ]

Author:

{u'username': u'vincentdo', u'name': u'Vincent Do', u'email': u'do.vincent@live.com'}

Message: SERVER-19642 Add check for duplicate keys in index spec
Branch: master
https://github.com/mongodb/mongo/commit/dbde7d0f140d54c2e84c4ec78f14c52ef94b9b37

Comment by Max Hirschhorn [ 28/Jul/15 ]

Running the query db.coll.find({a: 1, c: 1}) triggers a verify() failure because the same index is marked as relevant for the same leaf expression. This is because the "a" field appears as both the first field and not the first field in the index {a: 1, a: 1, b: 1}.

* thread #12: tid = 0x3b65f, 0x00007fff819a1eec libsystem_c.dylib`strftime_l + 32
    frame #0: 0x00007fff819a1eec libsystem_c.dylib`strftime_l + 32
    frame #1: 0x0000000101305489 mongod`mongo::(anonymous namespace)::_dateToISOString(date=(millis = 1438123105793), local=true, result=0x0000000114100f10)::DateStringBuffer*) + 553 at time_support.cpp:242
    frame #2: 0x00000001013058cd mongod`mongo::outputDateAsISOStringLocal(os=0x0000000114101170, date=(millis = 1438123105793)) + 61 at time_support.cpp:296
    frame #3: 0x0000000100f349c4 mongod`mongo::logger::MessageEventDetailsEncoder::encode(this=0x0000000114101168, event=0x0000000114101720, os=0x0000000114101170) + 84 at message_event_utf8_encoder.cpp:54
    frame #4: 0x0000000100f3f3c9 mongod`mongo::RamLogAppender::append(this=0x0000000103a419f0, event=0x0000000114101720) + 1113 at ramlog.cpp:203
    frame #5: 0x0000000100f357ae mongod`mongo::logger::LogDomain<mongo::logger::MessageEventEphemeral>::append(this=0x0000000103a29518, event=0x0000000114101720) + 574 at log_domain-impl.h:59
    frame #6: 0x0000000100f31a1f mongod`mongo::logger::LogstreamBuilder::~LogstreamBuilder(this=0x0000000114101ca8) + 1359 at logstream_builder.cpp:126
    frame #7: 0x0000000100f323c5 mongod`mongo::logger::LogstreamBuilder::~LogstreamBuilder(this=0x0000000114101ca8) + 21 at logstream_builder.cpp:119
    frame #8: 0x000000010122b305 mongod`mongo::verifyFailed(expr=0x0000000101e29cd9, file=0x0000000101e29935, line=1163) + 1877 at assert_util.cpp:143
  * frame #9: 0x000000010098197b mongod`mongo::PlanEnumerator::tagMemo(this=0x0000000114103b88, id=1) + 2395 at plan_enumerator.cpp:1163
    frame #10: 0x0000000100980c7f mongod`mongo::PlanEnumerator::getNext(this=0x0000000114103b88, tree=0x0000000114103b78) + 95 at plan_enumerator.cpp:176
    frame #11: 0x00000001009f920d mongod`mongo::QueryPlanner::plan(query=0x0000000103a2b6d0, params=0x0000000114106d50, out=0x0000000114106930) + 24813 at query_planner.cpp:727
    frame #12: 0x000000010090297a mongod`mongo::(anonymous namespace)::prepareExecution(opCtx=0x000000011410b318, collection=0x0000000103a50ce0, ws=0x0000000103a51f50, canonicalQuery=0x0000000103a2b6d0, plannerOptions=0, rootOut=0x00000001141077c8, querySolutionOut=0x00000001141077c0) + 9498 at get_executor.cpp:335
    frame #13: 0x00000001008fee11 mongod`mongo::getExecutor(txn=0x000000011410b318, collection=0x0000000103a50ce0, canonicalQuery=unique_ptr<mongo::CanonicalQuery, std::__1::default_delete<mongo::CanonicalQuery> > at 0x00000001141082f0, yieldPolicy=YIELD_AUTO, plannerOptions=0) + 209 at get_executor.cpp:416
    frame #14: 0x00000001009072ac mongod`mongo::getExecutorFind(txn=0x000000011410b318, collection=0x0000000103a50ce0, nss=0x000000011410b090, canonicalQuery=unique_ptr<mongo::CanonicalQuery, std::__1::default_delete<mongo::CanonicalQuery> > at 0x0000000114109100, yieldPolicy=YIELD_AUTO) + 1436 at get_executor.cpp:611
    frame #15: 0x00000001008f768a mongod`mongo::runQuery(txn=0x000000011410b318, q=0x0000000114109d98, nss=0x000000011410b090, result=0x0000000103a51830) + 3274 at find.cpp:515
    frame #16: 0x00000001006d86d5 mongod`mongo::receivedQuery(txn=0x000000011410b318, nss=0x000000011410b090, c=0x0000000103a281d0, dbResponse=0x000000011410b390, m=0x000000011410bb90) + 837 at instance.cpp:376
    frame #17: 0x00000001006d5c95 mongod`mongo::assembleResponse(txn=0x000000011410b318, m=0x000000011410bb90, dbresponse=0x000000011410b390, remote=0x000000011410b2f8) + 2389 at instance.cpp:504
    frame #18: 0x0000000100018623 mongod`mongo::MyMessageHandler::process(this=0x0000000103e000a0, m=0x000000011410bb90, port=0x0000000103e01260) + 307 at db.cpp:165
    frame #19: 0x000000010126f037 mongod`mongo::PortMessageServer::handleIncomingMsg(arg=0x0000000103e01260) + 2983 at message_server_port.cpp:229
    frame #20: 0x000000010126d3da mongod`void* std::__1::__thread_proxy<std::__1::tuple<std::__1::__bind<void* (*)(void*), mongo::(anonymous namespace)::MessagingPortWithHandler*> > >(void*) [inlined] decltype(__f=0x0000000103e01f90, __args=0x0000000103e01f98)(void*)>(fp)(std::__1::forward<mongo::(anonymous namespace)::MessagingPortWithHandler*&>(fp0))) std::__1::__invoke<void* (*&)(void*), mongo::(anonymous namespace)::MessagingPortWithHandler*&>(void* (*&&&)(void*), mongo::(anonymous namespace)::MessagingPortWithHandler*&&&) + 24 at __functional_base:413
    frame #21: 0x000000010126d3c2 mongod`void* std::__1::__thread_proxy<std::__1::tuple<std::__1::__bind<void* (*)(void*), mongo::(anonymous namespace)::MessagingPortWithHandler*> > >(void*) [inlined] std::__1::__bind_return<void* (__f=0x0000000103e01f90, __bound_args=0x0000000103e01f98, (null)=__tuple_indices<0> at 0x000000011410bea0, __args=0x000000011410be60)(void*), std::__1::tuple<mongo::(anonymous namespace)::MessagingPortWithHandler*>, std::__1::tuple<>, _is_valid_bind_return<void* (*)(void*), std::__1::tuple<mongo::(anonymous namespace)::MessagingPortWithHandler*>, std::__1::tuple<> >::value>::type std::__1::__apply_functor<void* (*)(void*), std::__1::tuple<mongo::(anonymous namespace)::MessagingPortWithHandler*>, 0ul, std::__1::tuple<> >(void* (*&)(void*), std::__1::tuple<mongo::(anonymous namespace)::MessagingPortWithHandler*>&, std::__1::__tuple_indices<0ul>, std::__1::tuple<>&&) + 40 at functional:2023
    frame #22: 0x000000010126d39a mongod`void* std::__1::__thread_proxy<std::__1::tuple<std::__1::__bind<void* (*)(void*), mongo::(anonymous namespace)::MessagingPortWithHandler*> > >(void*) [inlined] std::__1::__bind_return<void* (this=0x0000000103e01f90)(void*), std::__1::tuple<mongo::(anonymous namespace)::MessagingPortWithHandler*>, std::__1::tuple<>, _is_valid_bind_return<void* (*)(void*), std::__1::tuple<mongo::(anonymous namespace)::MessagingPortWithHandler*>, std::__1::tuple<> >::value>::type std::__1::__bind<void* (*)(void*), mongo::(anonymous namespace)::MessagingPortWithHandler*>::operator()<>() + 38 at functional:2086
    frame #23: 0x000000010126d374 mongod`void* std::__1::__thread_proxy<std::__1::tuple<std::__1::__bind<void* (*)(void*), mongo::(anonymous namespace)::MessagingPortWithHandler*> > >(void*) [inlined] decltype(__f=0x0000000103e01f90)(void*), mongo::(anonymous namespace)::MessagingPortWithHandler*> >(fp)(std::__1::forward<>(fp0))) std::__1::__invoke<std::__1::__bind<void* (*)(void*), mongo::(anonymous namespace)::MessagingPortWithHandler*> >(std::__1::__bind<void* (*)(void*), mongo::(anonymous namespace)::MessagingPortWithHandler*>&&) + 11 at __functional_base:413
    frame #24: 0x000000010126d369 mongod`void* std::__1::__thread_proxy<std::__1::tuple<std::__1::__bind<void* (*)(void*), mongo::(anonymous namespace)::MessagingPortWithHandler*> > >(void*) [inlined] void std::__1::__thread_execute<std::__1::__bind<void* (__t=0x0000000103e01f90, (null)=__tuple_indices<> at 0x000000011410be38)(void*), mongo::(anonymous namespace)::MessagingPortWithHandler*> >(std::__1::tuple<std::__1::__bind<void* (*)(void*), mongo::(anonymous namespace)::MessagingPortWithHandler*> >&, std::__1::__tuple_indices<>) + 25 at thread:337
    frame #25: 0x000000010126d350 mongod`void* std::__1::__thread_proxy<std::__1::tuple<std::__1::__bind<void* (__vp=0x0000000103e01f90)(void*), mongo::(anonymous namespace)::MessagingPortWithHandler*> > >(void*) + 368 at thread:347
    frame #26: 0x00007fff81552899 libsystem_pthread.dylib`_pthread_body + 138
    frame #27: 0x00007fff8155272a libsystem_pthread.dylib`_pthread_start + 137
    frame #28: 0x00007fff81556fc9 libsystem_pthread.dylib`thread_start + 13

Insert and remove operations work fine though. Dropping the bad index can be done as a workaround for the verify() failure.

Generated at Thu Feb 08 03:51:38 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.