diff --git a/lib/column/date_helpers.go b/lib/column/date_helpers.go index 2e6691ec6d..2bf74ee610 100644 --- a/lib/column/date_helpers.go +++ b/lib/column/date_helpers.go @@ -25,7 +25,7 @@ import ( const secInDay = 24 * 60 * 60 func dateOverflow(min, max, v time.Time, format string) error { - if v.Before(min) || v.After(max) { + if !v.IsZero() && (v.Before(min) || v.After(max)) { return &DateOverflowError{ Min: min, Max: max, diff --git a/lib/column/date_helpers_test.go b/lib/column/date_helpers_test.go new file mode 100644 index 0000000000..0ed5b8f9e7 --- /dev/null +++ b/lib/column/date_helpers_test.go @@ -0,0 +1,53 @@ +package column + +import ( + "testing" + "time" +) + +func TestDateOverflow(t *testing.T) { + t.Parallel() + zeroTime := time.Time{} + tests := []struct { + v time.Time + name string + err bool + }{ + { + name: "valid date", + v: time.Date(2020, 1, 1, 0, 0, 0, 0, time.UTC), + err: false, + }, + { + name: "before min date", + v: minDate.Add(-time.Second), + err: true, + }, + { + name: "after max date", + v: maxDate.Add(time.Second), + err: true, + }, + { + name: "zero value date", + v: zeroTime, + err: false, + }, + { + name: "non-zero value equal to zero date", + v: time.UnixMilli(zeroTime.UnixMilli()), + err: false, + }, + } + + for _, test := range tests { + test := test + t.Run(test.name, func(t *testing.T) { + t.Parallel() + err := dateOverflow(minDateTime, maxDateTime, test.v, defaultDateFormatNoZone) + if (err != nil) != test.err { + t.Errorf("expected error: %v, got: %v", test.err, err) + } + }) + } +} diff --git a/tests/std/date32_test.go b/tests/std/date32_test.go index 8caf327dd7..47ae31b510 100644 --- a/tests/std/date32_test.go +++ b/tests/std/date32_test.go @@ -21,14 +21,14 @@ import ( "context" "database/sql" "fmt" - "github.com/ClickHouse/clickhouse-go/v2" - clickhouse_tests "github.com/ClickHouse/clickhouse-go/v2/tests" - "github.com/stretchr/testify/require" "strconv" "testing" "time" + "github.com/ClickHouse/clickhouse-go/v2" + clickhouse_tests "github.com/ClickHouse/clickhouse-go/v2/tests" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestStdDate32(t *testing.T) { @@ -78,7 +78,7 @@ func TestStdDate32(t *testing.T) { ) _, err = batch.Exec(uint8(1), date1, &date2, []time.Time{date2}, []*time.Time{&date2, nil, &date1}, sql.NullTime{Time: time.Time{}, Valid: false}, sql.NullTime{Time: date1, Valid: true}) require.NoError(t, err) - _, err = batch.Exec(uint8(2), date2, nil, []time.Time{date1}, []*time.Time{nil, nil, &date2}, sql.NullTime{Time: time.Time{}, Valid: false}, sql.NullTime{Time: date2, Valid: true}) + _, err = batch.Exec(uint8(2), time.Time{}, nil, []time.Time{date1}, []*time.Time{nil, nil, &date2}, sql.NullTime{Time: time.Time{}, Valid: false}, sql.NullTime{Time: date2, Valid: true}) require.NoError(t, err) require.NoError(t, scope.Commit()) var ( @@ -110,7 +110,7 @@ func TestStdDate32(t *testing.T) { &result1.Col5, &result1.Col6, )) - require.Equal(t, date2, result2.Col1) + require.Equal(t, time.Unix(0, 0).UTC(), result2.Col1) require.Equal(t, "UTC", result2.Col1.Location().String()) require.Nil(t, result2.Col2) assert.Equal(t, []time.Time{date1}, result2.Col3) diff --git a/tests/std/date_test.go b/tests/std/date_test.go index e5015f6ab0..13d780f3b5 100644 --- a/tests/std/date_test.go +++ b/tests/std/date_test.go @@ -21,14 +21,14 @@ import ( "context" "database/sql" "fmt" - "github.com/ClickHouse/clickhouse-go/v2" - clickhouse_tests "github.com/ClickHouse/clickhouse-go/v2/tests" - "github.com/stretchr/testify/require" "strconv" "testing" "time" + "github.com/ClickHouse/clickhouse-go/v2" + clickhouse_tests "github.com/ClickHouse/clickhouse-go/v2/tests" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestStdDate(t *testing.T) { @@ -72,7 +72,7 @@ func TestStdDate(t *testing.T) { require.NoError(t, err) _, err = batch.Exec(uint8(1), date, &date, []time.Time{date}, []*time.Time{&date, nil, &date}, sql.NullTime{Time: date, Valid: true}, sql.NullTime{Time: time.Time{}, Valid: false}) require.NoError(t, err) - _, err = batch.Exec(uint8(2), date, nil, []time.Time{date}, []*time.Time{nil, nil, &date}, sql.NullTime{Time: date, Valid: true}, sql.NullTime{Time: time.Time{}, Valid: false}) + _, err = batch.Exec(uint8(2), time.Time{}, nil, []time.Time{date}, []*time.Time{nil, nil, &date}, sql.NullTime{Time: date, Valid: true}, sql.NullTime{Time: time.Time{}, Valid: false}) require.NoError(t, err) require.NoError(t, scope.Commit()) var ( @@ -104,7 +104,7 @@ func TestStdDate(t *testing.T) { &result2.Col5, &result2.Col6, )) - require.Equal(t, date, result2.Col1) + require.Equal(t, time.Unix(0, 0).UTC(), result2.Col1) assert.Equal(t, "UTC", result2.Col1.Location().String()) require.Nil(t, result2.Col2) assert.Equal(t, []time.Time{date}, result2.Col3) diff --git a/tests/std/datetime64_test.go b/tests/std/datetime64_test.go index 60b48c7d48..20ba9432d3 100644 --- a/tests/std/datetime64_test.go +++ b/tests/std/datetime64_test.go @@ -20,14 +20,14 @@ package std import ( "database/sql" "fmt" - "github.com/ClickHouse/clickhouse-go/v2" - clickhouse_tests "github.com/ClickHouse/clickhouse-go/v2/tests" - "github.com/stretchr/testify/require" "strconv" "testing" "time" + "github.com/ClickHouse/clickhouse-go/v2" + clickhouse_tests "github.com/ClickHouse/clickhouse-go/v2/tests" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestStdDateTime64(t *testing.T) { @@ -53,6 +53,7 @@ func TestStdDateTime64(t *testing.T) { , Col7 DateTime64(0, 'Europe/London') , Col8 Nullable(DateTime64(3, 'Europe/Moscow')) , Col9 DateTime64(9) + , Col10 DateTime64(9) ) Engine MergeTree() ORDER BY tuple() ` defer func() { @@ -81,21 +82,23 @@ func TestStdDateTime64(t *testing.T) { sql.NullTime{Time: datetime3, Valid: true}, sql.NullTime{Time: time.Time{}, Valid: false}, expectedMinDateTime, + time.Time{}, ) require.NoError(t, err) require.NoError(t, scope.Commit()) var ( - col1 time.Time - col2 time.Time - col3 time.Time - col4 *time.Time - col5 []time.Time - col6 []*time.Time - col7 sql.NullTime - col8 sql.NullTime - col9 time.Time + col1 time.Time + col2 time.Time + col3 time.Time + col4 *time.Time + col5 []time.Time + col6 []*time.Time + col7 sql.NullTime + col8 sql.NullTime + col9 time.Time + col10 time.Time ) - require.NoError(t, conn.QueryRow("SELECT * FROM test_datetime64").Scan(&col1, &col2, &col3, &col4, &col5, &col6, &col7, &col8, &col9)) + require.NoError(t, conn.QueryRow("SELECT * FROM test_datetime64").Scan(&col1, &col2, &col3, &col4, &col5, &col6, &col7, &col8, &col9, &col10)) assert.Equal(t, datetime1.In(time.UTC), col1) assert.Equal(t, datetime2.UnixNano(), col2.UnixNano()) assert.Equal(t, datetime3.UnixNano(), col3.UnixNano()) @@ -113,6 +116,7 @@ func TestStdDateTime64(t *testing.T) { require.Equal(t, sql.NullTime{Time: datetime3.In(col7.Time.Location()), Valid: true}, col7) require.Equal(t, sql.NullTime{Time: time.Time{}, Valid: false}, col8) require.Equal(t, time.Date(1900, 01, 01, 0, 0, 0, 0, time.UTC), col9) + require.Equal(t, time.Unix(0, 0).UTC(), col10) }) } } diff --git a/tests/std/datetime_test.go b/tests/std/datetime_test.go index e506d59160..a3c71187a6 100644 --- a/tests/std/datetime_test.go +++ b/tests/std/datetime_test.go @@ -20,14 +20,14 @@ package std import ( "database/sql" "fmt" - "github.com/ClickHouse/clickhouse-go/v2" - clickhouse_tests "github.com/ClickHouse/clickhouse-go/v2/tests" - "github.com/stretchr/testify/require" "strconv" "testing" "time" + "github.com/ClickHouse/clickhouse-go/v2" + clickhouse_tests "github.com/ClickHouse/clickhouse-go/v2/tests" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestStdDateTime(t *testing.T) { @@ -48,6 +48,7 @@ func TestStdDateTime(t *testing.T) { , Col6 Array(Nullable(DateTime('Europe/Moscow'))) , Col7 DateTime , Col8 Nullable(DateTime) + ,Col9 DateTime ) Engine MergeTree() ORDER BY tuple()` defer func() { conn.Exec("DROP TABLE test_datetime") @@ -74,6 +75,7 @@ func TestStdDateTime(t *testing.T) { Time: time.Time{}, Valid: false, }, + time.Time{}, ) require.NoError(t, err) require.NoError(t, scope.Commit()) @@ -86,8 +88,9 @@ func TestStdDateTime(t *testing.T) { col6 []*time.Time col7 sql.NullTime col8 sql.NullTime + col9 time.Time ) - require.NoError(t, conn.QueryRow("SELECT * FROM test_datetime").Scan(&col1, &col2, &col3, &col4, &col5, &col6, &col7, &col8)) + require.NoError(t, conn.QueryRow("SELECT * FROM test_datetime").Scan(&col1, &col2, &col3, &col4, &col5, &col6, &col7, &col8, &col9)) assert.Equal(t, datetime.In(time.UTC), col1) assert.Equal(t, datetime.Unix(), col2.Unix()) assert.Equal(t, datetime.Unix(), col3.Unix()) @@ -120,7 +123,7 @@ func TestStdDateTime(t *testing.T) { Time: time.Time{}, Valid: false, }, col8) - + assert.Equal(t, time.Unix(0, 0).UTC(), col9) }) } }