Check JDBC 4 getFunctions (for compatibility with PostgreSQL driver 42.2.11)
Closes gh-25399
This commit is contained in:
parent
01bab89dba
commit
30bf870810
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2018 the original author or authors.
|
* Copyright 2002-2020 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -46,9 +46,8 @@ public class GenericCallMetaDataProvider implements CallMetaDataProvider {
|
||||||
/** Logger available to subclasses. */
|
/** Logger available to subclasses. */
|
||||||
protected static final Log logger = LogFactory.getLog(CallMetaDataProvider.class);
|
protected static final Log logger = LogFactory.getLog(CallMetaDataProvider.class);
|
||||||
|
|
||||||
private boolean procedureColumnMetaDataUsed = false;
|
|
||||||
|
|
||||||
private String userName;
|
private final String userName;
|
||||||
|
|
||||||
private boolean supportsCatalogsInProcedureCalls = true;
|
private boolean supportsCatalogsInProcedureCalls = true;
|
||||||
|
|
||||||
|
@ -58,7 +57,9 @@ public class GenericCallMetaDataProvider implements CallMetaDataProvider {
|
||||||
|
|
||||||
private boolean storesLowerCaseIdentifiers = false;
|
private boolean storesLowerCaseIdentifiers = false;
|
||||||
|
|
||||||
private List<CallParameterMetaData> callParameterMetaData = new ArrayList<>();
|
private boolean procedureColumnMetaDataUsed = false;
|
||||||
|
|
||||||
|
private final List<CallParameterMetaData> callParameterMetaData = new ArrayList<>();
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -328,20 +329,34 @@ public class GenericCallMetaDataProvider implements CallMetaDataProvider {
|
||||||
metaDataSchemaName + '/' + metaDataProcedureName);
|
metaDataSchemaName + '/' + metaDataProcedureName);
|
||||||
}
|
}
|
||||||
|
|
||||||
ResultSet procs = null;
|
|
||||||
try {
|
try {
|
||||||
procs = databaseMetaData.getProcedures(metaDataCatalogName, metaDataSchemaName, metaDataProcedureName);
|
|
||||||
List<String> found = new ArrayList<>();
|
List<String> found = new ArrayList<>();
|
||||||
while (procs.next()) {
|
boolean function = false;
|
||||||
found.add(procs.getString("PROCEDURE_CAT") + '.' + procs.getString("PROCEDURE_SCHEM") +
|
|
||||||
'.' + procs.getString("PROCEDURE_NAME"));
|
try (ResultSet procedures = databaseMetaData.getProcedures(
|
||||||
|
metaDataCatalogName, metaDataSchemaName, metaDataProcedureName)) {
|
||||||
|
while (procedures.next()) {
|
||||||
|
found.add(procedures.getString("PROCEDURE_CAT") + '.' + procedures.getString("PROCEDURE_SCHEM") +
|
||||||
|
'.' + procedures.getString("PROCEDURE_NAME"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (found.isEmpty()) {
|
||||||
|
// Functions not exposed as procedures anymore on PostgreSQL driver 42.2.11
|
||||||
|
try (ResultSet functions = databaseMetaData.getFunctions(
|
||||||
|
metaDataCatalogName, metaDataSchemaName, metaDataProcedureName)) {
|
||||||
|
while (functions.next()) {
|
||||||
|
found.add(functions.getString("FUNCTION_CAT") + '.' + functions.getString("FUNCTION_SCHEM") +
|
||||||
|
'.' + functions.getString("FUNCTION_NAME"));
|
||||||
|
function = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
procs.close();
|
|
||||||
|
|
||||||
if (found.size() > 1) {
|
if (found.size() > 1) {
|
||||||
throw new InvalidDataAccessApiUsageException(
|
throw new InvalidDataAccessApiUsageException(
|
||||||
"Unable to determine the correct call signature - multiple " +
|
"Unable to determine the correct call signature - multiple signatures for '" +
|
||||||
"procedures/functions/signatures for '" + metaDataProcedureName + "': found " + found);
|
metaDataProcedureName + "': found " + found + " " + (function ? "functions" : "procedures"));
|
||||||
}
|
}
|
||||||
else if (found.isEmpty()) {
|
else if (found.isEmpty()) {
|
||||||
if (metaDataProcedureName != null && metaDataProcedureName.contains(".") &&
|
if (metaDataProcedureName != null && metaDataProcedureName.contains(".") &&
|
||||||
|
@ -365,30 +380,34 @@ public class GenericCallMetaDataProvider implements CallMetaDataProvider {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
procs = databaseMetaData.getProcedureColumns(
|
if (logger.isDebugEnabled()) {
|
||||||
metaDataCatalogName, metaDataSchemaName, metaDataProcedureName, null);
|
logger.debug("Retrieving column meta-data for " + (function ? "function" : "procedure") + ' ' +
|
||||||
while (procs.next()) {
|
metaDataCatalogName + '/' + metaDataSchemaName + '/' + metaDataProcedureName);
|
||||||
String columnName = procs.getString("COLUMN_NAME");
|
}
|
||||||
int columnType = procs.getInt("COLUMN_TYPE");
|
try (ResultSet columns = function ?
|
||||||
if (columnName == null && (
|
databaseMetaData.getFunctionColumns(metaDataCatalogName, metaDataSchemaName, metaDataProcedureName, null) :
|
||||||
columnType == DatabaseMetaData.procedureColumnIn ||
|
databaseMetaData.getProcedureColumns(metaDataCatalogName, metaDataSchemaName, metaDataProcedureName, null)) {
|
||||||
columnType == DatabaseMetaData.procedureColumnInOut ||
|
while (columns.next()) {
|
||||||
columnType == DatabaseMetaData.procedureColumnOut)) {
|
String columnName = columns.getString("COLUMN_NAME");
|
||||||
if (logger.isDebugEnabled()) {
|
int columnType = columns.getInt("COLUMN_TYPE");
|
||||||
logger.debug("Skipping meta-data for: " + columnType + " " + procs.getInt("DATA_TYPE") +
|
if (columnName == null && isInOrOutColumn(columnType, function)) {
|
||||||
" " + procs.getString("TYPE_NAME") + " " + procs.getInt("NULLABLE") +
|
if (logger.isDebugEnabled()) {
|
||||||
" (probably a member of a collection)");
|
logger.debug("Skipping meta-data for: " + columnType + " " + columns.getInt("DATA_TYPE") +
|
||||||
|
" " + columns.getString("TYPE_NAME") + " " + columns.getInt("NULLABLE") +
|
||||||
|
" (probably a member of a collection)");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
else {
|
||||||
else {
|
int nullable = (function ? DatabaseMetaData.functionNullable : DatabaseMetaData.procedureNullable);
|
||||||
CallParameterMetaData meta = new CallParameterMetaData(columnName, columnType,
|
CallParameterMetaData meta = new CallParameterMetaData(columnName, columnType,
|
||||||
procs.getInt("DATA_TYPE"), procs.getString("TYPE_NAME"),
|
columns.getInt("DATA_TYPE"), columns.getString("TYPE_NAME"),
|
||||||
procs.getInt("NULLABLE") == DatabaseMetaData.procedureNullable);
|
columns.getInt("NULLABLE") == nullable);
|
||||||
this.callParameterMetaData.add(meta);
|
this.callParameterMetaData.add(meta);
|
||||||
if (logger.isDebugEnabled()) {
|
if (logger.isDebugEnabled()) {
|
||||||
logger.debug("Retrieved meta-data: " + meta.getParameterName() + " " +
|
logger.debug("Retrieved meta-data: " + meta.getParameterName() + " " +
|
||||||
meta.getParameterType() + " " + meta.getSqlType() + " " +
|
meta.getParameterType() + " " + meta.getSqlType() + " " +
|
||||||
meta.getTypeName() + " " + meta.isNullable());
|
meta.getTypeName() + " " + meta.isNullable());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -398,17 +417,18 @@ public class GenericCallMetaDataProvider implements CallMetaDataProvider {
|
||||||
logger.warn("Error while retrieving meta-data for procedure columns: " + ex);
|
logger.warn("Error while retrieving meta-data for procedure columns: " + ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
finally {
|
}
|
||||||
try {
|
|
||||||
if (procs != null) {
|
private static boolean isInOrOutColumn(int columnType, boolean function) {
|
||||||
procs.close();
|
if (function) {
|
||||||
}
|
return (columnType == DatabaseMetaData.functionColumnIn ||
|
||||||
}
|
columnType == DatabaseMetaData.functionColumnInOut ||
|
||||||
catch (SQLException ex) {
|
columnType == DatabaseMetaData.functionColumnOut);
|
||||||
if (logger.isWarnEnabled()) {
|
}
|
||||||
logger.warn("Problem closing ResultSet for procedure column meta-data: " + ex);
|
else {
|
||||||
}
|
return (columnType == DatabaseMetaData.procedureColumnIn ||
|
||||||
}
|
columnType == DatabaseMetaData.procedureColumnInOut ||
|
||||||
|
columnType == DatabaseMetaData.procedureColumnOut);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue