ClickHouse / ClickHouse/ClickHouse
The MySQL connector to ClickHouse does not work properly with the Decimal type
- Dominant language
- C++
- Stars
- 49.9k
- Forks
- 9k
- Avg merge
- 21h 32m
- Merged PRs (30d)
- 515
Description
**Company or project name**
Clickhouse user in Seoul, Korea
**Describe what's wrong**
When using the MySQL connector to connect to ClickHouse(on port 9004) and executing a query on a table containing a Decimal type, a parsing error occurs.
**Does it reproduce on the most recent release?**
Yes, I tried it on ClickHouse version 24.8.2.3, but the same problem occurred.
**Enable crash reporting**
Not available because the server is in a closed network.
**How to reproduce**
There's a sample table
```sql
CREATE TABLE default.sample_decimal
(
`column_a` Nullable(String),
`column_b` Date,
`column_c` Nullable(Float64),
`column_d` Nullable(Decimal(38, 0)),
`column_e` Nullable(Decimal(38, 0))
)
ENGINE = MergeTree
ORDER BY tuple()
```
When I run the query below on the MySQL client, I get an error instead of the expected result.
```sql
mysql> SHOW FULL COLUMNS FROM `sample_decimal` FROM `default`;
ERROR 6 (00000): Code: 6. DB::Exception: Cannot parse string 'Decimal' as Int8: syntax error at begin of string. Note: there are toInt8OrZero and toInt8OrNull functions, which returns zero/NULL instead of throwing exception.: while executing 'FUNCTION and(equals(multiIf(startsWith(__table1.type_, 'LowCardinality(Nullable'_String), arrayElement(splitByRegexp('\\(|\\)'_String, __table1.type_), 3_UInt8), startsWith(__table1.type_, 'LowCardinality'_String), arrayElement(splitByRegexp('\\(|\\)'_String, __table1.type_), 2_UInt8)
```
The query ran fine on the ClickHouse client.
```sql
clickhouse> SHOW FULL COLUMNS FROM sample_decimal FROM default
┌─field────┬─type─────────────────────┬─null─┬─key─┬─default─┬─extra─┬─collation─┬─comment─┬─privileges─┐
1. │ column_a │ Nullable(String) │ YES │ │ ᴺᵁᴸᴸ │ │ ᴺᵁᴸᴸ │ │ │
2. │ column_b │ Date │ NO │ │ ᴺᵁᴸᴸ │ │ ᴺᵁᴸᴸ │ │ │
3. │ column_c │ Nullable(Float64) │ YES │ │ ᴺᵁᴸᴸ │ │ ᴺᵁᴸᴸ │ │ │
4. │ column_d │ Nullable(Decimal(38, 0)) │ YES │ │ ᴺᵁᴸᴸ │ │ ᴺᵁᴸᴸ │ │ │
5. │ column_e │ Nullable(Decimal(38, 0)) │ YES │ │ ᴺᵁᴸᴸ │ │ ᴺᵁᴸᴸ │ │ │
└──────────┴──────────────────────────┴──────┴─────┴─────────┴───────┴───────────┴─────────┴────────────┘
```
If I create a table with Int128 instead of Decimal(38,0), there is no problem.
```sql
CREATE TABLE default.sample_int128
(
`column_a` Nullable(String),
`column_b` Date,
`column_c` Nullable(Float64),
`column_d` Nullable(Int128),
`column_e` Nullable(Int128)
)
ENGINE = MergeTree
ORDER BY tuple()
```
The result is shown below
```sql
mysql> SHOW FULL COLUMNS FROM `sample_int128` FROM `default`;
+----------+--------+------+------+---------+-------+-----------+---------+------------+
| field | type | null | key | default | extra | collation | comment | privileges |
+----------+--------+------+------+---------+-------+-----------+---------+------------+
| column_a | TEXT | YES | | NULL | | NULL | | |
| column_b | DATE | NO | | NULL | | NULL | | |
| column_c | DOUBLE | YES | | NULL | | NULL | | |
| column_d | TEXT | YES | | NULL | | NULL | | |
| column_e | TEXT | YES | | NULL | | NULL | | |
+----------+--------+------+------+---------+-------+-----------+---------+------------+
5 rows in set (0.01 sec)
Read 5 rows, 534.00 B in 0.007464 sec., 669 rows/sec., 69.87 KiB/sec.
```
**Expected behavior**
How can this be resolved?
**Error message and/or stacktrace**
Here's original clickhouse server error message >>
```
DB::Exception: Cannot parse string 'Decimal' as Int8: syntax error at begin of string. Note: there are toInt8OrZero and toInt8OrNull functions, which returns zero/NULL instead of throwing exception.: while executing 'FUNCTION and(equals(multiIf(startsWith(__table1.type_, 'LowCardinality(Nullable'_String), arrayElement(splitByRegexp('\\(|\\)'_String, __table1.type_), 3_UInt8), startsWith(__table1.type_, 'LowCardinality'_String), arrayElement(splitByRegexp('\\(|\\)'_String, __table1.type_), 2_UInt8), startsWith(__table1.type_, 'Nullable'_String), arrayElement(splitByRegexp('\\(|\\)'_String, __table1.type_), 2_UInt8), arrayElement(splitByRegexp('\\(|\\)'_String, __table1.type_), 1_UInt8)), 'Decimal'_String) :: 6, lessOrEquals(toInt8(arrayElement(if(greater(length(splitByRegexp('\\(|\\)'_String, __table1.type_)), 1_UInt8), splitByString(', '_String, arrayElement(splitByRegexp('\\(|\\)'_String, __table1.type_), 2_UInt8)), CAST([]_Array(Nothing), 'Array(Nothing)'_String)), 1_UInt8)), 65_UInt8) :: 19, lessOrEquals(toInt8(arrayElement(if(greater(length(splitByRegexp('\\(|\\)'_String, __table1.type)), 1_UInt8), splitByString(', '_String, arrayElement(splitByRegexp('\\(|\\)'_String, __table1.type_), 2_UInt8)), CAST([]_Array(Nothing), 'Array(Nothing)'_String)), 2_UInt8)), 30_UInt8) :: 16) -> and(equals(multiIf(startsWith(__table1.type, 'LowCardinality(Nullable'_String), arrayElement(splitByRegexp('\\(|\\)'_String, __table1.type_), 3_UInt8), startsWith(__table1.type_, 'LowCardinality'_String), arrayElement(splitByRegexp('\\(|\\)'_String, __table1.type_), 2_UInt8), startsWith(__table1.type_, 'Nullable'_String), arrayElement(splitByRegexp('\\(|\\)'_String, __table1.type_), 2_UInt8), arrayElement(splitByRegexp('\\(|\\)'_String, __table1.type_), 1_UInt8)), 'Decimal'_String), lessOrEquals(toInt8(arrayElement(if(greater(length(splitByRegexp('\\(|\\)'_String, __table1.type_)), 1_UInt8), splitByString(', '_String, arrayElement(splitByRegexp('\\(|\\)'_String, __table1.type_), 2_UInt8)), CAST([]_Array(Nothing), 'Array(Nothing)'_String)), 1_UInt8)), 65_UInt8), lessOrEquals(toInt8(arrayElement(if(greater(length(splitByRegexp('\\(|\\)'_String, __table1.type)), 1_UInt8), splitByString(', '_String, arrayElement(splitByRegexp('\\(|\\)'_String, __table1.type_), 2_UInt8)), _CAST([]_Array(Nothing), 'Array(Nothing)'_String)), 2_UInt8)), 30_UInt8)) UInt8 : 17'. (CANNOT_PARSE_TEXT) (version 24.7.3.42 (official build))...
```
Thank you!
Contributor guide
Assessment
This issue has not been assessed yet.