80
83
public class ConnectionImpl extends ConnectionPropertiesImpl implements
86
private static final long serialVersionUID = 2877471301981509474L;
88
private static final SQLPermission SET_NETWORK_TIMEOUT_PERM = new SQLPermission("setNetworkTimeout");
90
private static final SQLPermission ABORT_PERM = new SQLPermission("abort");
82
92
private static final String JDBC_LOCAL_CHARACTER_SET_RESULTS = "jdbc.local.character_set_results";
84
public String getHost() {
88
private MySQLConnection proxy = null;
90
public boolean isProxySet(){
91
return this.proxy != null;
94
public void setProxy(MySQLConnection proxy) {
98
// We have to proxy ourselves when we're load balanced so that
99
// statements get routed to the right physical connection
100
// (when load balanced, we're a "logical" connection)
101
private MySQLConnection getProxy() {
102
return (proxy != null) ? proxy : (MySQLConnection) this;
105
public MySQLConnection getLoadBalanceSafeProxy() {
106
return this.getProxy();
94
public String getHost() {
98
private MySQLConnection proxy = null;
100
private InvocationHandler realProxy = null;
102
public boolean isProxySet(){
103
return this.proxy != null;
106
public void setProxy(MySQLConnection proxy) {
110
public void setRealProxy(InvocationHandler proxy) {
111
this.realProxy = proxy;
114
// We have to proxy ourselves when we're load balanced so that
115
// statements get routed to the right physical connection
116
// (when load balanced, we're a "logical" connection)
117
private MySQLConnection getProxy() {
118
return (proxy != null) ? proxy : (MySQLConnection) this;
121
public MySQLConnection getLoadBalanceSafeProxy() {
122
return this.getProxy();
125
public Object getConnectionMutex() {
126
return (this.realProxy != null) ? this.realProxy : this;
110
129
class ExceptionInterceptorChain implements ExceptionInterceptor {
130
List<Extension> interceptors;
113
132
ExceptionInterceptorChain(String interceptorClasses) throws SQLException {
114
133
interceptors = Util.loadExtensions(ConnectionImpl.this, props, interceptorClasses, "Connection.BadExceptionInterceptor", this);
136
void addRingZero(ExceptionInterceptor interceptor) throws SQLException {
137
interceptors.add(0, interceptor);
117
140
public SQLException interceptException(SQLException sqlEx, Connection conn) {
118
141
if (interceptors != null) {
119
Iterator iter = interceptors.iterator();
142
Iterator<Extension> iter = interceptors.iterator();
121
144
while (iter.hasNext()) {
122
145
sqlEx = ((ExceptionInterceptor)iter.next()).interceptException(sqlEx, ConnectionImpl.this);
229
252
* Map mysql transaction isolation level name to
230
253
* java.sql.Connection.TRANSACTION_XXX
232
private static Map mapTransIsolationNameToValue = null;
255
private static Map<String, Integer> mapTransIsolationNameToValue = null;
234
257
/** Null logger shared by all connections at startup */
235
258
private static final Log NULL_LOGGER = new NullLogger(LOGGER_INSTANCE_NAME);
237
private static Map roundRobinStatsMap;
239
private static final Map serverCollationByUrl = new HashMap();
241
private static final Map serverConfigByUrl = new HashMap();
260
protected static Map<?, ?> roundRobinStatsMap;
262
private static final Map<String, Map<Long, String>> serverCollationByUrl = new HashMap<String, Map<Long,String>>();
265
* Map for Java charsets of user defined charsets. We can't map them statically, because
266
* they can be different for different server URLs.
268
private static final Map<String, Map<Integer, String>> serverJavaCharsetByUrl = new HashMap<String, Map<Integer,String>>();
270
* Map for user defined charsets. We can't map them statically, because
271
* they can be different for different server URLs.
273
private static final Map<String, Map<Integer, String>> serverCustomCharsetByUrl = new HashMap<String, Map<Integer,String>>();
275
* Map for user defined charsets. We can't map them statically, because
276
* they can be different for different server URLs.
278
private static final Map<String, Map<String, Integer>> serverCustomMblenByUrl = new HashMap<String, Map<String, Integer>>();
280
private CacheAdapter<String, Map<String, String>> serverConfigCache;
243
282
private long queryTimeCount;
244
283
private double queryTimeSum;
248
287
private transient Timer cancelTimer;
250
private List connectionLifecycleInterceptors;
289
private List<Extension> connectionLifecycleInterceptors;
252
private static final Constructor JDBC_4_CONNECTION_CTOR;
291
private static final Constructor<?> JDBC_4_CONNECTION_CTOR;
254
293
private static final int DEFAULT_RESULT_SET_TYPE = ResultSet.TYPE_FORWARD_ONLY;
256
295
private static final int DEFAULT_RESULT_SET_CONCURRENCY = ResultSet.CONCUR_READ_ONLY;
259
mapTransIsolationNameToValue = new HashMap(8);
260
mapTransIsolationNameToValue.put("READ-UNCOMMITED", Integer.valueOf(
261
TRANSACTION_READ_UNCOMMITTED));
262
mapTransIsolationNameToValue.put("READ-UNCOMMITTED", Integer.valueOf(
263
TRANSACTION_READ_UNCOMMITTED));
264
mapTransIsolationNameToValue.put("READ-COMMITTED", Integer.valueOf(
265
TRANSACTION_READ_COMMITTED));
266
mapTransIsolationNameToValue.put("REPEATABLE-READ", Integer.valueOf(
267
TRANSACTION_REPEATABLE_READ));
268
mapTransIsolationNameToValue.put("SERIALIZABLE", Integer.valueOf(
269
TRANSACTION_SERIALIZABLE));
298
mapTransIsolationNameToValue = new HashMap<String, Integer>(8);
299
mapTransIsolationNameToValue.put("READ-UNCOMMITED", TRANSACTION_READ_UNCOMMITTED);
300
mapTransIsolationNameToValue.put("READ-UNCOMMITTED", TRANSACTION_READ_UNCOMMITTED);
301
mapTransIsolationNameToValue.put("READ-COMMITTED", TRANSACTION_READ_COMMITTED);
302
mapTransIsolationNameToValue.put("REPEATABLE-READ", TRANSACTION_REPEATABLE_READ);
303
mapTransIsolationNameToValue.put("SERIALIZABLE", TRANSACTION_SERIALIZABLE);
271
305
if (Util.isJdbc4()) {
339
372
return sqlExceptionWithNewMessage;
342
public synchronized Timer getCancelTimer() {
343
if (cancelTimer == null) {
344
boolean createdNamedTimer = false;
346
// Use reflection magic to try this on JDK's 1.5 and newer, fallback to non-named
347
// timer on older VMs.
349
Constructor ctr = Timer.class.getConstructor(new Class[] {String.class, Boolean.TYPE});
351
cancelTimer = (Timer)ctr.newInstance(new Object[] { "MySQL Statement Cancellation Timer", Boolean.TRUE});
352
createdNamedTimer = true;
353
} catch (Throwable t) {
354
createdNamedTimer = false;
357
if (!createdNamedTimer) {
358
cancelTimer = new Timer(true);
375
public Timer getCancelTimer() {
376
synchronized (getConnectionMutex()) {
377
if (cancelTimer == null) {
378
boolean createdNamedTimer = false;
380
// Use reflection magic to try this on JDK's 1.5 and newer, fallback to non-named
381
// timer on older VMs.
383
Constructor<Timer> ctr = Timer.class.getConstructor(new Class[] {String.class, Boolean.TYPE});
385
cancelTimer = ctr.newInstance(new Object[] { "MySQL Statement Cancellation Timer", Boolean.TRUE});
386
createdNamedTimer = true;
387
} catch (Throwable t) {
388
createdNamedTimer = false;
391
if (!createdNamedTimer) {
392
cancelTimer = new Timer(true);
942
993
if (sortedCollationMap == null) {
943
sortedCollationMap = new TreeMap();
994
sortedCollationMap = new TreeMap<Long, String>();
995
javaCharset = new HashMap<Integer, String>();
996
customCharset = new HashMap<Integer, String>();
997
customMblen = new HashMap<String, Integer>();
945
999
stmt = getMetadataSafeStatement();
948
.executeQuery("SHOW COLLATION");
950
while (results.next()) {
951
String charsetName = results.getString(2);
952
Integer charsetIndex = Integer.valueOf(results.getInt(3));
954
sortedCollationMap.put(charsetIndex, charsetName);
1002
results = stmt.executeQuery("SHOW COLLATION");
1003
if (versionMeetsMinimum(5, 0, 0)) {
1004
Util.resultSetToMap(sortedCollationMap, results, 3, 2);
1006
while (results.next()) {
1007
sortedCollationMap.put(results.getLong(3), results.getString(2));
1010
} catch (SQLException ex) {
1011
if (ex.getErrorCode() != MysqlErrorNumbers.ER_MUST_CHANGE_PASSWORD || getDisconnectOnExpiredPasswords()) {
1016
for (Iterator<Map.Entry<Long, String>> indexIter = sortedCollationMap.entrySet().iterator(); indexIter.hasNext();) {
1017
Map.Entry<Long, String> indexEntry = indexIter.next();
1019
int collationIndex = indexEntry.getKey().intValue();
1020
String charsetName = indexEntry.getValue();
1022
javaCharset.put(collationIndex, getJavaEncodingForMysqlEncoding(charsetName));
1024
// if no static map for charsetIndex
1025
// or server has a different mapping then our static map,
1026
// adding it to custom map
1027
if (collationIndex >= CharsetMapping.MAP_SIZE ||
1028
!charsetName.equals(CharsetMapping.STATIC_INDEX_TO_MYSQL_CHARSET_MAP.get(collationIndex))) {
1029
customCharset.put(collationIndex, charsetName);
1032
// if no static map for charsetName adding to custom map
1033
if (!CharsetMapping.STATIC_CHARSET_TO_NUM_BYTES_MAP.containsKey(charsetName) &&
1034
!CharsetMapping.STATIC_4_0_CHARSET_TO_NUM_BYTES_MAP.containsKey(charsetName)) {
1035
customMblen.put(charsetName, null);
1039
// if there is a number of custom charsets we should execute SHOW CHARACTER SET to know theirs mblen
1040
if (customMblen.size() > 0) {
1042
results = stmt.executeQuery("SHOW CHARACTER SET");
1043
while (results.next()) {
1044
String charsetName = results.getString("Charset");
1045
if (customMblen.containsKey(charsetName)) {
1046
customMblen.put(charsetName, results.getInt("Maxlen"));
1049
} catch (SQLException ex) {
1050
if (ex.getErrorCode() != MysqlErrorNumbers.ER_MUST_CHANGE_PASSWORD || getDisconnectOnExpiredPasswords()) {
957
1056
if (getCacheServerConfiguration()) {
958
synchronized (serverConfigByUrl) {
959
serverCollationByUrl.put(getURL(),
1057
synchronized (serverCollationByUrl) {
1058
serverCollationByUrl.put(getURL(), sortedCollationMap);
1059
serverJavaCharsetByUrl.put(getURL(), javaCharset);
1060
serverCustomCharsetByUrl.put(getURL(), customCharset);
1061
serverCustomMblenByUrl.put(getURL(), customMblen);
966
// Now, merge with what we already know
967
int highestIndex = ((Integer) sortedCollationMap.lastKey())
970
if (CharsetMapping.INDEX_TO_CHARSET.length > highestIndex) {
971
highestIndex = CharsetMapping.INDEX_TO_CHARSET.length;
974
this.indexToCharsetMapping = new String[highestIndex + 1];
976
for (int i = 0; i < CharsetMapping.INDEX_TO_CHARSET.length; i++) {
977
this.indexToCharsetMapping[i] = CharsetMapping.INDEX_TO_CHARSET[i];
980
for (Iterator indexIter = sortedCollationMap.entrySet()
981
.iterator(); indexIter.hasNext();) {
982
Map.Entry indexEntry = (Map.Entry) indexIter.next();
984
String mysqlCharsetName = (String) indexEntry.getValue();
986
this.indexToCharsetMapping[((Integer) indexEntry.getKey())
987
.intValue()] = CharsetMapping
988
.getJavaEncodingForMysqlEncoding(mysqlCharsetName,
991
} catch (java.sql.SQLException e) {
1067
this.indexToJavaCharset = Collections.unmodifiableMap(javaCharset);
1068
this.indexToCustomMysqlCharset = Collections.unmodifiableMap(customCharset);
1069
this.mysqlCharsetToCustomMblen = Collections.unmodifiableMap(customMblen);
1071
} catch (SQLException ex) {
1073
} catch (RuntimeException ex) {
1074
SQLException sqlEx = SQLError.createSQLException(ex.toString(), SQLError.SQL_STATE_ILLEGAL_ARGUMENT, null);
1075
sqlEx.initCause(ex);
994
1078
if (results != null) {
1144
1239
public void changeUser(String userName, String newPassword)
1145
1240
throws SQLException {
1146
if ((userName == null) || userName.equals("")) {
1150
if (newPassword == null) {
1154
this.io.changeUser(userName, newPassword, this.database);
1155
this.user = userName;
1156
this.password = newPassword;
1158
if (versionMeetsMinimum(4, 1, 0)) {
1159
configureClientCharacterSet(true);
1162
setSessionVariables();
1164
setupServerForTruncationChecks();
1241
synchronized (getConnectionMutex()) {
1244
if ((userName == null) || userName.equals("")) {
1248
if (newPassword == null) {
1252
this.io.changeUser(userName, newPassword, this.database);
1253
this.user = userName;
1254
this.password = newPassword;
1256
if (versionMeetsMinimum(4, 1, 0)) {
1257
configureClientCharacterSet(true);
1260
setSessionVariables();
1262
setupServerForTruncationChecks();
1167
1266
private boolean characterSetNamesMatches(String mysqlEncodingName) {
1168
1267
// set names is equivalent to character_set_client ..._results and ..._connection,
1169
1268
// but we set _results later, so don't check it here.
1171
1269
return (mysqlEncodingName != null &&
1172
mysqlEncodingName.equalsIgnoreCase((String)this.serverVariables.get("character_set_client")) &&
1173
mysqlEncodingName.equalsIgnoreCase((String)this.serverVariables.get("character_set_connection")));
1270
mysqlEncodingName.equalsIgnoreCase(this.serverVariables.get("character_set_client")) &&
1271
mysqlEncodingName.equalsIgnoreCase(this.serverVariables.get("character_set_connection")));
1176
1274
private void checkAndCreatePerformanceHistogram() {
1444
1547
PreparedStatement pStmt = null;
1446
1549
if (getCachePreparedStatements()) {
1447
synchronized (this.cachedPreparedStatementParams) {
1448
PreparedStatement.ParseInfo pStmtInfo = (PreparedStatement.ParseInfo) this.cachedPreparedStatementParams
1451
if (pStmtInfo == null) {
1452
pStmt = com.mysql.jdbc.PreparedStatement.getInstance(getLoadBalanceSafeProxy(), nativeSql,
1455
PreparedStatement.ParseInfo parseInfo = pStmt.getParseInfo();
1457
if (parseInfo.statementLength < getPreparedStatementCacheSqlLimit()) {
1458
if (this.cachedPreparedStatementParams.size() >= getPreparedStatementCacheSize()) {
1459
Iterator oldestIter = this.cachedPreparedStatementParams
1460
.keySet().iterator();
1461
long lruTime = Long.MAX_VALUE;
1462
String oldestSql = null;
1464
while (oldestIter.hasNext()) {
1465
String sqlKey = (String) oldestIter.next();
1466
PreparedStatement.ParseInfo lruInfo = (PreparedStatement.ParseInfo) this.cachedPreparedStatementParams
1469
if (lruInfo.lastUsed < lruTime) {
1470
lruTime = lruInfo.lastUsed;
1475
if (oldestSql != null) {
1476
this.cachedPreparedStatementParams
1481
this.cachedPreparedStatementParams.put(nativeSql, pStmt
1485
pStmtInfo.lastUsed = System.currentTimeMillis();
1486
pStmt = new com.mysql.jdbc.PreparedStatement(getLoadBalanceSafeProxy(), nativeSql,
1487
this.database, pStmtInfo);
1550
PreparedStatement.ParseInfo pStmtInfo = this.cachedPreparedStatementParams.get(nativeSql);
1552
if (pStmtInfo == null) {
1553
pStmt = com.mysql.jdbc.PreparedStatement.getInstance(getLoadBalanceSafeProxy(), nativeSql,
1556
this.cachedPreparedStatementParams.put(nativeSql, pStmt
1559
pStmt = new com.mysql.jdbc.PreparedStatement(getLoadBalanceSafeProxy(), nativeSql,
1560
this.database, pStmtInfo);
1491
1563
pStmt = com.mysql.jdbc.PreparedStatement.getInstance(getLoadBalanceSafeProxy(), nativeSql,
1621
1694
* if a database access error occurs
1622
1695
* @see setAutoCommit
1624
public synchronized void commit() throws SQLException {
1628
if (this.connectionLifecycleInterceptors != null) {
1629
IterateBlock iter = new IterateBlock(this.connectionLifecycleInterceptors.iterator()) {
1631
void forEach(Object each) throws SQLException {
1632
if (!((ConnectionLifecycleInterceptor)each).commit()) {
1633
this.stopIterating = true;
1640
if (!iter.fullIteration()) {
1645
// no-op if _relaxAutoCommit == true
1646
if (this.autoCommit && !getRelaxAutoCommit()) {
1647
throw SQLError.createSQLException("Can't call commit when autocommit=true", getExceptionInterceptor());
1648
} else if (this.transactionsSupported) {
1649
if (getUseLocalTransactionState() && versionMeetsMinimum(5, 0, 0)) {
1650
if (!this.io.inTransactionOnServer()) {
1651
return; // effectively a no-op
1655
execSQL(null, "commit", -1, null,
1656
DEFAULT_RESULT_SET_TYPE,
1657
DEFAULT_RESULT_SET_CONCURRENCY, false,
1658
this.database, null,
1661
} catch (SQLException sqlException) {
1662
if (SQLError.SQL_STATE_COMMUNICATION_LINK_FAILURE
1663
.equals(sqlException.getSQLState())) {
1665
.createSQLException(
1666
"Communications link failure during commit(). Transaction resolution unknown.",
1667
SQLError.SQL_STATE_TRANSACTION_RESOLUTION_UNKNOWN,
1668
getExceptionInterceptor());
1673
this.needsPing = this.getReconnectAtTxEnd();
1697
public void commit() throws SQLException {
1698
synchronized (getConnectionMutex()) {
1702
if (this.connectionLifecycleInterceptors != null) {
1703
IterateBlock<Extension> iter = new IterateBlock<Extension>(this.connectionLifecycleInterceptors.iterator()) {
1705
void forEach(Extension each) throws SQLException {
1706
if (!((ConnectionLifecycleInterceptor)each).commit()) {
1707
this.stopIterating = true;
1714
if (!iter.fullIteration()) {
1719
// no-op if _relaxAutoCommit == true
1720
if (this.autoCommit && !getRelaxAutoCommit()) {
1721
throw SQLError.createSQLException("Can't call commit when autocommit=true", getExceptionInterceptor());
1722
} else if (this.transactionsSupported) {
1723
if (getUseLocalTransactionState() && versionMeetsMinimum(5, 0, 0)) {
1724
if (!this.io.inTransactionOnServer()) {
1725
return; // effectively a no-op
1729
execSQL(null, "commit", -1, null,
1730
DEFAULT_RESULT_SET_TYPE,
1731
DEFAULT_RESULT_SET_CONCURRENCY, false,
1732
this.database, null,
1735
} catch (SQLException sqlException) {
1736
if (SQLError.SQL_STATE_COMMUNICATION_LINK_FAILURE
1737
.equals(sqlException.getSQLState())) {
1739
.createSQLException(
1740
"Communications link failure during commit(). Transaction resolution unknown.",
1741
SQLError.SQL_STATE_TRANSACTION_RESOLUTION_UNKNOWN,
1742
getExceptionInterceptor());
1747
this.needsPing = this.getReconnectAtTxEnd();
1869
1963
// Tell the server we'll use the server default charset
1871
1965
// queries from now on....
1872
String mysqlEncodingName = CharsetMapping
1873
.getMysqlEncodingForJavaEncoding(getEncoding()
1874
.toUpperCase(Locale.ENGLISH), this);
1966
String mysqlEncodingName = getServerCharacterEncoding();
1876
1968
if(getUseOldUTF8Behavior()){
1877
1969
mysqlEncodingName = "latin1";
1880
if (dontCheckServerMatch || !characterSetNamesMatches(mysqlEncodingName)) {
1881
execSQL(null, "SET NAMES " + mysqlEncodingName, -1,
1882
null, DEFAULT_RESULT_SET_TYPE,
1883
DEFAULT_RESULT_SET_CONCURRENCY, false,
1884
this.database, null, false);
1972
boolean ucs2 = false;
1973
if ( "ucs2".equalsIgnoreCase(mysqlEncodingName) ||
1974
"utf16".equalsIgnoreCase(mysqlEncodingName) ||
1975
"utf16le".equalsIgnoreCase(mysqlEncodingName) ||
1976
"utf32".equalsIgnoreCase(mysqlEncodingName)) {
1977
mysqlEncodingName = "utf8";
1979
if (getCharacterSetResults() == null) {
1980
setCharacterSetResults("UTF-8");
1984
if (dontCheckServerMatch || !characterSetNamesMatches(mysqlEncodingName) || ucs2) {
1986
execSQL(null, "SET NAMES " + mysqlEncodingName, -1,
1987
null, DEFAULT_RESULT_SET_TYPE,
1988
DEFAULT_RESULT_SET_CONCURRENCY, false,
1989
this.database, null, false);
1990
} catch (SQLException ex) {
1991
if (ex.getErrorCode() != MysqlErrorNumbers.ER_MUST_CHANGE_PASSWORD || getDisconnectOnExpiredPasswords()) {
1887
1997
realJavaEncoding = getEncoding();
1949
2073
// Only change the value if needed
2076
if (mysqlEncodingName == null) {
2077
throw SQLError.createSQLException(
2078
"Can't map "+charsetResults+" given for characterSetResults to a supported MySQL encoding.",
2079
SQLError.SQL_STATE_ILLEGAL_ARGUMENT, getExceptionInterceptor());
1952
2082
if (!mysqlEncodingName.equalsIgnoreCase(
1953
(String)this.serverVariables.get("character_set_results"))) {
2083
this.serverVariables.get("character_set_results"))) {
1954
2084
StringBuffer setBuf = new StringBuffer(
1955
2085
"SET character_set_results = ".length()
1956
2086
+ mysqlEncodingName.length());
1957
2087
setBuf.append("SET character_set_results = ").append(
1958
2088
mysqlEncodingName);
1960
execSQL(null, setBuf.toString(), -1, null,
1961
DEFAULT_RESULT_SET_TYPE,
1962
DEFAULT_RESULT_SET_CONCURRENCY, false,
1963
this.database, null, false);
2091
execSQL(null, setBuf.toString(), -1, null,
2092
DEFAULT_RESULT_SET_TYPE,
2093
DEFAULT_RESULT_SET_CONCURRENCY, false,
2094
this.database, null, false);
2095
} catch (SQLException ex) {
2096
if (ex.getErrorCode() != MysqlErrorNumbers.ER_MUST_CHANGE_PASSWORD || getDisconnectOnExpiredPasswords()) {
1965
2101
if (!this.usingCachedConfig) {
1966
2102
this.serverVariables.put(JDBC_LOCAL_CHARACTER_SET_RESULTS,
1967
2103
mysqlEncodingName);
2106
// We have to set errorMessageEncoding according to new value
2107
// of charsetResults for server version 5.5 and higher
2108
if (versionMeetsMinimum(5, 5, 0)) {
2109
this.errorMessageEncoding = charsetResults;
1970
2113
if (!this.usingCachedConfig) {
1971
2114
this.serverVariables.put(JDBC_LOCAL_CHARACTER_SET_RESULTS, onServer);
2139
2285
* @throws CommunicationsException
2142
public synchronized void createNewIO(boolean isForReconnect)
2288
public void createNewIO(boolean isForReconnect)
2143
2289
throws SQLException {
2144
// Synchronization Not needed for *new* connections, but defintely for
2145
// connections going through fail-over, since we might get the
2146
// new connection up and running *enough* to start sending
2147
// cached or still-open server-side prepared statements over
2148
// to the backend before we get a chance to re-prepare them...
2151
Properties mergedProps = exposeAsProperties(this.props);
2153
if (!getHighAvailability()) {
2154
connectOneTryOnly(isForReconnect, mergedProps);
2290
synchronized (getConnectionMutex()) {
2291
// Synchronization Not needed for *new* connections, but defintely for
2292
// connections going through fail-over, since we might get the
2293
// new connection up and running *enough* to start sending
2294
// cached or still-open server-side prepared statements over
2295
// to the backend before we get a chance to re-prepare them...
2159
connectWithRetries(isForReconnect, mergedProps);
2298
Properties mergedProps = exposeAsProperties(this.props);
2300
if (!getHighAvailability()) {
2301
connectOneTryOnly(isForReconnect, mergedProps);
2306
connectWithRetries(isForReconnect, mergedProps);
2163
2310
private void connectWithRetries(boolean isForReconnect,
2421
private synchronized void createPreparedStatementCaches() {
2422
int cacheSize = getPreparedStatementCacheSize();
2424
this.cachedPreparedStatementParams = new HashMap(cacheSize);
2426
if (getUseServerPreparedStmts()) {
2427
this.serverSideStatementCheckCache = new LRUCache(cacheSize);
2574
private void createPreparedStatementCaches() throws SQLException {
2575
synchronized (getConnectionMutex()) {
2576
int cacheSize = getPreparedStatementCacheSize();
2429
this.serverSideStatementCache = new LRUCache(cacheSize) {
2430
protected boolean removeEldestEntry(java.util.Map.Entry eldest) {
2431
if (this.maxElements <= 1) {
2435
boolean removeIt = super.removeEldestEntry(eldest);
2438
ServerPreparedStatement ps =
2439
(ServerPreparedStatement)eldest.getValue();
2440
ps.isCached = false;
2441
ps.setClosed(false);
2445
} catch (SQLException sqlEx) {
2579
Class<?> factoryClass;
2581
factoryClass = Class.forName(getParseInfoCacheFactory());
2583
@SuppressWarnings("unchecked")
2584
CacheAdapterFactory<String, ParseInfo> cacheFactory = ((CacheAdapterFactory<String, ParseInfo>)factoryClass.newInstance());
2586
this.cachedPreparedStatementParams = cacheFactory.getInstance(this, myURL, getPreparedStatementCacheSize(), getPreparedStatementCacheSqlLimit(), props);
2588
} catch (ClassNotFoundException e) {
2589
SQLException sqlEx = SQLError.createSQLException(
2590
Messages.getString("Connection.CantFindCacheFactory", new Object[] {getParseInfoCacheFactory(), "parseInfoCacheFactory"}),
2591
getExceptionInterceptor());
2595
} catch (InstantiationException e) {
2596
SQLException sqlEx = SQLError.createSQLException(
2597
Messages.getString("Connection.CantLoadCacheFactory", new Object[] {getParseInfoCacheFactory(), "parseInfoCacheFactory"}),
2598
getExceptionInterceptor());
2602
} catch (IllegalAccessException e) {
2603
SQLException sqlEx = SQLError.createSQLException(
2604
Messages.getString("Connection.CantLoadCacheFactory", new Object[] {getParseInfoCacheFactory(), "parseInfoCacheFactory"}),
2605
getExceptionInterceptor());
2611
if (getUseServerPreparedStmts()) {
2612
this.serverSideStatementCheckCache = new LRUCache(cacheSize);
2614
this.serverSideStatementCache = new LRUCache(cacheSize) {
2616
private static final long serialVersionUID = 7692318650375988114L;
2618
protected boolean removeEldestEntry(java.util.Map.Entry<Object, Object> eldest) {
2619
if (this.maxElements <= 1) {
2623
boolean removeIt = super.removeEldestEntry(eldest);
2626
ServerPreparedStatement ps =
2627
(ServerPreparedStatement)eldest.getValue();
2628
ps.isCached = false;
2629
ps.setClosed(false);
2633
} catch (SQLException sqlEx) {
2571
2760
catalog, cachedMetadata, false);
2574
public synchronized ResultSetInternalMethods execSQL(StatementImpl callingStatement, String sql, int maxRows,
2763
public ResultSetInternalMethods execSQL(StatementImpl callingStatement, String sql, int maxRows,
2575
2764
Buffer packet, int resultSetType, int resultSetConcurrency,
2576
2765
boolean streamResults, String catalog,
2577
2766
Field[] cachedMetadata,
2578
2767
boolean isBatch) throws SQLException {
2580
// Fall-back if the master is back online if we've
2581
// issued queriesBeforeRetryMaster queries since
2585
long queryStartTime = 0;
2587
int endOfQueryPacketPosition = 0;
2589
if (packet != null) {
2590
endOfQueryPacketPosition = packet.getPosition();
2593
if (getGatherPerformanceMetrics()) {
2594
queryStartTime = System.currentTimeMillis();
2597
this.lastQueryFinishedTime = 0; // we're busy!
2599
if ((getHighAvailability())
2600
&& (this.autoCommit || getAutoReconnectForPools())
2601
&& this.needsPing && !isBatch) {
2768
synchronized (getConnectionMutex()) {
2770
// Fall-back if the master is back online if we've
2771
// issued queriesBeforeRetryMaster queries since
2775
long queryStartTime = 0;
2777
int endOfQueryPacketPosition = 0;
2779
if (packet != null) {
2780
endOfQueryPacketPosition = packet.getPosition();
2783
if (getGatherPerformanceMetrics()) {
2784
queryStartTime = System.currentTimeMillis();
2787
this.lastQueryFinishedTime = 0; // we're busy!
2789
if ((getHighAvailability())
2790
&& (this.autoCommit || getAutoReconnectForPools())
2791
&& this.needsPing && !isBatch) {
2793
pingInternal(false, 0);
2795
this.needsPing = false;
2796
} catch (Exception Ex) {
2603
pingInternal(false, 0);
2605
this.needsPing = false;
2606
} catch (Exception Ex) {
2612
if (packet == null) {
2613
String encoding = null;
2615
if (getUseUnicode()) {
2616
encoding = getEncoding();
2802
if (packet == null) {
2803
String encoding = null;
2805
if (getUseUnicode()) {
2806
encoding = getEncoding();
2809
return this.io.sqlQueryDirect(callingStatement, sql,
2810
encoding, null, maxRows, resultSetType,
2811
resultSetConcurrency, streamResults, catalog,
2619
return this.io.sqlQueryDirect(callingStatement, sql,
2620
encoding, null, maxRows, resultSetType,
2815
return this.io.sqlQueryDirect(callingStatement, null, null,
2816
packet, maxRows, resultSetType,
2621
2817
resultSetConcurrency, streamResults, catalog,
2622
2818
cachedMetadata);
2625
return this.io.sqlQueryDirect(callingStatement, null, null,
2626
packet, maxRows, resultSetType,
2627
resultSetConcurrency, streamResults, catalog,
2629
} catch (java.sql.SQLException sqlE) {
2630
// don't clobber SQL exceptions
2632
if (getDumpQueriesOnException()) {
2633
String extractedSql = extractSqlFromPacket(sql, packet,
2634
endOfQueryPacketPosition);
2635
StringBuffer messageBuf = new StringBuffer(extractedSql
2638
.append("\n\nQuery being executed when exception was thrown:\n");
2639
messageBuf.append(extractedSql);
2640
messageBuf.append("\n\n");
2642
sqlE = appendMessageToException(sqlE, messageBuf.toString(), getExceptionInterceptor());
2645
if ((getHighAvailability())) {
2646
this.needsPing = true;
2648
String sqlState = sqlE.getSQLState();
2650
if ((sqlState != null)
2652
.equals(SQLError.SQL_STATE_COMMUNICATION_LINK_FAILURE)) {
2658
} catch (Exception ex) {
2659
if (getHighAvailability()) {
2660
this.needsPing = true;
2661
} else if (ex instanceof IOException) {
2665
SQLException sqlEx = SQLError.createSQLException(
2666
Messages.getString("Connection.UnexpectedException"),
2667
SQLError.SQL_STATE_GENERAL_ERROR, getExceptionInterceptor());
2668
sqlEx.initCause(ex);
2672
if (getMaintainTimeStats()) {
2673
this.lastQueryFinishedTime = System.currentTimeMillis();
2677
if (getGatherPerformanceMetrics()) {
2678
long queryTime = System.currentTimeMillis()
2681
registerQueryExecutionTime(queryTime);
2819
} catch (java.sql.SQLException sqlE) {
2820
// don't clobber SQL exceptions
2822
if (getDumpQueriesOnException()) {
2823
String extractedSql = extractSqlFromPacket(sql, packet,
2824
endOfQueryPacketPosition);
2825
StringBuffer messageBuf = new StringBuffer(extractedSql
2828
.append("\n\nQuery being executed when exception was thrown:\n");
2829
messageBuf.append(extractedSql);
2830
messageBuf.append("\n\n");
2832
sqlE = appendMessageToException(sqlE, messageBuf.toString(), getExceptionInterceptor());
2835
if ((getHighAvailability())) {
2836
this.needsPing = true;
2838
String sqlState = sqlE.getSQLState();
2840
if ((sqlState != null)
2842
.equals(SQLError.SQL_STATE_COMMUNICATION_LINK_FAILURE)) {
2848
} catch (Exception ex) {
2849
if (getHighAvailability()) {
2850
this.needsPing = true;
2851
} else if (ex instanceof IOException) {
2855
SQLException sqlEx = SQLError.createSQLException(
2856
Messages.getString("Connection.UnexpectedException"),
2857
SQLError.SQL_STATE_GENERAL_ERROR, getExceptionInterceptor());
2858
sqlEx.initCause(ex);
2862
if (getMaintainTimeStats()) {
2863
this.lastQueryFinishedTime = System.currentTimeMillis();
2867
if (getGatherPerformanceMetrics()) {
2868
long queryTime = System.currentTimeMillis()
2871
registerQueryExecutionTime(queryTime);
2972
3171
return this.log;
2975
public int getMaxBytesPerChar(String javaCharsetName)
2976
throws SQLException {
2977
// TODO: Check if we can actually run this query at this point in time
2978
String charset = CharsetMapping.getMysqlEncodingForJavaEncoding(
2979
javaCharsetName, this);
2981
if ((this.io.serverCharsetIndex == 33) && (versionMeetsMinimum(5, 5, 3)) && (javaCharsetName.equalsIgnoreCase("UTF-8"))) {
2986
if (versionMeetsMinimum(4, 1, 0)) {
2987
Map mapToCheck = null;
2989
if (!getUseDynamicCharsetInfo()) {
2990
mapToCheck = CharsetMapping.STATIC_CHARSET_TO_NUM_BYTES_MAP;
2992
mapToCheck = this.charsetToNumBytesMap;
2994
synchronized (this.charsetToNumBytesMap) {
2995
if (this.charsetToNumBytesMap.isEmpty()) {
2997
java.sql.Statement stmt = null;
2998
java.sql.ResultSet rs = null;
3001
stmt = getMetadataSafeStatement();
3003
rs = stmt.executeQuery("SHOW CHARACTER SET");
3006
this.charsetToNumBytesMap.put(rs.getString("Charset"),
3007
Integer.valueOf(rs.getInt("Maxlen")));
3174
public int getMaxBytesPerChar(String javaCharsetName) throws SQLException {
3175
return getMaxBytesPerChar(null, javaCharsetName);
3178
public int getMaxBytesPerChar(Integer charsetIndex, String javaCharsetName) throws SQLException {
3180
String charset = null;
3183
// if we can get it by charsetIndex just doing it
3185
// getting charset name from dynamic maps in connection;
3186
// we do it before checking against static maps because custom charset on server
3187
// can be mapped to index from our static map key's diapason
3188
charset = this.indexToCustomMysqlCharset.get(charsetIndex);
3189
// checking against static maps if no custom charset found
3190
if (charset==null) charset = CharsetMapping.STATIC_INDEX_TO_MYSQL_CHARSET_MAP.get(charsetIndex);
3192
// if we didn't find charset name by index
3193
if (charset == null) {
3194
charset = CharsetMapping.getMysqlEncodingForJavaEncoding(javaCharsetName, this);
3195
if ((this.io.serverCharsetIndex == 33) && (versionMeetsMinimum(5, 5, 3)) && (javaCharsetName.equalsIgnoreCase("UTF-8"))) {
3031
//Pin down the case when user with 5.5.3 server actually uses 3 byte UTF8
3032
//We have already overridden users preference by mapping UTF8 to UTF8mb4
3034
Integer mbPerChar = (Integer) mapToCheck.get(charset);
3036
if (mbPerChar != null) {
3037
return mbPerChar.intValue();
3040
return 1; // we don't know
3201
// checking against dynamic maps in connection
3202
Integer mblen = this.mysqlCharsetToCustomMblen.get(charset);
3204
// checking against static maps
3205
if (mblen == null) mblen = CharsetMapping.STATIC_CHARSET_TO_NUM_BYTES_MAP.get(charset);
3206
if (mblen == null) mblen = CharsetMapping.STATIC_4_0_CHARSET_TO_NUM_BYTES_MAP.get(charset);
3208
if (mblen != null) return mblen.intValue();
3209
} catch (SQLException ex) {
3211
} catch (RuntimeException ex) {
3212
SQLException sqlEx = SQLError.createSQLException(ex.toString(), SQLError.SQL_STATE_ILLEGAL_ARGUMENT, null);
3213
sqlEx.initCause(ex);
3043
3217
return 1; // we don't know
3149
3324
* @exception SQLException
3150
3325
* if a database access error occurs
3152
public synchronized int getTransactionIsolation() throws SQLException {
3154
if (this.hasIsolationLevels && !getUseLocalSessionState()) {
3155
java.sql.Statement stmt = null;
3156
java.sql.ResultSet rs = null;
3159
stmt = getMetadataSafeStatement();
3161
String query = null;
3165
if (versionMeetsMinimum(4, 0, 3)) {
3166
query = "SELECT @@session.tx_isolation";
3169
query = "SHOW VARIABLES LIKE 'transaction_isolation'";
3173
rs = stmt.executeQuery(query);
3176
String s = rs.getString(offset);
3179
Integer intTI = (Integer) mapTransIsolationNameToValue
3182
if (intTI != null) {
3183
return intTI.intValue();
3327
public int getTransactionIsolation() throws SQLException {
3329
synchronized (getConnectionMutex()) {
3330
if (this.hasIsolationLevels && !getUseLocalSessionState()) {
3331
java.sql.Statement stmt = null;
3332
java.sql.ResultSet rs = null;
3335
stmt = getMetadataSafeStatement();
3337
String query = null;
3341
if (versionMeetsMinimum(4, 0, 3)) {
3342
query = "SELECT @@session.tx_isolation";
3345
query = "SHOW VARIABLES LIKE 'transaction_isolation'";
3349
rs = stmt.executeQuery(query);
3352
String s = rs.getString(offset);
3355
Integer intTI = mapTransIsolationNameToValue.get(s);
3357
if (intTI != null) {
3358
return intTI.intValue();
3362
throw SQLError.createSQLException(
3363
"Could not map transaction isolation '" + s
3364
+ " to a valid JDBC level.",
3365
SQLError.SQL_STATE_GENERAL_ERROR, getExceptionInterceptor());
3187
3368
throw SQLError.createSQLException(
3188
"Could not map transaction isolation '" + s
3189
+ " to a valid JDBC level.",
3369
"Could not retrieve transaction isolation level from server",
3190
3370
SQLError.SQL_STATE_GENERAL_ERROR, getExceptionInterceptor());
3193
throw SQLError.createSQLException(
3194
"Could not retrieve transaction isolation level from server",
3195
SQLError.SQL_STATE_GENERAL_ERROR, getExceptionInterceptor());
3201
} catch (Exception ex) {
3212
} catch (Exception ex) {
3376
} catch (Exception ex) {
3387
} catch (Exception ex) {
3397
return this.isolationLevel;
3222
return this.isolationLevel;
3527
3717
// was originally on the server, which is why we use the
3528
3718
// "special" key to retrieve it
3529
3719
if (this.io.versionMeetsMinimum(4, 1, 0)) {
3530
String characterSetResultsOnServerMysql = (String) this.serverVariables
3531
.get(JDBC_LOCAL_CHARACTER_SET_RESULTS);
3720
String characterSetResultsOnServerMysql = this.serverVariables.get(JDBC_LOCAL_CHARACTER_SET_RESULTS);
3533
3722
if (characterSetResultsOnServerMysql == null
3534
3723
|| StringUtils.startsWithIgnoreCaseAndWs(
3535
3724
characterSetResultsOnServerMysql, "NULL")
3536
3725
|| characterSetResultsOnServerMysql.length() == 0) {
3537
String defaultMetadataCharsetMysql = (String) this.serverVariables
3538
.get("character_set_system");
3726
String defaultMetadataCharsetMysql = this.serverVariables.get("character_set_system");
3539
3727
String defaultMetadataCharset = null;
3541
3729
if (defaultMetadataCharsetMysql != null) {
3542
defaultMetadataCharset = CharsetMapping
3543
.getJavaEncodingForMysqlEncoding(
3544
defaultMetadataCharsetMysql, this);
3730
defaultMetadataCharset = getJavaEncodingForMysqlEncoding(defaultMetadataCharsetMysql);
3546
3732
defaultMetadataCharset = "UTF-8";
3549
3735
this.characterSetMetadata = defaultMetadataCharset;
3551
this.characterSetResultsOnServer = CharsetMapping
3552
.getJavaEncodingForMysqlEncoding(
3553
characterSetResultsOnServerMysql, this);
3737
this.characterSetResultsOnServer = getJavaEncodingForMysqlEncoding(characterSetResultsOnServerMysql);
3554
3738
this.characterSetMetadata = this.characterSetResultsOnServer;
3717
* Tests to see if the connection is in Read Only Mode. Note that we cannot
3718
* really put the database in read only mode, but we pretend we can by
3899
* Tests to see if the connection is in Read Only Mode. Note that prior to 5.6,
3900
* we cannot really put the database in read only mode, but we pretend we can by
3719
3901
* returning the value of the readOnly flag
3721
3903
* @return true if the connection is read only
3722
* @exception SQLException
3723
* if a database access error occurs
3904
* @exception SQLException if a database access error occurs
3725
3906
public boolean isReadOnly() throws SQLException {
3907
return isReadOnly(true);
3911
* Tests to see if the connection is in Read Only Mode. Note that prior to 5.6,
3912
* we cannot really put the database in read only mode, but we pretend we can by
3913
* returning the value of the readOnly flag
3915
* @param useSessionStatus in some cases, for example when restoring connection with autoReconnect=true,
3916
* we can rely only on saved readOnly state, so use useSessionStatus=false in that case
3918
* @return true if the connection is read only
3919
* @exception SQLException if a database access error occurs
3921
public boolean isReadOnly(boolean useSessionStatus) throws SQLException {
3922
if (useSessionStatus && !this.isClosed && versionMeetsMinimum(5, 6, 5) && !getUseLocalSessionState()) {
3923
java.sql.Statement stmt = null;
3924
java.sql.ResultSet rs = null;
3928
stmt = getMetadataSafeStatement();
3930
rs = stmt.executeQuery("select @@session.tx_read_only");
3932
return rs.getInt(1) != 0; // mysql has a habit of tri+ state booleans
3934
} catch (SQLException ex1) {
3935
if (ex1.getErrorCode() != MysqlErrorNumbers.ER_MUST_CHANGE_PASSWORD || getDisconnectOnExpiredPasswords()) {
3936
throw SQLError.createSQLException(
3937
"Could not retrieve transation read-only status server",
3938
SQLError.SQL_STATE_GENERAL_ERROR, ex1, getExceptionInterceptor());
3946
} catch (Exception ex) {
3956
} catch (Exception ex) {
3726
3965
return this.readOnly;
3730
3969
return this.isRunningOnJDK13;
3733
public synchronized boolean isSameResource(Connection otherConnection) {
3734
if (otherConnection == null) {
3738
boolean directCompare = true;
3740
String otherHost = ((ConnectionImpl)otherConnection).origHostToConnectTo;
3741
String otherOrigDatabase = ((ConnectionImpl)otherConnection).origDatabaseToConnectTo;
3742
String otherCurrentCatalog = ((ConnectionImpl)otherConnection).database;
3744
if (!nullSafeCompare(otherHost, this.origHostToConnectTo)) {
3745
directCompare = false;
3746
} else if (otherHost != null && otherHost.indexOf(',') == -1 &&
3747
otherHost.indexOf(':') == -1) {
3748
// need to check port numbers
3749
directCompare = (((ConnectionImpl)otherConnection).origPortToConnectTo ==
3750
this.origPortToConnectTo);
3753
if (directCompare) {
3754
if (!nullSafeCompare(otherOrigDatabase, this.origDatabaseToConnectTo)) { directCompare = false;
3755
directCompare = false;
3756
} else if (!nullSafeCompare(otherCurrentCatalog, this.database)) {
3757
directCompare = false;
3761
if (directCompare) {
3765
// Has the user explicitly set a resourceId?
3766
String otherResourceId = ((ConnectionImpl)otherConnection).getResourceId();
3767
String myResourceId = getResourceId();
3769
if (otherResourceId != null || myResourceId != null) {
3770
directCompare = nullSafeCompare(otherResourceId, myResourceId);
3972
public boolean isSameResource(Connection otherConnection) {
3973
synchronized (getConnectionMutex()) {
3974
if (otherConnection == null) {
3978
boolean directCompare = true;
3980
String otherHost = ((ConnectionImpl)otherConnection).origHostToConnectTo;
3981
String otherOrigDatabase = ((ConnectionImpl)otherConnection).origDatabaseToConnectTo;
3982
String otherCurrentCatalog = ((ConnectionImpl)otherConnection).database;
3984
if (!nullSafeCompare(otherHost, this.origHostToConnectTo)) {
3985
directCompare = false;
3986
} else if (otherHost != null && otherHost.indexOf(',') == -1 &&
3987
otherHost.indexOf(':') == -1) {
3988
// need to check port numbers
3989
directCompare = (((ConnectionImpl)otherConnection).origPortToConnectTo ==
3990
this.origPortToConnectTo);
3993
if (directCompare) {
3994
if (!nullSafeCompare(otherOrigDatabase, this.origDatabaseToConnectTo)) { directCompare = false;
3995
directCompare = false;
3996
} else if (!nullSafeCompare(otherCurrentCatalog, this.database)) {
3997
directCompare = false;
3772
4001
if (directCompare) {
4005
// Has the user explicitly set a resourceId?
4006
String otherResourceId = ((ConnectionImpl)otherConnection).getResourceId();
4007
String myResourceId = getResourceId();
4009
if (otherResourceId != null || myResourceId != null) {
4010
directCompare = nullSafeCompare(otherResourceId, myResourceId);
4012
if (directCompare) {
3780
4021
public boolean isServerTzUTC() {
3781
4022
return this.isServerTzUTC;
3784
4026
private boolean usingCachedConfig = false;
4028
private void createConfigCacheIfNeeded() throws SQLException {
4029
synchronized (getConnectionMutex()) {
4030
if (this.serverConfigCache != null) {
4035
Class<?> factoryClass;
4037
factoryClass = Class.forName(getServerConfigCacheFactory());
4039
@SuppressWarnings("unchecked")
4040
CacheAdapterFactory<String, Map<String, String>> cacheFactory = ((CacheAdapterFactory<String, Map<String, String>>)factoryClass.newInstance());
4042
this.serverConfigCache = cacheFactory.getInstance(this, myURL, Integer.MAX_VALUE, Integer.MAX_VALUE, props);
4044
ExceptionInterceptor evictOnCommsError = new ExceptionInterceptor() {
4046
public void init(Connection conn, Properties config)
4047
throws SQLException {
4050
public void destroy() {
4053
@SuppressWarnings("synthetic-access")
4054
public SQLException interceptException(SQLException sqlEx,
4056
if (sqlEx.getSQLState() != null && sqlEx.getSQLState().startsWith("08")) {
4057
serverConfigCache.invalidate(getURL());
4062
if (this.exceptionInterceptor == null) {
4063
this.exceptionInterceptor = evictOnCommsError;
4065
((ExceptionInterceptorChain)this.exceptionInterceptor).addRingZero(evictOnCommsError);
4067
} catch (ClassNotFoundException e) {
4068
SQLException sqlEx = SQLError.createSQLException(
4069
Messages.getString("Connection.CantFindCacheFactory", new Object[] {getParseInfoCacheFactory(), "parseInfoCacheFactory"}),
4070
getExceptionInterceptor());
4074
} catch (InstantiationException e) {
4075
SQLException sqlEx = SQLError.createSQLException(
4076
Messages.getString("Connection.CantLoadCacheFactory", new Object[] {getParseInfoCacheFactory(), "parseInfoCacheFactory"}),
4077
getExceptionInterceptor());
4081
} catch (IllegalAccessException e) {
4082
SQLException sqlEx = SQLError.createSQLException(
4083
Messages.getString("Connection.CantLoadCacheFactory", new Object[] {getParseInfoCacheFactory(), "parseInfoCacheFactory"}),
4084
getExceptionInterceptor());
4092
private final static String SERVER_VERSION_STRING_VAR_NAME = "server_version_string";
3787
4095
* Loads the result of 'SHOW VARIABLES' into the serverVariables field so
3788
4096
* that the driver can configure itself.
3860
4173
+ " OR Variable_name = 'init_connect'";
3863
this.serverVariables = new HashMap();
4176
this.serverVariables = new HashMap<String, String>();
3865
results = stmt.executeQuery(query);
3867
while (results.next()) {
3868
this.serverVariables.put(results.getString(1), results
4179
results = stmt.executeQuery(query);
4181
while (results.next()) {
4182
this.serverVariables.put(results.getString(1), results
4188
} catch (SQLException ex) {
4189
if (ex.getErrorCode() != MysqlErrorNumbers.ER_MUST_CHANGE_PASSWORD || getDisconnectOnExpiredPasswords()) {
3875
4194
if (versionMeetsMinimum(5, 0, 2)) {
3876
results = stmt.executeQuery(versionComment + "SELECT @@session.auto_increment_increment");
3878
if (results.next()) {
3879
this.serverVariables.put("auto_increment_increment", results.getString(1));
4196
results = stmt.executeQuery(versionComment + "SELECT @@session.auto_increment_increment");
4198
if (results.next()) {
4199
this.serverVariables.put("auto_increment_increment", results.getString(1));
4201
} catch (SQLException ex) {
4202
if (ex.getErrorCode() != MysqlErrorNumbers.ER_MUST_CHANGE_PASSWORD || getDisconnectOnExpiredPasswords()) {
3883
4208
if (getCacheServerConfiguration()) {
3884
synchronized (serverConfigByUrl) {
3885
serverConfigByUrl.put(getURL(), this.serverVariables);
3887
this.usingCachedConfig = true;
4209
this.serverVariables.put(SERVER_VERSION_STRING_VAR_NAME, this.io.getServerVersion());
4211
serverConfigCache.put(getURL(), this.serverVariables);
4213
this.usingCachedConfig = true;
3890
4215
} catch (SQLException e) {
4178
4505
* @exception SQLException
4179
4506
* if a database-access error occurs.
4181
public synchronized java.sql.PreparedStatement prepareStatement(String sql,
4508
public java.sql.PreparedStatement prepareStatement(String sql,
4182
4509
int resultSetType, int resultSetConcurrency) throws SQLException {
4186
// FIXME: Create warnings if can't create results of the given
4187
// type or concurrency
4189
PreparedStatement pStmt = null;
4191
boolean canServerPrepare = true;
4193
String nativeSql = getProcessEscapeCodesForPrepStmts() ? nativeSQL(sql): sql;
4195
if (this.useServerPreparedStmts && getEmulateUnsupportedPstmts()) {
4196
canServerPrepare = canHandleAsServerPreparedStatement(nativeSql);
4199
if (this.useServerPreparedStmts && canServerPrepare) {
4200
if (this.getCachePreparedStatements()) {
4201
synchronized (this.serverSideStatementCache) {
4202
pStmt = (com.mysql.jdbc.ServerPreparedStatement)this.serverSideStatementCache.remove(sql);
4204
if (pStmt != null) {
4205
((com.mysql.jdbc.ServerPreparedStatement)pStmt).setClosed(false);
4206
pStmt.clearParameters();
4209
if (pStmt == null) {
4211
pStmt = ServerPreparedStatement.getInstance(getLoadBalanceSafeProxy(), nativeSql,
4212
this.database, resultSetType, resultSetConcurrency);
4213
if (sql.length() < getPreparedStatementCacheSqlLimit()) {
4214
((com.mysql.jdbc.ServerPreparedStatement)pStmt).isCached = true;
4217
pStmt.setResultSetType(resultSetType);
4218
pStmt.setResultSetConcurrency(resultSetConcurrency);
4219
} catch (SQLException sqlEx) {
4220
// Punt, if necessary
4221
if (getEmulateUnsupportedPstmts()) {
4222
pStmt = (PreparedStatement) clientPrepareStatement(nativeSql, resultSetType, resultSetConcurrency, false);
4510
synchronized (getConnectionMutex()) {
4514
// FIXME: Create warnings if can't create results of the given
4515
// type or concurrency
4517
PreparedStatement pStmt = null;
4519
boolean canServerPrepare = true;
4521
String nativeSql = getProcessEscapeCodesForPrepStmts() ? nativeSQL(sql): sql;
4523
if (this.useServerPreparedStmts && getEmulateUnsupportedPstmts()) {
4524
canServerPrepare = canHandleAsServerPreparedStatement(nativeSql);
4527
if (this.useServerPreparedStmts && canServerPrepare) {
4528
if (this.getCachePreparedStatements()) {
4529
synchronized (this.serverSideStatementCache) {
4530
pStmt = (com.mysql.jdbc.ServerPreparedStatement)this.serverSideStatementCache.remove(sql);
4532
if (pStmt != null) {
4533
((com.mysql.jdbc.ServerPreparedStatement)pStmt).setClosed(false);
4534
pStmt.clearParameters();
4537
if (pStmt == null) {
4539
pStmt = ServerPreparedStatement.getInstance(getLoadBalanceSafeProxy(), nativeSql,
4540
this.database, resultSetType, resultSetConcurrency);
4224
4541
if (sql.length() < getPreparedStatementCacheSqlLimit()) {
4225
this.serverSideStatementCheckCache.put(sql, Boolean.FALSE);
4542
((com.mysql.jdbc.ServerPreparedStatement)pStmt).isCached = true;
4545
pStmt.setResultSetType(resultSetType);
4546
pStmt.setResultSetConcurrency(resultSetConcurrency);
4547
} catch (SQLException sqlEx) {
4548
// Punt, if necessary
4549
if (getEmulateUnsupportedPstmts()) {
4550
pStmt = (PreparedStatement) clientPrepareStatement(nativeSql, resultSetType, resultSetConcurrency, false);
4552
if (sql.length() < getPreparedStatementCacheSqlLimit()) {
4553
this.serverSideStatementCheckCache.put(sql, Boolean.FALSE);
4563
pStmt = ServerPreparedStatement.getInstance(getLoadBalanceSafeProxy(), nativeSql,
4564
this.database, resultSetType, resultSetConcurrency);
4566
pStmt.setResultSetType(resultSetType);
4567
pStmt.setResultSetConcurrency(resultSetConcurrency);
4568
} catch (SQLException sqlEx) {
4569
// Punt, if necessary
4570
if (getEmulateUnsupportedPstmts()) {
4571
pStmt = (PreparedStatement) clientPrepareStatement(nativeSql, resultSetType, resultSetConcurrency, false);
4235
pStmt = ServerPreparedStatement.getInstance(getLoadBalanceSafeProxy(), nativeSql,
4236
this.database, resultSetType, resultSetConcurrency);
4238
pStmt.setResultSetType(resultSetType);
4239
pStmt.setResultSetConcurrency(resultSetConcurrency);
4240
} catch (SQLException sqlEx) {
4241
// Punt, if necessary
4242
if (getEmulateUnsupportedPstmts()) {
4243
pStmt = (PreparedStatement) clientPrepareStatement(nativeSql, resultSetType, resultSetConcurrency, false);
4578
pStmt = (PreparedStatement) clientPrepareStatement(nativeSql, resultSetType, resultSetConcurrency, false);
4250
pStmt = (PreparedStatement) clientPrepareStatement(nativeSql, resultSetType, resultSetConcurrency, false);
4686
5017
* if a database access error occurs
4689
public synchronized void rollback() throws SQLException {
4693
if (this.connectionLifecycleInterceptors != null) {
4694
IterateBlock iter = new IterateBlock(this.connectionLifecycleInterceptors.iterator()) {
4696
void forEach(Object each) throws SQLException {
4697
if (!((ConnectionLifecycleInterceptor)each).rollback()) {
4698
this.stopIterating = true;
5020
public void rollback() throws SQLException {
5021
synchronized (getConnectionMutex()) {
5025
if (this.connectionLifecycleInterceptors != null) {
5026
IterateBlock<Extension> iter = new IterateBlock<Extension>(this.connectionLifecycleInterceptors.iterator()) {
5028
void forEach(Extension each) throws SQLException {
5029
if (!((ConnectionLifecycleInterceptor)each).rollback()) {
5030
this.stopIterating = true;
4705
if (!iter.fullIteration()) {
4709
// no-op if _relaxAutoCommit == true
4710
if (this.autoCommit && !getRelaxAutoCommit()) {
4711
throw SQLError.createSQLException(
4712
"Can't call rollback when autocommit=true",
4713
SQLError.SQL_STATE_CONNECTION_NOT_OPEN, getExceptionInterceptor());
4714
} else if (this.transactionsSupported) {
4717
} catch (SQLException sqlEx) {
4718
// We ignore non-transactional tables if told to do so
4719
if (getIgnoreNonTxTables()
4720
&& (sqlEx.getErrorCode() == SQLError.ER_WARNING_NOT_COMPLETE_ROLLBACK)) {
5037
if (!iter.fullIteration()) {
4727
} catch (SQLException sqlException) {
4728
if (SQLError.SQL_STATE_COMMUNICATION_LINK_FAILURE
4729
.equals(sqlException.getSQLState())) {
4730
throw SQLError.createSQLException(
4731
"Communications link failure during rollback(). Transaction resolution unknown.",
4732
SQLError.SQL_STATE_TRANSACTION_RESOLUTION_UNKNOWN, getExceptionInterceptor());
4737
this.needsPing = this.getReconnectAtTxEnd();
5041
// no-op if _relaxAutoCommit == true
5042
if (this.autoCommit && !getRelaxAutoCommit()) {
5043
throw SQLError.createSQLException(
5044
"Can't call rollback when autocommit=true",
5045
SQLError.SQL_STATE_CONNECTION_NOT_OPEN, getExceptionInterceptor());
5046
} else if (this.transactionsSupported) {
5049
} catch (SQLException sqlEx) {
5050
// We ignore non-transactional tables if told to do so
5051
if (getIgnoreNonTxTables()
5052
&& (sqlEx.getErrorCode() == SQLError.ER_WARNING_NOT_COMPLETE_ROLLBACK)) {
5059
} catch (SQLException sqlException) {
5060
if (SQLError.SQL_STATE_COMMUNICATION_LINK_FAILURE
5061
.equals(sqlException.getSQLState())) {
5062
throw SQLError.createSQLException(
5063
"Communications link failure during rollback(). Transaction resolution unknown.",
5064
SQLError.SQL_STATE_TRANSACTION_RESOLUTION_UNKNOWN, getExceptionInterceptor());
5069
this.needsPing = this.getReconnectAtTxEnd();
4742
5075
* @see Connection#rollback(Savepoint)
4744
public synchronized void rollback(final Savepoint savepoint) throws SQLException {
4746
if (versionMeetsMinimum(4, 0, 14) || versionMeetsMinimum(4, 1, 1)) {
4750
if (this.connectionLifecycleInterceptors != null) {
4751
IterateBlock iter = new IterateBlock(this.connectionLifecycleInterceptors.iterator()) {
4753
void forEach(Object each) throws SQLException {
4754
if (!((ConnectionLifecycleInterceptor)each).rollback(savepoint)) {
4755
this.stopIterating = true;
4762
if (!iter.fullIteration()) {
4767
StringBuffer rollbackQuery = new StringBuffer(
4768
"ROLLBACK TO SAVEPOINT ");
4769
rollbackQuery.append('`');
4770
rollbackQuery.append(savepoint.getSavepointName());
4771
rollbackQuery.append('`');
4773
java.sql.Statement stmt = null;
5077
public void rollback(final Savepoint savepoint) throws SQLException {
5079
synchronized (getConnectionMutex()) {
5080
if (versionMeetsMinimum(4, 0, 14) || versionMeetsMinimum(4, 1, 1)) {
4776
stmt = getMetadataSafeStatement();
4778
stmt.executeUpdate(rollbackQuery.toString());
4779
} catch (SQLException sqlEx) {
4780
int errno = sqlEx.getErrorCode();
4782
if (errno == 1181) {
4783
String msg = sqlEx.getMessage();
4786
int indexOfError153 = msg.indexOf("153");
4788
if (indexOfError153 != -1) {
4789
throw SQLError.createSQLException("Savepoint '"
4790
+ savepoint.getSavepointName()
4791
+ "' does not exist",
4792
SQLError.SQL_STATE_ILLEGAL_ARGUMENT,
4793
errno, getExceptionInterceptor());
5084
if (this.connectionLifecycleInterceptors != null) {
5085
IterateBlock<Extension> iter = new IterateBlock<Extension>(this.connectionLifecycleInterceptors.iterator()) {
5087
void forEach(Extension each) throws SQLException {
5088
if (!((ConnectionLifecycleInterceptor)each).rollback(savepoint)) {
5089
this.stopIterating = true;
5096
if (!iter.fullIteration()) {
4798
// We ignore non-transactional tables if told to do so
4799
if (getIgnoreNonTxTables()
4800
&& (sqlEx.getErrorCode() != SQLError.ER_WARNING_NOT_COMPLETE_ROLLBACK)) {
5101
StringBuffer rollbackQuery = new StringBuffer(
5102
"ROLLBACK TO SAVEPOINT ");
5103
rollbackQuery.append('`');
5104
rollbackQuery.append(savepoint.getSavepointName());
5105
rollbackQuery.append('`');
5107
java.sql.Statement stmt = null;
5110
stmt = getMetadataSafeStatement();
5112
stmt.executeUpdate(rollbackQuery.toString());
5113
} catch (SQLException sqlEx) {
5114
int errno = sqlEx.getErrorCode();
5116
if (errno == 1181) {
5117
String msg = sqlEx.getMessage();
5120
int indexOfError153 = msg.indexOf("153");
5122
if (indexOfError153 != -1) {
5123
throw SQLError.createSQLException("Savepoint '"
5124
+ savepoint.getSavepointName()
5125
+ "' does not exist",
5126
SQLError.SQL_STATE_ILLEGAL_ARGUMENT,
5127
errno, getExceptionInterceptor());
5132
// We ignore non-transactional tables if told to do so
5133
if (getIgnoreNonTxTables()
5134
&& (sqlEx.getErrorCode() != SQLError.ER_WARNING_NOT_COMPLETE_ROLLBACK)) {
5138
if (SQLError.SQL_STATE_COMMUNICATION_LINK_FAILURE
5139
.equals(sqlEx.getSQLState())) {
5140
throw SQLError.createSQLException(
5141
"Communications link failure during rollback(). Transaction resolution unknown.",
5142
SQLError.SQL_STATE_TRANSACTION_RESOLUTION_UNKNOWN, getExceptionInterceptor());
4804
if (SQLError.SQL_STATE_COMMUNICATION_LINK_FAILURE
4805
.equals(sqlEx.getSQLState())) {
4806
throw SQLError.createSQLException(
4807
"Communications link failure during rollback(). Transaction resolution unknown.",
4808
SQLError.SQL_STATE_TRANSACTION_RESOLUTION_UNKNOWN, getExceptionInterceptor());
5147
closeStatement(stmt);
4813
closeStatement(stmt);
5150
this.needsPing = this.getReconnectAtTxEnd();
4816
this.needsPing = this.getReconnectAtTxEnd();
5153
throw SQLError.notImplemented();
4819
throw SQLError.notImplemented();
4947
5282
* @exception SQLException
4948
5283
* if a database access error occurs
4950
public synchronized void setAutoCommit(final boolean autoCommitFlag) throws SQLException {
4953
if (this.connectionLifecycleInterceptors != null) {
4954
IterateBlock iter = new IterateBlock(this.connectionLifecycleInterceptors.iterator()) {
4956
void forEach(Object each) throws SQLException {
4957
if (!((ConnectionLifecycleInterceptor)each).setAutoCommit(autoCommitFlag)) {
4958
this.stopIterating = true;
4965
if (!iter.fullIteration()) {
4970
if (getAutoReconnectForPools()) {
4971
setHighAvailability(true);
4975
if (this.transactionsSupported) {
4977
boolean needsSetOnServer = true;
4979
if (this.getUseLocalSessionState()
4980
&& this.autoCommit == autoCommitFlag) {
4981
needsSetOnServer = false;
4982
} else if (!this.getHighAvailability()) {
4983
needsSetOnServer = this.getIO()
4984
.isSetNeededForAutoCommitMode(autoCommitFlag);
4987
// this internal value must be set first as failover depends on
4989
// being set to true to fail over (which is done by most
4990
// app servers and connection pools at the end of
4991
// a transaction), and the driver issues an implicit set
4992
// based on this value when it (re)-connects to a server
4993
// so the value holds across connections
4994
this.autoCommit = autoCommitFlag;
4996
if (needsSetOnServer) {
4997
execSQL(null, autoCommitFlag ? "SET autocommit=1"
4998
: "SET autocommit=0", -1, null,
4999
DEFAULT_RESULT_SET_TYPE,
5000
DEFAULT_RESULT_SET_CONCURRENCY, false,
5001
this.database, null, false);
5005
if ((autoCommitFlag == false) && !getRelaxAutoCommit()) {
5006
throw SQLError.createSQLException("MySQL Versions Older than 3.23.15 "
5007
+ "do not support transactions",
5008
SQLError.SQL_STATE_CONNECTION_NOT_OPEN, getExceptionInterceptor());
5011
this.autoCommit = autoCommitFlag;
5014
if (this.getAutoReconnectForPools()) {
5015
setHighAvailability(false);
5285
public void setAutoCommit(final boolean autoCommitFlag) throws SQLException {
5286
synchronized (getConnectionMutex()) {
5289
if (this.connectionLifecycleInterceptors != null) {
5290
IterateBlock<Extension> iter = new IterateBlock<Extension>(this.connectionLifecycleInterceptors.iterator()) {
5292
void forEach(Extension each) throws SQLException {
5293
if (!((ConnectionLifecycleInterceptor)each).setAutoCommit(autoCommitFlag)) {
5294
this.stopIterating = true;
5301
if (!iter.fullIteration()) {
5306
if (getAutoReconnectForPools()) {
5307
setHighAvailability(true);
5311
if (this.transactionsSupported) {
5313
boolean needsSetOnServer = true;
5315
if (this.getUseLocalSessionState()
5316
&& this.autoCommit == autoCommitFlag) {
5317
needsSetOnServer = false;
5318
} else if (!this.getHighAvailability()) {
5319
needsSetOnServer = this.getIO()
5320
.isSetNeededForAutoCommitMode(autoCommitFlag);
5323
// this internal value must be set first as failover depends on
5325
// being set to true to fail over (which is done by most
5326
// app servers and connection pools at the end of
5327
// a transaction), and the driver issues an implicit set
5328
// based on this value when it (re)-connects to a server
5329
// so the value holds across connections
5330
this.autoCommit = autoCommitFlag;
5332
if (needsSetOnServer) {
5333
execSQL(null, autoCommitFlag ? "SET autocommit=1"
5334
: "SET autocommit=0", -1, null,
5335
DEFAULT_RESULT_SET_TYPE,
5336
DEFAULT_RESULT_SET_CONCURRENCY, false,
5337
this.database, null, false);
5341
if ((autoCommitFlag == false) && !getRelaxAutoCommit()) {
5342
throw SQLError.createSQLException("MySQL Versions Older than 3.23.15 "
5343
+ "do not support transactions",
5344
SQLError.SQL_STATE_CONNECTION_NOT_OPEN, getExceptionInterceptor());
5347
this.autoCommit = autoCommitFlag;
5350
if (this.getAutoReconnectForPools()) {
5351
setHighAvailability(false);
5032
5369
* @throws SQLException
5033
5370
* if a database access error occurs
5035
public synchronized void setCatalog(final String catalog) throws SQLException {
5038
if (catalog == null) {
5039
throw SQLError.createSQLException("Catalog can not be null",
5040
SQLError.SQL_STATE_ILLEGAL_ARGUMENT, getExceptionInterceptor());
5043
if (this.connectionLifecycleInterceptors != null) {
5044
IterateBlock iter = new IterateBlock(this.connectionLifecycleInterceptors.iterator()) {
5046
void forEach(Object each) throws SQLException {
5047
if (!((ConnectionLifecycleInterceptor)each).setCatalog(catalog)) {
5048
this.stopIterating = true;
5055
if (!iter.fullIteration()) {
5060
if (getUseLocalSessionState()) {
5061
if (this.lowerCaseTableNames) {
5062
if (this.database.equalsIgnoreCase(catalog)) {
5066
if (this.database.equals(catalog)) {
5072
String quotedId = this.dbmd.getIdentifierQuoteString();
5074
if ((quotedId == null) || quotedId.equals(" ")) {
5078
StringBuffer query = new StringBuffer("USE ");
5079
query.append(quotedId);
5080
query.append(catalog);
5081
query.append(quotedId);
5083
execSQL(null, query.toString(), -1, null,
5084
DEFAULT_RESULT_SET_TYPE,
5085
DEFAULT_RESULT_SET_CONCURRENCY, false,
5086
this.database, null, false);
5088
this.database = catalog;
5372
public void setCatalog(final String catalog) throws SQLException {
5373
synchronized (getConnectionMutex()) {
5376
if (catalog == null) {
5377
throw SQLError.createSQLException("Catalog can not be null",
5378
SQLError.SQL_STATE_ILLEGAL_ARGUMENT, getExceptionInterceptor());
5381
if (this.connectionLifecycleInterceptors != null) {
5382
IterateBlock<Extension> iter = new IterateBlock<Extension>(this.connectionLifecycleInterceptors.iterator()) {
5384
void forEach(Extension each) throws SQLException {
5385
if (!((ConnectionLifecycleInterceptor)each).setCatalog(catalog)) {
5386
this.stopIterating = true;
5393
if (!iter.fullIteration()) {
5398
if (getUseLocalSessionState()) {
5399
if (this.lowerCaseTableNames) {
5400
if (this.database.equalsIgnoreCase(catalog)) {
5404
if (this.database.equals(catalog)) {
5410
String quotedId = this.dbmd.getIdentifierQuoteString();
5412
if ((quotedId == null) || quotedId.equals(" ")) {
5416
StringBuffer query = new StringBuffer("USE ");
5417
query.append(quotedId);
5418
query.append(catalog);
5419
query.append(quotedId);
5421
execSQL(null, query.toString(), -1, null,
5422
DEFAULT_RESULT_SET_TYPE,
5423
DEFAULT_RESULT_SET_CONCURRENCY, false,
5424
this.database, null, false);
5426
this.database = catalog;
5092
5431
* @param failedOver
5093
5432
* The failedOver to set.
5095
public synchronized void setFailedOver(boolean flag) {
5096
// handled higher up
5434
public void setFailedOver(boolean flag) {
5435
synchronized (getConnectionMutex()) {
5436
// handled higher up
5151
5503
return savepoint;
5154
private synchronized void setSavepoint(MysqlSavepoint savepoint) throws SQLException {
5156
if (versionMeetsMinimum(4, 0, 14) || versionMeetsMinimum(4, 1, 1)) {
5159
StringBuffer savePointQuery = new StringBuffer("SAVEPOINT ");
5160
savePointQuery.append('`');
5161
savePointQuery.append(savepoint.getSavepointName());
5162
savePointQuery.append('`');
5164
java.sql.Statement stmt = null;
5167
stmt = getMetadataSafeStatement();
5169
stmt.executeUpdate(savePointQuery.toString());
5171
closeStatement(stmt);
5506
private void setSavepoint(MysqlSavepoint savepoint) throws SQLException {
5508
synchronized (getConnectionMutex()) {
5509
if (versionMeetsMinimum(4, 0, 14) || versionMeetsMinimum(4, 1, 1)) {
5512
StringBuffer savePointQuery = new StringBuffer("SAVEPOINT ");
5513
savePointQuery.append('`');
5514
savePointQuery.append(savepoint.getSavepointName());
5515
savePointQuery.append('`');
5517
java.sql.Statement stmt = null;
5520
stmt = getMetadataSafeStatement();
5522
stmt.executeUpdate(savePointQuery.toString());
5524
closeStatement(stmt);
5527
throw SQLError.notImplemented();
5174
throw SQLError.notImplemented();
5179
5533
* @see Connection#setSavepoint(String)
5181
public synchronized java.sql.Savepoint setSavepoint(String name) throws SQLException {
5182
MysqlSavepoint savepoint = new MysqlSavepoint(name, getExceptionInterceptor());
5184
setSavepoint(savepoint);
5535
public java.sql.Savepoint setSavepoint(String name) throws SQLException {
5536
synchronized (getConnectionMutex()) {
5537
MysqlSavepoint savepoint = new MysqlSavepoint(name, getExceptionInterceptor());
5539
setSavepoint(savepoint);
5227
5583
* @throws SQLException
5230
public synchronized void setTransactionIsolation(int level) throws SQLException {
5233
if (this.hasIsolationLevels) {
5236
boolean shouldSendSet = false;
5238
if (getAlwaysSendSetIsolation()) {
5239
shouldSendSet = true;
5241
if (level != this.isolationLevel) {
5586
public void setTransactionIsolation(int level) throws SQLException {
5587
synchronized (getConnectionMutex()) {
5590
if (this.hasIsolationLevels) {
5593
boolean shouldSendSet = false;
5595
if (getAlwaysSendSetIsolation()) {
5242
5596
shouldSendSet = true;
5246
if (getUseLocalSessionState()) {
5247
shouldSendSet = this.isolationLevel != level;
5250
if (shouldSendSet) {
5252
case java.sql.Connection.TRANSACTION_NONE:
5253
throw SQLError.createSQLException("Transaction isolation level "
5254
+ "NONE not supported by MySQL", getExceptionInterceptor());
5256
case java.sql.Connection.TRANSACTION_READ_COMMITTED:
5257
sql = "SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED";
5261
case java.sql.Connection.TRANSACTION_READ_UNCOMMITTED:
5262
sql = "SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED";
5266
case java.sql.Connection.TRANSACTION_REPEATABLE_READ:
5267
sql = "SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ";
5271
case java.sql.Connection.TRANSACTION_SERIALIZABLE:
5272
sql = "SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE";
5277
throw SQLError.createSQLException("Unsupported transaction "
5278
+ "isolation level '" + level + "'",
5279
SQLError.SQL_STATE_DRIVER_NOT_CAPABLE, getExceptionInterceptor());
5282
execSQL(null, sql, -1, null,
5283
DEFAULT_RESULT_SET_TYPE,
5284
DEFAULT_RESULT_SET_CONCURRENCY,false,
5285
this.database, null, false);
5287
this.isolationLevel = level;
5290
throw SQLError.createSQLException("Transaction Isolation Levels are "
5291
+ "not supported on MySQL versions older than 3.23.36.",
5292
SQLError.SQL_STATE_DRIVER_NOT_CAPABLE, getExceptionInterceptor());
5598
if (level != this.isolationLevel) {
5599
shouldSendSet = true;
5603
if (getUseLocalSessionState()) {
5604
shouldSendSet = this.isolationLevel != level;
5607
if (shouldSendSet) {
5609
case java.sql.Connection.TRANSACTION_NONE:
5610
throw SQLError.createSQLException("Transaction isolation level "
5611
+ "NONE not supported by MySQL", getExceptionInterceptor());
5613
case java.sql.Connection.TRANSACTION_READ_COMMITTED:
5614
sql = "SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED";
5618
case java.sql.Connection.TRANSACTION_READ_UNCOMMITTED:
5619
sql = "SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED";
5623
case java.sql.Connection.TRANSACTION_REPEATABLE_READ:
5624
sql = "SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ";
5628
case java.sql.Connection.TRANSACTION_SERIALIZABLE:
5629
sql = "SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE";
5634
throw SQLError.createSQLException("Unsupported transaction "
5635
+ "isolation level '" + level + "'",
5636
SQLError.SQL_STATE_DRIVER_NOT_CAPABLE, getExceptionInterceptor());
5639
execSQL(null, sql, -1, null,
5640
DEFAULT_RESULT_SET_TYPE,
5641
DEFAULT_RESULT_SET_CONCURRENCY,false,
5642
this.database, null, false);
5644
this.isolationLevel = level;
5647
throw SQLError.createSQLException("Transaction Isolation Levels are "
5648
+ "not supported on MySQL versions older than 3.23.36.",
5649
SQLError.SQL_STATE_DRIVER_NOT_CAPABLE, getExceptionInterceptor());
5412
5772
* if a database error occurs issuing the statement that sets
5413
5773
* the limit default.
5415
public synchronized void unsetMaxRows(Statement stmt) throws SQLException {
5416
if (this.statementsUsingMaxRows != null) {
5417
Object found = this.statementsUsingMaxRows.remove(stmt);
5420
&& (this.statementsUsingMaxRows.size() == 0)) {
5421
execSQL(null, "SET OPTION SQL_SELECT_LIMIT=DEFAULT", -1,
5422
null, DEFAULT_RESULT_SET_TYPE,
5423
DEFAULT_RESULT_SET_CONCURRENCY, false,
5424
this.database, null, false);
5426
this.maxRowsChanged = false;
5775
public void unsetMaxRows(Statement stmt) throws SQLException {
5776
synchronized (getConnectionMutex()) {
5777
if (this.statementsUsingMaxRows != null) {
5778
Object found = this.statementsUsingMaxRows.remove(stmt);
5781
&& (this.statementsUsingMaxRows.size() == 0)) {
5782
execSQL(null, "SET SQL_SELECT_LIMIT=DEFAULT", -1,
5783
null, DEFAULT_RESULT_SET_TYPE,
5784
DEFAULT_RESULT_SET_CONCURRENCY, false,
5785
this.database, null, false);
5787
this.maxRowsChanged = false;
5431
public synchronized boolean useAnsiQuotedIdentifiers() {
5432
return this.useAnsiQuotes;
5793
public boolean useAnsiQuotedIdentifiers() {
5794
synchronized (getConnectionMutex()) {
5795
return this.useAnsiQuotes;
5541
5907
this.statementComment = comment;
5544
public synchronized void reportQueryTime(long millisOrNanos) {
5545
this.queryTimeCount++;
5546
this.queryTimeSum += millisOrNanos;
5547
this.queryTimeSumSquares += (millisOrNanos * millisOrNanos);
5548
this.queryTimeMean = ((this.queryTimeMean * (this.queryTimeCount - 1)) + millisOrNanos)
5549
/ this.queryTimeCount;
5910
public void reportQueryTime(long millisOrNanos) {
5911
synchronized (getConnectionMutex()) {
5912
this.queryTimeCount++;
5913
this.queryTimeSum += millisOrNanos;
5914
this.queryTimeSumSquares += (millisOrNanos * millisOrNanos);
5915
this.queryTimeMean = ((this.queryTimeMean * (this.queryTimeCount - 1)) + millisOrNanos)
5916
/ this.queryTimeCount;
5552
public synchronized boolean isAbonormallyLongQuery(long millisOrNanos) {
5553
if (this.queryTimeCount < 15) {
5554
return false; // need a minimum amount for this to make sense
5920
public boolean isAbonormallyLongQuery(long millisOrNanos) {
5921
synchronized (getConnectionMutex()) {
5922
if (this.queryTimeCount < 15) {
5923
return false; // need a minimum amount for this to make sense
5926
double stddev = Math.sqrt((this.queryTimeSumSquares - ((this.queryTimeSum*this.queryTimeSum) / this.queryTimeCount)) / (this.queryTimeCount - 1));
5928
return millisOrNanos > (this.queryTimeMean + 5 * stddev);
5557
double stddev = Math.sqrt((this.queryTimeSumSquares - ((this.queryTimeSum*this.queryTimeSum) / this.queryTimeCount)) / (this.queryTimeCount - 1));
5559
return millisOrNanos > (this.queryTimeMean + 5 * stddev);
5562
5932
public void initializeExtension(Extension ex) throws SQLException {
5563
5933
ex.init(this, this.props);
5566
public synchronized void transactionBegun() throws SQLException {
5567
if (this.connectionLifecycleInterceptors != null) {
5568
IterateBlock iter = new IterateBlock(this.connectionLifecycleInterceptors.iterator()) {
5570
void forEach(Object each) throws SQLException {
5571
((ConnectionLifecycleInterceptor)each).transactionBegun();
5936
public void transactionBegun() throws SQLException {
5937
synchronized (getConnectionMutex()) {
5938
if (this.connectionLifecycleInterceptors != null) {
5939
IterateBlock<Extension> iter = new IterateBlock<Extension>(this.connectionLifecycleInterceptors.iterator()) {
5941
void forEach(Extension each) throws SQLException {
5942
((ConnectionLifecycleInterceptor)each).transactionBegun();
5579
public synchronized void transactionCompleted() throws SQLException {
5580
if (this.connectionLifecycleInterceptors != null) {
5581
IterateBlock iter = new IterateBlock(this.connectionLifecycleInterceptors.iterator()) {
5583
void forEach(Object each) throws SQLException {
5584
((ConnectionLifecycleInterceptor)each).transactionCompleted();
5951
public void transactionCompleted() throws SQLException {
5952
synchronized (getConnectionMutex()) {
5953
if (this.connectionLifecycleInterceptors != null) {
5954
IterateBlock<Extension> iter = new IterateBlock<Extension>(this.connectionLifecycleInterceptors.iterator()) {
5956
void forEach(Extension each) throws SQLException {
5957
((ConnectionLifecycleInterceptor)each).transactionCompleted();
5603
5977
return requiresEscapingEncoder;
5606
public synchronized boolean isServerLocal() throws SQLException {
5607
SocketFactory factory = getIO().socketFactory;
5609
if (factory instanceof SocketMetadata) {
5610
return ((SocketMetadata)factory).isLocallyConnected(this);
5980
public boolean isServerLocal() throws SQLException {
5981
synchronized (getConnectionMutex()) {
5982
SocketFactory factory = getIO().socketFactory;
5984
if (factory instanceof SocketMetadata) {
5985
return ((SocketMetadata)factory).isLocallyConnected(this);
5612
5987
getLog().logWarn(Messages.getString("Connection.NoMetadataOnSocketFactory"));
5993
// until we flip catalog/schema, this is a no-op
5994
public void setSchema(String schema) throws SQLException {
5995
synchronized (getConnectionMutex()) {
6001
public String getSchema() throws SQLException {
6002
synchronized (getConnectionMutex()) {
6010
* Terminates an open connection. Calling <code>abort</code> results in:
6012
* <li>The connection marked as closed
6013
* <li>Closes any physical connection to the database
6014
* <li>Releases resources used by the connection
6015
* <li>Insures that any thread that is currently accessing the connection
6016
* will either progress to completion or throw an <code>SQLException</code>.
6019
* Calling <code>abort</code> marks the connection closed and releases any
6020
* resources. Calling <code>abort</code> on a closed connection is a
6023
* It is possible that the aborting and releasing of the resources that are
6024
* held by the connection can take an extended period of time. When the
6025
* <code>abort</code> method returns, the connection will have been marked as
6026
* closed and the <code>Executor</code> that was passed as a parameter to abort
6027
* may still be executing tasks to release resources.
6029
* This method checks to see that there is an <code>SQLPermission</code>
6030
* object before allowing the method to proceed. If a
6031
* <code>SecurityManager</code> exists and its
6032
* <code>checkPermission</code> method denies calling <code>abort</code>,
6033
* this method throws a
6034
* <code>java.lang.SecurityException</code>.
6035
* @param executor The <code>Executor</code> implementation which will
6036
* be used by <code>abort</code>.
6037
* @throws java.sql.SQLException if a database access error occurs or
6038
* the {@code executor} is {@code null},
6039
* @throws java.lang.SecurityException if a security manager exists and its
6040
* <code>checkPermission</code> method denies calling <code>abort</code>
6041
* @see SecurityManager#checkPermission
6045
public void abort(Executor executor) throws SQLException {
6046
SecurityManager sec = System.getSecurityManager();
6049
sec.checkPermission(ABORT_PERM);
6052
if (executor == null) {
6053
throw SQLError.createSQLException("Executor can not be null", SQLError.SQL_STATE_ILLEGAL_ARGUMENT, getExceptionInterceptor());
6056
executor.execute(new Runnable() {
6061
} catch (SQLException e) {
6062
throw new RuntimeException(e);
6069
public void setNetworkTimeout(Executor executor, final int milliseconds) throws SQLException {
6070
synchronized (getConnectionMutex()) {
6071
SecurityManager sec = System.getSecurityManager();
6074
sec.checkPermission(SET_NETWORK_TIMEOUT_PERM);
6077
if (executor == null) {
6078
throw SQLError.createSQLException("Executor can not be null", SQLError.SQL_STATE_ILLEGAL_ARGUMENT, getExceptionInterceptor());
6082
final MysqlIO mysqlIo = this.io;
6084
executor.execute(new Runnable() {
6087
setSocketTimeout(milliseconds); // for re-connects
6089
mysqlIo.setSocketTimeout(milliseconds);
6090
} catch (SQLException e) {
6091
throw new RuntimeException(e);
6098
public int getNetworkTimeout() throws SQLException {
6099
synchronized (getConnectionMutex()) {
6101
return getSocketTimeout();
6105
public java.sql.Clob createClob() throws SQLException {
6106
throw new UnsupportedOperationException();
6109
public java.sql.Blob createBlob() throws SQLException {
6110
throw new UnsupportedOperationException();
6113
public java.sql.NClob createNClob() throws SQLException {
6114
throw new UnsupportedOperationException();
6117
public java.sql.SQLXML createSQLXML() throws SQLException {
6118
throw new UnsupportedOperationException();
6121
public boolean isValid(int timeout) throws SQLException {
6122
throw new UnsupportedOperationException();
6125
public void setClientInfo(String name, String value) throws java.sql.SQLClientInfoException {
6126
throw new UnsupportedOperationException();
6129
public void setClientInfo(Properties properties) throws java.sql.SQLClientInfoException {
6130
throw new UnsupportedOperationException();
6133
public String getClientInfo(String name) throws SQLException {
6134
throw new UnsupportedOperationException();
6137
public Properties getClientInfo() throws SQLException {
6138
throw new UnsupportedOperationException();
6141
public java.sql.Array createArrayOf(String typeName, Object[] elements) throws SQLException {
6142
throw new UnsupportedOperationException();
6145
public java.sql.Struct createStruct(String typeName, Object[] attributes) throws SQLException {
6146
throw new UnsupportedOperationException();
6149
public <T> T unwrap(Class<T> iface) throws SQLException {
6150
throw new UnsupportedOperationException();
6153
public boolean isWrapperFor(Class<?> iface) throws SQLException {
6154
throw new UnsupportedOperationException();