diff --git a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerDatabaseMetaData.java b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerDatabaseMetaData.java index 88d09f4ab..65f363332 100644 --- a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerDatabaseMetaData.java +++ b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerDatabaseMetaData.java @@ -1130,6 +1130,7 @@ public java.sql.ResultSet getFunctionColumns(String catalog, String schemaPatter rs.getColumn(9).setFilter(new ZeroFixupFilter()); rs.getColumn(17).setFilter(new ZeroFixupFilter()); } + rs.getColumn(3).setFilter(new ColumnNameFilter()); } return rs; } @@ -1648,6 +1649,7 @@ public java.sql.ResultSet getProcedureColumns(String catalog, String schema, Str rs.getColumn(9).setFilter(new ZeroFixupFilter()); rs.getColumn(17).setFilter(new ZeroFixupFilter()); } + rs.getColumn(3).setFilter(new ColumnNameFilter()); } return rs; } @@ -2946,6 +2948,20 @@ int oneValueToAnother(int precl) { } } +/** + * Provides filter to remove numbered prefixes from procedure and function names. + */ +class ColumnNameFilter extends ColumnFilter { + @Override + public Object apply(Object value, JDBCType asJDBCType) throws SQLServerException { + if (value instanceof String) { + String name = (String) value; + int idx = name.lastIndexOf(';'); + return (idx > 0) ? name.substring(0, idx) : name; + } + return value; + } +} /** * Converts one value to another solely based on the column integer value. Apply to integer columns only diff --git a/src/test/java/com/microsoft/sqlserver/jdbc/databasemetadata/DatabaseMetaDataTest.java b/src/test/java/com/microsoft/sqlserver/jdbc/databasemetadata/DatabaseMetaDataTest.java index 0a28218d6..cb85761e0 100644 --- a/src/test/java/com/microsoft/sqlserver/jdbc/databasemetadata/DatabaseMetaDataTest.java +++ b/src/test/java/com/microsoft/sqlserver/jdbc/databasemetadata/DatabaseMetaDataTest.java @@ -1438,6 +1438,98 @@ public void testGetFunctionsWithData() throws SQLException { } } + /** + * Test procedure columns retrieval with validation. + */ + @Test + public void testGetProcedureColumnsWithValidation() throws SQLException { + String schemaName = "test_Schema" + uuid; + String proc1 = "sproc_test1" + uuid; + String proc2 = "sproc_test2" + uuid; + + // Setup procedures + setupProcedures(schemaName, + proc1, "@val INT AS BEGIN SELECT @val * 2; END", + proc2, "@val INT AS BEGIN SELECT @val * 2; END"); + + try (Connection conn = getConnection()) { + DatabaseMetaData databaseMetaData = conn.getMetaData(); + + // Fetch procedure columns + try (ResultSet rs = databaseMetaData.getProcedureColumns(null, schemaName, "%", "%")) { + int count = 0; + while (rs.next()) { + String procedureName = rs.getString("PROCEDURE_NAME"); + String schema = rs.getString("PROCEDURE_SCHEM"); + + // Validate procedure name + assertTrue(procedureName.equals(proc1) || procedureName.equals(proc2), + "Unexpected procedure name: " + procedureName); + + // Validate schema name + assertEquals(schemaName, schema, "Schema name does not match"); + + count++; + } + + assertEquals(2, count, "Unexpected number of procedures found"); + } + } finally { + try (Connection conn = getConnection(); Statement stmt = conn.createStatement()) { + TestUtils.dropProcedureWithSchemaIfExists(schemaName + "." + proc1, stmt); + TestUtils.dropProcedureWithSchemaIfExists(schemaName + "." + proc2, stmt); + + TestUtils.dropSchemaIfExists(schemaName, stmt); + } + } + } + + /** + * Test function columns retrieval with validation. + */ + @Test + public void testGetFunctionColumnsWithValidation() throws SQLException { + String schemaName = "test_Schema" + uuid; + String func1 = "function_test1" + uuid; + String func2 = "function_test2" + uuid; + + // Setup functions + setupFunctions(schemaName, + func1, "() RETURNS INT AS BEGIN RETURN 42; END", + func2, "() RETURNS INT AS BEGIN RETURN 42; END"); + + try (Connection conn = getConnection()) { + DatabaseMetaData databaseMetaData = conn.getMetaData(); + + // Fetch function columns + try (ResultSet rs = databaseMetaData.getFunctionColumns(null, schemaName, "%", "%")) { + int count = 0; + while (rs.next()) { + String functionName = rs.getString("FUNCTION_NAME"); + String schema = rs.getString("FUNCTION_SCHEM"); + + // Validate function name + assertTrue(functionName.equals(func1) || functionName.equals(func2), + "Unexpected function name: " + functionName); + + // Validate schema name + assertEquals(schemaName, schema, "Schema name does not match"); + + count++; + } + + assertEquals(2, count, "Unexpected number of functions found"); + } + } finally { + try (Connection conn = getConnection(); Statement stmt = conn.createStatement()) { + TestUtils.dropFunctionWithSchemaIfExists(schemaName + "." + func1, stmt); + TestUtils.dropFunctionWithSchemaIfExists(schemaName + "." + func2, stmt); + + TestUtils.dropSchemaIfExists(schemaName, stmt); + } + } + } + @BeforeAll public static void setupTable() throws Exception { setConnection();