{"record":{"id":"10b55fa7dac71b2a","repo":"bytebase/bytebase","slug":"mongodb-does-not-support-explain","errorCode":null,"errorMessage":"MongoDB does not support EXPLAIN","messagePattern":"MongoDB does not support EXPLAIN","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"backend/plugin/db/mongodb/mongodb.go","lineNumber":186,"sourceCode":"\tif connConfig.DataSource.GetDirectConnection() {\n\t\tvalues.Add(\"directConnection\", \"true\")\n\t}\n\n\tfor k, v := range connConfig.DataSource.GetExtraConnectionParameters() {\n\t\tif k == \"\" {\n\t\t\tcontinue\n\t\t}\n\t\tvalues.Add(k, v)\n\t}\n\tu.RawQuery = values.Encode()\n\n\treturn u.String()\n}\n\n// QueryConn queries a SQL statement in a given connection.\nfunc (d *Driver) QueryConn(ctx context.Context, _ *sql.Conn, statement string, queryContext db.QueryContext) ([]*v1pb.QueryResult, error) {\n\tif queryContext.Explain {\n\t\treturn nil, errors.New(\"MongoDB does not support EXPLAIN\")\n\t}\n\n\tstatement = strings.Trim(statement, \" \\t\\n\\r\\f;\")\n\tstartTime := time.Now()\n\n\tgmClient := gomongo.NewClient(d.client)\n\tvar gmOpts []gomongo.ExecuteOption\n\tif queryContext.Limit > 0 {\n\t\tgmOpts = append(gmOpts, gomongo.WithMaxRows(int64(queryContext.Limit)))\n\t}\n\tresult, err := gmClient.Execute(ctx, d.databaseName, statement, gmOpts...)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn d.convertGomongoResult(result, statement, startTime), nil\n}\n\nfunc (*Driver) convertGomongoResult(res *gomongo.Result, statement string, startTime time.Time) []*v1pb.QueryResult {","sourceCodeStart":168,"sourceCodeEnd":204,"githubUrl":"https://github.com/bytebase/bytebase/blob/1870550677fe08f0d2a78c07acd27541464eb945/backend/plugin/db/mongodb/mongodb.go#L168-L204","documentation":"MongoDB has no EXPLAIN-equivalent handled by this driver. When a query arrives through the unified SQL interface with the Explain flag set, the driver rejects the request outright instead of attempting an unsupported execution plan command.","triggerScenarios":"QueryConn(ctx, conn, statement, queryContext) invoked with queryContext.Explain == true — e.g. the UI's 'explain' button or an API caller requesting a plan for a MongoDB query.","commonSituations":"Users clicking explain/plan preview on a MongoDB datasource in the UI; automation that generically sets Explain for all engines; ported tooling that assumed every driver supports EXPLAIN.","solutions":["Don't set queryContext.Explain for MongoDB queries — run the statement normally","Hide/disable the explain action in UI/API layers for MongoDB connections","If plan inspection is needed, run explain-compatible aggregation stages ($explain or .explain()) directly via a MongoDB client instead","Return a structured 'unsupported' result upstream so callers can degrade gracefully"],"exampleFix":"// before\nqueryCtx := db.QueryContext{Explain: true}\nresults, err := driver.QueryConn(ctx, conn, stmt, queryCtx)\n// after\nqueryCtx := db.QueryContext{Explain: engine != storepb.Engine_MONGODB}\nresults, err := driver.QueryConn(ctx, conn, stmt, queryCtx)","handlingStrategy":"validation","validationCode":"if engine == storepb.Engine_MONGODB && queryContext.Explain {\n\treturn errors.New(\"explain is not supported for MongoDB\")\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Gate the explain feature per engine — disable it for MongoDB","Don't blanket-set Explain across all datasources","Offer MongoDB plan inspection via .explain() in a dedicated path instead","Return a typed 'unsupported' error upstream so callers can degrade"],"tags":["mongodb","explain","unsupported-feature"],"backgroundTag":"operation-not-supported","analyzedSha":"1870550677fe08f0d2a78c07acd27541464eb945","analyzedAt":"2026-09-06T21:16:13.665Z","contentChangedAt":"2026-09-06T21:16:13.665Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}