Categories:
Audio (13)
Biotech (29)
Bytecode (36)
Database (77)
Framework (7)
Game (7)
General (507)
Graphics (53)
I/O (35)
IDE (2)
JAR Tools (102)
JavaBeans (21)
JDBC (121)
JDK (426)
JSP (20)
Logging (108)
Mail (58)
Messaging (8)
Network (84)
PDF (97)
Report (7)
Scripting (84)
Security (32)
Server (121)
Servlet (26)
SOAP (24)
Testing (54)
Web (15)
XML (322)
Collections:
Other Resources:
Source Code for Connector/J 8.0.31 - User Impl
Where to get the Java source code for Connector/J 8.0 User Impl module?
✍: FYIcenter.com
Java source code files for Connector/J 8.0 User Impl module are:
⏎ com/mysql/cj/jdbc/CallableStatement.java
/*
* Copyright (c) 2002, 2022, Oracle and/or its affiliates.
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, version 2.0, as published by the
* Free Software Foundation.
*
* This program is also distributed with certain software (including but not
* limited to OpenSSL) that is licensed under separate terms, as designated in a
* particular file or component or in included license documentation. The
* authors of MySQL hereby grant you an additional permission to link the
* program and your derivative works with the separately licensed software that
* they have included with MySQL.
*
* Without limiting anything contained in the foregoing, this file, which is
* part of MySQL Connector/J, is also subject to the Universal FOSS Exception,
* version 1.0, a copy of which can be found at
* http://oss.oracle.com/licenses/universal-foss-exception.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License, version 2.0,
* for more details.
*
* 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.,
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
package com.mysql.cj.jdbc;
import java.io.InputStream;
import java.io.Reader;
import java.math.BigDecimal;
import java.net.URL;
import java.sql.Array;
import java.sql.Blob;
import java.sql.Clob;
import java.sql.Date;
import java.sql.JDBCType;
import java.sql.NClob;
import java.sql.ParameterMetaData;
import java.sql.Ref;
import java.sql.ResultSet;
import java.sql.RowId;
import java.sql.SQLException;
import java.sql.SQLType;
import java.sql.SQLXML;
import java.sql.Time;
import java.sql.Timestamp;
import java.sql.Wrapper;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import com.mysql.cj.Messages;
import com.mysql.cj.MysqlType;
import com.mysql.cj.QueryInfo;
import com.mysql.cj.PreparedQuery;
import com.mysql.cj.conf.PropertyDefinitions.DatabaseTerm;
import com.mysql.cj.conf.PropertyKey;
import com.mysql.cj.exceptions.FeatureNotAvailableException;
import com.mysql.cj.exceptions.MysqlErrorNumbers;
import com.mysql.cj.jdbc.exceptions.SQLError;
import com.mysql.cj.jdbc.result.ResultSetImpl;
import com.mysql.cj.jdbc.result.ResultSetInternalMethods;
import com.mysql.cj.protocol.a.result.ByteArrayRow;
import com.mysql.cj.protocol.a.result.ResultsetRowsStatic;
import com.mysql.cj.result.DefaultColumnDefinition;
import com.mysql.cj.result.Field;
import com.mysql.cj.result.Row;
import com.mysql.cj.util.SearchMode;
import com.mysql.cj.util.StringUtils;
import com.mysql.cj.util.Util;
/**
* Representation of stored procedures for JDBC
*/
public class CallableStatement extends ClientPreparedStatement implements java.sql.CallableStatement {
protected static class CallableStatementParam {
int index;
int inOutModifier;
boolean isIn;
boolean isOut;
int jdbcType;
short nullability;
String paramName;
int precision;
int scale;
String typeName;
MysqlType desiredMysqlType = MysqlType.UNKNOWN;
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;
this.scale = scale;
this.nullability = nullability;
this.inOutModifier = inOutModifier;
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
public class CallableStatementParamInfo implements ParameterMetaData {
String dbInUse;
boolean isFunctionCall;
String nativeSql;
int numParameters;
List<CallableStatementParam> parameterList;
Map<String, CallableStatementParam> parameterMap;
/**
* synchronized externally in checkReadOnlyProcedure()
*/
boolean isReadOnlySafeProcedure = false;
/**
* synchronized externally in checkReadOnlyProcedure()
*/
boolean isReadOnlySafeChecked = false;
/**
* 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 = ((PreparedQuery) CallableStatement.this.query).getOriginalSql();
this.dbInUse = CallableStatement.this.getCurrentDatabase();
this.isFunctionCall = fullParamInfo.isFunctionCall;
@SuppressWarnings("synthetic-access")
int[] localParameterMap = CallableStatement.this.placeholderToParameterIndexMap;
int parameterMapLength = localParameterMap.length;
this.isReadOnlySafeProcedure = fullParamInfo.isReadOnlySafeProcedure;
this.isReadOnlySafeChecked = fullParamInfo.isReadOnlySafeChecked;
this.parameterList = new ArrayList<>(fullParamInfo.numParameters);
this.parameterMap = new HashMap<>(fullParamInfo.numParameters);
if (this.isFunctionCall) {
// Take the return value
this.parameterList.add(fullParamInfo.parameterList.get(0));
}
int offset = this.isFunctionCall ? 1 : 0;
for (int i = 0; i < parameterMapLength; i++) {
if (localParameterMap[i] != 0) {
CallableStatementParam param = fullParamInfo.parameterList.get(localParameterMap[i] + offset);
this.parameterList.add(param);
this.parameterMap.put(param.paramName, param);
}
}
this.numParameters = this.parameterList.size();
}
@SuppressWarnings("synthetic-access")
CallableStatementParamInfo(java.sql.ResultSet paramTypesRs) throws SQLException {
boolean hadRows = paramTypesRs.last();
this.nativeSql = ((PreparedQuery) CallableStatement.this.query).getOriginalSql();
this.dbInUse = CallableStatement.this.getCurrentDatabase();
this.isFunctionCall = CallableStatement.this.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 (this.isFunctionCall) {
this.numParameters += 1;
}
}
private void addParametersFromDBMD(java.sql.ResultSet paramTypesRs) throws SQLException {
int i = 0;
while (paramTypesRs.next()) {
String paramName = paramTypesRs.getString(4);
int inOutModifier;
switch (paramTypesRs.getInt(5)) {
case DatabaseMetaData.procedureColumnIn:
inOutModifier = ParameterMetaData.parameterModeIn;
break;
case DatabaseMetaData.procedureColumnInOut:
inOutModifier = ParameterMetaData.parameterModeInOut;
break;
case DatabaseMetaData.procedureColumnOut:
case DatabaseMetaData.procedureColumnReturn:
inOutModifier = ParameterMetaData.parameterModeOut;
break;
default:
inOutModifier = ParameterMetaData.parameterModeUnknown;
}
boolean isOutParameter = false;
boolean isInParameter = false;
if (i == 0 && this.isFunctionCall) {
isOutParameter = true;
isInParameter = false;
} else if (inOutModifier == java.sql.DatabaseMetaData.procedureColumnInOut) {
isOutParameter = true;
isInParameter = true;
} else if (inOutModifier == java.sql.DatabaseMetaData.procedureColumnIn) {
isOutParameter = false;
isInParameter = true;
} else if (inOutModifier == java.sql.DatabaseMetaData.procedureColumnOut) {
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 SQLError.createSQLException(Messages.getString("CallableStatement.11", new Object[] { paramIndex, this.numParameters }),
MysqlErrorNumbers.SQL_STATE_ILLEGAL_ARGUMENT, getExceptionInterceptor());
}
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
CallableStatementParam getParameter(int index) {
return this.parameterList.get(index);
}
CallableStatementParam getParameter(String name) {
return this.parameterMap.get(name);
}
@Override
public String getParameterClassName(int arg0) throws SQLException {
String mysqlTypeName = getParameterTypeName(arg0);
MysqlType mysqlType = MysqlType.getByName(mysqlTypeName);
switch (mysqlType) {
case YEAR:
if (!CallableStatement.this.session.getPropertySet().getBooleanProperty(PropertyKey.yearIsDateType).getValue()) {
return Short.class.getName();
}
// TODO Adjust for pseudo-boolean ?
//if (length == 1) {
// if (propertySet.getBooleanReadableProperty(PropertyKey.transformedBitIsBoolean).getValue()) {
// return MysqlType.BOOLEAN;
// } else if (propertySet.getBooleanReadableProperty(PropertyKey.tinyInt1isBit).getValue()) {
// return MysqlType.BIT;
// }
//}
return mysqlType.getClassName();
default:
return mysqlType.getClassName();
}
}
@Override
public int getParameterCount() throws SQLException {
if (this.parameterList == null) {
return 0;
}
return this.parameterList.size();
}
@Override
public int getParameterMode(int arg0) throws SQLException {
checkBounds(arg0);
return getParameter(arg0 - 1).inOutModifier;
}
@Override
public int getParameterType(int arg0) throws SQLException {
checkBounds(arg0);
return getParameter(arg0 - 1).jdbcType;
}
@Override
public String getParameterTypeName(int arg0) throws SQLException {
checkBounds(arg0);
return getParameter(arg0 - 1).typeName;
}
@Override
public int getPrecision(int arg0) throws SQLException {
checkBounds(arg0);
return getParameter(arg0 - 1).precision;
}
@Override
public int getScale(int arg0) throws SQLException {
checkBounds(arg0);
return getParameter(arg0 - 1).scale;
}
@Override
public int isNullable(int arg0) throws SQLException {
checkBounds(arg0);
return getParameter(arg0 - 1).nullability;
}
@Override
public boolean isSigned(int arg0) throws SQLException {
checkBounds(arg0);
return false;
}
Iterator<CallableStatementParam> iterator() {
return this.parameterList.iterator();
}
int numberOfParameters() {
return this.numParameters;
}
@Override
public boolean isWrapperFor(Class<?> iface) throws SQLException {
checkClosed();
// This works for classes that aren't actually wrapping anything
return iface.isInstance(this);
}
@Override
public <T> T unwrap(Class<T> iface) throws java.sql.SQLException {
try {
// This works for classes that aren't actually wrapping anything
return iface.cast(this);
} catch (ClassCastException cce) {
throw SQLError.createSQLException(Messages.getString("Common.UnableToUnwrap", new Object[] { iface.toString() }),
MysqlErrorNumbers.SQL_STATE_ILLEGAL_ARGUMENT, getExceptionInterceptor());
}
}
}
private final static int NOT_OUTPUT_PARAMETER_INDICATOR = Integer.MIN_VALUE;
private final static String PARAMETER_NAMESPACE_PREFIX = "@com_mysql_jdbc_outparam_";
private static String mangleParameterName(String origParameterName) {
if (origParameterName == null) {
return null;
}
int offset = 0;
if (origParameterName.length() > 0 && origParameterName.charAt(0) == '@') {
offset = 1;
}
StringBuilder paramNameBuf = new StringBuilder(PARAMETER_NAMESPACE_PREFIX.length() + origParameterName.length());
paramNameBuf.append(PARAMETER_NAMESPACE_PREFIX);
paramNameBuf.append(origParameterName.substring(offset));
return paramNameBuf.toString();
}
private boolean callingStoredFunction = false;
private ResultSetInternalMethods functionReturnValueResults;
private boolean hasOutputParams = false;
private ResultSetInternalMethods outputParameterResults;
protected boolean outputParamWasNull = false;
private int[] parameterIndexToRsIndex;
protected CallableStatementParamInfo paramInfo;
private CallableStatementParam returnValueParam;
private boolean noAccessToProcedureBodies;
/**
* Creates a new CallableStatement
*
* @param conn
* the connection creating this statement
* @param paramInfo
* the SQL to prepare
*
* @throws SQLException
* if an error occurs
*/
public CallableStatement(JdbcConnection conn, CallableStatementParamInfo paramInfo) throws SQLException {
super(conn, paramInfo.nativeSql, paramInfo.dbInUse);
this.paramInfo = paramInfo;
this.callingStoredFunction = this.paramInfo.isFunctionCall;
if (this.callingStoredFunction) {
((PreparedQuery) this.query).setParameterCount(((PreparedQuery) this.query).getParameterCount() + 1);
}
this.retrieveGeneratedKeys = true; // not provided for in the JDBC spec
this.noAccessToProcedureBodies = conn.getPropertySet().getBooleanProperty(PropertyKey.noAccessToProcedureBodies).getValue();
}
/**
* Creates a callable statement instance
*
* @param conn
* the connection creating this statement
* @param sql
* the SQL to prepare
* @param db
* the current database
* @param isFunctionCall
* is it a function call or a procedure call?
* @return CallableStatement
* @throws SQLException
* if an error occurs
*/
protected static CallableStatement getInstance(JdbcConnection conn, String sql, String db, boolean isFunctionCall) throws SQLException {
return new CallableStatement(conn, sql, db, isFunctionCall);
}
/**
* Creates a callable statement instance
*
* @param conn
* the connection creating this statement
* @param paramInfo
* the SQL to prepare
* @return CallableStatement
* @throws SQLException
* if an error occurs
*/
protected static CallableStatement getInstance(JdbcConnection conn, CallableStatementParamInfo paramInfo) throws SQLException {
return new CallableStatement(conn, paramInfo);
}
private int[] placeholderToParameterIndexMap;
private void generateParameterMap() throws SQLException {
synchronized (checkClosed().getConnectionMutex()) {
if (this.paramInfo == null) {
return;
}
// 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--;
}
PreparedQuery q = ((PreparedQuery) this.query);
if (this.paramInfo != null && q.getParameterCount() != parameterCountFromMetaData) {
this.placeholderToParameterIndexMap = new int[q.getParameterCount()];
int startPos = this.callingStoredFunction ? StringUtils.indexOfIgnoreCase(q.getOriginalSql(), "SELECT")
: StringUtils.indexOfIgnoreCase(q.getOriginalSql(), "CALL");
if (startPos != -1) {
int parenOpenPos = q.getOriginalSql().indexOf('(', startPos + 4);
if (parenOpenPos != -1) {
int parenClosePos = StringUtils.indexOfIgnoreCase(parenOpenPos, q.getOriginalSql(), ")", "'", "'", SearchMode.__FULL);
if (parenClosePos != -1) {
List<?> parsedParameters = StringUtils.split(q.getOriginalSql().substring(parenOpenPos + 1, parenClosePos), ",", "'\"", "'\"",
true);
int numParsedParameters = parsedParameters.size();
// sanity check
if (numParsedParameters != q.getParameterCount()) {
// bail?
}
int placeholderCount = 0;
for (int i = 0; i < numParsedParameters; i++) {
if (((String) parsedParameters.get(i)).equals("?")) {
this.placeholderToParameterIndexMap[placeholderCount++] = i;
}
}
}
}
}
}
}
}
/**
* Creates a new CallableStatement
*
* @param conn
* the connection creating this statement
* @param sql
* the SQL to prepare
* @param db
* the current database
* @param isFunctionCall
* is it a function call or a procedure call?
*
* @throws SQLException
* if an error occurs
*/
public CallableStatement(JdbcConnection conn, String sql, String db, boolean isFunctionCall) throws SQLException {
super(conn, sql, db);
this.callingStoredFunction = isFunctionCall;
if (!this.callingStoredFunction) {
if (!StringUtils.startsWithIgnoreCaseAndWs(sql, "CALL")) {
// not really a stored procedure call
fakeParameterTypes(false);
} else {
determineParameterTypes();
}
generateParameterMap();
} else {
determineParameterTypes();
generateParameterMap();
((PreparedQuery) this.query).setParameterCount(((PreparedQuery) this.query).getParameterCount() + 1);
}
this.retrieveGeneratedKeys = true; // not provided for in the JDBC spec
this.noAccessToProcedureBodies = conn.getPropertySet().getBooleanProperty(PropertyKey.noAccessToProcedureBodies).getValue();
}
@Override
public void addBatch() throws SQLException {
setOutParams();
super.addBatch();
}
private CallableStatementParam checkIsOutputParam(int paramIndex) throws SQLException {
synchronized (checkClosed().getConnectionMutex()) {
if (this.callingStoredFunction) {
if (paramIndex == 1) {
if (this.returnValueParam == null) {
this.returnValueParam = new CallableStatementParam("", 0, false, true, MysqlType.VARCHAR.getJdbcType(), "VARCHAR", 0, 0,
java.sql.DatabaseMetaData.attributeNullableUnknown, java.sql.DatabaseMetaData.procedureColumnReturn);
}
return this.returnValueParam;
}
// Move to position in output result set
paramIndex--;
}
checkParameterIndexBounds(paramIndex);
int localParamIndex = paramIndex - 1;
if (this.placeholderToParameterIndexMap != null) {
localParamIndex = this.placeholderToParameterIndexMap[localParamIndex];
}
CallableStatementParam paramDescriptor = this.paramInfo.getParameter(localParamIndex);
// We don't have reliable metadata in this case, trust the caller
if (this.noAccessToProcedureBodies) {
paramDescriptor.isOut = true;
paramDescriptor.isIn = true;
paramDescriptor.inOutModifier = java.sql.DatabaseMetaData.procedureColumnInOut;
} else if (!paramDescriptor.isOut) {
throw SQLError.createSQLException(Messages.getString("CallableStatement.9", new Object[] { paramIndex }),
MysqlErrorNumbers.SQL_STATE_ILLEGAL_ARGUMENT, getExceptionInterceptor());
}
this.hasOutputParams = true;
return paramDescriptor;
}
}
/**
* @param paramIndex
* parameter index
*
* @throws SQLException
* if a database access error occurs or this method is called on a closed PreparedStatement
*/
private void checkParameterIndexBounds(int paramIndex) throws SQLException {
synchronized (checkClosed().getConnectionMutex()) {
this.paramInfo.checkBounds(paramIndex);
}
}
/**
* Checks whether or not this statement is supposed to be providing
* streamable result sets...If output parameters are registered, the driver
* can not stream the results.
*
* @throws SQLException
* if a database access error occurs
*/
private void checkStreamability() throws SQLException {
if (this.hasOutputParams && createStreamingResultSet()) {
throw SQLError.createSQLException(Messages.getString("CallableStatement.14"), MysqlErrorNumbers.SQL_STATE_DRIVER_NOT_CAPABLE,
getExceptionInterceptor());
}
}
@Override
public void clearParameters() throws SQLException {
synchronized (checkClosed().getConnectionMutex()) {
super.clearParameters();
try {
if (this.outputParameterResults != null) {
this.outputParameterResults.close();
}
} finally {
this.outputParameterResults = null;
}
}
}
/**
* Used to fake up some metadata when we don't have access to
* SHOW CREATE PROCEDURE or mysql.proc.
*
* @param isReallyProcedure
* is it a procedure or function
*
* @throws SQLException
* if we can't build the metadata.
*/
private void fakeParameterTypes(boolean isReallyProcedure) throws SQLException {
synchronized (checkClosed().getConnectionMutex()) {
String encoding = this.connection.getSession().getServerSession().getCharsetSettings().getMetadataEncoding();
int collationIndex = this.connection.getSession().getServerSession().getCharsetSettings().getMetadataCollationIndex();
Field[] fields = new Field[13];
fields[0] = new Field("", "PROCEDURE_CAT", collationIndex, encoding, MysqlType.CHAR, 0);
fields[1] = new Field("", "PROCEDURE_SCHEM", collationIndex, encoding, MysqlType.CHAR, 0);
fields[2] = new Field("", "PROCEDURE_NAME", collationIndex, encoding, MysqlType.CHAR, 0);
fields[3] = new Field("", "COLUMN_NAME", collationIndex, encoding, MysqlType.CHAR, 0);
fields[4] = new Field("", "COLUMN_TYPE", collationIndex, encoding, MysqlType.CHAR, 0);
fields[5] = new Field("", "DATA_TYPE", collationIndex, encoding, MysqlType.SMALLINT, 0);
fields[6] = new Field("", "TYPE_NAME", collationIndex, encoding, MysqlType.CHAR, 0);
fields[7] = new Field("", "PRECISION", collationIndex, encoding, MysqlType.INT, 0);
fields[8] = new Field("", "LENGTH", collationIndex, encoding, MysqlType.INT, 0);
fields[9] = new Field("", "SCALE", collationIndex, encoding, MysqlType.SMALLINT, 0);
fields[10] = new Field("", "RADIX", collationIndex, encoding, MysqlType.SMALLINT, 0);
fields[11] = new Field("", "NULLABLE", collationIndex, encoding, MysqlType.SMALLINT, 0);
fields[12] = new Field("", "REMARKS", collationIndex, encoding, MysqlType.CHAR, 0);
String procName = isReallyProcedure ? extractProcedureName() : null;
byte[] procNameAsBytes = null;
procNameAsBytes = procName == null ? null : StringUtils.getBytes(procName, "UTF-8");
ArrayList<Row> resultRows = new ArrayList<>();
for (int i = 0; i < ((PreparedQuery) this.query).getParameterCount(); i++) {
byte[][] row = new byte[13][];
row[0] = null; // PROCEDURE_CAT
row[1] = null; // PROCEDURE_SCHEM
row[2] = procNameAsBytes; // PROCEDURE/NAME
row[3] = s2b(String.valueOf(i)); // COLUMN_NAME
row[4] = s2b(String.valueOf(java.sql.DatabaseMetaData.procedureColumnIn));
row[5] = s2b(String.valueOf(MysqlType.VARCHAR.getJdbcType())); // DATA_TYPE
row[6] = s2b(MysqlType.VARCHAR.getName()); // TYPE_NAME
row[7] = s2b(Integer.toString(65535)); // PRECISION
row[8] = s2b(Integer.toString(65535)); // LENGTH
row[9] = s2b(Integer.toString(0)); // SCALE
row[10] = s2b(Integer.toString(10)); // RADIX
row[11] = s2b(Integer.toString(java.sql.DatabaseMetaData.procedureNullableUnknown)); // nullable
row[12] = null;
resultRows.add(new ByteArrayRow(row, getExceptionInterceptor()));
}
java.sql.ResultSet paramTypesRs = this.resultSetFactory.createFromResultsetRows(ResultSet.CONCUR_READ_ONLY, ResultSet.TYPE_SCROLL_INSENSITIVE,
new ResultsetRowsStatic(resultRows, new DefaultColumnDefinition(fields)));
convertGetProcedureColumnsToInternalDescriptors(paramTypesRs);
}
}
private void determineParameterTypes() throws SQLException {
synchronized (checkClosed().getConnectionMutex()) {
java.sql.ResultSet paramTypesRs = null;
try {
//Bug#57022, we need to check for db.SPname notation first and pass on only SPname
String procName = extractProcedureName();
String quotedId = this.session.getIdentifierQuoteString();
List<?> parseList = StringUtils.splitDBdotName(procName, "", quotedId, this.session.getServerSession().isNoBackslashEscapesSet());
String tmpDb = "";
//There *should* be 2 rows, if any.
if (parseList.size() == 2) {
tmpDb = (String) parseList.get(0);
procName = (String) parseList.get(1);
} else {
//keep values as they are
}
java.sql.DatabaseMetaData dbmd = this.connection.getMetaData();
boolean useDb = false;
if (tmpDb.length() <= 0) {
useDb = true;
}
paramTypesRs = this.session.getPropertySet().<DatabaseTerm>getEnumProperty(PropertyKey.databaseTerm).getValue() == DatabaseTerm.SCHEMA
? dbmd.getProcedureColumns(null, useDb ? this.getCurrentDatabase() : tmpDb/* null */, procName, "%")
: dbmd.getProcedureColumns(useDb ? this.getCurrentDatabase() : tmpDb/* null */, null, procName, "%");
boolean hasResults = false;
try {
if (paramTypesRs.next()) {
paramTypesRs.previous();
hasResults = true;
}
} catch (Exception e) {
// paramTypesRs is empty, proceed with fake params. swallow, was expected
}
if (hasResults) {
convertGetProcedureColumnsToInternalDescriptors(paramTypesRs);
} else {
fakeParameterTypes(true);
}
} finally {
SQLException sqlExRethrow = null;
if (paramTypesRs != null) {
try {
paramTypesRs.close();
} catch (SQLException sqlEx) {
sqlExRethrow = sqlEx;
}
paramTypesRs = null;
}
if (sqlExRethrow != null) {
throw sqlExRethrow;
}
}
}
}
private void convertGetProcedureColumnsToInternalDescriptors(java.sql.ResultSet paramTypesRs) throws SQLException {
synchronized (checkClosed().getConnectionMutex()) {
this.paramInfo = new CallableStatementParamInfo(paramTypesRs);
}
}
@Override
public boolean execute() throws SQLException {
synchronized (checkClosed().getConnectionMutex()) {
boolean returnVal = false;
checkStreamability();
setInOutParamsOnServer();
setOutParams();
returnVal = super.execute();
if (this.callingStoredFunction) {
this.functionReturnValueResults = this.results;
this.functionReturnValueResults.next();
this.results = null;
}
// TODO There is something strange here:
// From ResultSetRegressionTest.testBug14562():
//
// $ CREATE TABLE testBug14562 (row_order INT, signed_field MEDIUMINT, unsigned_field MEDIUMINT UNSIGNED)
// $ INSERT INTO testBug14562 VALUES (1, -8388608, 0), (2, 8388607, 16777215)
// $ CREATE PROCEDURE sp_testBug14562_1 (OUT param_1 MEDIUMINT, OUT param_2 MEDIUMINT UNSIGNED)
// BEGIN
// SELECT signed_field, unsigned_field INTO param_1, param_2 FROM testBug14562 WHERE row_order=1;
// END
// $ CALL sp_testBug14562_1(@com_mysql_jdbc_outparam_param_1, @com_mysql_jdbc_outparam_param_2)
// $ SELECT @com_mysql_jdbc_outparam_param_1,@com_mysql_jdbc_outparam_param_2
//
// ResultSet metadata returns BIGINT for @com_mysql_jdbc_outparam_param_1 and @com_mysql_jdbc_outparam_param_2
// instead of expected MEDIUMINT. I wonder what happens to other types...
retrieveOutParams();
if (!this.callingStoredFunction) {
return returnVal;
}
// Functions can't return results
return false;
}
}
@Override
public java.sql.ResultSet executeQuery() throws SQLException {
synchronized (checkClosed().getConnectionMutex()) {
checkStreamability();
java.sql.ResultSet execResults = null;
setInOutParamsOnServer();
setOutParams();
execResults = super.executeQuery();
retrieveOutParams();
return execResults;
}
}
@Override
public int executeUpdate() throws SQLException {
return Util.truncateAndConvertToInt(executeLargeUpdate());
}
private String extractProcedureName() throws SQLException {
String sanitizedSql = StringUtils.stripCommentsAndHints(((PreparedQuery) this.query).getOriginalSql(), "`'\"", "`'\"",
!this.session.getServerSession().isNoBackslashEscapesSet());
// TODO: Do this with less memory allocation
int endCallIndex = StringUtils.indexOfIgnoreCase(sanitizedSql, "CALL ");
int offset = 5;
if (endCallIndex == -1) {
endCallIndex = StringUtils.indexOfIgnoreCase(sanitizedSql, "SELECT ");
offset = 7;
}
if (endCallIndex != -1) {
StringBuilder nameBuf = new StringBuilder();
String trimmedStatement = sanitizedSql.substring(endCallIndex + offset).trim();
int statementLength = trimmedStatement.length();
for (int i = 0; i < statementLength; i++) {
char c = trimmedStatement.charAt(i);
if (Character.isWhitespace(c) || (c == '(') || (c == '?')) {
break;
}
nameBuf.append(c);
}
return nameBuf.toString();
}
throw SQLError.createSQLException(Messages.getString("CallableStatement.1"), MysqlErrorNumbers.SQL_STATE_GENERAL_ERROR, getExceptionInterceptor());
}
/**
* Adds 'at' symbol to beginning of parameter names if needed.
*
* @param paramNameIn
* the parameter name to 'fix'
*
* @return the parameter name with an 'a' prepended, if needed
*
* @throws SQLException
* if the parameter name is null or empty.
*/
protected String fixParameterName(String paramNameIn) throws SQLException {
synchronized (checkClosed().getConnectionMutex()) {
if (paramNameIn == null) {
paramNameIn = "nullpn";
}
if (this.noAccessToProcedureBodies) {
throw SQLError.createSQLException(Messages.getString("CallableStatement.23"), MysqlErrorNumbers.SQL_STATE_ILLEGAL_ARGUMENT,
getExceptionInterceptor());
}
return mangleParameterName(paramNameIn);
}
}
@Override
public Array getArray(int i) throws SQLException {
synchronized (checkClosed().getConnectionMutex()) {
ResultSetInternalMethods rs = getOutputParameters(i);
Array retValue = rs.getArray(mapOutputParameterIndexToRsIndex(i));
this.outputParamWasNull = rs.wasNull();
return retValue;
}
}
@Override
public Array getArray(String parameterName) throws SQLException {
synchronized (checkClosed().getConnectionMutex()) {
ResultSetInternalMethods rs = getOutputParameters(0); // definitely not going to be from ?=
Array retValue = rs.getArray(fixParameterName(parameterName));
this.outputParamWasNull = rs.wasNull();
return retValue;
}
}
@Override
public BigDecimal getBigDecimal(int parameterIndex) throws SQLException {
synchronized (checkClosed().getConnectionMutex()) {
ResultSetInternalMethods rs = getOutputParameters(parameterIndex);
BigDecimal retValue = rs.getBigDecimal(mapOutputParameterIndexToRsIndex(parameterIndex));
this.outputParamWasNull = rs.wasNull();
return retValue;
}
}
@Override
@Deprecated
public BigDecimal getBigDecimal(int parameterIndex, int scale) throws SQLException {
synchronized (checkClosed().getConnectionMutex()) {
ResultSetInternalMethods rs = getOutputParameters(parameterIndex);
BigDecimal retValue = rs.getBigDecimal(mapOutputParameterIndexToRsIndex(parameterIndex), scale);
this.outputParamWasNull = rs.wasNull();
return retValue;
}
}
@Override
public BigDecimal getBigDecimal(String parameterName) throws SQLException {
synchronized (checkClosed().getConnectionMutex()) {
ResultSetInternalMethods rs = getOutputParameters(0); // definitely not going to be from ?=
BigDecimal retValue = rs.getBigDecimal(fixParameterName(parameterName));
this.outputParamWasNull = rs.wasNull();
return retValue;
}
}
@Override
public Blob getBlob(int parameterIndex) throws SQLException {
synchronized (checkClosed().getConnectionMutex()) {
ResultSetInternalMethods rs = getOutputParameters(parameterIndex);
Blob retValue = rs.getBlob(mapOutputParameterIndexToRsIndex(parameterIndex));
this.outputParamWasNull = rs.wasNull();
return retValue;
}
}
@Override
public Blob getBlob(String parameterName) throws SQLException {
synchronized (checkClosed().getConnectionMutex()) {
ResultSetInternalMethods rs = getOutputParameters(0); // definitely not going to be from ?=
Blob retValue = rs.getBlob(fixParameterName(parameterName));
this.outputParamWasNull = rs.wasNull();
return retValue;
}
}
@Override
public boolean getBoolean(int parameterIndex) throws SQLException {
synchronized (checkClosed().getConnectionMutex()) {
ResultSetInternalMethods rs = getOutputParameters(parameterIndex);
boolean retValue = rs.getBoolean(mapOutputParameterIndexToRsIndex(parameterIndex));
this.outputParamWasNull = rs.wasNull();
return retValue;
}
}
@Override
public boolean getBoolean(String parameterName) throws SQLException {
synchronized (checkClosed().getConnectionMutex()) {
ResultSetInternalMethods rs = getOutputParameters(0); // definitely not going to be from ?=
boolean retValue = rs.getBoolean(fixParameterName(parameterName));
this.outputParamWasNull = rs.wasNull();
return retValue;
}
}
@Override
public byte getByte(int parameterIndex) throws SQLException {
synchronized (checkClosed().getConnectionMutex()) {
ResultSetInternalMethods rs = getOutputParameters(parameterIndex);
byte retValue = rs.getByte(mapOutputParameterIndexToRsIndex(parameterIndex));
this.outputParamWasNull = rs.wasNull();
return retValue;
}
}
@Override
public byte getByte(String parameterName) throws SQLException {
synchronized (checkClosed().getConnectionMutex()) {
ResultSetInternalMethods rs = getOutputParameters(0); // definitely not going to be from ?=
byte retValue = rs.getByte(fixParameterName(parameterName));
this.outputParamWasNull = rs.wasNull();
return retValue;
}
}
@Override
public byte[] getBytes(int parameterIndex) throws SQLException {
synchronized (checkClosed().getConnectionMutex()) {
ResultSetInternalMethods rs = getOutputParameters(parameterIndex);
byte[] retValue = rs.getBytes(mapOutputParameterIndexToRsIndex(parameterIndex));
this.outputParamWasNull = rs.wasNull();
return retValue;
}
}
@Override
public byte[] getBytes(String parameterName) throws SQLException {
synchronized (checkClosed().getConnectionMutex()) {
ResultSetInternalMethods rs = getOutputParameters(0); // definitely not going to be from ?=
byte[] retValue = rs.getBytes(fixParameterName(parameterName));
this.outputParamWasNull = rs.wasNull();
return retValue;
}
}
@Override
public Clob getClob(int parameterIndex) throws SQLException {
synchronized (checkClosed().getConnectionMutex()) {
ResultSetInternalMethods rs = getOutputParameters(parameterIndex);
Clob retValue = rs.getClob(mapOutputParameterIndexToRsIndex(parameterIndex));
this.outputParamWasNull = rs.wasNull();
return retValue;
}
}
@Override
public Clob getClob(String parameterName) throws SQLException {
synchronized (checkClosed().getConnectionMutex()) {
ResultSetInternalMethods rs = getOutputParameters(0); // definitely not going to be from ?=
Clob retValue = rs.getClob(fixParameterName(parameterName));
this.outputParamWasNull = rs.wasNull();
return retValue;
}
}
@Override
public Date getDate(int parameterIndex) throws SQLException {
synchronized (checkClosed().getConnectionMutex()) {
ResultSetInternalMethods rs = getOutputParameters(parameterIndex);
Date retValue = rs.getDate(mapOutputParameterIndexToRsIndex(parameterIndex));
this.outputParamWasNull = rs.wasNull();
return retValue;
}
}
@Override
public Date getDate(int parameterIndex, Calendar cal) throws SQLException {
synchronized (checkClosed().getConnectionMutex()) {
ResultSetInternalMethods rs = getOutputParameters(parameterIndex);
Date retValue = rs.getDate(mapOutputParameterIndexToRsIndex(parameterIndex), cal);
this.outputParamWasNull = rs.wasNull();
return retValue;
}
}
@Override
public Date getDate(String parameterName) throws SQLException {
synchronized (checkClosed().getConnectionMutex()) {
ResultSetInternalMethods rs = getOutputParameters(0); // definitely not going to be from ?=
Date retValue = rs.getDate(fixParameterName(parameterName));
this.outputParamWasNull = rs.wasNull();
return retValue;
}
}
@Override
public Date getDate(String parameterName, Calendar cal) throws SQLException {
synchronized (checkClosed().getConnectionMutex()) {
ResultSetInternalMethods rs = getOutputParameters(0); // definitely not going to be from ?=
Date retValue = rs.getDate(fixParameterName(parameterName), cal);
this.outputParamWasNull = rs.wasNull();
return retValue;
}
}
@Override
public double getDouble(int parameterIndex) throws SQLException {
synchronized (checkClosed().getConnectionMutex()) {
ResultSetInternalMethods rs = getOutputParameters(parameterIndex);
double retValue = rs.getDouble(mapOutputParameterIndexToRsIndex(parameterIndex));
this.outputParamWasNull = rs.wasNull();
return retValue;
}
}
@Override
public double getDouble(String parameterName) throws SQLException {
synchronized (checkClosed().getConnectionMutex()) {
ResultSetInternalMethods rs = getOutputParameters(0); // definitely not going to be from ?=
double retValue = rs.getDouble(fixParameterName(parameterName));
this.outputParamWasNull = rs.wasNull();
return retValue;
}
}
@Override
public float getFloat(int parameterIndex) throws SQLException {
synchronized (checkClosed().getConnectionMutex()) {
ResultSetInternalMethods rs = getOutputParameters(parameterIndex);
float retValue = rs.getFloat(mapOutputParameterIndexToRsIndex(parameterIndex));
this.outputParamWasNull = rs.wasNull();
return retValue;
}
}
@Override
public float getFloat(String parameterName) throws SQLException {
synchronized (checkClosed().getConnectionMutex()) {
ResultSetInternalMethods rs = getOutputParameters(0); // definitely not going to be from ?=
float retValue = rs.getFloat(fixParameterName(parameterName));
this.outputParamWasNull = rs.wasNull();
return retValue;
}
}
@Override
public int getInt(int parameterIndex) throws SQLException {
synchronized (checkClosed().getConnectionMutex()) {
ResultSetInternalMethods rs = getOutputParameters(parameterIndex);
int retValue = rs.getInt(mapOutputParameterIndexToRsIndex(parameterIndex));
this.outputParamWasNull = rs.wasNull();
return retValue;
}
}
@Override
public int getInt(String parameterName) throws SQLException {
synchronized (checkClosed().getConnectionMutex()) {
ResultSetInternalMethods rs = getOutputParameters(0); // definitely not going to be from ?=
int retValue = rs.getInt(fixParameterName(parameterName));
this.outputParamWasNull = rs.wasNull();
return retValue;
}
}
@Override
public long getLong(int parameterIndex) throws SQLException {
synchronized (checkClosed().getConnectionMutex()) {
ResultSetInternalMethods rs = getOutputParameters(parameterIndex);
long retValue = rs.getLong(mapOutputParameterIndexToRsIndex(parameterIndex));
this.outputParamWasNull = rs.wasNull();
return retValue;
}
}
@Override
public long getLong(String parameterName) throws SQLException {
synchronized (checkClosed().getConnectionMutex()) {
ResultSetInternalMethods rs = getOutputParameters(0); // definitely not going to be from ?=
long retValue = rs.getLong(fixParameterName(parameterName));
this.outputParamWasNull = rs.wasNull();
return retValue;
}
}
protected int getNamedParamIndex(String paramName, boolean forOut) throws SQLException {
synchronized (checkClosed().getConnectionMutex()) {
if (this.noAccessToProcedureBodies) {
throw SQLError.createSQLException("No access to parameters by name when connection has been configured not to access procedure bodies",
MysqlErrorNumbers.SQL_STATE_ILLEGAL_ARGUMENT, getExceptionInterceptor());
}
if ((paramName == null) || (paramName.length() == 0)) {
throw SQLError.createSQLException(Messages.getString("CallableStatement.2"), MysqlErrorNumbers.SQL_STATE_ILLEGAL_ARGUMENT,
getExceptionInterceptor());
}
CallableStatementParam namedParamInfo;
if (this.paramInfo == null || (namedParamInfo = this.paramInfo.getParameter(paramName)) == null) {
throw SQLError.createSQLException(Messages.getString("CallableStatement.3", new Object[] { paramName }),
MysqlErrorNumbers.SQL_STATE_ILLEGAL_ARGUMENT, getExceptionInterceptor());
}
if (forOut && !namedParamInfo.isOut) {
throw SQLError.createSQLException(Messages.getString("CallableStatement.5", new Object[] { paramName }),
MysqlErrorNumbers.SQL_STATE_ILLEGAL_ARGUMENT, getExceptionInterceptor());
}
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 SQLError.createSQLException(Messages.getString("CallableStatement.6", new Object[] { paramName }),
MysqlErrorNumbers.SQL_STATE_ILLEGAL_ARGUMENT, getExceptionInterceptor());
}
}
@Override
public Object getObject(int parameterIndex) throws SQLException {
synchronized (checkClosed().getConnectionMutex()) {
CallableStatementParam paramDescriptor = checkIsOutputParam(parameterIndex);
ResultSetInternalMethods rs = getOutputParameters(parameterIndex);
Object retVal = rs.getObjectStoredProc(mapOutputParameterIndexToRsIndex(parameterIndex), paramDescriptor.desiredMysqlType.getJdbcType());
this.outputParamWasNull = rs.wasNull();
return retVal;
}
}
@Override
public Object getObject(int parameterIndex, Map<String, Class<?>> map) throws SQLException {
synchronized (checkClosed().getConnectionMutex()) {
ResultSetInternalMethods rs = getOutputParameters(parameterIndex);
Object retVal = rs.getObject(mapOutputParameterIndexToRsIndex(parameterIndex), map);
this.outputParamWasNull = rs.wasNull();
return retVal;
}
}
@Override
public Object getObject(String parameterName) throws SQLException {
synchronized (checkClosed().getConnectionMutex()) {
ResultSetInternalMethods rs = getOutputParameters(0); // definitely not going to be from ?=
Object retValue = rs.getObject(fixParameterName(parameterName));
this.outputParamWasNull = rs.wasNull();
return retValue;
}
}
@Override
public Object getObject(String parameterName, Map<String, Class<?>> map) throws SQLException {
synchronized (checkClosed().getConnectionMutex()) {
ResultSetInternalMethods rs = getOutputParameters(0); // definitely not going to be from ?=
Object retValue = rs.getObject(fixParameterName(parameterName), map);
this.outputParamWasNull = rs.wasNull();
return retValue;
}
}
@Override
public <T> T getObject(int parameterIndex, Class<T> type) throws SQLException {
synchronized (checkClosed().getConnectionMutex()) {
ResultSetInternalMethods rs = getOutputParameters(parameterIndex);
// remove cast once 1.5, 1.6 EOL'd
T retVal = ((ResultSetImpl) rs).getObject(mapOutputParameterIndexToRsIndex(parameterIndex), type);
this.outputParamWasNull = rs.wasNull();
return retVal;
}
}
@Override
public <T> T getObject(String parameterName, Class<T> type) throws SQLException {
synchronized (checkClosed().getConnectionMutex()) {
ResultSetInternalMethods rs = getOutputParameters(0); // definitely not going to be from ?=
T retValue = ((ResultSetImpl) rs).getObject(fixParameterName(parameterName), type);
this.outputParamWasNull = rs.wasNull();
return retValue;
}
}
/**
* Returns the ResultSet that holds the output parameters, or throws an
* appropriate exception if none exist, or they weren't returned.
*
* @param paramIndex
* parameter index
*
* @return the ResultSet that holds the output parameters
*
* @throws SQLException
* if no output parameters were defined, or if no output
* parameters were returned.
*/
protected ResultSetInternalMethods getOutputParameters(int paramIndex) throws SQLException {
synchronized (checkClosed().getConnectionMutex()) {
this.outputParamWasNull = false;
if (paramIndex == 1 && this.callingStoredFunction && this.returnValueParam != null) {
return this.functionReturnValueResults;
}
if (this.outputParameterResults == null) {
if (this.paramInfo.numberOfParameters() == 0) {
throw SQLError.createSQLException(Messages.getString("CallableStatement.7"), MysqlErrorNumbers.SQL_STATE_ILLEGAL_ARGUMENT,
getExceptionInterceptor());
}
throw SQLError.createSQLException(Messages.getString("CallableStatement.8"), MysqlErrorNumbers.SQL_STATE_GENERAL_ERROR,
getExceptionInterceptor());
}
return this.outputParameterResults;
}
}
@Override
public ParameterMetaData getParameterMetaData() throws SQLException {
synchronized (checkClosed().getConnectionMutex()) {
if (this.placeholderToParameterIndexMap == null) {
return this.paramInfo;
}
return new CallableStatementParamInfo(this.paramInfo);
}
}
@Override
public Ref getRef(int parameterIndex) throws SQLException {
synchronized (checkClosed().getConnectionMutex()) {
ResultSetInternalMethods rs = getOutputParameters(parameterIndex);
Ref retValue = rs.getRef(mapOutputParameterIndexToRsIndex(parameterIndex));
this.outputParamWasNull = rs.wasNull();
return retValue;
}
}
@Override
public Ref getRef(String parameterName) throws SQLException {
synchronized (checkClosed().getConnectionMutex()) {
ResultSetInternalMethods rs = getOutputParameters(0); // definitely not going to be from ?=
Ref retValue = rs.getRef(fixParameterName(parameterName));
this.outputParamWasNull = rs.wasNull();
return retValue;
}
}
@Override
public short getShort(int parameterIndex) throws SQLException {
synchronized (checkClosed().getConnectionMutex()) {
ResultSetInternalMethods rs = getOutputParameters(parameterIndex);
short retValue = rs.getShort(mapOutputParameterIndexToRsIndex(parameterIndex));
this.outputParamWasNull = rs.wasNull();
return retValue;
}
}
@Override
public short getShort(String parameterName) throws SQLException {
synchronized (checkClosed().getConnectionMutex()) {
ResultSetInternalMethods rs = getOutputParameters(0); // definitely not going to be from ?=
short retValue = rs.getShort(fixParameterName(parameterName));
this.outputParamWasNull = rs.wasNull();
return retValue;
}
}
@Override
public String getString(int parameterIndex) throws SQLException {
synchronized (checkClosed().getConnectionMutex()) {
ResultSetInternalMethods rs = getOutputParameters(parameterIndex);
String retValue = rs.getString(mapOutputParameterIndexToRsIndex(parameterIndex));
this.outputParamWasNull = rs.wasNull();
return retValue;
}
}
@Override
public String getString(String parameterName) throws SQLException {
synchronized (checkClosed().getConnectionMutex()) {
ResultSetInternalMethods rs = getOutputParameters(0); // definitely not going to be from ?=
String retValue = rs.getString(fixParameterName(parameterName));
this.outputParamWasNull = rs.wasNull();
return retValue;
}
}
@Override
public Time getTime(int parameterIndex) throws SQLException {
synchronized (checkClosed().getConnectionMutex()) {
ResultSetInternalMethods rs = getOutputParameters(parameterIndex);
Time retValue = rs.getTime(mapOutputParameterIndexToRsIndex(parameterIndex));
this.outputParamWasNull = rs.wasNull();
return retValue;
}
}
@Override
public Time getTime(int parameterIndex, Calendar cal) throws SQLException {
synchronized (checkClosed().getConnectionMutex()) {
ResultSetInternalMethods rs = getOutputParameters(parameterIndex);
Time retValue = rs.getTime(mapOutputParameterIndexToRsIndex(parameterIndex), cal);
this.outputParamWasNull = rs.wasNull();
return retValue;
}
}
@Override
public Time getTime(String parameterName) throws SQLException {
synchronized (checkClosed().getConnectionMutex()) {
ResultSetInternalMethods rs = getOutputParameters(0); // definitely not going to be from ?=
Time retValue = rs.getTime(fixParameterName(parameterName));
this.outputParamWasNull = rs.wasNull();
return retValue;
}
}
@Override
public Time getTime(String parameterName, Calendar cal) throws SQLException {
synchronized (checkClosed().getConnectionMutex()) {
ResultSetInternalMethods rs = getOutputParameters(0); // definitely not going to be from ?=
Time retValue = rs.getTime(fixParameterName(parameterName), cal);
this.outputParamWasNull = rs.wasNull();
return retValue;
}
}
@Override
public Timestamp getTimestamp(int parameterIndex) throws SQLException {
synchronized (checkClosed().getConnectionMutex()) {
ResultSetInternalMethods rs = getOutputParameters(parameterIndex);
Timestamp retValue = rs.getTimestamp(mapOutputParameterIndexToRsIndex(parameterIndex));
this.outputParamWasNull = rs.wasNull();
return retValue;
}
}
@Override
public Timestamp getTimestamp(int parameterIndex, Calendar cal) throws SQLException {
synchronized (checkClosed().getConnectionMutex()) {
ResultSetInternalMethods rs = getOutputParameters(parameterIndex);
Timestamp retValue = rs.getTimestamp(mapOutputParameterIndexToRsIndex(parameterIndex), cal);
this.outputParamWasNull = rs.wasNull();
return retValue;
}
}
@Override
public Timestamp getTimestamp(String parameterName) throws SQLException {
synchronized (checkClosed().getConnectionMutex()) {
ResultSetInternalMethods rs = getOutputParameters(0); // definitely not going to be from ?=
Timestamp retValue = rs.getTimestamp(fixParameterName(parameterName));
this.outputParamWasNull = rs.wasNull();
return retValue;
}
}
@Override
public Timestamp getTimestamp(String parameterName, Calendar cal) throws SQLException {
synchronized (checkClosed().getConnectionMutex()) {
ResultSetInternalMethods rs = getOutputParameters(0); // definitely not going to be from ?=
Timestamp retValue = rs.getTimestamp(fixParameterName(parameterName), cal);
this.outputParamWasNull = rs.wasNull();
return retValue;
}
}
@Override
public URL getURL(int parameterIndex) throws SQLException {
synchronized (checkClosed().getConnectionMutex()) {
ResultSetInternalMethods rs = getOutputParameters(parameterIndex);
URL retValue = rs.getURL(mapOutputParameterIndexToRsIndex(parameterIndex));
this.outputParamWasNull = rs.wasNull();
return retValue;
}
}
@Override
public URL getURL(String parameterName) throws SQLException {
synchronized (checkClosed().getConnectionMutex()) {
ResultSetInternalMethods rs = getOutputParameters(0); // definitely not going to be from ?=
URL retValue = rs.getURL(fixParameterName(parameterName));
this.outputParamWasNull = rs.wasNull();
return retValue;
}
}
protected int mapOutputParameterIndexToRsIndex(int paramIndex) throws SQLException {
synchronized (checkClosed().getConnectionMutex()) {
if (this.returnValueParam != null && paramIndex == 1) {
return 1;
}
checkParameterIndexBounds(paramIndex);
int localParamIndex = paramIndex - 1;
if (this.placeholderToParameterIndexMap != null) {
localParamIndex = this.placeholderToParameterIndexMap[localParamIndex];
}
int rsIndex = this.parameterIndexToRsIndex[localParamIndex];
if (rsIndex == NOT_OUTPUT_PARAMETER_INDICATOR) {
throw SQLError.createSQLException(Messages.getString("CallableStatement.21", new Object[] { paramIndex }),
MysqlErrorNumbers.SQL_STATE_ILLEGAL_ARGUMENT, getExceptionInterceptor());
}
return rsIndex + 1;
}
}
protected void registerOutParameter(int parameterIndex, MysqlType mysqlType) throws SQLException {
CallableStatementParam paramDescriptor = checkIsOutputParam(parameterIndex);
paramDescriptor.desiredMysqlType = mysqlType;
}
@Override
public void registerOutParameter(int parameterIndex, int sqlType) throws SQLException {
try {
MysqlType mt = MysqlType.getByJdbcType(sqlType);
registerOutParameter(parameterIndex, mt);
} catch (FeatureNotAvailableException nae) {
throw SQLError.createSQLFeatureNotSupportedException(Messages.getString("Statement.UnsupportedSQLType") + JDBCType.valueOf(sqlType),
MysqlErrorNumbers.SQL_STATE_DRIVER_NOT_CAPABLE, getExceptionInterceptor());
}
}
@Override
public void registerOutParameter(int parameterIndex, SQLType sqlType) throws SQLException {
if (sqlType instanceof MysqlType) {
registerOutParameter(parameterIndex, (MysqlType) sqlType);
} else {
registerOutParameter(parameterIndex, sqlType.getVendorTypeNumber());
}
}
protected void registerOutParameter(int parameterIndex, MysqlType mysqlType, @SuppressWarnings("unused") int scale) throws SQLException {
registerOutParameter(parameterIndex, mysqlType); // TODO is that correct that we ignore scale?
}
@Override
public void registerOutParameter(int parameterIndex, int sqlType, int scale) throws SQLException {
registerOutParameter(parameterIndex, sqlType); // TODO is that correct that we ignore scale?
}
@Override
public void registerOutParameter(int parameterIndex, SQLType sqlType, int scale) throws SQLException {
if (sqlType instanceof MysqlType) {
registerOutParameter(parameterIndex, (MysqlType) sqlType, scale);
} else {
registerOutParameter(parameterIndex, sqlType.getVendorTypeNumber(), scale);
}
}
protected void registerOutParameter(int parameterIndex, MysqlType mysqlType, @SuppressWarnings("unused") String typeName) throws SQLException {
registerOutParameter(parameterIndex, mysqlType); // TODO is that correct that we ignore typeName?
}
@Override
public void registerOutParameter(int parameterIndex, int sqlType, String typeName) throws SQLException {
try {
MysqlType mt = MysqlType.getByJdbcType(sqlType);
registerOutParameter(parameterIndex, mt, typeName);
} catch (FeatureNotAvailableException nae) {
throw SQLError.createSQLFeatureNotSupportedException(Messages.getString("Statement.UnsupportedSQLType") + JDBCType.valueOf(sqlType),
MysqlErrorNumbers.SQL_STATE_DRIVER_NOT_CAPABLE, getExceptionInterceptor());
}
}
@Override
public void registerOutParameter(int parameterIndex, SQLType sqlType, String typeName) throws SQLException {
if (sqlType instanceof MysqlType) {
registerOutParameter(parameterIndex, (MysqlType) sqlType, typeName);
} else {
registerOutParameter(parameterIndex, sqlType.getVendorTypeNumber(), typeName);
}
}
@Override
public void registerOutParameter(String parameterName, int sqlType) throws SQLException {
synchronized (checkClosed().getConnectionMutex()) {
registerOutParameter(getNamedParamIndex(parameterName, true), sqlType);
}
}
@Override
public void registerOutParameter(String parameterName, SQLType sqlType) throws SQLException {
if (sqlType instanceof MysqlType) {
registerOutParameter(getNamedParamIndex(parameterName, true), (MysqlType) sqlType);
} else {
registerOutParameter(getNamedParamIndex(parameterName, true), sqlType.getVendorTypeNumber());
}
}
@Override
public void registerOutParameter(String parameterName, int sqlType, int scale) throws SQLException {
registerOutParameter(getNamedParamIndex(parameterName, true), sqlType, scale);
}
@Override
public void registerOutParameter(String parameterName, SQLType sqlType, int scale) throws SQLException {
if (sqlType instanceof MysqlType) {
registerOutParameter(getNamedParamIndex(parameterName, true), (MysqlType) sqlType, scale);
} else {
registerOutParameter(getNamedParamIndex(parameterName, true), sqlType.getVendorTypeNumber(), scale);
}
}
@Override
public void registerOutParameter(String parameterName, int sqlType, String typeName) throws SQLException {
registerOutParameter(getNamedParamIndex(parameterName, true), sqlType, typeName);
}
@Override
public void registerOutParameter(String parameterName, SQLType sqlType, String typeName) throws SQLException {
if (sqlType instanceof MysqlType) {
registerOutParameter(getNamedParamIndex(parameterName, true), (MysqlType) sqlType, typeName);
} else {
registerOutParameter(parameterName, sqlType.getVendorTypeNumber(), typeName);
}
}
/**
* Issues a second query to retrieve all output parameters.
*
* @throws SQLException
* if an error occurs.
*/
private void retrieveOutParams() throws SQLException {
synchronized (checkClosed().getConnectionMutex()) {
int numParameters = this.paramInfo.numberOfParameters();
this.parameterIndexToRsIndex = new int[numParameters];
for (int i = 0; i < numParameters; i++) {
this.parameterIndexToRsIndex[i] = NOT_OUTPUT_PARAMETER_INDICATOR;
}
int localParamIndex = 0;
if (numParameters > 0) {
StringBuilder outParameterQuery = new StringBuilder("SELECT ");
boolean firstParam = true;
boolean hadOutputParams = false;
for (Iterator<CallableStatementParam> paramIter = this.paramInfo.iterator(); paramIter.hasNext();) {
CallableStatementParam retrParamInfo = paramIter.next();
if (retrParamInfo.isOut) {
hadOutputParams = true;
this.parameterIndexToRsIndex[retrParamInfo.index] = localParamIndex++;
if (retrParamInfo.paramName == null) {
retrParamInfo.paramName = "nullnp" + retrParamInfo.index;
}
String outParameterName = mangleParameterName(retrParamInfo.paramName);
if (!firstParam) {
outParameterQuery.append(",");
} else {
firstParam = false;
}
if (!outParameterName.startsWith("@")) {
outParameterQuery.append('@');
}
outParameterQuery.append(outParameterName);
}
}
if (hadOutputParams) {
// We can't use 'ourself' to execute this query, or any pending result sets would be overwritten
java.sql.Statement outParameterStmt = null;
java.sql.ResultSet outParamRs = null;
try {
outParameterStmt = this.connection.createStatement();
outParamRs = outParameterStmt.executeQuery(outParameterQuery.toString());
this.outputParameterResults = this.resultSetFactory.createFromResultsetRows(outParamRs.getConcurrency(), outParamRs.getType(),
((com.mysql.cj.jdbc.result.ResultSetInternalMethods) outParamRs).getRows()); // note, doesn't work for updatable result sets
if (!this.outputParameterResults.next()) {
this.outputParameterResults.close();
this.outputParameterResults = null;
}
} finally {
if (outParameterStmt != null) {
outParameterStmt.close();
}
}
} else {
this.outputParameterResults = null;
}
} else {
this.outputParameterResults = null;
}
}
}
@Override
public void setAsciiStream(String parameterName, InputStream x, int length) throws SQLException {
setAsciiStream(getNamedParamIndex(parameterName, false), x, length);
}
@Override
public void setBigDecimal(String parameterName, BigDecimal x) throws SQLException {
setBigDecimal(getNamedParamIndex(parameterName, false), x);
}
@Override
public void setBinaryStream(String parameterName, InputStream x, int length) throws SQLException {
setBinaryStream(getNamedParamIndex(parameterName, false), x, length);
}
@Override
public void setBoolean(String parameterName, boolean x) throws SQLException {
setBoolean(getNamedParamIndex(parameterName, false), x);
}
@Override
public void setByte(String parameterName, byte x) throws SQLException {
setByte(getNamedParamIndex(parameterName, false), x);
}
@Override
public void setBytes(String parameterName, byte[] x) throws SQLException {
setBytes(getNamedParamIndex(parameterName, false), x);
}
@Override
public void setCharacterStream(String parameterName, Reader reader, int length) throws SQLException {
setCharacterStream(getNamedParamIndex(parameterName, false), reader, length);
}
@Override
public void setDate(String parameterName, Date x) throws SQLException {
setDate(getNamedParamIndex(parameterName, false), x);
}
@Override
public void setDate(String parameterName, Date x, Calendar cal) throws SQLException {
setDate(getNamedParamIndex(parameterName, false), x, cal);
}
@Override
public void setDouble(String parameterName, double x) throws SQLException {
setDouble(getNamedParamIndex(parameterName, false), x);
}
@Override
public void setFloat(String parameterName, float x) throws SQLException {
setFloat(getNamedParamIndex(parameterName, false), x);
}
private void setInOutParamsOnServer() throws SQLException {
synchronized (checkClosed().getConnectionMutex()) {
if (this.paramInfo.numParameters > 0) {
for (Iterator<CallableStatementParam> paramIter = this.paramInfo.iterator(); paramIter.hasNext();) {
CallableStatementParam inParamInfo = paramIter.next();
if (inParamInfo.isOut && inParamInfo.isIn) {
if (inParamInfo.paramName == null) {
inParamInfo.paramName = "nullnp" + inParamInfo.index;
}
String inOutParameterName = mangleParameterName(inParamInfo.paramName);
StringBuilder queryBuf = new StringBuilder(4 + inOutParameterName.length() + 1 + 1);
queryBuf.append("SET ");
queryBuf.append(inOutParameterName);
queryBuf.append("=?");
ClientPreparedStatement setPstmt = null;
try {
setPstmt = ((Wrapper) this.connection.clientPrepareStatement(queryBuf.toString())).unwrap(ClientPreparedStatement.class);
setPstmt.getQueryBindings().setFromBindValue(0, ((PreparedQuery) this.query).getQueryBindings().getBindValues()[inParamInfo.index]);
setPstmt.executeUpdate();
} finally {
if (setPstmt != null) {
setPstmt.close();
}
}
}
}
}
}
}
@Override
public void setInt(String parameterName, int x) throws SQLException {
setInt(getNamedParamIndex(parameterName, false), x);
}
@Override
public void setLong(String parameterName, long x) throws SQLException {
setLong(getNamedParamIndex(parameterName, false), x);
}
@Override
public void setNull(String parameterName, int sqlType) throws SQLException {
setNull(getNamedParamIndex(parameterName, false), sqlType);
}
@Override
public void setNull(String parameterName, int sqlType, String typeName) throws SQLException {
setNull(getNamedParamIndex(parameterName, false), sqlType, typeName);
}
@Override
public void setObject(String parameterName, Object x) throws SQLException {
setObject(getNamedParamIndex(parameterName, false), x);
}
@Override
public void setObject(String parameterName, Object x, int targetSqlType) throws SQLException {
setObject(getNamedParamIndex(parameterName, false), x, targetSqlType);
}
@Override
public void setObject(String parameterName, Object x, SQLType targetSqlType) throws SQLException {
synchronized (checkClosed().getConnectionMutex()) {
setObject(getNamedParamIndex(parameterName, false), x, targetSqlType);
}
}
@Override
public void setObject(String parameterName, Object x, int targetSqlType, int scale) throws SQLException {
setObject(getNamedParamIndex(parameterName, false), x, targetSqlType, scale);
}
@Override
public void setObject(String parameterName, Object x, SQLType targetSqlType, int scaleOrLength) throws SQLException {
synchronized (checkClosed().getConnectionMutex()) {
setObject(getNamedParamIndex(parameterName, false), x, targetSqlType, scaleOrLength);
}
}
private void setOutParams() throws SQLException {
synchronized (checkClosed().getConnectionMutex()) {
if (this.paramInfo.numParameters > 0) {
for (Iterator<CallableStatementParam> paramIter = this.paramInfo.iterator(); paramIter.hasNext();) {
CallableStatementParam outParamInfo = paramIter.next();
if (!this.callingStoredFunction && outParamInfo.isOut) {
if (outParamInfo.paramName == null) {
outParamInfo.paramName = "nullnp" + outParamInfo.index;
}
String outParameterName = mangleParameterName(outParamInfo.paramName);
int outParamIndex = 0;
if (this.placeholderToParameterIndexMap == null) {
outParamIndex = outParamInfo.index + 1;
} else {
// Find it, todo: remove this linear search
boolean found = false;
for (int i = 0; i < this.placeholderToParameterIndexMap.length; i++) {
if (this.placeholderToParameterIndexMap[i] == outParamInfo.index) {
outParamIndex = i + 1; /* JDBC is 1-based */
found = true;
break;
}
}
if (!found) {
throw SQLError.createSQLException(Messages.getString("CallableStatement.21", new Object[] { outParamInfo.paramName }),
MysqlErrorNumbers.SQL_STATE_ILLEGAL_ARGUMENT, getExceptionInterceptor());
}
}
this.setBytes(outParamIndex, StringUtils.getBytes(outParameterName, this.charEncoding), false);
}
}
}
}
}
@Override
public void setShort(String parameterName, short x) throws SQLException {
setShort(getNamedParamIndex(parameterName, false), x);
}
@Override
public void setString(String parameterName, String x) throws SQLException {
setString(getNamedParamIndex(parameterName, false), x);
}
@Override
public void setTime(String parameterName, Time x) throws SQLException {
setTime(getNamedParamIndex(parameterName, false), x);
}
@Override
public void setTime(String parameterName, Time x, Calendar cal) throws SQLException {
setTime(getNamedParamIndex(parameterName, false), x, cal);
}
@Override
public void setTimestamp(String parameterName, Timestamp x) throws SQLException {
setTimestamp(getNamedParamIndex(parameterName, false), x);
}
@Override
public void setTimestamp(String parameterName, Timestamp x, Calendar cal) throws SQLException {
setTimestamp(getNamedParamIndex(parameterName, false), x, cal);
}
@Override
public void setURL(String parameterName, URL val) throws SQLException {
setURL(getNamedParamIndex(parameterName, false), val);
}
@Override
public boolean wasNull() throws SQLException {
synchronized (checkClosed().getConnectionMutex()) {
return this.outputParamWasNull;
}
}
@Override
public int[] executeBatch() throws SQLException {
return Util.truncateAndConvertToInt(executeLargeBatch());
}
@Override
protected int getParameterIndexOffset() {
if (this.callingStoredFunction) {
return -1;
}
return super.getParameterIndexOffset();
}
@Override
public void setAsciiStream(String parameterName, InputStream x) throws SQLException {
setAsciiStream(getNamedParamIndex(parameterName, false), x);
}
@Override
public void setAsciiStream(String parameterName, InputStream x, long length) throws SQLException {
setAsciiStream(getNamedParamIndex(parameterName, false), x, length);
}
@Override
public void setBinaryStream(String parameterName, InputStream x) throws SQLException {
setBinaryStream(getNamedParamIndex(parameterName, false), x);
}
@Override
public void setBinaryStream(String parameterName, InputStream x, long length) throws SQLException {
setBinaryStream(getNamedParamIndex(parameterName, false), x, length);
}
@Override
public void setBlob(String parameterName, Blob x) throws SQLException {
setBlob(getNamedParamIndex(parameterName, false), x);
}
@Override
public void setBlob(String parameterName, InputStream inputStream) throws SQLException {
setBlob(getNamedParamIndex(parameterName, false), inputStream);
}
@Override
public void setBlob(String parameterName, InputStream inputStream, long length) throws SQLException {
setBlob(getNamedParamIndex(parameterName, false), inputStream, length);
}
@Override
public void setCharacterStream(String parameterName, Reader reader) throws SQLException {
setCharacterStream(getNamedParamIndex(parameterName, false), reader);
}
@Override
public void setCharacterStream(String parameterName, Reader reader, long length) throws SQLException {
setCharacterStream(getNamedParamIndex(parameterName, false), reader, length);
}
@Override
public void setClob(String parameterName, Clob x) throws SQLException {
setClob(getNamedParamIndex(parameterName, false), x);
}
@Override
public void setClob(String parameterName, Reader reader) throws SQLException {
setClob(getNamedParamIndex(parameterName, false), reader);
}
@Override
public void setClob(String parameterName, Reader reader, long length) throws SQLException {
setClob(getNamedParamIndex(parameterName, false), reader, length);
}
@Override
public void setNCharacterStream(String parameterName, Reader value) throws SQLException {
setNCharacterStream(getNamedParamIndex(parameterName, false), value);
}
@Override
public void setNCharacterStream(String parameterName, Reader value, long length) throws SQLException {
setNCharacterStream(getNamedParamIndex(parameterName, false), value, length);
}
/**
* Check whether the stored procedure alters any data or is safe for read-only usage.
*
* @return true if procedure does not alter data
* @throws SQLException
* if a database access error occurs or this method is called on a closed PreparedStatement
*/
private boolean checkReadOnlyProcedure() throws SQLException {
synchronized (checkClosed().getConnectionMutex()) {
if (this.noAccessToProcedureBodies) {
return false;
}
if (this.paramInfo.isReadOnlySafeChecked) {
return this.paramInfo.isReadOnlySafeProcedure;
}
ResultSet rs = null;
java.sql.PreparedStatement ps = null;
try {
String procName = extractProcedureName();
String db = this.getCurrentDatabase();
if (procName.indexOf(".") != -1) {
db = procName.substring(0, procName.indexOf("."));
if (StringUtils.startsWithIgnoreCaseAndWs(db, "`") && db.trim().endsWith("`")) {
db = db.substring(1, db.length() - 1);
}
procName = procName.substring(procName.indexOf(".") + 1);
procName = StringUtils.toString(StringUtils.stripEnclosure(StringUtils.getBytes(procName), "`", "`"));
}
ps = this.connection.prepareStatement("SELECT SQL_DATA_ACCESS FROM information_schema.routines WHERE routine_schema = ? AND routine_name = ?");
ps.setMaxRows(0);
ps.setFetchSize(0);
ps.setString(1, db);
ps.setString(2, procName);
rs = ps.executeQuery();
if (rs.next()) {
String sqlDataAccess = rs.getString(1);
if ("READS SQL DATA".equalsIgnoreCase(sqlDataAccess) || "NO SQL".equalsIgnoreCase(sqlDataAccess)) {
synchronized (this.paramInfo) {
this.paramInfo.isReadOnlySafeChecked = true;
this.paramInfo.isReadOnlySafeProcedure = true;
}
return true;
}
}
} catch (SQLException e) {
// swallow the Exception
} finally {
if (rs != null) {
rs.close();
}
if (ps != null) {
ps.close();
}
}
this.paramInfo.isReadOnlySafeChecked = false;
this.paramInfo.isReadOnlySafeProcedure = false;
}
return false;
}
@Override
protected boolean checkReadOnlySafeStatement() throws SQLException {
if (QueryInfo.isReadOnlySafeQuery(((PreparedQuery) this.query).getOriginalSql(), this.session.getServerSession().isNoBackslashEscapesSet())) {
String sql = ((PreparedQuery) this.query).getOriginalSql();
int statementKeywordPos = QueryInfo.indexOfStatementKeyword(sql, this.session.getServerSession().isNoBackslashEscapesSet());
if (StringUtils.startsWithIgnoreCaseAndWs(sql, "CALL", statementKeywordPos)
|| StringUtils.startsWithIgnoreCaseAndWs(sql, "SELECT", statementKeywordPos)) {
// "CALL" and "SELECT" are read-only safe but the routine they call may not be.
if (!this.connection.isReadOnly()) { // Only proceed with checking the routine body if really needed.
return true;
}
return checkReadOnlyProcedure();
}
return true;
}
return !this.connection.isReadOnly();
}
@Override
public RowId getRowId(int parameterIndex) throws SQLException {
ResultSetInternalMethods rs = getOutputParameters(parameterIndex);
RowId retValue = rs.getRowId(mapOutputParameterIndexToRsIndex(parameterIndex));
this.outputParamWasNull = rs.wasNull();
return retValue;
}
@Override
public RowId getRowId(String parameterName) throws SQLException {
ResultSetInternalMethods rs = getOutputParameters(0); // definitely not going to be from ?=
RowId retValue = rs.getRowId(fixParameterName(parameterName));
this.outputParamWasNull = rs.wasNull();
return retValue;
}
@Override
public void setRowId(String parameterName, RowId x) throws SQLException {
setRowId(getNamedParamIndex(parameterName, false), x);
}
@Override
public void setNString(String parameterName, String value) throws SQLException {
setNString(getNamedParamIndex(parameterName, false), value);
}
@Override
public void setNClob(String parameterName, NClob value) throws SQLException {
setNClob(getNamedParamIndex(parameterName, false), value);
}
@Override
public void setNClob(String parameterName, Reader reader) throws SQLException {
setNClob(getNamedParamIndex(parameterName, false), reader);
}
@Override
public void setNClob(String parameterName, Reader reader, long length) throws SQLException {
setNClob(getNamedParamIndex(parameterName, false), reader, length);
}
@Override
public void setSQLXML(String parameterName, SQLXML xmlObject) throws SQLException {
setSQLXML(getNamedParamIndex(parameterName, false), xmlObject);
}
@Override
public SQLXML getSQLXML(int parameterIndex) throws SQLException {
ResultSetInternalMethods rs = getOutputParameters(parameterIndex);
SQLXML retValue = rs.getSQLXML(mapOutputParameterIndexToRsIndex(parameterIndex));
this.outputParamWasNull = rs.wasNull();
return retValue;
}
@Override
public SQLXML getSQLXML(String parameterName) throws SQLException {
ResultSetInternalMethods rs = getOutputParameters(0); // definitely not going to be from ?=
SQLXML retValue = rs.getSQLXML(fixParameterName(parameterName));
this.outputParamWasNull = rs.wasNull();
return retValue;
}
@Override
public String getNString(int parameterIndex) throws SQLException {
ResultSetInternalMethods rs = getOutputParameters(parameterIndex);
String retValue = rs.getNString(mapOutputParameterIndexToRsIndex(parameterIndex));
this.outputParamWasNull = rs.wasNull();
return retValue;
}
@Override
public String getNString(String parameterName) throws SQLException {
ResultSetInternalMethods rs = getOutputParameters(0); // definitely not going to be from ?=
String retValue = rs.getNString(fixParameterName(parameterName));
this.outputParamWasNull = rs.wasNull();
return retValue;
}
@Override
public Reader getNCharacterStream(int parameterIndex) throws SQLException {
ResultSetInternalMethods rs = getOutputParameters(parameterIndex);
Reader retValue = rs.getNCharacterStream(mapOutputParameterIndexToRsIndex(parameterIndex));
this.outputParamWasNull = rs.wasNull();
return retValue;
}
@Override
public Reader getNCharacterStream(String parameterName) throws SQLException {
ResultSetInternalMethods rs = getOutputParameters(0); // definitely not going to be from ?=
Reader retValue = rs.getNCharacterStream(fixParameterName(parameterName));
this.outputParamWasNull = rs.wasNull();
return retValue;
}
@Override
public Reader getCharacterStream(int parameterIndex) throws SQLException {
ResultSetInternalMethods rs = getOutputParameters(parameterIndex);
Reader retValue = rs.getCharacterStream(mapOutputParameterIndexToRsIndex(parameterIndex));
this.outputParamWasNull = rs.wasNull();
return retValue;
}
@Override
public Reader getCharacterStream(String parameterName) throws SQLException {
ResultSetInternalMethods rs = getOutputParameters(0); // definitely not going to be from ?=
Reader retValue = rs.getCharacterStream(fixParameterName(parameterName));
this.outputParamWasNull = rs.wasNull();
return retValue;
}
@Override
public NClob getNClob(int parameterIndex) throws SQLException {
ResultSetInternalMethods rs = getOutputParameters(parameterIndex);
NClob retValue = rs.getNClob(mapOutputParameterIndexToRsIndex(parameterIndex));
this.outputParamWasNull = rs.wasNull();
return retValue;
}
@Override
public NClob getNClob(String parameterName) throws SQLException {
ResultSetInternalMethods rs = getOutputParameters(0); // definitely not going to be from ?=
NClob retValue = rs.getNClob(fixParameterName(parameterName));
this.outputParamWasNull = rs.wasNull();
return retValue;
}
/**
* Converts the given string to bytes, using the connection's character
* encoding.
*
* @param s
* string
* @return bytes
*/
protected byte[] s2b(String s) {
return s == null ? null : StringUtils.getBytes(s, this.charEncoding);
}
@Override
public long executeLargeUpdate() throws SQLException {
synchronized (checkClosed().getConnectionMutex()) {
long returnVal = -1;
checkStreamability();
if (this.callingStoredFunction) {
execute();
return -1;
}
setInOutParamsOnServer();
setOutParams();
returnVal = super.executeLargeUpdate();
retrieveOutParams();
return returnVal;
}
}
@Override
public long[] executeLargeBatch() throws SQLException {
if (this.hasOutputParams) {
throw SQLError.createSQLException("Can't call executeBatch() on CallableStatement with OUTPUT parameters",
MysqlErrorNumbers.SQL_STATE_ILLEGAL_ARGUMENT, getExceptionInterceptor());
}
return super.executeLargeBatch();
}
}
⏎ com/mysql/cj/jdbc/CallableStatement.java
Or download all of them as a single archive file:
File name: mysql-connector-java-user-impl-8.0.31.zip File size: 429580 bytes Release date: 2022-09-03 Download
⇒ Downloading mysql-connector-java-5.1.40.zip
⇐ Source Code for Connector/J 8.0.31 - User API
2023-05-09, ≈28🔥, 0💬
Popular Posts:
HttpComponents Client Source Code Files are provided in the source package file, httpcomponents-clie...
maven-core-3.8.6.jar is the JAR file for Apache Maven 3.8.6 Core module. Apache Maven is a software ...
What Is mail.jar of JavaMail 1.3? I got the JAR file from javamail-1_3.zip. mail.jar in javamail-1_3...
JDK 11 jdk.xml.dom.jmod is the JMOD file for JDK 11 XML DOM module. JDK 11 XML DOM module compiled c...
Commons Pool provides an Object-pooling API, with three major aspects: 1. A generic object pool inte...