| Bug #81755 | Interpret BIT fails from MysqlaUtils class | ||
|---|---|---|---|
| Submitted: | 7 Jun 2016 15:41 | Modified: | 11 Jan 2020 17:02 |
| Reporter: | Illia Lavryk | Email Updates: | |
| Status: | Closed | Impact on me: | |
| Category: | Connector / J | Severity: | S3 (Non-critical) |
| Version: | 6.0.2 | OS: | Any |
| Assigned to: | CPU Architecture: | Any | |
| Tags: | Interpret, MysqlaUtils | ||
[9 Jun 2016 9:56]
Chiranjeevi Battula
Hello Illia Lavryk, Thank you for the bug report. Could you please provide repeatable test case (exact steps/sample code, create table script etc. - please make it as private if you prefer) to confirm this issue at our end? Thanks, Chiranjeevi.
[15 Jun 2016 11:29]
Chiranjeevi Battula
Hello Илья Лаврик, Thank you for your feedback. Could you please provide complete repeatable test case (exact steps, sample project/code without using external components, create table scripts, full stack trace etc. - please make it as private if you prefer) to confirm this issue at our end? Thanks, Chiranjeevi.
[31 Jul 2016 1:20]
Patrick Herrera
Hi, have the exact same issue. I'm using Spring/JPA/Hibernate, but my stack trace is fundamentally the same: at com.mysql.cj.mysqla.MysqlaUtils.bitToLong(MysqlaUtils.java:68) at com.mysql.cj.core.io.MysqlTextValueDecoder.decodeBit(MysqlTextValueDecoder.java:231) at com.mysql.cj.jdbc.ResultSetRow.decodeAndCreateReturnValue(ResultSetRow.java:170) at com.mysql.cj.jdbc.ResultSetRow.getValueFromBytes(ResultSetRow.java:269) at com.mysql.cj.jdbc.BufferRow.getValue(BufferRow.java:349) at com.mysql.cj.jdbc.ResultSetImpl.getNonStringValueFromRow(ResultSetImpl.java:813) at com.mysql.cj.jdbc.ResultSetImpl.getBoolean(ResultSetImpl.java:904) at com.mysql.cj.jdbc.ResultSetImpl.getBoolean(ResultSetImpl.java:908) at org.hibernate.type.descriptor.sql.BooleanTypeDescriptor$2.doExtract(BooleanTypeDescriptor.java:59) at org.hibernate.type.descriptor.sql.BasicExtractor.extract(BasicExtractor.java:47) ... snip at org.hibernate.loader.hql.QueryLoader.list(QueryLoader.java:501) at org.hibernate.hql.internal.ast.QueryTranslatorImpl.list(QueryTranslatorImpl.java:371) at org.hibernate.engine.query.spi.HQLQueryPlan.performList(HQLQueryPlan.java:216) at org.hibernate.internal.SessionImpl.list(SessionImpl.java:1326) at org.hibernate.internal.QueryImpl.list(QueryImpl.java:87) at org.hibernate.jpa.internal.QueryImpl.list(QueryImpl.java:606) at org.hibernate.jpa.internal.QueryImpl.getResultList(QueryImpl.java:483) at org.hibernate.jpa.criteria.compile.CriteriaQueryTypeQueryAdapter.getResultList(CriteriaQueryTypeQueryAdapter.java:50) at org.springframework.data.jpa.repository.query.JpaQueryExecution$CollectionExecution.doExecute(JpaQueryExecution.java:114) at org.springframework.data.jpa.repository.query.JpaQueryExecution.execute(JpaQueryExecution.java:78) at org.springframework.data.jpa.repository.query.AbstractJpaQuery.doExecute(AbstractJpaQuery.java:102) at org.springframework.data.jpa.repository.query.AbstractJpaQuery.execute(AbstractJpaQuery.java:92) I've tried changing the underlying column to a tiny int or a full int with no difference except the array index being checked (and out of bounds) changes. The query that is being executed in this case is effectively: select * from Competition as c where c.active = true I'm connecting to Mysql 5.6.27 and can confirm this issue occurs in version 6.0.3 and 6.0.2 of the mysql-connector. However, going back to version 5.1.39 and the problem disappears.
[5 Dec 2017 10:28]
Rudi Vankeirsbilck
I ran into the same issue with version 5.1.23 but it does not always occur, it depends on the bit value that I am reading. I think you will be able to reproduce this with the following code constructs:
CREATE TABLE `EXAMPLE` (
`ID` varchar(80) NOT NULL,
`BITS` bit(7) DEFAULT NULL,
PRIMARY KEY (`ID`),
);
INSERT INTO EXAMPLE VALUES('FINE', 0b1111111);
INSERT INTO EXAMPLE VALUES('FINE-TOO', 0b1100000);
INSERT INTO EXAMPLE VALUES('CRASH', 0b0011111);
Connection connection = ...;
PreparedStatement statement = connection.prepareStatement("select BITS from EXAMPLE where ID = 'CRASH'");
ResultSet rs = statement.executeQuery();
rs.getInt(1);
Note that running the same code for IDs "FINE" and "FINE-TOO" does not produce the error.

Description: I created a table with a BIT column. In my java app i tried to get it from ResultSet and it always fail. I noticed through debug mode that it fails in next method: public static long bitToLong(byte[] bytes, int offset, int length) from MysqlaUtils class. The input data was bytes - as 1024 length {1,57,1,0,10,49,57,56,56,45...} offset - 3 length - 1 StackTrace is: Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 3 at com.mysql.cj.mysqla.MysqlaUtils.bitToLong(MysqlaUtils.java:68) at com.mysql.cj.core.io.MysqlTextValueDecoder.decodeBit(MysqlTextValueDecoder.java:231) at com.mysql.cj.jdbc.ResultSetRow.decodeAndCreateReturnValue(ResultSetRow.java:170) at com.mysql.cj.jdbc.ResultSetRow.getValueFromBytes(ResultSetRow.java:269) at com.mysql.cj.jdbc.BufferRow.getValue(BufferRow.java:349) at com.mysql.cj.jdbc.ResultSetImpl.getNonStringValueFromRow(ResultSetImpl.java:813) at com.mysql.cj.jdbc.ResultSetImpl.getBoolean(ResultSetImpl.java:904) at com.mysql.cj.jdbc.ResultSetImpl.getBoolean(ResultSetImpl.java:908) How to repeat: it is not so hard to reproduce, Just call with parameters a specified before in description So in this method we declare long[] steps = new long[length]; and 'length' in my case was 1 and the problem with store result look at this for (int i = offset + length - 1; i >= offset; i--) { steps[i] = (long) (bytes[i] & 0xff) << shift; shift += 8; } 'i' kept offset + length value which was in my case as 3 Suggested fix: steps[i - offset] = (long) (bytes[i] & 0xff) << shift;