Bug #51912 Passing NULL as cat. param to getProcedureColumns with !nullCatalogMeansCurrent
Submitted: 10 Mar 2010 13:38 Modified: 20 Jul 2010 7:11
Reporter: Tonci Grgin Email Updates:
Status: Closed Impact on me:
None 
Category:Connector / J Severity:S3 (Non-critical)
Version:5.1 branch OS:Any
Assigned to: Tony Bedford CPU Architecture:Any

[10 Mar 2010 13:38] Tonci Grgin
Description:
Working on Bug#51904 I found out that calling 
  this.rs = dbmd.getProcedureColumns(null, null, "%", null);
while nullCatalogMeansCurrent=false leads to crash...

For servers < 5.4 code goes to DataBaseMetadata.java, 	private void getCallStmtParameterTypes(String catalog, String procName,...
and to this code:
	String dbName = null;
	if (dotIndex != -1 && (dotIndex + 1) < procName.length()) {
		dbName = procName.substring(0, dotIndex);
		procName = procName.substring(dotIndex + 1);
	} else {
		dbName = catalog;
	}

Being that "catalog" passed is null this crashes the whole thing.

How to repeat:
    DatabaseMetaData dbmd = this.conn.getMetaData();
    System.out.println("\nCalling getProcedureColumns(null, null, \"%\", null)");
    this.rs = dbmd.getProcedureColumns(null, null, "%", null); //this.conn.getCatalog()

Suggested fix:
First of all, we need to decide here is null catalog to be supported with getProcedureColumns when nullCatalogMeansCurrent=false.
Then, we can fortify this particular part of code if needs be.

Mark?
[18 Mar 2010 7:41] Tonci Grgin
Bug#52167 will be fixed together with this one.
[18 Mar 2010 9:45] Tonci Grgin
Bug#51904 will be fixed together with this one.
[18 Mar 2010 10:19] Tonci Grgin
Probably fixed Bug#51712 in process.
[24 Mar 2010 7:10] Tonci Grgin
Bug#51712 is actually tested with regression test for Bug#41269 as, after fixing PROC_CAT parameter, they are the same.
[24 Mar 2010 7:12] Tonci Grgin
Bug#51904 is fixed as a part of this bug report.
[24 Mar 2010 7:43] Tonci Grgin
Regression test case added.
[24 Mar 2010 10:20] Tonci Grgin
Pushed up to revision 918.
[24 Mar 2010 10:23] Tonci Grgin
Final diff file

Attachment: df.txt (text/plain), 10.46 KiB.

[24 Mar 2010 11:50] Tony Bedford
An entry has been added to the 5.1.13 changelog:

Calling getProcedureColumns with null as the catalog parameter and the connection string option nullCatalogMeansCurrent set to false resulted in a crash.
[25 Mar 2010 10:46] Tony Bedford
Changelog entry has been updated:

The catalog parameter, PARAM_CAT, was not correctly processed when calling for metadata with getMetaData() on stored procedures. This was because PARAM_CAT was hardcoded in the code to NULL. In the case where nullcatalogmeanscurrent was true, which is its default value, a crash did not occur, but the meta data returned was for the stored procedures from the catalog currently attached to. If, however, nullcatalogmeanscurrent was set to false then a crash resulted.

Connector/J has been changed so that when NULL is passed as PARAM_CAT it will not crash when nullcatalogmeanscurrent is false, but rather iterate all catalogs in search of stored procedures. This means that PARAM_CAT is no longer hardcoded to NULL (see Bug#51904).
[16 Jul 2010 5:41] Bogdan Degtyariov
The test case for this bug lacks the code checking metadata from getProcedureColumns():

=== modified file 'src/testsuite/regression/MetaDataRegressionTest.java'
--- src/testsuite/regression/MetaDataRegressionTest.java	2010-03-24 10:19:08 +0000
+++ src/testsuite/regression/MetaDataRegressionTest.java	2010-07-16 05:23:09 +0000
@@ -2612,6 +2612,16 @@
 
         	DatabaseMetaData dbmd = overrideConn.getMetaData();
             this.rs = dbmd.getProcedureColumns(null, null, "%", null);
+            ResultSetMetaData rsmd = this.rs.getMetaData();
+
+            // remark (column 13) is empty, so can be skipped
+            for (int i = 1; i < 13; i++)
+            {
+                // skip PROCEDURE_SCHEM
+                if (i == 2)
+                    continue;
+                assertTrue(rsmd.getColumnDisplaySize(i) > 0);
+            }
             this.rs.close();
             
 		} finally {

Next, the fix has been discussed with Tonci. Because the length has been added for compatibility with ODBC it does not really matter what the actual length is (Tonci can correct the numbers):

=== modified file 'src/com/mysql/jdbc/DatabaseMetaData.java'
--- src/com/mysql/jdbc/DatabaseMetaData.java	2010-04-06 17:20:14 +0000
+++ src/com/mysql/jdbc/DatabaseMetaData.java	2010-07-16 05:24:32 +0000
@@ -4083,18 +4083,18 @@
 	protected Field[] createProcedureColumnsFields() {
 		Field[] fields = new Field[13];
 
-		fields[0] = new Field("", "PROCEDURE_CAT", Types.CHAR, 0);
+		fields[0] = new Field("", "PROCEDURE_CAT", Types.CHAR, 255);
 		fields[1] = new Field("", "PROCEDURE_SCHEM", Types.CHAR, 0);
-		fields[2] = new Field("", "PROCEDURE_NAME", Types.CHAR, 0);
-		fields[3] = new Field("", "COLUMN_NAME", Types.CHAR, 0);
-		fields[4] = new Field("", "COLUMN_TYPE", Types.CHAR, 0);
-		fields[5] = new Field("", "DATA_TYPE", Types.SMALLINT, 0);
-		fields[6] = new Field("", "TYPE_NAME", Types.CHAR, 0);
-		fields[7] = new Field("", "PRECISION", Types.INTEGER, 0);
-		fields[8] = new Field("", "LENGTH", Types.INTEGER, 0);
-		fields[9] = new Field("", "SCALE", Types.SMALLINT, 0);
-		fields[10] = new Field("", "RADIX", Types.SMALLINT, 0);
-		fields[11] = new Field("", "NULLABLE", Types.SMALLINT, 0);
+		fields[2] = new Field("", "PROCEDURE_NAME", Types.CHAR, 255);
+		fields[3] = new Field("", "COLUMN_NAME", Types.CHAR, 255);
+		fields[4] = new Field("", "COLUMN_TYPE", Types.CHAR, 255);
+		fields[5] = new Field("", "DATA_TYPE", Types.SMALLINT, 255);
+		fields[6] = new Field("", "TYPE_NAME", Types.CHAR, 255);
+		fields[7] = new Field("", "PRECISION", Types.INTEGER, 255);
+		fields[8] = new Field("", "LENGTH", Types.INTEGER, 255);
+		fields[9] = new Field("", "SCALE", Types.SMALLINT, 255);
+		fields[10] = new Field("", "RADIX", Types.SMALLINT, 255);
+		fields[11] = new Field("", "NULLABLE", Types.SMALLINT, 255);
 		fields[12] = new Field("", "REMARKS", Types.CHAR, 0);
 		return fields;
 	}
[20 Jul 2010 7:11] Tonci Grgin
The proposed fix for src/com/mysql/jdbc/DatabaseMetaData.java is pushed 13 days ago in revno 956.