{"record":{"id":"61e98ee181e5469a","repo":"t8y2/dbx","slug":"sql-is-required-61e98e","errorCode":null,"errorMessage":"SQL is required","messagePattern":"SQL is required","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"agents/drivers/hive-go/metadata.go","lineNumber":812,"sourceCode":"\t\t}\n\t\tlines := make([]string, 0, len(result.Rows))\n\t\tfor _, row := range result.Rows {\n\t\t\tif line := firstRowValue(row); line != \"\" {\n\t\t\t\tlines = append(lines, line)\n\t\t\t}\n\t\t}\n\t\tif len(lines) == 0 {\n\t\t\tcontinue\n\t\t}\n\t\treturn strings.Join(lines, \"\\n\") + \"\\n\", nil\n\t}\n\treturn \"\", nil\n}\n\nfunc (server *server) getExplainInfo(sqlText string) (string, error) {\n\tsqlText = trimStatementSQL(sqlText)\n\tif sqlText == \"\" {\n\t\treturn \"\", errors.New(\"SQL is required\")\n\t}\n\tresult, err := server.executeQuery(queryOptions{SQL: \"EXPLAIN \" + sqlText, MaxRows: metadataQueryLimit})\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\tlines := make([]string, 0, len(result.Rows))\n\tfor _, row := range result.Rows {\n\t\tlines = append(lines, firstRowValue(row))\n\t}\n\treturn strings.Join(lines, \"\\n\"), nil\n}\n\nfunc (server *server) completionAssistantSearch(input completionAssistantRequest) (completionAssistantResponse, error) {\n\tmaxResults := input.MaxResults\n\tif maxResults <= 0 {\n\t\tmaxResults = 200\n\t}\n\tschemas := []string{firstNonEmpty(input.Schema, input.Database, server.config.Database)}","sourceCodeStart":794,"sourceCodeEnd":830,"githubUrl":"https://github.com/t8y2/dbx/blob/c0390bff16418b651f4728520d99adf8ce48829a/agents/drivers/hive-go/metadata.go#L794-L830","documentation":"getExplainInfo() runs \"EXPLAIN <sql>\" and requires the statement text to be non-empty after trimStatementSQL normalization. An empty EXPLAIN target is meaningless, so it throws \"SQL is required\" before touching the connection.","triggerScenarios":"Calling getExplainInfo / the explain dispatch path with sqlText=\"\", whitespace, or a string that trims to empty (e.g. only comments/semicolons stripped by trimStatementSQL).","commonSituations":"Query-analyzer UI sending the explain request before the user typed SQL; a pipeline passing a stripped/normalized statement that ended up empty; comment-only SQL input reduced to nothing by trimming.","solutions":["Pass the actual SQL statement text to getExplainInfo.","Check that trimStatementSQL isn't reducing your statement (e.g. pure comments) to an empty string; keep a non-comment statement body.","Validate SQL presence in the client before invoking the explain endpoint.","If explaining an empty/placeholder query intentionally, skip the explain call rather than sending it."],"exampleFix":"// before\nexplain, err := getExplainInfo(\"-- TODO\") // trims to empty -> error\n// after\nstmt := \"SELECT * FROM sales WHERE dt = '2026-01-01'\"\nexplain, err := getExplainInfo(stmt)","handlingStrategy":"validation","validationCode":"if strings.TrimSpace(sqlText) == \"\" {\n    return \"\", errors.New(\"cannot EXPLAIN an empty statement\")\n}","typeGuard":null,"tryCatchPattern":"plan, err := srv.GetExplainInfo(sqlText)\nif err != nil && strings.Contains(err.Error(), \"SQL is required\") {\n    return fmt.Errorf(\"explain request had no statement text\")\n}","preventionTips":["Disable the Explain action in UIs until SQL text exists.","Check that trimming/comment-stripping doesn't empty the statement.","Validate SQL presence client-side before explain calls."],"tags":["hive","validation","explain","missing-argument","go"],"backgroundTag":"missing-required-parameter","analyzedSha":"c0390bff16418b651f4728520d99adf8ce48829a","analyzedAt":"2026-09-05T23:05:10.900Z","contentChangedAt":"2026-09-05T23:05:10.900Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}