List:Commits« Previous MessageNext Message »
From:mmatthews Date:October 18 2006 5:08pm
Subject:Connector/J commit: r5890 - in branches/branch_3_1/connector-j: . src/com/mysql/jdbc src/testsuite/regression
View as plain text  
Modified:
   branches/branch_3_1/connector-j/CHANGES
   branches/branch_3_1/connector-j/src/com/mysql/jdbc/CallableStatement.java
   branches/branch_3_1/connector-j/src/com/mysql/jdbc/StringUtils.java
   branches/branch_3_1/connector-j/src/testsuite/regression/CallableStatementRegressionTest.java
Log:
Fixed bug when calling stored functions, where parameters weren't 
      numbered correctly (first parameter is now the return value, subsequent
      parameters if specified start at index "2").
        	  	    

Modified: branches/branch_3_1/connector-j/CHANGES
===================================================================
--- branches/branch_3_1/connector-j/CHANGES	2006-10-18 17:04:37 UTC (rev 5889)
+++ branches/branch_3_1/connector-j/CHANGES	2006-10-18 17:08:03 UTC (rev 5890)
@@ -66,6 +66,10 @@
       closed out from underneath statements don't cause NullPointerExceptions
       when it's required to check this property.
       
+    - Fixed bug when calling stored functions, where parameters weren't 
+      numbered correctly (first parameter is now the return value, subsequent
+      parameters if specified start at index "2").
+        	  	        
 05-26-06 - Version 3.1.13
 
     - Fixed BUG#15464 - INOUT parameter does not store IN value.

Modified: branches/branch_3_1/connector-j/src/com/mysql/jdbc/CallableStatement.java
===================================================================
--- branches/branch_3_1/connector-j/src/com/mysql/jdbc/CallableStatement.java	2006-10-18 17:04:37 UTC (rev 5889)
+++ branches/branch_3_1/connector-j/src/com/mysql/jdbc/CallableStatement.java	2006-10-18 17:08:03 UTC (rev 5890)
@@ -1,5 +1,5 @@
 /*
- Copyright (C) 2002-2004 MySQL AB
+ Copyright (C) 2002-2005 MySQL AB
 
  This program is free software; you can redistribute it and/or modify
  it under the terms of version 2 of the GNU General Public License as 
@@ -18,14 +18,13 @@
  You should have received a copy of the GNU General Public License
  along with this program; if not, write to the Free Software
  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-
-
-
+ 
  */
 package com.mysql.jdbc;
 
 import java.io.InputStream;
 import java.io.Reader;
+import java.io.UnsupportedEncodingException;
 
 import java.math.BigDecimal;
 
@@ -71,21 +70,25 @@
 		boolean isOut;
 
 		int jdbcType;
-		short nullability; 
+
+		short nullability;
+
 		String paramName;
-		int precision; 
-		int scale; 
+
+		int precision;
+
+		int scale;
+
 		String typeName;
