Repository: microsoft/mssql-jdbc
Pull request #2074 (2023-02-13 21:18:30)

Accounted for 0 cstmt meta query results
Fix for https://github.com/microsoft/mssql-jdbc/issues/2063


Patch:
diff --git a/build.gradle b/build.gradle
index 4a3be342..9b7652ad 100644
--- a/build.gradle
+++ b/build.gradle
@@ -128,7 +128,7 @@ repositories {
 
 dependencies {
     implementation 'org.osgi:org.osgi.core:6.0.0',
-			'org.osgi:org.osgi.compendium:5.0.0'
+			'org.osgi:org.osgi.service.jdbc:1.1.0'
 	compileOnly 'com.azure:azure-security-keyvault-keys:4.5.2',
 			'com.azure:azure-identity:1.7.0',
 			'org.antlr:antlr4-runtime:4.9.3',
diff --git a/pom.xml b/pom.xml
index 8a44976d..37540dac 100644
--- a/pom.xml
+++ b/pom.xml
@@ -66,7 +66,7 @@
 		<azure-security-keyvault-keys.version>4.5.3</azure-security-keyvault-keys.version>
 		<azure-identity.version>1.7.0</azure-identity.version>
 		<msal.version>1.13.3</msal.version>
-		<org.osgi.compendium.version>5.0.0</org.osgi.compendium.version>
+		<osgi.jdbc.version>1.1.0</osgi.jdbc.version>
 		<antlr-runtime.version>4.9.3</antlr-runtime.version>
 		<com.google.code.gson.version>2.9.0</com.google.code.gson.version>
 		<bcprov-jdk15on.version>1.70</bcprov-jdk15on.version>
@@ -150,8 +150,8 @@
 		</dependency>
 		<dependency>
 			<groupId>org.osgi</groupId>
-			<artifactId>org.osgi.compendium</artifactId>
-			<version>${org.osgi.compendium.version}</version>
+			<artifactId>org.osgi.service.jdbc</artifactId>
+			<version>${osgi.jdbc.version}</version>
 			<scope>provided</scope>
 		</dependency>
 
diff --git a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerCallableStatement.java b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerCallableStatement.java
index 7b332f0a..ee6be290 100644
--- a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerCallableStatement.java
+++ b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerCallableStatement.java
@@ -1362,10 +1362,10 @@ public class SQLServerCallableStatement extends SQLServerPreparedStatement imple
 
         }
 
-        // @RETURN_VALUE will always be in the parameterNames map, so parameterNamesSize will always be at least of size 1.
-        // If the server didn't return anything (eg. the param names for the sproc), user might not have access.
-        // So, parameterNamesSize must be of size 1.
-        if (null != parameterNames && parameterNames.size() == 1) {
+        // If the server didn't return anything (eg. the param names for the sp_sproc_columns), user might not
+        // have required permissions to view all the parameterNames. And, there's also the case depending on the permissions,
+        // @RETURN_VALUE may or may not be present. So, the parameterNames list might have an additional +1 parameter.
+        if (null != parameterNames && parameterNames.size() <= 1) {
             return map.computeIfAbsent(columnName, ifAbsent -> ai.incrementAndGet());
         }
 
diff --git a/src/main/java/com/microsoft/sqlserver/jdbc/osgi/Activator.java b/src/main/java/com/microsoft/sqlserver/jdbc/osgi/Activator.java
index 241448ca..df29400e 100644
--- a/src/main/java/com/microsoft/sqlserver/jdbc/osgi/Activator.java
+++ b/src/main/java/com/microsoft/sqlserver/jdbc/osgi/Activator.java
@@ -38,6 +38,12 @@ public class Activator implements BundleActivator {
         properties.put(DataSourceFactory.OSGI_JDBC_DRIVER_NAME, "Microsoft JDBC Driver for SQL Server");
         properties.put(DataSourceFactory.OSGI_JDBC_DRIVER_VERSION,
                 driver.getMajorVersion() + "." + driver.getMinorVersion());
+        properties.put(DataSourceFactory.OSGI_JDBC_CAPABILITY, new String[] {
+                DataSourceFactory.OSGI_JDBC_CAPABILITY_DRIVER,
+                DataSourceFactory.OSGI_JDBC_CAPABILITY_DATASOURCE,
+                DataSourceFactory.OSGI_JDBC_CAPABILITY_CONNECTIONPOOLDATASOURCE,
+                DataSourceFactory.OSGI_JDBC_CAPABILITY_XADATASOURCE
+        });
         service = context.registerService(DataSourceFactory.class, new SQLServerDataSourceFactory(), properties);
         SQLServerDriver.register();
     }


Test patch:
diff --git a/src/test/java/com/microsoft/sqlserver/jdbc/osgi/DataFactoryTest.java b/src/test/java/com/microsoft/sqlserver/jdbc/osgi/DataFactoryTest.java
index bfa8c3fe..62731692 100644
--- a/src/test/java/com/microsoft/sqlserver/jdbc/osgi/DataFactoryTest.java
+++ b/src/test/java/com/microsoft/sqlserver/jdbc/osgi/DataFactoryTest.java
@@ -10,8 +10,11 @@ import java.sql.Connection;
 import java.sql.ResultSet;
 import java.sql.SQLException;
 import java.sql.Statement;
+import java.util.Arrays;
 import java.util.Dictionary;
+import java.util.HashSet;
 import java.util.Properties;
+import java.util.Set;
 
 import javax.sql.ConnectionPoolDataSource;
 import javax.sql.DataSource;
@@ -19,7 +22,6 @@ import javax.sql.PooledConnection;
 import javax.sql.XAConnection;
 import javax.sql.XADataSource;
 
-import com.microsoft.sqlserver.jdbc.TestUtils;
 import org.eclipse.gemini.blueprint.mock.MockBundleContext;
 import org.eclipse.gemini.blueprint.mock.MockServiceRegistration;
 import org.junit.jupiter.api.BeforeAll;
@@ -87,6 +89,12 @@ public class DataFactoryTest extends AbstractTest {
         boolean correctClass = false;
         boolean correctName = false;
         boolean correctVersion = false;
+        String[] required_capabilities=new String[] {
+                DataSourceFactory.OSGI_JDBC_CAPABILITY_DRIVER,
+                DataSourceFactory.OSGI_JDBC_CAPABILITY_DATASOURCE,
+                DataSourceFactory.OSGI_JDBC_CAPABILITY_CONNECTIONPOOLDATASOURCE,
+                DataSourceFactory.OSGI_JDBC_CAPABILITY_XADATASOURCE};
+        boolean driverCap = false;
         SQLServerDriver driver = new SQLServerDriver();
 
         for (String key : propertyKeys) {
@@ -110,9 +118,18 @@ public class DataFactoryTest extends AbstractTest {
                         "Driver version mismatch. Expected: " + bundleDriverVer + ", Actual: " + actualDriverVer + ".",
                         bundleDriverVer.equals(actualDriverVer));
                 correctVersion = true;
+            }else if (key.equals(DataSourceFactory.OSGI_JDBC_CAPABILITY)) {
+                Object property = sr.getProperty(key);
+                if (property instanceof String[]) {
+                    Set<String> set = new HashSet<>(Arrays.asList( (String[]) property));
+                    for (String cap : required_capabilities) {
+                        assertTrue("Capability "+cap+" is missing!", set.contains(cap));
+                    }
+                }
+                driverCap=true;
             }
         }
-        assertTrue("Not all properties were checked.", correctClass && correctName && correctVersion);
+        assertTrue("Not all properties were checked.", correctClass && correctName && correctVersion && driverCap);
         DataSourceFactory dsf = bc.getService(sr);
         verifyFactoryNormalConnection(dsf);
         verifyFactoryPooledConnection(dsf);