Skip to content

Conversation

imtbkcat
Copy link

What have you changed? (mandatory)

I add code to fix bug when query column size of set and enum type.
Originally the column size of set and enum type while be default value 2^64 - 1. (See mysql/util:65)
This is different from MySQL's result.
For example, in MySQL 5.7.

mysql> create table bug22613 ( s set('a','bc','def','ghij') default NULL, t enum('a', 'ab', 'cdef'), s2 
SET('1','2','3','4','1585','ONE','TWO','Y','N','THREE'));
Query OK, 0 rows affected (0.11 sec)

mysql> SELECT column_name,         character_maximum_length  FROM   
information_schema.columns  WHERE  table_schema = Database()         AND         table_name = 
'bug22613'         AND         column_name = 't';
+-------------+--------------------------+
| column_name | character_maximum_length |
+-------------+--------------------------+
| t           |                        4 |
+-------------+--------------------------+
1 row in set (0.00 sec)

But in TiDB:

mysql> SELECT column_name,         character_maximum_length  FROM   
information_schema.columns  WHERE  table_schema = Database()         AND         table_name = 
'bug22613'         AND         column_name = 't';
+-------------+--------------------------+
| column_name | character_maximum_length |
+-------------+--------------------------+
| t           |     18446744073709551615 |
+-------------+--------------------------+
1 row in set (0.00 sec)

I fix this bug by adding code to calculate size of set and enum like MySQL.

What is the type of the changes? (mandatory)

  • Bug fix (non-breaking change which fixes an issue)

How has this PR been tested? (mandatory)

unit test

Does this PR affect documentation (docs/docs-cn) update? (mandatory)

No

Does this PR affect tidb-ansible update? (mandatory)

No

Does this PR need to be added to the release notes? (mandatory)

No

Refer to a related PR or issue link (optional)

Fix #7297

Benchmark result if necessary (optional)

Add a few positive/negative examples (optional)

testkit.Rows("s2 30"))
tk.MustQuery("select column_name, character_maximum_length from information_schema.columns where table_schema=Database() and table_name = 't' and column_name = 'e1'").Check(
testkit.Rows("e1 4"))
//
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove this line.

}
colLen = sumLen + cnt
}
if col.Tp == mysql.TypeEnum {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

else if

@@ -797,6 +797,30 @@ func dataForColumnsInTable(schema *model.DBInfo, tbl *model.TableInfo) [][]types
if colLen == types.UnspecifiedLength {
colLen = defaultFlen
}
if col.Tp == mysql.TypeSet {
//example: In MySQL set('a','bc','def','ghij') has length 13, This is because
//len('a')+len('bc')+len('def')+len('ghij')+len(ThreeComma)=13
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's better to check whether MySQL uses this rule.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is better to add a reference link.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, I'm looking for MySQL's method.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's better to add the link to the comments.

}
if col.Tp == mysql.TypeEnum {
//exapmle: In MySQL enum('a', 'ab', 'cdef') has length 4, This is because
//the longest string in the enum is 'cdef'
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ditto

@imtbkcat
Copy link
Author

/run-all-tests

@imtbkcat
Copy link
Author

/rebuild

@imtbkcat
Copy link
Author

/run-all-tests

@@ -77,6 +77,16 @@ func (s *testSuite) TestDataForTableRowsCountField(c *C) {
tk.MustExec("create user xxx")
tk.MustExec("flush privileges")

//Test for length of enmu and set
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

enmu -> enum. And it is better to add a space between // and comment.

}
colLen = sumLen + cnt
} else if col.Tp == mysql.TypeEnum {
//exapmle: In MySQL enum('a', 'ab', 'cdef') has length 4, This is because
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • exapmle-> example.
  • It is better to add a space between // and comment.
  • It is better to remove the This is.

@imtbkcat
Copy link
Author

/run-all-tests

@imtbkcat
Copy link
Author

PTAL @jackysp @zhexuany @shenli

Copy link
Member

@jackysp jackysp left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@imtbkcat imtbkcat added the status/LGT1 Indicates that a PR has LGTM 1. label Aug 13, 2018
// Example: In MySQL set('a','bc','def','ghij') has length 13, because
// len('a')+len('bc')+len('def')+len('ghij')+len(ThreeComma)=13
// Reference link: https://bugs.mysql.com/bug.php?id=22613
sumLen, cnt := 0, 0
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

how about this:

colLen = 0
for _, ele := range col.Elems {
	colLen += len(ele)
}
if len(col.Elems) != 0 {
	colLen = len(col.Elems) - 1
}

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@crazycs520
it looks grate. But it should be:

if len(col.Elems) != 0 {
    colLen += (len(col.Elems) - 1)
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ye~😢

@@ -77,6 +77,16 @@ func (s *testSuite) TestDataForTableRowsCountField(c *C) {
tk.MustExec("create user xxx")
tk.MustExec("flush privileges")

//Test for length of enum and set
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add space. // Test....

Copy link
Contributor

@crazycs520 crazycs520 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@imtbkcat
Copy link
Author

PTAL @winoros @crazycs520

@crazycs520 crazycs520 added status/LGT2 Indicates that a PR has LGTM 2. and removed status/LGT1 Indicates that a PR has LGTM 1. labels Aug 13, 2018
@imtbkcat
Copy link
Author

/run-all-tests

@imtbkcat imtbkcat merged commit e43e548 into pingcap:master Aug 13, 2018
@imtbkcat imtbkcat deleted the fix7297 branch August 13, 2018 11:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status/LGT2 Indicates that a PR has LGTM 2. type/bugfix This PR fixes a bug. type/compatibility
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Column length is wrong for type set
7 participants