in src/main/user-impl/java/com/mysql/cj/jdbc/DatabaseMetaDataMysqlSchema.java [636:736]
private ResultSet getStoredRoutines(String catalog, String schemaPattern, String routineNamePattern, StoredRoutineType targetMetaData) throws SQLException {
final String dbFilter = chooseDatabaseTerm(catalog, schemaPattern);
final String routineNameFilter = normalizeIdentifierQuoting(routineNamePattern);
final SortedMap<MultiComparable, Row> sortedRows = new TreeMap<>();
List<String> dbList = chooseBasedOnDatabaseTerm(() -> getDatabasesByLiteral(dbFilter), () -> getDatabasesByPattern(dbFilter));
for (String db : dbList) {
// Collect functions metadata.
if (targetMetaData == StoredRoutineType.FUNCTION || getProceduresReturnsFunctionsValue()) {
StringBuilder query = new StringBuilder("SHOW FUNCTION STATUS WHERE ");
query.append(chooseBasedOnDatabaseTerm(() -> "Db = ?", () -> "Db LIKE ?"));
if (!StringUtils.isNullOrEmpty(routineNameFilter)) {
query.append(" AND Name LIKE ?");
}
try (PreparedStatement functionsStmt = prepareMetaDataSafeStatement(query.toString())) {
functionsStmt.setString(1, db);
if (!StringUtils.isNullOrEmpty(routineNameFilter)) {
functionsStmt.setString(2, routineNameFilter);
}
ResultSet functionsRs = functionsStmt.executeQuery();
while (functionsRs.next()) {
String funcDb = functionsRs.getString("db");
String functionName = functionsRs.getString("name");
byte[][] row = null;
if (targetMetaData == StoredRoutineType.PROCEDURE) { // Exposing functions as procedures.
row = new byte[9][];
row[0] = chooseBasedOnDatabaseTerm(() -> s2b(funcDb), () -> s2b("def")); // PROCEDURE_CAT
row[1] = chooseBasedOnDatabaseTerm(() -> null, () -> s2b(funcDb)); // PROCEDURE_SCHEM
row[2] = s2b(functionName); // PROCEDURE_NAME
row[3] = null; // reserved for future use
row[4] = null; // reserved for future use
row[5] = null; // reserved for future use
row[6] = s2b(functionsRs.getString("comment")); // REMARKS
row[7] = n2b(procedureReturnsResult); // PROCEDURE_TYPE
row[8] = s2b(functionName); // SPECFIC_NAME
} else {
row = new byte[6][];
row[0] = chooseBasedOnDatabaseTerm(() -> s2b(funcDb), () -> s2b("def")); // FUNCTION_CAT
row[1] = chooseBasedOnDatabaseTerm(() -> null, () -> s2b(funcDb)); // FUNCTION_SCHEM
row[2] = s2b(functionName); // FUNCTION_NAME
row[3] = s2b(functionsRs.getString("comment")); // REMARKS
row[4] = n2b(functionNoTable); // FUNCTION_TYPE
row[5] = s2b(functionName); // SPECFIC_NAME
}
sortedRows.put(new MultiComparable(funcDb, functionName, StoredRoutineType.FUNCTION), new ByteArrayRow(row, getExceptionInterceptor()));
}
try {
functionsRs.close();
} catch (Exception sqlEx) {
AssertionFailedException.shouldNotHappen(sqlEx);
}
functionsRs = null;
}
}
// Collect procedures metadata.
if (targetMetaData == StoredRoutineType.PROCEDURE) {
StringBuilder query = new StringBuilder("SHOW PROCEDURE STATUS WHERE ");
query.append(chooseBasedOnDatabaseTerm(() -> "Db = ?", () -> "Db LIKE ?"));
if (!StringUtils.isNullOrEmpty(routineNameFilter)) {
query.append(" AND Name LIKE ?");
}
try (PreparedStatement proceduresStmt = prepareMetaDataSafeStatement(query.toString())) {
proceduresStmt.setString(1, db);
if (!StringUtils.isNullOrEmpty(routineNameFilter)) {
proceduresStmt.setString(2, routineNameFilter);
}
ResultSet proceduresRs = proceduresStmt.executeQuery();
while (proceduresRs.next()) {
String procDb = proceduresRs.getString("db");
String procedureName = proceduresRs.getString("name");
byte[][] row = new byte[9][];
row[0] = chooseBasedOnDatabaseTerm(() -> s2b(procDb), () -> s2b("def")); // PROCEDURE_CAT
row[1] = chooseBasedOnDatabaseTerm(() -> null, () -> s2b(procDb)); // PROCEDURE_SCHEM
row[2] = s2b(procedureName); // PROCEDURE_NAME
row[3] = null; // reserved for future use
row[4] = null; // reserved for future use
row[5] = null; // reserved for future use
row[6] = s2b(proceduresRs.getString("comment")); // REMARKS
row[7] = n2b(procedureNoResult); // PROCEDURE_TYPE
row[8] = s2b(procedureName); // SPECFIC_NAME
sortedRows.put(new MultiComparable(procDb, procedureName, StoredRoutineType.PROCEDURE),
new ByteArrayRow(row, getExceptionInterceptor()));
}
try {
proceduresRs.close();
} catch (Exception sqlEx) {
AssertionFailedException.shouldNotHappen(sqlEx);
}
proceduresRs = null;
}
}
}
final List<Row> rows = new ArrayList<>(sortedRows.values());
// Procedures metadata support both but not the other way around.
final Field[] fields = targetMetaData == StoredRoutineType.PROCEDURE ? createProceduresFields() : createFunctionsFields();
return getResultSetFactory().createFromResultsetRows(ResultSet.CONCUR_READ_ONLY, ResultSet.TYPE_SCROLL_INSENSITIVE,
new ResultsetRowsStatic(rows, new DefaultColumnDefinition(fields)));
}