PMM-6256 Updated ExplainCmd for MongoDB (#459)

* PMM-6256 Updated ExplainCmd for MongoDB

In order to make explain for MongoDB work, we need to remove the "$db"
field from the explain command generated in proto.system.profile since
it is a duplicated field that triggers a MongoDB error.

* PMM-6256 New test

* PMM-6256 Removed commented out code

Co-authored-by: Carlos <cfsalguero@gmail.com>
This commit is contained in:
Carlos Salguero
2020-07-29 08:39:07 -03:00
committed by GitHub
parent 8d59ef2051
commit 002303fc2e
2 changed files with 71 additions and 1 deletions

View File

@@ -178,7 +178,6 @@ func (self ExampleQuery) ExplainCmd() bson.D {
} else {
cmd = append(cmd[:i], cmd[i+1:]...)
}
break
}
}
}
@@ -250,6 +249,8 @@ func (self ExampleQuery) ExplainCmd() bson.D {
}
}
case "command":
cmd = sanitizeCommand(cmd)
if len(cmd) == 0 || cmd[0].Key != "group" {
break
}
@@ -284,3 +285,28 @@ func (self ExampleQuery) ExplainCmd() bson.D {
},
}
}
func sanitizeCommand(cmd bson.D) bson.D {
if len(cmd) < 1 {
return cmd
}
key := cmd[0].Key
if key != "count" && key != "distinct" {
return cmd
}
for i := range cmd {
// drop $db param as it is not supported in MongoDB 3.0
if cmd[i].Key == "$db" {
if len(cmd)-1 == i {
cmd = cmd[:i]
} else {
cmd = append(cmd[:i], cmd[i+1:]...)
}
break
}
}
return cmd
}

View File

@@ -0,0 +1,44 @@
package proto_test
import (
"testing"
"github.com/percona/percona-toolkit/src/go/mongolib/proto"
"github.com/stretchr/testify/assert"
"go.mongodb.org/mongo-driver/bson"
)
func TestExplainCmd(t *testing.T) {
tests := []struct {
inDoc []byte
want []byte
}{
{
inDoc: []byte(`{"ns":"sbtest.orders","op":"command","command":{"aggregate":"orders",` +
`"pipeline":[{"$match":{"status":"A"}},{"$group":{"_id":"$cust_id","total":{"$sum":"$amount"}}},` +
`{"$sort":{"total":-1}}],"cursor":{},"$db":"sbtest"}}`),
want: []byte(`{"explain":{"aggregate":"orders","pipeline":[{"$match":{"status":"A"}},` +
`{"$group":{"_id":"$cust_id","total":{"$sum":"$amount"}}},` +
`{"$sort":{"total":-1}}],"cursor":{},"$db":"sbtest"}}`),
},
{
inDoc: []byte(`{"ns":"sbtest.people","op":"command","command":` +
`{"count":"people","query":{},"fields":{},"$db":"sbtest"}}`),
want: []byte(`{"explain":{"count":"people","query":{},"fields":{}}}`),
},
}
for _, tc := range tests {
var want bson.D
err := bson.UnmarshalExtJSON(tc.want, false, &want)
assert.NoError(t, err)
var doc proto.SystemProfile
err = bson.UnmarshalExtJSON(tc.inDoc, false, &doc)
assert.NoError(t, err)
eq := proto.NewExampleQuery(doc)
assert.Equal(t, want, eq.ExplainCmd())
}
}