@@ -57,6 +57,32 @@ final class PooledConnection extends ConnectionDelegator {
5757
5858 private static final int RO_MYSQL_1290 = 1290 ;
5959
60+ /**
61+ * Constant for schema/catalog, when we are in SCHEMA_CATALOG_UNKNOWN state
62+ * This is used for correct cache key computation. (We cannot use 'null'
63+ * here, as we might get a collision in edge cases)
64+ */
65+ private static final String UNKNOWN = "@unknown" ;
66+
67+ /**
68+ * The schema/catalog is unknown, that means, we have not yet touched the
69+ * value on the underlying connection.
70+ * We do not have to restore it.
71+ */
72+ private static final int SCHEMA_CATALOG_UNKNOWN = 0 ;
73+
74+ /**
75+ * The schema/catalog is changed. The original value has to be restored on
76+ * close()
77+ */
78+ private static final int SCHEMA_CATALOG_CHANGED = 1 ;
79+
80+ /**
81+ * We know the original value of the underlying connection, but there is no
82+ * demand to restore it.
83+ */
84+ private static final int SCHEMA_CATALOG_KNOWN = 2 ;
85+
6086 private final String name ;
6187 private final ConnectionPool pool ;
6288 private final Connection connection ;
@@ -82,12 +108,14 @@ final class PooledConnection extends ConnectionDelegator {
82108 */
83109 private boolean failoverToReadOnly ;
84110 private boolean resetAutoCommit ;
85- private boolean resetSchema ;
86- private boolean resetCatalog ;
87- private boolean initialisedSchema ;
88- private boolean initialisedCatalog ;
89- private String currentSchema ;
90- private String currentCatalog ;
111+ private int schemaState = SCHEMA_CATALOG_UNKNOWN ;
112+ private int catalogState = SCHEMA_CATALOG_UNKNOWN ;
113+
114+ // this is used for cache computation
115+ private String cacheKeySchema = UNKNOWN ;
116+ private String cacheKeyCatalog = UNKNOWN ;
117+
118+ // original values are lazily initialized and restored on close()
91119 private String originalSchema ;
92120 private String originalCatalog ;
93121
@@ -122,10 +150,17 @@ final class PooledConnection extends ConnectionDelegator {
122150 this .name = pool .name () + uniqueId ;
123151 this .originalSchema = pool .schema ();
124152 this .originalCatalog = pool .catalog ();
125- this .initialisedSchema = originalSchema != null ;
126- this .initialisedCatalog = originalCatalog != null ;
127- this .currentSchema = originalSchema != null ? originalSchema : "@default" ;
128- this .currentCatalog = originalCatalog != null ? originalCatalog : "@default" ;
153+ if (originalSchema != null ) {
154+ schemaState = SCHEMA_CATALOG_KNOWN ;
155+ this .cacheKeySchema = originalSchema ;
156+ // if schema & catalog is defined, we can be sure, that connection is initialized properly
157+ assert originalSchema .equals (connection .getSchema ()) : "Connection is in the wrong schema: " + connection .getSchema () + ", expected: " + originalSchema ;
158+ }
159+ if (originalCatalog != null ) {
160+ catalogState = SCHEMA_CATALOG_KNOWN ;
161+ this .cacheKeyCatalog = originalCatalog ;
162+ assert originalCatalog .equals (connection .getCatalog ()) : "Connection is in the wrong catalog: " + connection .getCatalog () + ", expected: " + originalCatalog ;
163+ }
129164 this .pstmtCache = new PstmtCache (pool .pstmtCacheSize ());
130165 this .maxStackTrace = pool .maxStackTraceSize ();
131166 this .creationTime = System .currentTimeMillis ();
@@ -287,7 +322,7 @@ void returnPreparedStatement(ExtendedPreparedStatement pstmt) {
287322 */
288323 @ Override
289324 public PreparedStatement prepareStatement (String sql , int returnKeysFlag ) throws SQLException {
290- String key = sql + ':' + currentSchema + ':' + currentCatalog + ':' + returnKeysFlag ;
325+ String key = sql + ':' + cacheKeySchema + ':' + cacheKeyCatalog + ':' + returnKeysFlag ;
291326 return prepareStatement (sql , true , returnKeysFlag , key );
292327 }
293328
@@ -296,7 +331,7 @@ public PreparedStatement prepareStatement(String sql, int returnKeysFlag) throws
296331 */
297332 @ Override
298333 public PreparedStatement prepareStatement (String sql ) throws SQLException {
299- String key = sql + ':' + currentSchema + ':' + currentCatalog ;
334+ String key = sql + ':' + cacheKeySchema + ':' + cacheKeyCatalog ;
300335 return prepareStatement (sql , false , 0 , key );
301336 }
302337
@@ -350,12 +385,21 @@ public PreparedStatement prepareStatement(String sql, int resultSetType, int res
350385 * Reset the connection for returning to the client. Resets the status,
351386 * startUseTime and hadErrors.
352387 */
353- void resetForUse () {
388+ void resetForUse () throws SQLException {
354389 this .status = STATUS_ACTIVE ;
355390 this .startUseTime = System .currentTimeMillis ();
356391 this .createdByMethod = null ;
357392 this .lastStatement = null ;
358393 this .hadErrors = false ;
394+ // CHECKME: Shoud we keep the asserts here or should we even reset schema/catalog here
395+ assert schemaState != SCHEMA_CATALOG_CHANGED : "connection is in the wrong state (not properly closed)" ;
396+ if (schemaState == SCHEMA_CATALOG_KNOWN ) {
397+ assert originalSchema .equals (getSchema ()) : "connection is in the wrong schema: " + getSchema () + ", expected: " + originalSchema ;
398+ }
399+ assert catalogState != SCHEMA_CATALOG_CHANGED : "connection is in the wrong state (not properly closed)" ;
400+ if (catalogState == SCHEMA_CATALOG_KNOWN ) {
401+ assert originalCatalog .equals (getCatalog ()) : "connection is in the wrong catalog: " + getCatalog () + ", expected: " + originalCatalog ;
402+ }
359403 }
360404
361405 /**
@@ -426,16 +470,17 @@ public void close() throws SQLException {
426470 resetIsolationReadOnlyRequired = false ;
427471 }
428472
429- if (resetSchema ) {
473+ if (schemaState == SCHEMA_CATALOG_CHANGED ) {
430474 connection .setSchema (originalSchema );
431- currentSchema = null ;
432- resetSchema = false ;
475+ // we can use original value for cache computation from now on
476+ cacheKeySchema = originalSchema ;
477+ schemaState = SCHEMA_CATALOG_KNOWN ;
433478 }
434479
435- if (resetCatalog ) {
480+ if (catalogState == SCHEMA_CATALOG_CHANGED ) {
436481 connection .setCatalog (originalCatalog );
437- currentCatalog = null ;
438- resetCatalog = false ;
482+ cacheKeyCatalog = originalCatalog ;
483+ catalogState = SCHEMA_CATALOG_KNOWN ;
439484 }
440485
441486 // the connection is assumed GOOD so put it back in the pool
@@ -706,13 +751,13 @@ public void setSchema(String schema) throws SQLException {
706751 if (status == STATUS_IDLE ) {
707752 throw new SQLException (IDLE_CONNECTION_ACCESSED_ERROR + "setSchema()" );
708753 }
709- if (! initialisedSchema ) {
754+ if (schemaState == SCHEMA_CATALOG_UNKNOWN ) {
710755 // lazily initialise the originalSchema
711756 originalSchema = getSchema ();
712- initialisedSchema = true ;
757+ // state would be KNOWN here
713758 }
714- currentSchema = schema ;
715- resetSchema = true ;
759+ schemaState = SCHEMA_CATALOG_CHANGED ;
760+ cacheKeySchema = schema ;
716761 connection .setSchema (schema );
717762 }
718763
@@ -721,12 +766,11 @@ public void setCatalog(String catalog) throws SQLException {
721766 if (status == STATUS_IDLE ) {
722767 throw new SQLException (IDLE_CONNECTION_ACCESSED_ERROR + "setCatalog()" );
723768 }
724- if (! initialisedCatalog ) {
769+ if (schemaState == SCHEMA_CATALOG_UNKNOWN ) {
725770 originalCatalog = getCatalog ();
726- initialisedCatalog = true ;
727771 }
728- currentCatalog = catalog ;
729- resetCatalog = true ;
772+ catalogState = SCHEMA_CATALOG_CHANGED ;
773+ cacheKeyCatalog = catalog ;
730774 connection .setCatalog (catalog );
731775 }
732776
0 commit comments