-		
-		CallableStatementParam(String name, int idx, boolean in, 
-				boolean out, int jdbcType, String typeName, 
-				int precision, int scale, short nullability, 
-				int inOutModifier) {
+
+		CallableStatementParam(String name, int idx, boolean in, boolean out,
+				int jdbcType, String typeName, int precision, int scale,
+				short nullability, int inOutModifier) {
 			this.paramName = name;
 			this.isIn = in;
 			this.isOut = out;
 			this.index = idx;
-			
+
 			this.jdbcType = jdbcType;
 			this.typeName = typeName;
 			this.precision = precision;
@@ -106,57 +109,95 @@
 
 	class CallableStatementParamInfo {
 		String catalogInUse;
-	
+
 		boolean isFunctionCall;
-	
+
 		String nativeSql;
-	
+
 		int numParameters;
-	
+
 		List parameterList;
-	
+
 		Map parameterMap;
-	
+
+		/**
+		 * Constructor that converts a full list of parameter metadata into one
+		 * that only represents the placeholders present in the {CALL ()}.
+		 * 
+		 * @param fullParamInfo the metadata for all parameters for this stored 
+		 * procedure or function.
+		 */
+		CallableStatementParamInfo(CallableStatementParamInfo fullParamInfo) {
+			this.nativeSql = originalSql;
+			this.catalogInUse = currentCatalog;
+			isFunctionCall = fullParamInfo.isFunctionCall;
+			int[] localParameterMap = placeholderToParameterIndexMap;
+			int parameterMapLength = localParameterMap.length;
+			
+			parameterList = new ArrayList(fullParamInfo.numParameters);
+			parameterMap = new HashMap(fullParamInfo.numParameters);
+			
+			if (isFunctionCall) {
+				// Take the return value
+				parameterList.add(fullParamInfo.parameterList.get(0));
+			}
+			
+			int offset = isFunctionCall ? 1 : 0;
+			
+			for (int i = 0; i < parameterMapLength; i++) {
+				if (localParameterMap[i] != 0) {
+					CallableStatementParam param = (CallableStatementParam)fullParamInfo.parameterList.get(localParameterMap[i] + offset);
+					
+					parameterList.add(param);
+					parameterMap.put(param.paramName, param);
+				}
+			}
+			
+			this.numParameters = parameterList.size();
+		}
+		
 		CallableStatementParamInfo(java.sql.ResultSet paramTypesRs)
 				throws SQLException {
 			boolean hadRows = paramTypesRs.last();
-	
+
 			this.nativeSql = originalSql;
 			this.catalogInUse = currentCatalog;
 			isFunctionCall = callingStoredFunction;
-	
+
 			if (hadRows) {
 				this.numParameters = paramTypesRs.getRow();
-	
+
 				this.parameterList = new ArrayList(this.numParameters);
 				this.parameterMap = new HashMap(this.numParameters);
-	
+
 				paramTypesRs.beforeFirst();
-	
+
 				addParametersFromDBMD(paramTypesRs);
 			} else {
 				this.numParameters = 0;
 			}
+			
+			if (isFunctionCall) {
+				this.numParameters += 1;
+			}
 		}
-	
+
 		private void addParametersFromDBMD(java.sql.ResultSet paramTypesRs)
 				throws SQLException {
 			int i = 0;
-	
-			if (isFunctionCall) {
-				// first row will be return value parameter
-				paramTypesRs.next();
-			}
-	
+
 			while (paramTypesRs.next()) {
 				String paramName = paramTypesRs.getString(4);
 				int inOutModifier = paramTypesRs.getInt(5);
-	
+
 				boolean isOutParameter = false;
 				boolean isInParameter = false;
-	
-				if (inOutModifier == DatabaseMetaData.procedureColumnInOut) {
+
+				if (i == 0 && isFunctionCall) {
 					isOutParameter = true;
+					isInParameter = false;
+				} else if (inOutModifier == DatabaseMetaData.procedureColumnInOut) {
+					isOutParameter = true;
 					isInParameter = true;
 				} else if (inOutModifier == DatabaseMetaData.procedureColumnIn) {
 					isOutParameter = false;
@@ -165,34 +206,34 @@
 					isOutParameter = true;
 					isInParameter = false;
 				}
-	
+
 				int jdbcType = paramTypesRs.getInt(6);
 				String typeName = paramTypesRs.getString(7);
 				int precision = paramTypesRs.getInt(8);
 				int scale = paramTypesRs.getInt(10);
 				short nullability = paramTypesRs.getShort(12);
-	
+
 				CallableStatementParam paramInfoToAdd = new CallableStatementParam(
 						paramName, i++, isInParameter, isOutParameter,
 						jdbcType, typeName, precision, scale, nullability,
 						inOutModifier);
-	
+
 				this.parameterList.add(paramInfoToAdd);
 				this.parameterMap.put(paramName, paramInfoToAdd);
 			}
 		}
-	
+
 		protected void checkBounds(int paramIndex) throws SQLException {
 			int localParamIndex = paramIndex - 1;
-	
+
 			if ((paramIndex < 0) || (localParamIndex >= this.numParameters)) {
-				throw new SQLException (
+				throw new SQLException(
 						Messages.getString("CallableStatement.11") + paramIndex //$NON-NLS-1$
 								+ Messages.getString("CallableStatement.12") + numParameters //$NON-NLS-1$
 								+ Messages.getString("CallableStatement.13"), SQLError.SQL_STATE_ILLEGAL_ARGUMENT); //$NON-NLS-1$
 			}
 		}
-	
+
 		/*
 		 * (non-Javadoc)
 		 * 
@@ -202,15 +243,15 @@
 			// TODO Auto-generated method stub
 			return super.clone();
 		}
-	
+
 		CallableStatementParam getParameter(int index) {
 			return (CallableStatementParam) this.parameterList.get(index);
 		}
-	
+
 		CallableStatementParam getParameter(String name) {
 			return (CallableStatementParam) this.parameterMap.get(name);
 		}
-	
+
 		public String getParameterClassName(int arg0) throws SQLException {
 			String mysqlTypeName = getParameterTypeName(arg0);
 			
@@ -228,61 +269,61 @@
 			return ResultSetMetaData.getClassNameForJavaType(getParameterType(arg0), 
 					isUnsigned, mysqlTypeIfKnown, isBinaryOrBlob, false);
 		}
-	
+
 		public int getParameterCount() throws SQLException {
 			if (this.parameterList == null) {
 				return 0;
 			}
-			
+
 			return this.parameterList.size();
 		}
-	
+
 		public int getParameterMode(int arg0) throws SQLException {
 			checkBounds(arg0);
-	
+
 			return getParameter(arg0 - 1).inOutModifier;
 		}
-	
+
 		public int getParameterType(int arg0) throws SQLException {
 			checkBounds(arg0);
-	
+
 			return getParameter(arg0 - 1).jdbcType;
 		}
-	
+
 		public String getParameterTypeName(int arg0) throws SQLException {
 			checkBounds(arg0);
-	
+
 			return getParameter(arg0 - 1).typeName;
 		}
-	
+
 		public int getPrecision(int arg0) throws SQLException {
 			checkBounds(arg0);
-	
+
 			return getParameter(arg0 - 1).precision;
 		}
-	
+
 		public int getScale(int arg0) throws SQLException {
 			checkBounds(arg0);
-	
+
 			return getParameter(arg0 - 1).scale;
 		}
-	
+
 		public int isNullable(int arg0) throws SQLException {
 			checkBounds(arg0);
-	
+
 			return getParameter(arg0 - 1).nullability;
 		}
-	
+
 		public boolean isSigned(int arg0) throws SQLException {
 			checkBounds(arg0);
-	
+
 			return false;
 		}
-	
+
 		Iterator iterator() {
 			return this.parameterList.iterator();
 		}
-	
+
 		int numberOfParameters() {
 			return this.numParameters;
 		}
@@ -293,14 +334,18 @@
 	 * on JDK-1.3.1, which unfortunately isn't EOL'd yet, and still present
 	 * quite a bit out there in the wild (Websphere, FreeBSD, anyone?)
 	 */
-	
+
 	class CallableStatementParamInfoJDBC3 extends CallableStatementParamInfo
 			implements ParameterMetaData {
-	
+
 		CallableStatementParamInfoJDBC3(java.sql.ResultSet paramTypesRs)
 				throws SQLException {
 			super(paramTypesRs);
 		}
+
+		public CallableStatementParamInfoJDBC3(CallableStatementParamInfo paramInfo) {
+			super(paramInfo);
+		}
 	}
 
 	private final static int NOT_OUTPUT_PARAMETER_INDICATOR = Integer.MIN_VALUE;
@@ -363,6 +408,10 @@
 
 		this.paramInfo = paramInfo;
 		this.callingStoredFunction = this.paramInfo.isFunctionCall;
+		
+		if (this.callingStoredFunction) {
+			this.parameterCount += 1;
+		}
 	}
 
 	/**
@@ -382,21 +431,35 @@
 
 		determineParameterTypes();
 		generateParameterMap();
+		
+		if (this.callingStoredFunction) {
+			this.parameterCount += 1;
+		}
 	}
 
 	private int[] placeholderToParameterIndexMap;
 	
+	
 	private void generateParameterMap() throws SQLException {
 		// if the user specified some parameters as literals, we need to
 		// provide a map from the specified placeholders to the actual
 		// parameter numbers
 		
+		int parameterCountFromMetaData = this.paramInfo.getParameterCount();
+		
+		// Ignore the first ? if this is a stored function, it doesn't count
+		
+		if (this.callingStoredFunction) {
+			parameterCountFromMetaData--;
+		}
+		
 		if (this.paramInfo != null &&
-				this.parameterCount != this.paramInfo.getParameterCount()) {
+				this.parameterCount != parameterCountFromMetaData) {
 			this.placeholderToParameterIndexMap = new int[this.parameterCount];
 			
-			int startPos = StringUtils.indexOfIgnoreCase(this.originalSql, 
-					"CALL");
+			int startPos = this.callingStoredFunction ? StringUtils.indexOfIgnoreCase(this.originalSql, 
+			"SELECT") : StringUtils.indexOfIgnoreCase(this.originalSql, "CALL");
+			
 			if (startPos != -1) {
 				int parenOpenPos = this.originalSql.indexOf('(', startPos + 4);
 				
@@ -449,6 +512,10 @@
 
 		determineParameterTypes();
 		generateParameterMap();
+		
+		if (this.callingStoredFunction) {
+			this.parameterCount += 1;
+		}
 	}
 
 	/*
@@ -470,8 +537,8 @@
 
 				if (this.returnValueParam == null) {
 					this.returnValueParam = new CallableStatementParam("", 0,
-							false, true, Types.VARCHAR, "VARCHAR", 0, 0, 
-							DatabaseMetaData.attributeNullableUnknown, 
+							false, true, Types.VARCHAR, "VARCHAR", 0, 0,
+							DatabaseMetaData.attributeNullableUnknown,
 							DatabaseMetaData.procedureColumnReturn);
 				}
 
@@ -533,7 +600,7 @@
 
 	public synchronized void clearParameters() throws SQLException {
 		super.clearParameters();
-		
+
 		try {
 			if (this.outputParameterResults != null) {
 				this.outputParameterResults.close();
@@ -542,8 +609,9 @@
 			this.outputParameterResults = null;
 		}
 	}
-
+	
 	private void determineParameterTypes() throws SQLException {
+		
 		java.sql.ResultSet paramTypesRs = null;
 
 		try {
@@ -562,12 +630,7 @@
 					& useCatalog ? this.currentCatalog : null, null, procName,
 					"%"); //$NON-NLS-1$
 
-			if (!this.connection.isRunningOnJDK13()) {
-				this.paramInfo = new CallableStatementParamInfoJDBC3(
-						paramTypesRs);
-			} else {
-				this.paramInfo = new CallableStatementParamInfo(paramTypesRs);
-			}
+			convertGetProcedureColumnsToInternalDescriptors(paramTypesRs);
 		} finally {
 			SQLException sqlExRethrow = null;
 
@@ -587,6 +650,15 @@
 		}
 	}
 
+	private void convertGetProcedureColumnsToInternalDescriptors(java.sql.ResultSet paramTypesRs) throws SQLException {
+		if (!this.connection.isRunningOnJDK13()) {
+			this.paramInfo = new CallableStatementParamInfoJDBC3(
+					paramTypesRs);
+		} else {
+			this.paramInfo = new CallableStatementParamInfo(paramTypesRs);
+		}
+	}
+
 	/*
 	 * (non-Javadoc)
 	 * 
@@ -627,7 +699,7 @@
 	 * 
 	 * @see java.sql.PreparedStatement#executeQuery()
 	 */
-	public synchronized java.sql.ResultSet executeQuery() throws SQLException {
+	public java.sql.ResultSet executeQuery() throws SQLException {
 		checkClosed();
 
 		checkStreamability();
@@ -651,7 +723,7 @@
 	 * 
 	 * @see java.sql.PreparedStatement#executeUpdate()
 	 */
-	public synchronized int executeUpdate() throws SQLException {
+	public int executeUpdate() throws SQLException {
 		int returnVal = -1;
 
 		checkClosed();
@@ -731,15 +803,8 @@
 							? Messages.getString("CallableStatement.15") : Messages.getString("CallableStatement.16"), SQLError.SQL_STATE_ILLEGAL_ARGUMENT); //$NON-NLS-1$ //$NON-NLS-2$
 		}
 
+		
 		return mangleParameterName(paramNameIn);
-
-		/*
-		 * if (paramNameIn.startsWith("@")) { return paramNameIn; } else {
-		 * StringBuffer paramNameBuf = new StringBuffer("@");
-		 * paramNameBuf.append(paramNameIn);
-		 * 
-		 * return paramNameBuf.toString(); }
-		 */
 	}
 
 	/**
@@ -761,7 +826,7 @@
 	public synchronized Array getArray(String parameterName)
 			throws SQLException {
 		ResultSet rs = getOutputParameters(0); // definitely not going to be
-												// from ?=
+		// from ?=
 
 		Array retValue = rs.getArray(fixParameterName(parameterName));
 
@@ -819,7 +884,7 @@
 	public synchronized BigDecimal getBigDecimal(String parameterName)
 			throws SQLException {
 		ResultSet rs = getOutputParameters(0); // definitely not going to be
-												// from ?=
+		// from ?=
 
 		BigDecimal retValue = rs.getBigDecimal(fixParameterName(parameterName));
 
@@ -847,7 +912,7 @@
 	 */
 	public synchronized Blob getBlob(String parameterName) throws SQLException {
 		ResultSet rs = getOutputParameters(0); // definitely not going to be
-												// from ?=
+		// from ?=
 
 		Blob retValue = rs.getBlob(fixParameterName(parameterName));
 
@@ -877,7 +942,7 @@
 	public synchronized boolean getBoolean(String parameterName)
 			throws SQLException {
 		ResultSet rs = getOutputParameters(0); // definitely not going to be
-												// from ?=
+		// from ?=
 
 		boolean retValue = rs.getBoolean(fixParameterName(parameterName));
 
@@ -905,7 +970,7 @@
 	 */
 	public synchronized byte getByte(String parameterName) throws SQLException {
 		ResultSet rs = getOutputParameters(0); // definitely not going to be
-												// from ?=
+		// from ?=
 
 		byte retValue = rs.getByte(fixParameterName(parameterName));
 
@@ -934,7 +999,7 @@
 	public synchronized byte[] getBytes(String parameterName)
 			throws SQLException {
 		ResultSet rs = getOutputParameters(0); // definitely not going to be
-												// from ?=
+		// from ?=
 
 		byte[] retValue = rs.getBytes(fixParameterName(parameterName));
 
@@ -962,7 +1027,7 @@
 	 */
 	public synchronized Clob getClob(String parameterName) throws SQLException {
 		ResultSet rs = getOutputParameters(0); // definitely not going to be
-												// from ?=
+		// from ?=
 
 		Clob retValue = rs.getClob(fixParameterName(parameterName));
 
@@ -1005,7 +1070,7 @@
 	 */
 	public synchronized Date getDate(String parameterName) throws SQLException {
 		ResultSet rs = getOutputParameters(0); // definitely not going to be
-												// from ?=
+		// from ?=
 
 		Date retValue = rs.getDate(fixParameterName(parameterName));
 
@@ -1021,7 +1086,7 @@
 	public synchronized Date getDate(String parameterName, Calendar cal)
 			throws SQLException {
 		ResultSet rs = getOutputParameters(0); // definitely not going to be
-												// from ?=
+		// from ?=
 
 		Date retValue = rs.getDate(fixParameterName(parameterName), cal);
 
@@ -1051,7 +1116,7 @@
 	public synchronized double getDouble(String parameterName)
 			throws SQLException {
 		ResultSet rs = getOutputParameters(0); // definitely not going to be
-												// from ?=
+		// from ?=
 
 		double retValue = rs.getDouble(fixParameterName(parameterName));
 
@@ -1080,7 +1145,7 @@
 	public synchronized float getFloat(String parameterName)
 			throws SQLException {
 		ResultSet rs = getOutputParameters(0); // definitely not going to be
-												// from ?=
+		// from ?=
 
 		float retValue = rs.getFloat(fixParameterName(parameterName));
 
@@ -1108,7 +1173,7 @@
 	 */
 	public synchronized int getInt(String parameterName) throws SQLException {
 		ResultSet rs = getOutputParameters(0); // definitely not going to be
-												// from ?=
+		// from ?=
 
 		int retValue = rs.getInt(fixParameterName(parameterName));
 
@@ -1136,7 +1201,7 @@
 	 */
 	public synchronized long getLong(String parameterName) throws SQLException {
 		ResultSet rs = getOutputParameters(0); // definitely not going to be
-												// from ?=
+		// from ?=
 
 		long retValue = rs.getLong(fixParameterName(parameterName));
 
@@ -1146,14 +1211,15 @@
 	}
 
 	private int getNamedParamIndex(String paramName, boolean forOut)
-			throws SQLException {
+	throws SQLException {
+		
 		if ((paramName == null) || (paramName.length() == 0)) {
 			throw new SQLException(Messages.getString("CallableStatement.2"), //$NON-NLS-1$
 					SQLError.SQL_STATE_ILLEGAL_ARGUMENT);
 		}
 
 		CallableStatementParam namedParamInfo = this.paramInfo
-				.getParameter(paramName);
+		.getParameter(paramName);
 
 		if (this.paramInfo == null) {
 			throw new SQLException(
@@ -1164,21 +1230,21 @@
 		if (forOut && !namedParamInfo.isOut) {
 			throw new SQLException(
 					Messages.getString("CallableStatement.5") + paramName //$NON-NLS-1$
-							+ Messages.getString("CallableStatement.6"), //$NON-NLS-1$
+					+ Messages.getString("CallableStatement.6"), //$NON-NLS-1$
 					SQLError.SQL_STATE_ILLEGAL_ARGUMENT);
 		}
 
-		
+
 		if (this.placeholderToParameterIndexMap == null) {
 			return namedParamInfo.index + 1; // JDBC indices are 1-based
 		} 
-		
+
 		for (int i = 0; i < this.placeholderToParameterIndexMap.length; i++) {
 			if (this.placeholderToParameterIndexMap[i] == namedParamInfo.index) {
 				return i + 1;
 			}
 		}
-		
+
 		throw new SQLException("Can't find local placeholder mapping for parameter named \"" + 
 				paramName + "\".", SQLError.SQL_STATE_ILLEGAL_ARGUMENT);
 	}
@@ -1222,7 +1288,7 @@
 	public synchronized Object getObject(String parameterName)
 			throws SQLException {
 		ResultSet rs = getOutputParameters(0); // definitely not going to be
-												// from ?=
+		// from ?=
 
 		Object retValue = rs.getObject(fixParameterName(parameterName));
 
@@ -1238,7 +1304,7 @@
 	public synchronized Object getObject(String parameterName, Map map)
 			throws SQLException {
 		ResultSet rs = getOutputParameters(0); // definitely not going to be
-												// from ?=
+		// from ?=
 
 		Object retValue = rs.getObject(fixParameterName(parameterName), map);
 
@@ -1246,11 +1312,6 @@
 
 		return retValue;
 	}
-	
-	public synchronized ParameterMetaData getParameterMetaData()
-			throws SQLException {
-		return (CallableStatementParamInfoJDBC3) this.paramInfo;
-	}
 
 	/**
 	 * Returns the ResultSet that holds the output parameters, or throws an
@@ -1284,6 +1345,15 @@
 
 	}
 
+	public synchronized ParameterMetaData getParameterMetaData()
+			throws SQLException {
+		if (this.placeholderToParameterIndexMap == null) {
+			return (CallableStatementParamInfoJDBC3) this.paramInfo;
+		} else {
+			return new CallableStatementParamInfoJDBC3(this.paramInfo);
+		}
+	}
+
 	/**
 	 * @see java.sql.CallableStatement#getRef(int)
 	 */
@@ -1303,7 +1373,7 @@
 	 */
 	public synchronized Ref getRef(String parameterName) throws SQLException {
 		ResultSet rs = getOutputParameters(0); // definitely not going to be
-												// from ?=
+		// from ?=
 
 		Ref retValue = rs.getRef(fixParameterName(parameterName));
 
@@ -1332,7 +1402,7 @@
 	public synchronized short getShort(String parameterName)
 			throws SQLException {
 		ResultSet rs = getOutputParameters(0); // definitely not going to be
-												// from ?=
+		// from ?=
 
 		short retValue = rs.getShort(fixParameterName(parameterName));
 
@@ -1362,7 +1432,7 @@
 	public synchronized String getString(String parameterName)
 			throws SQLException {
 		ResultSet rs = getOutputParameters(0); // definitely not going to be
-												// from ?=
+		// from ?=
 
 		String retValue = rs.getString(fixParameterName(parameterName));
 
@@ -1405,7 +1475,7 @@
 	 */
 	public synchronized Time getTime(String parameterName) throws SQLException {
 		ResultSet rs = getOutputParameters(0); // definitely not going to be
-												// from ?=
+		// from ?=
 
 		Time retValue = rs.getTime(fixParameterName(parameterName));
 
@@ -1421,7 +1491,7 @@
 	public synchronized Time getTime(String parameterName, Calendar cal)
 			throws SQLException {
 		ResultSet rs = getOutputParameters(0); // definitely not going to be
-												// from ?=
+		// from ?=
 
 		Time retValue = rs.getTime(fixParameterName(parameterName), cal);
 
@@ -1466,7 +1536,7 @@
 	public synchronized Timestamp getTimestamp(String parameterName)
 			throws SQLException {
 		ResultSet rs = getOutputParameters(0); // definitely not going to be
-												// from ?=
+		// from ?=
 
 		Timestamp retValue = rs.getTimestamp(fixParameterName(parameterName));
 
@@ -1482,7 +1552,7 @@
 	public synchronized Timestamp getTimestamp(String parameterName,
 			Calendar cal) throws SQLException {
 		ResultSet rs = getOutputParameters(0); // definitely not going to be
-												// from ?=
+		// from ?=
 
 		Timestamp retValue = rs.getTimestamp(fixParameterName(parameterName),
 				cal);
@@ -1511,7 +1581,7 @@
 	 */
 	public synchronized URL getURL(String parameterName) throws SQLException {
 		ResultSet rs = getOutputParameters(0); // definitely not going to be
-												// from ?=
+		// from ?=
 
 		URL retValue = rs.getURL(fixParameterName(parameterName));
 
@@ -1530,7 +1600,7 @@
 		checkParameterIndexBounds(paramIndex);
 
 		int localParamIndex = paramIndex - 1;
-		
+
 		if (this.placeholderToParameterIndexMap != null) {
 			localParamIndex = this.placeholderToParameterIndexMap[localParamIndex];
 		}
@@ -1823,22 +1893,11 @@
 							setPstmt.close();
 						}
 					}
+				}
 
-					// StringBuffer fullName = new StringBuffer("@");
-					// fullName.append(outParameterName);
-					/*
-					 * this.setBytesNoEscapeNoQuotes(paramInfo.index + 1,
-					 * StringUtils.getBytes(outParameterName,
-					 * this.charConverter, this.charEncoding,
-					 * this.connection.getServerCharacterEncoding(),
-					 * this.connection.parserKnowsUnicode()));
-					 */
-				}
+				parameterIndex++;
 			}
-
-			parameterIndex++;
 		}
-
 	}
 
 	/**
@@ -1903,7 +1962,7 @@
 				CallableStatementParam outParamInfo = (CallableStatementParam) paramIter
 						.next();
 
-				if (outParamInfo.isOut) {
+				if (!this.callingStoredFunction && outParamInfo.isOut) {
 					String outParameterName = mangleParameterName(outParamInfo.paramName);
 
 					int outParamIndex;
@@ -1996,4 +2055,12 @@
 		
 		return super.executeBatch();
 	}
+
+	protected int getParameterIndexOffset() {
+		if (this.callingStoredFunction) {
+			return -1;
+		}
+		
+		return super.getParameterIndexOffset();
+	}
 }

Modified: branches/branch_3_1/connector-j/src/com/mysql/jdbc/StringUtils.java
===================================================================
--- branches/branch_3_1/connector-j/src/com/mysql/jdbc/StringUtils.java	2006-10-18 17:04:37 UTC (rev 5889)
+++ branches/branch_3_1/connector-j/src/com/mysql/jdbc/StringUtils.java	2006-10-18 17:08:03 UTC (rev 5890)
@@ -1388,4 +1388,33 @@
 		return ((searchInPos != searchInEnd) ? WILD_COMPARE_MATCH_WITH_WILD
 				: WILD_COMPARE_MATCH_NO_WILD);
 	}
+	
+	static byte[] s2b(String s, Connection conn) throws SQLException {
+		if (s == null) {
+			return null;
+		}
+		
+		if ((conn != null) && conn.getUseUnicode()) {
+			try {
+				String encoding = conn.getEncoding();
+
+				if (encoding == null) {
+					return s.getBytes();
+				}
+
+				SingleByteCharsetConverter converter = conn
+						.getCharsetConverter(encoding);
+
+				if (converter != null) {
+					return converter.toBytes(s);
+				}
+
+				return s.getBytes(encoding);
+			} catch (java.io.UnsupportedEncodingException E) {
+				return s.getBytes();
+			}
+		}
+
+		return s.getBytes();
+	}
 }

Modified: branches/branch_3_1/connector-j/src/testsuite/regression/CallableStatementRegressionTest.java
===================================================================
--- branches/branch_3_1/connector-j/src/testsuite/regression/CallableStatementRegressionTest.java	2006-10-18 17:04:37 UTC (rev 5889)
+++ branches/branch_3_1/connector-j/src/testsuite/regression/CallableStatementRegressionTest.java	2006-10-18 17:08:03 UTC (rev 5890)
@@ -468,11 +468,14 @@
 			try {
 				this.stmt.executeUpdate("DROP FUNCTION IF EXISTS testBug10310");
 				this.stmt
-						.executeUpdate("CREATE FUNCTION testBug10310(a float) RETURNS INT"
+						.executeUpdate("CREATE FUNCTION testBug10310(a float, b int, c int) RETURNS INT"
 								+ "\nBEGIN" + "\nRETURN a;" + "\nEND");
-				cStmt = this.conn.prepareCall("{? = CALL testBug10310(?)}");
+				cStmt = this.conn.prepareCall("{? = CALL testBug10310(?,?,?)}");
 				cStmt.registerOutParameter(1, Types.INTEGER);
-				cStmt.setFloat(1, 2);
+				cStmt.setFloat(2, 2);
+				cStmt.setInt(3, 1);
+				cStmt.setInt(4, 1);
+				
 				assertFalse(cStmt.execute());
 				assertEquals(2f, cStmt.getInt(1), .001);
 				assertEquals("java.lang.Integer", cStmt.getObject(1).getClass()
@@ -483,6 +486,20 @@
 				assertEquals("java.lang.Integer", cStmt.getObject(1).getClass()
 						.getName());
 
+				cStmt.setFloat("a", 4);
+				cStmt.setInt("b", 1);
+				cStmt.setInt("c", 1);
+				
+				assertFalse(cStmt.execute());
+				assertEquals(4f, cStmt.getInt(1), .001);
+				assertEquals("java.lang.Integer", cStmt.getObject(1).getClass()
+						.getName());
+				
+				assertEquals(-1, cStmt.executeUpdate());
+				assertEquals(4f, cStmt.getInt(1), .001);
+				assertEquals("java.lang.Integer", cStmt.getObject(1).getClass()
+						.getName());
+				
 				// Check metadata while we're at it
 
 				java.sql.DatabaseMetaData dbmd = this.conn.getMetaData();
@@ -494,8 +511,10 @@
 						.getString("PROCEDURE_NAME"));
 				assertEquals(DatabaseMetaData.procedureReturnsResult, this.rs
 						.getShort("PROCEDURE_TYPE"));
-				cStmt.setNull(1, Types.FLOAT);
-
+				cStmt.setNull(2, Types.FLOAT);
+				cStmt.setInt(3, 1);
+				cStmt.setInt(4, 1);
+				
 				assertFalse(cStmt.execute());
 				assertEquals(0f, cStmt.getInt(1), .001);
 				assertEquals(true, cStmt.wasNull());
@@ -508,6 +527,19 @@
 				assertEquals(null, cStmt.getObject(1));
 				assertEquals(true, cStmt.wasNull());
 
+				cStmt = this.conn.prepareCall("{? = CALL testBug10310(4,5,?)}");
+				cStmt.registerOutParameter(1, Types.INTEGER);
+				cStmt.setInt(2, 1);
+				
+				assertFalse(cStmt.execute());
+				assertEquals(4f, cStmt.getInt(1), .001);
+				assertEquals("java.lang.Integer", cStmt.getObject(1).getClass()
+						.getName());
+				
+				assertEquals(-1, cStmt.executeUpdate());
+				assertEquals(4f, cStmt.getInt(1), .001);
+				assertEquals("java.lang.Integer", cStmt.getObject(1).getClass()
+						.getName());
 			} finally {
 				if (this.rs != null) {
 					this.rs.close();

Thread
Connector/J commit: r5890 - in branches/branch_3_1/connector-j: . src/com/mysql/jdbc src/testsuite/regressionmmatthews18 Oct