mongo icon indicating copy to clipboard operation
mongo copied to clipboard

SERVER-27976 Do not accept unknown argument for the explain command.

Open krk opened this issue 5 years ago • 7 comments

Example error message added with this PR:

> db.runCommand({explain: {find: "c"}, unknownArg: "unknown"})
{
	"ok" : 0,
	"errmsg" : "explain command requires a single argument with an optional verbosity",
	"code" : 72,
	"codeName" : "InvalidOptions"
}

krk avatar Jul 03 '19 20:07 krk

Thanks for the Pull Request! I've forwarded this on to the Query team to take a look.

dhatcher42 avatar Jul 03 '19 21:07 dhatcher42

I was shown that you already signed the agreement, so never mind that part. Sorry about that

TedTuckman avatar Jul 29 '19 19:07 TedTuckman

I have added javascript tests to the new file explain_invalid_arguments.js.

krk avatar Jul 30 '19 20:07 krk

This is looking good. I ran our javascript tests against your patch and a large number failed. In order to merge this the tests have to be fixed in the patch with the changes.

In order to run the javascript tests, see this page. I would suggest testing using resmoke.py to test suites to figure out which tests in those suites failed. The suites I would look at first are: jsCore, aggregation, auth, noPassthrough, and sharding. There are at least a few tests in each one of those that fail because of this change. Feel free to reach out if you run into any problems with the tests.

Also, could you run the formatter again?

TedTuckman avatar Aug 05 '19 19:08 TedTuckman

Thank you for the explanations. It seems that tests are using the explain command in an undocumented way, at least I could not find any documentation for this behavior:

var cName = "explain_find_and_modify";
var t = db.getCollection(cName);
// Insert a document to make sure the database exists.
t.insert({ will: "be dropped" });
// Make sure the collection doesn't exist.
t.drop();

var explainUpsert = {
  explain: {
    findAndModify: cName,
    update: { $inc: { i: 1 } },
    query: { _id: 0 },
    upsert: true
  }
};

var correct = {
  explain: Object.merge(explainUpsert.explain, { fields: { x: 1 } })
};
db.runCommand(correct);

// explain_find_and_modify.js:54 `assert.commandWorked(db.runCommand(Object.merge(explainUpsert, {fields: {x: 1}})));`
// is equivalent to:
var merged = Object.merge(explainUpsert, { fields: { x: 1 } });
db.runCommand(merged);
  1. correct command succeeds on both vanilla master and this PR.
  2. merged command succeeds on vanilla and fails with this PR.

Could you point to the documentation or code that handles the fields in this:

db.runCommand({
  explain: {
    findAndModify: "explain_find_and_modify",
    update: { $inc: { i: 1 } },
    query: { _id: 0 },
    upsert: true
  },
  fields: { x: 1 }
});

krk avatar Aug 06 '19 19:08 krk

Rebased and formatted with clang-format-7.0.1.

krk avatar Aug 06 '19 19:08 krk

In this situation my guess is that the fields argument is part of the findAndModify command, and can probably be moved inside explain. From when I was looking through the tests it looked like there were a number of cases where there were arguments outside the command object instead of inside -- you may have to find and move those.

TedTuckman avatar Aug 07 '19 14:08 TedTuckman