[SERVER-12647] Sort criteria with empty field name results in confusing error message Created: 06/Feb/14  Updated: 11/Jul/16  Resolved: 13/Feb/14

Status: Closed
Project: Core Server
Component/s: Querying
Affects Version/s: 2.5.5
Fix Version/s: 2.6.0-rc0

Type: Bug Priority: Major - P3
Reporter: Ben Becker Assignee: Benety Goh
Resolution: Done Votes: 0
Labels: 26Query, 26qa, nqf, query_triage
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Backwards Compatibility: Fully Compatible
Operating System: ALL
Participants:

 Description   

Sorting on an empty field name causes a flood of assertions which do not clearly indicate that the sort criteria is invalid. Note that in the following case, the only index is the default index on _id. Also note this query was sent via DBDirectClient.

Simplified Query:

{ query: { arrayField: "To the man who only has a hammer, everything he encounters begins to look like a nail. anything" }, orderby: { : -1 } }

From generated C++ code (which is a bit convoluted):

struct GeneratedQuery980 {
      static Query getQuery() { return sortedQuery; }
      static BSONObj* getProjection() { return NULL; }
      static int nToSkip() { return 10; }
      static int nToLimit() { return -1; }
      static Query& appendSort(Query& query) { return query.sort(fromjson("{\"\":-1}")); }
      static Query query;
      static Query sortedQuery;
};
Query GeneratedQuery980::query("{\"arrayField\":'To the man who only has a hammer, everything he encounters begins to look like a nail. anything'}");
Query GeneratedQuery980::sortedQuery = appendSort(GeneratedQuery980::query);    
 
...
 
    template <typename Q>
    struct GeneratedQueryRunner : ClientBase {
        virtual void run(){
            ::mongo::unittest::ScopedProbe::lastQuery = Q::getQuery();
            ::mongo::unittest::ScopedProbe::lastLimit = Q::nToLimit();
            ::mongo::unittest::ScopedProbe::lastSkip = Q::nToSkip();
            ::mongo::unittest::ScopedProbe::lastProjection = Q::getProjection();
            ::mongo::unittest::ScopedProbe::lastCount = -1;
            auto_ptr<DBClientCursor> cursor = _client.query(kNameSpace,
                                                            Q::getQuery(),
                                                            Q::nToLimit(),
                                                            Q::nToSkip(),
                                                            Q::getProjection());
            ASSERT(!error());
            int count = 0;
            while (cursor->more()) {
                ++count;
                cursor->next();
            }
            ::mongo::unittest::ScopedProbe::lastCount = count;
        }
    };
 
...
 
    class All : public Suite {
    public:
        All() : Suite( "GeneratedQueries" ) { }
        void setupTests() {
            add< GeneratedQueryRunner<GeneratedQuery980> >();
        }
    } myall;

Output:

2014-01-19T05:16:14.652-0800 [testsuite] 	 going to run test: GeneratedTests::GeneratedQueryRunner<GeneratedTests::GeneratedQuery980>
2014-01-19T05:16:14.652-0800 [testsuite] Assertion failure !e.eoo() src/mongo/bson/bsonobjbuilder.h 93
2014-01-19T05:16:14.663-0800 [testsuite] 0x1497186 0x1456888 0x143e72f 0x9f2763 0x1104acd 0x1105091 0x11025ec 0x10aadbb 0x10ab42f 0x10ad5ce 0x10aa733 0x1218f29 0x1209108 0x1116547 0x111803f 0xf3408d 0xf24150 0x110e56d 0xb3ce41 0x143a4d3 
 ./test(_ZN5mongo15printStackTraceERSo+0x26) [0x1497186]
 ./test(_ZN5mongo10logContextEPKc+0x188) [0x1456888]
 ./test(_ZN5mongo12verifyFailedEPKcS1_j+0xef) [0x143e72f]
 ./test() [0x9f2763]
 ./test(_ZNK5mongo19BtreeKeyGeneratorV120getKeysImplWithArrayESt6vectorIPKcSaIS3_EES1_INS_11BSONElementESaIS6_EERKNS_7BSONObjEPSt3setIS9_NS_10BSONObjCmpESaIS9_EEjSB_+0x59d) [0x1104acd]
 ./test(_ZNK5mongo19BtreeKeyGeneratorV111getKeysImplESt6vectorIPKcSaIS3_EES1_INS_11BSONElementESaIS6_EERKNS_7BSONObjEPSt3setIS9_NS_10BSONObjCmpESaIS9_EE+0x151) [0x1105091]
 ./test(_ZNK5mongo17BtreeKeyGenerator7getKeysERKNS_7BSONObjEPSt3setIS1_NS_10BSONObjCmpESaIS1_EE+0x1cc) [0x11025ec]
 ./test(_ZNK5mongo21SortStageKeyGenerator11getBtreeKeyERKNS_7BSONObjE+0xab) [0x10aadbb]
 ./test(_ZNK5mongo21SortStageKeyGenerator10getSortKeyERKNS_16WorkingSetMemberE+0x2f) [0x10ab42f]
 ./test(_ZN5mongo9SortStage4workEPm+0x38e) [0x10ad5ce]
 ./test(_ZN5mongo9SkipStage4workEPm+0x33) [0x10aa733]
 ./test(_ZN5mongo12PlanExecutor7getNextEPNS_7BSONObjEPNS_7DiskLocE+0xb9) [0x1218f29]
 ./test(_ZN5mongo11newRunQueryERNS_7MessageERNS_12QueryMessageERNS_5CurOpES1_+0x878) [0x1209108]
 ./test(_ZN5mongo16assembleResponseERNS_7MessageERNS_10DbResponseERKNS_11HostAndPortE+0x5e7) [0x1116547]
 ./test(_ZN5mongo14DBDirectClient4callERNS_7MessageES2_bPSs+0x9f) [0x111803f]
 ./test(_ZN5mongo14DBClientCursor4initEv+0x9d) [0xf3408d]
 ./test(_ZN5mongo12DBClientBase5queryERKSsNS_5QueryEiiPKNS_7BSONObjEii+0x270) [0xf24150]
 ./test(_ZN5mongo14DBDirectClient5queryERKSsNS_5QueryEiiPKNS_7BSONObjEii+0x4d) [0x110e56d]
 ./test(_ZN5mongo8unittest5Suite13runTestObjectIN14GeneratedTests20GeneratedQueryRunnerINS3_17GeneratedQuery980EEEEEvv+0x101) [0xb3ce41]
 ./test(_ZN5mongo8unittest5Suite3runERKSsi+0x3a3) [0x143a4d3]
