2

When save the value (0.0003) in decimal column (Decimal(12,4)) in Clickhouse, the saved value was 0.0002.
Why is it behaved like this?
But when I did insert by SQL directly, I was able to save it without a problem.
Which means, the go program that I wrote is wrong?

■ create table

CREATE TABLE test_ch (
    id Decimal(12,4),
    created_at DateTime
) ENGINE = MergeTree() PARTITION BY toYYYYMMDD(created_at) ORDER BY (created_at);

■ source

import (
    "database/sql"
    "fmt"
    "time"

    "github.com/ClickHouse/clickhouse-go"
    sq "github.com/Masterminds/squirrel"
)

var ConnectCH *sql.DB

func main() {
    SetClickHouse()
    insert()
}

func insert() error {
    return Exec(func(tx *sql.Tx) error {
        prepare, _, _ := sq.Insert("test_ch").
            Columns(
                "id",
                "created_at",
            ).Values().ToSql()
        stmt, _ := tx.Prepare(prepare)

        createdAt := time.Now().Format("2006-01-02 15:04:05")
        if _, err := stmt.Exec(
            0.0003,
            createdAt,
        ); err != nil {
            return err
        }
        return nil
    })
}

func recoverAndRollback(tx *sql.Tx) {
    if r := recover(); r != nil {
        tx.Rollback()
    }
}

func Exec(t func(*sql.Tx) error) error {
    tx, err := ConnectCH.Begin()
    if err != nil {
        tx.Rollback()
        return err
    }
    defer recoverAndRollback(tx)
    if err := t(tx); err != nil {
        tx.Rollback()
        return err
    }
    if err := tx.Commit(); err != nil {
        tx.Rollback()
        return err
    }
    return nil
}

func SetClickHouse() error {
    var err error

    url := fmt.Sprintf("tcp://%s:%s", "clickhouse", "9000")
    ConnectCH, err = sql.Open("clickhouse", url)
    if err != nil {
        return err
    }

    if err := ConnectCH.Ping(); err != nil {
        if exception, ok := err.(*clickhouse.Exception); ok {
            fmt.Printf("[%d] %s \n%s\n", exception.Code, exception.Message, exception.StackTrace)
        } else {
            fmt.Println(err)
        }
        return err
    }

    return nil
}

■ output

when id = 0.0001
SELECT *
FROM test_ch

┌─────id─┬──────────created_at─┐
│ 0.0001 │ 2020-01-09 01:58:49 │
└────────┴─────────────────────┘

is OK

when id = 0.0002
SELECT *
FROM test_ch

┌─────id─┬──────────created_at─┐
│ 0.0002 │ 2020-01-09 01:59:33 │
└────────┴─────────────────────┘

is OK

when id = 0.0003
SELECT *
FROM test_ch

┌─────id─┬──────────created_at─┐
│ 0.0002 │ 2020-01-09 02:00:30 │
└────────┴─────────────────────┘

Why is it 0.0002?

vladimir
  • 13,428
  • 2
  • 44
  • 70
user3321541
  • 221
  • 1
  • 16
  • just remark: *Decimal* is not marked as a supported type in [clickhouse-go](https://github.com/ClickHouse/clickhouse-go#supported-data-types); another driver [go-clickhouse](https://github.com/mailru/go-clickhouse#supported-data-types) supports this type.. – vladimir Jan 08 '20 at 20:45

1 Answers1

0

performance

SELECT CAST(toFloat64('0.0003'), 'Decimal(12, 8)')    
┌─CAST(toFloat64('0.0003'), 'Decimal(12, 8)')─┐
│                                  0.00029999 │
└─────────────────────────────────────────────┘


SELECT CAST('0.0003', 'Decimal(12, 8)')
┌─CAST('0.0003', 'Decimal(12, 8)')─┐
│                       0.00030000 │
└──────────────────────────────────┘
Denny Crane
  • 11,574
  • 2
  • 19
  • 30
  • Thank you for your answer. Which means, since [clickhouse-go](https://github.com/ClickHouse/clickhouse-go#supported-data-types) cast float64, is this rounded off? – user3321541 Jan 09 '20 at 01:31
  • smth like that. I suggest to create a ticket at https://github.com/ClickHouse/clickhouse-go/issues – Denny Crane Jan 09 '20 at 15:35