{"record":{"id":"4dd7c5a5be676e3b","repo":"NationalSecurityAgency/ghidra","slug":"sql-database-does-not-have-callgraph-information-e","errorCode":null,"errorMessage":"SQL database does not have callgraph information enabled","messagePattern":"SQL database does not have callgraph information enabled","errorType":"exception","errorClass":"SQLException","httpStatus":null,"severity":"error","filePath":"Ghidra/Features/BSim/src/main/java/ghidra/features/bsim/query/client/tables/CallgraphTable.java","lineNumber":84,"sourceCode":"\t */\n\tpublic static CallgraphRow extractCallgraphRow(ResultSet pgres) throws SQLException {\n\t\tCallgraphRow res = new CallgraphRow();\n\t\tres.src = pgres.getLong(1);\n\t\tres.dest = pgres.getLong(2);\n\t\treturn res;\n\t}\n\n\t/**\n\t * \n\t * @param func the function description\n\t * @param trackcallgraph true if the database tracks call graph information\n\t * @return the list of {@link CallgraphRow}s\n\t * @throws SQLException if there is a problem parsing the {@link ResultSet} objects\n\t */\n\tpublic List<CallgraphRow> queryCallgraphRows(FunctionDescription func,\n\t\tboolean trackcallgraph) throws SQLException {\n\t\tif (!trackcallgraph) {\n\t\t\tthrow new SQLException(\"SQL database does not have callgraph information enabled\");\n\t\t}\n\t\tPreparedStatement s =\n\t\t\tselectStatement.prepareIfNeeded(() -> db.prepareStatement(SELECT_STMT));\n\t\tRowKey funcid = func.getId();\n\t\tif (funcid == null) {\n\t\t\tthrow new SQLException(\"FunctionDescription does not have id\");\n\t\t}\n\t\ts.setLong(1, funcid.getLong());\n\t\ttry (ResultSet rs = s.executeQuery()) {\n\t\t\tList<CallgraphRow> callvec = new ArrayList<>();\n\t\t\twhile (rs.next()) {\n\t\t\t\tCallgraphRow row = extractCallgraphRow(rs);\n\t\t\t\tif (row.dest == 0) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tcallvec.add(row);\n\t\t\t}\n\t\t\treturn callvec;","sourceCodeStart":66,"sourceCodeEnd":102,"githubUrl":"https://github.com/NationalSecurityAgency/ghidra/blob/d5f144c24d6bc53c9cbf4448c6d11143e7696206/Ghidra/Features/BSim/src/main/java/ghidra/features/bsim/query/client/tables/CallgraphTable.java#L66-L102","documentation":"Thrown by CallgraphTable.queryCallgraphRows when the boolean trackcallgraph parameter is false, meaning the BSim SQL database was created/configured without call-graph tracking enabled. The call-graph table stores function-to-function call edges; if the database does not populate them, querying callgraph rows is meaningless and is rejected upfront.","triggerScenarios":"Calling queryCallgraphRows(func, false) — i.e., the caller passed trackcallgraph=false. This typically happens when the database's capabilities flag indicates no callgraph support, and the higher-level code forwards that flag down. The database was built with callgraph tracking disabled (a BSim database creation/layout option).","commonSituations":"Creating a BSim database without the callgraph layout option enabled, then attempting a query or analysis mode that requires call-graph edges (e.g., function reachability, callgraph-based clustering). Version or layout mismatch between the database generator and the analysis tool. Assuming all BSim databases track call graphs when some layouts omit them.","solutions":["Recreate or choose a BSim database that was created with call-graph tracking enabled.","Before calling callgraph-dependent APIs, check the database capabilities/layout and skip or warn if callgraph is unsupported.","Pass trackcallgraph=true only when the database actually supports it; gate the call behind a capability check.","Consult the BSim database creation options to enable the callgraph table at build time."],"exampleFix":"// before\nList<CallgraphRow> rows = callgraphTable.queryCallgraphRows(func, dbTracksCallgraph);\n\n// after\nif (!dbTracksCallgraph) {\n    log.warning(\"Callgraph not enabled on this database; skipping callgraph query.\");\n    return Collections.emptyList();\n}\nList<CallgraphRow> rows = callgraphTable.queryCallgraphRows(func, true);","handlingStrategy":"validation","validationCode":"// Check the database capability before invoking callgraph queries.\nif (!bsimDatabase.tracksCallgraph()) {\n    log.warning(\"Callgraph not enabled; skipping callgraph query.\");\n    return Collections.emptyList();\n}\nreturn callgraphTable.queryCallgraphRows(func, true);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Create BSim databases with callgraph tracking if your analysis needs call edges.","Gate all callgraph-dependent code behind a capability check.","Document per-database which features are enabled at creation time."],"tags":["bsim","database","callgraph","configuration","sql-exception"],"backgroundTag":null,"analyzedSha":"d5f144c24d6bc53c9cbf4448c6d11143e7696206","analyzedAt":"2026-08-14T01:00:57.564Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}