2014-01-19T05:16:14.663-0800 [testsuite] Assertion failure !e.eoo() src/mongo/bson/bsonobjbuilder.h 93
2014-01-19T05:16:14.674-0800 [testsuite] 0x1497186 0x1456888 0x143e72f 0x9f2763 0x1104acd 0x1105091 0x11025ec 0x10aadbb 0x10ab42f 0x10ad5ce 0x10aa733 0x1218f29 0x1209108 0x1116547 0x111803f 0xf3408d 0xf24150 0x110e56d 0xb3ce41 0x143a4d3 
 ./test(_ZN5mongo15printStackTraceERSo+0x26) [0x1497186]
 ./test(_ZN5mongo10logContextEPKc+0x188) [0x1456888]
 ./test(_ZN5mongo12verifyFailedEPKcS1_j+0xef) [0x143e72f]
 ./test() [0x9f2763]
 ./test(_ZNK5mongo19BtreeKeyGeneratorV120getKeysImplWithArrayESt6vectorIPKcSaIS3_EES1_INS_11BSONElementESaIS6_EERKNS_7BSONObjEPSt3setIS9_NS_10BSONObjCmpESaIS9_EEjSB_+0x59d) [0x1104acd]
 ./test(_ZNK5mongo19BtreeKeyGeneratorV111getKeysImplESt6vectorIPKcSaIS3_EES1_INS_11BSONElementESaIS6_EERKNS_7BSONObjEPSt3setIS9_NS_10BSONObjCmpESaIS9_EE+0x151) [0x1105091]
 ./test(_ZNK5mongo17BtreeKeyGenerator7getKeysERKNS_7BSONObjEPSt3setIS1_NS_10BSONObjCmpESaIS1_EE+0x1cc) [0x11025ec]
 ./test(_ZNK5mongo21SortStageKeyGenerator11getBtreeKeyERKNS_7BSONObjE+0xab) [0x10aadbb]
 ./test(_ZNK5mongo21SortStageKeyGenerator10getSortKeyERKNS_16WorkingSetMemberE+0x2f) [0x10ab42f]
 ./test(_ZN5mongo9SortStage4workEPm+0x38e) [0x10ad5ce]
 ./test(_ZN5mongo9SkipStage4workEPm+0x33) [0x10aa733]
 ./test(_ZN5mongo12PlanExecutor7getNextEPNS_7BSONObjEPNS_7DiskLocE+0xb9) [0x1218f29]
 ./test(_ZN5mongo11newRunQueryERNS_7MessageERNS_12QueryMessageERNS_5CurOpES1_+0x878) [0x1209108]
 ./test(_ZN5mongo16assembleResponseERNS_7MessageERNS_10DbResponseERKNS_11HostAndPortE+0x5e7) [0x1116547]
 ./test(_ZN5mongo14DBDirectClient4callERNS_7MessageES2_bPSs+0x9f) [0x111803f]
 ./test(_ZN5mongo14DBClientCursor4initEv+0x9d) [0xf3408d]
 ./test(_ZN5mongo12DBClientBase5queryERKSsNS_5QueryEiiPKNS_7BSONObjEii+0x270) [0xf24150]
 ./test(_ZN5mongo14DBDirectClient5queryERKSsNS_5QueryEiiPKNS_7BSONObjEii+0x4d) [0x110e56d]
 ./test(_ZN5mongo8unittest5Suite13runTestObjectIN14GeneratedTests20GeneratedQueryRunnerINS3_17GeneratedQuery980EEEEEvv+0x101) [0xb3ce41]
 ./test(_ZN5mongo8unittest5Suite3runERKSsi+0x3a3) [0x143a4d3]
