[MDEV-29491] InnoDB: Strange printed result on SELECT DISTINCT col_bit ... ORDER BY col_bit Created: 2022-09-07  Updated: 2022-09-08

Status: Open
Project: MariaDB Server
Component/s: Data types
Affects Version/s: 10.5.18, 10.6.10
Fix Version/s: 10.5, 10.6

Type: Bug Priority: Major
Reporter: Matthias Leich Assignee: Alexander Barkov
Resolution: Unresolved Votes: 0
Labels: None


 Description   

CREATE TABLE `t_innodb` ( `pk` int(11) NOT NULL, `col_bit` bit(29) NOT NULL DEFAULT b'0',  PRIMARY KEY (`pk`))  ENGINE = InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE `t_myisam` ( `pk` int(11) NOT NULL, `col_bit` bit(29) NOT NULL DEFAULT b'0',  PRIMARY KEY (`pk`))  ENGINE = MyISAM DEFAULT CHARSET=latin1;
INSERT INTO `t_innodb` ( `pk` ) VALUES ( 38502 ) ;
INSERT INTO t_myisam SELECT * FROM t_innodb;
SELECT `col_bit` FROM `t_innodb`;
col_bit
                  <= I guess the value is just not printable like in several other cases below.
SELECT `col_bit` FROM `t_myisam`;
col_bit
 
SELECT `col_bit` FROM `t_innodb` ORDER BY `col_bit`;
col_bit
 
SELECT `col_bit` FROM `t_myisam` ORDER BY `col_bit`;
col_bit
 
SELECT DISTINCT `col_bit` FROM `t_innodb` ORDER BY `pk`;
col_bit
 
SELECT DISTINCT `col_bit` FROM `t_myisam` ORDER BY `pk`;
col_bit
 
SELECT DISTINCT `col_bit` FROM `t_innodb` ORDER BY `col_bit`;
col_bit
0                     <== Why that?
SELECT DISTINCT `col_bit` FROM `t_myisam` ORDER BY `col_bit`;
col_bit
 
CREATE TABLE t_aux AS SELECT DISTINCT `col_bit` FROM `t_innodb` ORDER BY `pk`;
SHOW CREATE TABLE t_aux;
Table   Create Table
t_aux   CREATE TABLE `t_aux` (
  `col_bit` bit(29) NOT NULL DEFAULT b'0'
) ENGINE=MyISAM DEFAULT CHARSET=latin1
SELECT * FROM t_aux;
col_bit
                   
SELECT pk, col_bit FROM t_innodb INNER JOIN t_myisam USING (pk, col_bit);
pk      col_bit
38502                <==  This looks reasonable.
DROP TABLE t_innodb;
DROP TABLE t_myisam;
DROP TABLE t_aux;



 Comments   
Comment by Alexander Barkov [ 2022-09-08 ]

BIT was implemented in an unfortunate way. It has hybrid nature. In some context it looks like INT, in some context it looks like BINARY.

SELECT bit_col FROM t1; -- works like BINARY

A possible workaround is to cast BIT to a number, either implicitly through a numeric expression, or explicitly through CAST:

MariaDB [test]> SELECT col_bit + 0, CAST(col_bit AS UNSIGNED) FROM t_innodb;
+-------------+---------------------------+
| col_bit + 0 | CAST(col_bit AS UNSIGNED) |
+-------------+---------------------------+
|           0 |                         0 |
+-------------+---------------------------+

The manual at https://mariadb.com/kb/en/bit/ also suggests to use HEX(), OCT() or BIN() functions to see a BIT column value.

Strictly, this is not a bug. It was intentionally implemented this way.
However, it looks confusing. I'd prefer BIT did not have hybrid BINARY-alike properties.

It could be displayed as:

  • either as a number
  • or as a bit string

Displaying it as BINARY(NBYTES) represending the underlying array of bytes looks meaningless.

Comment by Matthias Leich [ 2022-09-08 ]

Hi Bar,
many thanks for your explanation.
The things which make me nervous are the difference of the printed results for
- InnoDB versus MyISAM  == The storage engine used has obvious an impact on how certain values are printed.
  SELECT DISTINCT `col_bit` FROM t_innodb ORDER BY `col_bit`    --> 0
  SELECT DISTINCT `col_bit` FROM t_myisam ORDER BY `col_bit`   --> not printable
- ORDER BY pk versus ORDER BY col_bit for InnoDB  == The column used for ORDER BY has obvious an impact on how certain values are printed.
   SELECT DISTINCT `col_bit` FROM t_innodb ORDER BY `pk`           --> not printable
   SELECT DISTINCT `col_bit` FROM t_innodb ORDER BY `col_bit`  --> 0
Regarding my testing for InnoDB with the random query generator (RQG) that all played fortunately only
a minor and temporary role.
I tried to reuse some existing RQG component (lib/GenTest/Validator/RepeatableRead.pm) for a RQG grammar it was not 100% compatible with.
And that combination caused that RQG detected a result set difference and declared to have met a defect. 

Generated at Thu Feb 08 10:09:00 UTC 2024 using Jira 8.20.16#820016-sha1:9d11dbea5f4be3d4cc21f03a88dd11d8c8687422.