ClickHouse / ClickHouse/ClickHouse

The MySQL connector to ClickHouse does not work properly with the Decimal type

Open
#68,922 0 comments 0 reactions 0 assignees View on GitHub
comp-protocols external potential bug
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

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.