2014-01-19T05:16:14.674-0800 [testsuite] Assertion failure !e.eoo() src/mongo/bson/bsonobjbuilder.h 93
2014-01-19T05:16:14.685-0800 [testsuite] 0x1497186 0x1456888 0x143e72f 0x9f2763 0x1104acd 0x1105091 0x11025ec 0x10aadbb 0x10ab42f 0x10ad5ce 0x10aa733 0x1218f29 0x1209108 0x1116547 0x111803f 0xf3408d 0xf24150 0x110e56d 0xb3ce41 0x143a4d3 
 ./test(_ZN5mongo15printStackTraceERSo+0x26) [0x1497186]
 ./test(_ZN5mongo10logContextEPKc+0x188) [0x1456888]
 ./test(_ZN5mongo12verifyFailedEPKcS1_j+0xef) [0x143e72f]
 ./test() [0x9f2763]
 ./test(_ZNK5mongo19BtreeKeyGeneratorV120getKeysImplWithArrayESt6vectorIPKcSaIS3_EES1_INS_11BSONElementESaIS6_EERKNS_7BSONObjEPSt3setIS9_NS_10BSONObjCmpESaIS9_EEjSB_+0x59d) [0x1104acd]
 ./test(_ZNK5mongo19BtreeKeyGeneratorV111getKeysImplESt6vectorIPKcSaIS3_EES1_INS_11BSONElementESaIS6_EERKNS_7BSONObjEPSt3setIS9_NS_10BSONObjCmpESaIS9_EE+0x151) [0x1105091]
 ./test(_ZNK5mongo17BtreeKeyGenerator7getKeysERKNS_7BSONObjEPSt3setIS1_NS_10BSONObjCmpESaIS1_EE+0x1cc) [0x11025ec]
 ./test(_ZNK5mongo21SortStageKeyGenerator11getBtreeKeyERKNS_7BSONObjE+0xab) [0x10aadbb]
 ./test(_ZNK5mongo21SortStageKeyGenerator10getSortKeyERKNS_16WorkingSetMemberE+0x2f) [0x10ab42f]
 ./test(_ZN5mongo9SortStage4workEPm+0x38e) [0x10ad5ce]
 ./test(_ZN5mongo9SkipStage4workEPm+0x33) [0x10aa733]
 ./test(_ZN5mongo12PlanExecutor7getNextEPNS_7BSONObjEPNS_7DiskLocE+0xb9) [0x1218f29]
 ./test(_ZN5mongo11newRunQueryERNS_7MessageERNS_12QueryMessageERNS_5CurOpES1_+0x878) [0x1209108]
 ./test(_ZN5mongo16assembleResponseERNS_7MessageERNS_10DbResponseERKNS_11HostAndPortE+0x5e7) [0x1116547]
 ./test(_ZN5mongo14DBDirectClient4callERNS_7MessageES2_bPSs+0x9f) [0x111803f]
 ./test(_ZN5mongo14DBClientCursor4initEv+0x9d) [0xf3408d]
 ./test(_ZN5mongo12DBClientBase5queryERKSsNS_5QueryEiiPKNS_7BSONObjEii+0x270) [0xf24150]
 ./test(_ZN5mongo14DBDirectClient5queryERKSsNS_5QueryEiiPKNS_7BSONObjEii+0x4d) [0x110e56d]
 ./test(_ZN5mongo8unittest5Suite13runTestObjectIN14GeneratedTests20GeneratedQueryRunnerINS3_17GeneratedQuery980EEEEEvv+0x101) [0xb3ce41]
 ./test(_ZN5mongo8unittest5Suite3runERKSsi+0x3a3) [0x143a4d3]
2014-01-19T05:16:14.685-0800 [testsuite] FAIL: GeneratedTests::GeneratedQueryRunner<GeneratedTests::GeneratedQuery980>	Expected: !error() @src/mongo/dbtests/QA401.cpp:83



 Comments   
Comment by Githook User [ 13/Feb/14 ]

Author:

{u'username': u'benety', u'name': u'Benety Goh', u'email': u'benety@mongodb.com'}

Message: SERVER-12647 disallow empty field name in sort order
Branch: master
https://github.com/mongodb/mongo/commit/d2de709c117c016dadafcc889a40778d734a979b

Comment by Benety Goh [ 13/Feb/14 ]

we get the following error message when we try to create an index on an empty field name:

> db.t.ensureIndex({'':1})
{
	"ok" : 0,
	"errmsg" : "bad index key pattern { : 1.0 }: Index keys cannot be an empty field.",
	"code" : 67
}

2.4 also disallows indexes and sorting on empty field names.

I guess we can disallow sort orders on empty field name during the query canonicalization.

Comment by Daniel Pasette (Inactive) [ 10/Feb/14 ]

can repro this by simply:

db.coll.find().sort({'':1})

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