From 3659ab5e579985aa2c5a3ba9a8322737fb992adf Mon Sep 17 00:00:00 2001 From: Filipe Silva Date: Fri, 13 May 2022 17:47:54 +0100 Subject: [PATCH] Fix for Bug#106758 (33973048), DatabaseMetaData.getTypeInfo returns AUTO_INCREMENT = false for all datatypes. Change-Id: I3fa914c4a092be95758a3fe70dbcfb47fbfc0f86 --- CHANGES | 2 + .../com/mysql/cj/jdbc/DatabaseMetaData.java | 85 ++++++++++++------- .../regression/MetaDataRegressionTest.java | 39 +++++++++ 3 files changed, 94 insertions(+), 32 deletions(-) diff --git a/CHANGES b/CHANGES index 044220194..b65d3d94b 100644 --- a/CHANGES +++ b/CHANGES @@ -3,6 +3,8 @@ Version 8.0.30 + - Fix for Bug#106758 (33973048), DatabaseMetaData.getTypeInfo returns AUTO_INCREMENT = false for all datatypes. + - Fix for Bug#34090350, Update mappings for utf8mb3 and utf8mb4 collations. - Fix for Bug#106880 (34022110), Outdated description in connection property 'rewriteBatchedStatements'. diff --git a/src/main/user-impl/java/com/mysql/cj/jdbc/DatabaseMetaData.java b/src/main/user-impl/java/com/mysql/cj/jdbc/DatabaseMetaData.java index ba421e872..ada0f7928 100644 --- a/src/main/user-impl/java/com/mysql/cj/jdbc/DatabaseMetaData.java +++ b/src/main/user-impl/java/com/mysql/cj/jdbc/DatabaseMetaData.java @@ -3987,7 +3987,29 @@ private byte[][] getTypeInfo(String mysqlTypeName) throws SQLException { rowVal[8] = Integer.toString(java.sql.DatabaseMetaData.typeSearchable).getBytes(); // Searchable rowVal[9] = s2b(mt.isAllowed(MysqlType.FIELD_FLAG_UNSIGNED) ? "true" : "false"); // Unsignable rowVal[10] = s2b("false"); // Fixed Prec Scale - rowVal[11] = s2b("false"); // Auto Increment + switch (mt) { + case BIGINT: + case BIGINT_UNSIGNED: + case BOOLEAN: + case DOUBLE: + case DOUBLE_UNSIGNED: + case FLOAT: + case FLOAT_UNSIGNED: + case INT: + case INT_UNSIGNED: + case MEDIUMINT: + case MEDIUMINT_UNSIGNED: + case SMALLINT: + case SMALLINT_UNSIGNED: + case TINYINT: + case TINYINT_UNSIGNED: + rowVal[11] = s2b("true"); // Auto Increment + break; + default: + rowVal[11] = s2b("false"); // Auto Increment + break; + + } rowVal[12] = s2b(mt.getName()); // Locale Type Name switch (mt) { case DECIMAL: // TODO is it right? DECIMAL isn't a floating-point number... @@ -4038,50 +4060,49 @@ public java.sql.ResultSet getTypeInfo() throws SQLException { ArrayList tuples = new ArrayList<>(); - /* - * The following are ordered by java.sql.Types, and then by how closely the MySQL type matches the JDBC Type (per spec) - */ - tuples.add(new ByteArrayRow(getTypeInfo("BIT"), getExceptionInterceptor())); - tuples.add(new ByteArrayRow(getTypeInfo("BOOL"), getExceptionInterceptor())); - tuples.add(new ByteArrayRow(getTypeInfo("TINYINT"), getExceptionInterceptor())); - tuples.add(new ByteArrayRow(getTypeInfo("TINYINT UNSIGNED"), getExceptionInterceptor())); tuples.add(new ByteArrayRow(getTypeInfo("BIGINT"), getExceptionInterceptor())); tuples.add(new ByteArrayRow(getTypeInfo("BIGINT UNSIGNED"), getExceptionInterceptor())); - tuples.add(new ByteArrayRow(getTypeInfo("LONG VARBINARY"), getExceptionInterceptor())); - tuples.add(new ByteArrayRow(getTypeInfo("MEDIUMBLOB"), getExceptionInterceptor())); - tuples.add(new ByteArrayRow(getTypeInfo("LONGBLOB"), getExceptionInterceptor())); - tuples.add(new ByteArrayRow(getTypeInfo("BLOB"), getExceptionInterceptor())); - tuples.add(new ByteArrayRow(getTypeInfo("VARBINARY"), getExceptionInterceptor())); - tuples.add(new ByteArrayRow(getTypeInfo("TINYBLOB"), getExceptionInterceptor())); tuples.add(new ByteArrayRow(getTypeInfo("BINARY"), getExceptionInterceptor())); - tuples.add(new ByteArrayRow(getTypeInfo("LONG VARCHAR"), getExceptionInterceptor())); - tuples.add(new ByteArrayRow(getTypeInfo("MEDIUMTEXT"), getExceptionInterceptor())); - tuples.add(new ByteArrayRow(getTypeInfo("LONGTEXT"), getExceptionInterceptor())); - tuples.add(new ByteArrayRow(getTypeInfo("TEXT"), getExceptionInterceptor())); + tuples.add(new ByteArrayRow(getTypeInfo("BIT"), getExceptionInterceptor())); + tuples.add(new ByteArrayRow(getTypeInfo("BLOB"), getExceptionInterceptor())); + tuples.add(new ByteArrayRow(getTypeInfo("BOOL"), getExceptionInterceptor())); tuples.add(new ByteArrayRow(getTypeInfo("CHAR"), getExceptionInterceptor())); - tuples.add(new ByteArrayRow(getTypeInfo("ENUM"), getExceptionInterceptor())); - tuples.add(new ByteArrayRow(getTypeInfo("SET"), getExceptionInterceptor())); + tuples.add(new ByteArrayRow(getTypeInfo("DATE"), getExceptionInterceptor())); + tuples.add(new ByteArrayRow(getTypeInfo("DATETIME"), getExceptionInterceptor())); tuples.add(new ByteArrayRow(getTypeInfo("DECIMAL"), getExceptionInterceptor())); - tuples.add(new ByteArrayRow(getTypeInfo("NUMERIC"), getExceptionInterceptor())); - tuples.add(new ByteArrayRow(getTypeInfo("INTEGER"), getExceptionInterceptor())); - tuples.add(new ByteArrayRow(getTypeInfo("INTEGER UNSIGNED"), getExceptionInterceptor())); + tuples.add(new ByteArrayRow(getTypeInfo("DOUBLE PRECISION"), getExceptionInterceptor())); + tuples.add(new ByteArrayRow(getTypeInfo("DOUBLE PRECISION UNSIGNED"), getExceptionInterceptor())); + tuples.add(new ByteArrayRow(getTypeInfo("DOUBLE"), getExceptionInterceptor())); + tuples.add(new ByteArrayRow(getTypeInfo("DOUBLE UNSIGNED"), getExceptionInterceptor())); + tuples.add(new ByteArrayRow(getTypeInfo("ENUM"), getExceptionInterceptor())); + tuples.add(new ByteArrayRow(getTypeInfo("FLOAT"), getExceptionInterceptor())); tuples.add(new ByteArrayRow(getTypeInfo("INT"), getExceptionInterceptor())); tuples.add(new ByteArrayRow(getTypeInfo("INT UNSIGNED"), getExceptionInterceptor())); + tuples.add(new ByteArrayRow(getTypeInfo("INTEGER"), getExceptionInterceptor())); + tuples.add(new ByteArrayRow(getTypeInfo("INTEGER UNSIGNED"), getExceptionInterceptor())); + tuples.add(new ByteArrayRow(getTypeInfo("LONG VARBINARY"), getExceptionInterceptor())); + tuples.add(new ByteArrayRow(getTypeInfo("LONG VARCHAR"), getExceptionInterceptor())); + tuples.add(new ByteArrayRow(getTypeInfo("LONGBLOB"), getExceptionInterceptor())); + tuples.add(new ByteArrayRow(getTypeInfo("LONGTEXT"), getExceptionInterceptor())); + tuples.add(new ByteArrayRow(getTypeInfo("MEDIUMBLOB"), getExceptionInterceptor())); tuples.add(new ByteArrayRow(getTypeInfo("MEDIUMINT"), getExceptionInterceptor())); tuples.add(new ByteArrayRow(getTypeInfo("MEDIUMINT UNSIGNED"), getExceptionInterceptor())); + tuples.add(new ByteArrayRow(getTypeInfo("MEDIUMTEXT"), getExceptionInterceptor())); + tuples.add(new ByteArrayRow(getTypeInfo("NUMERIC"), getExceptionInterceptor())); + tuples.add(new ByteArrayRow(getTypeInfo("REAL"), getExceptionInterceptor())); + tuples.add(new ByteArrayRow(getTypeInfo("SET"), getExceptionInterceptor())); tuples.add(new ByteArrayRow(getTypeInfo("SMALLINT"), getExceptionInterceptor())); tuples.add(new ByteArrayRow(getTypeInfo("SMALLINT UNSIGNED"), getExceptionInterceptor())); - tuples.add(new ByteArrayRow(getTypeInfo("FLOAT"), getExceptionInterceptor())); - tuples.add(new ByteArrayRow(getTypeInfo("DOUBLE"), getExceptionInterceptor())); - tuples.add(new ByteArrayRow(getTypeInfo("DOUBLE PRECISION"), getExceptionInterceptor())); - tuples.add(new ByteArrayRow(getTypeInfo("REAL"), getExceptionInterceptor())); - tuples.add(new ByteArrayRow(getTypeInfo("VARCHAR"), getExceptionInterceptor())); - tuples.add(new ByteArrayRow(getTypeInfo("TINYTEXT"), getExceptionInterceptor())); - tuples.add(new ByteArrayRow(getTypeInfo("DATE"), getExceptionInterceptor())); - tuples.add(new ByteArrayRow(getTypeInfo("YEAR"), getExceptionInterceptor())); + tuples.add(new ByteArrayRow(getTypeInfo("TEXT"), getExceptionInterceptor())); tuples.add(new ByteArrayRow(getTypeInfo("TIME"), getExceptionInterceptor())); - tuples.add(new ByteArrayRow(getTypeInfo("DATETIME"), getExceptionInterceptor())); tuples.add(new ByteArrayRow(getTypeInfo("TIMESTAMP"), getExceptionInterceptor())); + tuples.add(new ByteArrayRow(getTypeInfo("TINYBLOB"), getExceptionInterceptor())); + tuples.add(new ByteArrayRow(getTypeInfo("TINYINT"), getExceptionInterceptor())); + tuples.add(new ByteArrayRow(getTypeInfo("TINYINT UNSIGNED"), getExceptionInterceptor())); + tuples.add(new ByteArrayRow(getTypeInfo("TINYTEXT"), getExceptionInterceptor())); + tuples.add(new ByteArrayRow(getTypeInfo("VARBINARY"), getExceptionInterceptor())); + tuples.add(new ByteArrayRow(getTypeInfo("VARCHAR"), getExceptionInterceptor())); + tuples.add(new ByteArrayRow(getTypeInfo("YEAR"), getExceptionInterceptor())); // TODO add missed types (aliases) diff --git a/src/test/java/testsuite/regression/MetaDataRegressionTest.java b/src/test/java/testsuite/regression/MetaDataRegressionTest.java index 28c9a8486..2c60ebcd1 100644 --- a/src/test/java/testsuite/regression/MetaDataRegressionTest.java +++ b/src/test/java/testsuite/regression/MetaDataRegressionTest.java @@ -5465,4 +5465,43 @@ public void testBug82084() throws Exception { } } } + + /** + * Tests fix for Bug#106758 (33973048), DatabaseMetaData.getTypeInfo returns AUTO_INCREMENT = false for all datatypes. + * + * @throws Exception + */ + @Test + public void testBug106758() throws Exception { + DatabaseMetaData dbmd = this.conn.getMetaData(); + + this.rs = dbmd.getTypeInfo(); + while (this.rs.next()) { + StringBuilder sb = new StringBuilder("CREATE TEMPORARY TABLE testBug106758 (col "); + sb.append(this.rs.getString("TYPE_NAME")); + if (this.rs.getString("CREATE_PARAMS").startsWith("(M)")) { + sb.append("(5)"); + } else if (this.rs.getString("CREATE_PARAMS").startsWith("('value")) { + sb.append(" ('value')"); + } + sb.append(" AUTO_INCREMENT PRIMARY KEY)"); // Some types don't support primary keys like this, however, the query fails due to AUTO_INCREMENT first. + + if (this.rs.getBoolean("AUTO_INCREMENT")) { + try { + this.stmt.execute(sb.toString()); + } catch (SQLException e) { + fail("Type " + this.rs.getString("TYPE_NAME") + " does not support AUTO_INCREMENT."); + } finally { + this.stmt.execute("DROP TABLE IF EXISTS testBug106758"); + } + } else { + assertThrows("Type " + this.rs.getString("TYPE_NAME") + " supports AUTO_INCREMENT.", SQLException.class, + "Incorrect column specifier for column 'col'", () -> { + this.stmt.execute(sb.toString()); + this.stmt.execute("DROP TABLE IF EXISTS testBug106758"); + return null; + }); + } + } + } }