2626import java .sql .Statement ;
2727import java .sql .Types ;
2828import java .util .ArrayList ;
29+ import java .util .Collections ;
2930import java .util .List ;
31+ import java .util .Map ;
32+ import java .util .concurrent .locks .Lock ;
33+ import java .util .concurrent .locks .ReentrantLock ;
3034import java .util .stream .Collectors ;
3135
36+ import com .mysql .cj .CharsetSettings ;
3237import com .mysql .cj .Messages ;
3338import com .mysql .cj .MysqlType ;
3439import com .mysql .cj .ServerVersion ;
3540import com .mysql .cj .conf .PropertyDefinitions .DatabaseTerm ;
3641import com .mysql .cj .exceptions .MysqlErrorNumbers ;
3742import com .mysql .cj .jdbc .exceptions .SQLError ;
3843import com .mysql .cj .jdbc .result .ResultSetFactory ;
44+ import com .mysql .cj .util .LRUCache ;
3945import com .mysql .cj .util .StringUtils ;
4046
4147/**
4248 * DatabaseMetaData implementation that uses INFORMATION_SCHEMA
4349 */
4450public class DatabaseMetaDataInformationSchema extends DatabaseMetaData {
4551
52+ static final Lock INFORMATION_SCHEMA_COLLATION_CACHE_LOCK = new ReentrantLock ();
53+ static Map <ServerVersion , String > informationSchemaCollationCache = Collections .synchronizedMap (new LRUCache <>(10 ));
54+
4655 protected DatabaseMetaDataInformationSchema (JdbcConnection connToSet , String databaseToSet , ResultSetFactory resultSetFactory ) {
4756 super (connToSet , databaseToSet , resultSetFactory );
4857 }
@@ -351,6 +360,7 @@ public ResultSet getColumns(String catalog, String schemaPattern, String tableNa
351360 final String dbFilter = normalizeIdentifierQuoting (chooseDatabaseTerm (catalog , schemaPattern ));
352361 final String tableNameFilter = normalizeIdentifierQuoting (tableNamePattern );
353362 final String columnNameFilter = normalizeIdentifierQuoting (columnNamePattern );
363+ final String infScCollation = getInformationSchemaCollation ();
354364
355365 StringBuilder query = new StringBuilder ("SELECT" );
356366 query .append (chooseBasedOnDatabaseTerm (() -> " TABLE_SCHEMA, NULL," , () -> " TABLE_CATALOG, TABLE_SCHEMA," )); // TABLE_CAT, TABLE_SCHEM
@@ -362,8 +372,8 @@ public ResultSet getColumns(String catalog, String schemaPattern, String tableNa
362372 query .append (" " ).append (MAX_BUFFER_SIZE ).append (" AS BUFFER_LENGTH," ); // BUFFER_LENGTH
363373 appendDecimalDigitsClause (query ).append (" AS DECIMAL_DIGITS," ); // DECIMAL_DIGITS
364374 query .append (" 10 AS NUM_PREC_RADIX," ); // NUM_PREC_RADIX
365- query .append (" CASE WHEN IS_NULLABLE = 'NO' THEN " ).append (columnNoNulls );
366- query .append (" ELSE CASE WHEN IS_NULLABLE = 'YES' THEN " ).append (columnNullable );
375+ query .append (" CASE WHEN IS_NULLABLE COLLATE " + infScCollation + " = 'NO' THEN " ).append (columnNoNulls );
376+ query .append (" ELSE CASE WHEN IS_NULLABLE COLLATE " + infScCollation + " = 'YES' THEN " ).append (columnNullable );
367377 query .append (" ELSE " ).append (columnNullableUnknown ).append (" END END AS NULLABLE," ); // NULLABLE
368378 query .append (" COLUMN_COMMENT AS REMARKS," ); // REMARKS
369379 query .append (" COLUMN_DEFAULT AS COLUMN_DEF," ); // COLUMN_DEF
@@ -377,8 +387,8 @@ public ResultSet getColumns(String catalog, String schemaPattern, String tableNa
377387 query .append (" NULL AS SCOPE_SCHEMA," ); // SCOPE_SCHEMA
378388 query .append (" NULL AS SCOPE_TABLE," ); // SCOPE_TABLE
379389 query .append (" NULL AS SOURCE_DATA_TYPE," ); // SOURCE_DATA_TYPE
380- query .append (" IF (EXTRA LIKE '%auto_increment%','YES','NO') AS IS_AUTOINCREMENT," ); // IS_AUTOINCREMENT
381- query .append (" IF (EXTRA LIKE '%GENERATED%','YES','NO') AS IS_GENERATEDCOLUMN" ); // IS_GENERATEDCOLUMN
390+ query .append (" IF (EXTRA COLLATE " + infScCollation + " LIKE '%auto_increment%','YES','NO') AS IS_AUTOINCREMENT," ); // IS_AUTOINCREMENT
391+ query .append (" IF (EXTRA COLLATE " + infScCollation + " LIKE '%GENERATED%','YES','NO') AS IS_GENERATEDCOLUMN" ); // IS_GENERATEDCOLUMN
382392 query .append (" FROM INFORMATION_SCHEMA.COLUMNS" );
383393
384394 StringBuilder condition = new StringBuilder ();
@@ -1141,4 +1151,34 @@ public ResultSet getVersionColumns(String catalog, String schema, String table)
11411151 }
11421152 }
11431153
1154+ private String getInformationSchemaCollation () throws SQLException {
1155+ String informationSchemaCollation = informationSchemaCollationCache .get (getJdbcConnection ().getServerVersion ());
1156+ if (informationSchemaCollation != null ) {
1157+ return informationSchemaCollation ;
1158+ }
1159+
1160+ INFORMATION_SCHEMA_COLLATION_CACHE_LOCK .lock ();
1161+ try {
1162+ // Double check, maybe another thread already added it.
1163+ informationSchemaCollation = informationSchemaCollationCache .get (getJdbcConnection ().getServerVersion ());
1164+ if (informationSchemaCollation != null ) {
1165+ return informationSchemaCollation ;
1166+ }
1167+
1168+ Statement stmt = getJdbcConnection ().getMetaDataSafeStatement ();
1169+ ResultSet rs = stmt .executeQuery ("SELECT DEFAULT_COLLATION_NAME FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME = 'information_schema'" );
1170+ if (rs .next ()) {
1171+ informationSchemaCollation = rs .getString (1 );
1172+ } else {
1173+ informationSchemaCollation = getSession ().getServerSession ().getServerVariable (CharsetSettings .COLLATION_CONNECTION );
1174+ }
1175+ stmt .close ();
1176+
1177+ informationSchemaCollationCache .put (getJdbcConnection ().getServerVersion (), informationSchemaCollation );
1178+ return informationSchemaCollation ;
1179+ } finally {
1180+ INFORMATION_SCHEMA_COLLATION_CACHE_LOCK .unlock ();
1181+ }
1182+ }
1183+
11441184}
0 commit comments