@@ -2,7 +2,6 @@ package qvalue
22
33import (
44 "context"
5- "log/slog"
65 "math/big"
76 "strings"
87 "testing"
@@ -78,74 +77,6 @@ func TestColumnNameAvroFieldConvert(t *testing.T) {
7877 }
7978}
8079
81- func TestClickHouseDateTimeRange (t * testing.T ) {
82- ctx := context .Background ()
83- logger := log .NewStructuredLogger (slog .New (slog .DiscardHandler ))
84-
85- inRange := time .Date (2000 , 1 , 2 , 3 , 4 , 5 , 0 , time .UTC )
86- belowRange := time .Date (1000 , 6 , 15 , 5 , 30 , 45 , 123456000 , time .UTC )
87- aboveRange := time .Date (9999 , 6 , 15 , 5 , 30 , 45 , 123456000 , time .UTC )
88- // ClickHouse clamps the date to the [1900, 2299] boundary but preserves the time-of-day,
89- // matching parseDateTime64BestEffortOrNull. This holds regardless of column nullability.
90- belowClamped := time .Date (clickHouseMinYear , time .January , 1 , 5 , 30 , 45 , 123456000 , time .UTC )
91- aboveClamped := time .Date (clickHouseMaxYear , time .December , 31 , 5 , 30 , 45 , 123456000 , time .UTC )
92- // Dates truncate the time-of-day, so both boundaries land on midnight of the boundary day.
93- belowDate := time .Date (clickHouseMinYear , time .January , 1 , 0 , 0 , 0 , 0 , time .UTC )
94- aboveDate := time .Date (clickHouseMaxYear , time .December , 31 , 0 , 0 , 0 , 0 , time .UTC )
95-
96- convert := func (t * testing.T , qv types.QValue , dwh protos.DBType , nullable bool ) any {
97- t .Helper ()
98- field := types.QField {Type : qv .Kind (), Nullable : nullable }
99- val , _ , err := QValueToAvro (ctx , qv , & field , dwh , logger , false , nil , internal .BinaryFormatRaw , false )
100- require .NoError (t , err )
101- if p , ok := val .(* any ); ok {
102- return * p
103- }
104- return val
105- }
106-
107- // isDate marks date values, which are encoded as whole days (time-of-day truncated).
108- tests := []struct {
109- name string
110- qv types.QValue
111- nullable bool
112- isDate bool
113- expected time.Time
114- }{
115- {"timestamp_in_range" , types.QValueTimestamp {Val : inRange }, false , false , inRange },
116- {"timestamp_below_clamps" , types.QValueTimestamp {Val : belowRange }, false , false , belowClamped },
117- {"timestamp_above_clamps" , types.QValueTimestamp {Val : aboveRange }, false , false , aboveClamped },
118- {"timestamp_below_nullable_clamps" , types.QValueTimestamp {Val : belowRange }, true , false , belowClamped },
119- {"timestamp_above_nullable_clamps" , types.QValueTimestamp {Val : aboveRange }, true , false , aboveClamped },
120- {"timestamptz_below_clamps" , types.QValueTimestampTZ {Val : belowRange }, false , false , belowClamped },
121- {"timestamptz_above_nullable_clamps" , types.QValueTimestampTZ {Val : aboveRange }, true , false , aboveClamped },
122- {"date_below_clamps" , types.QValueDate {Val : belowRange }, false , true , belowDate },
123- {"date_above_nullable_clamps" , types.QValueDate {Val : aboveRange }, true , true , aboveDate },
124- }
125-
126- for _ , tt := range tests {
127- t .Run (tt .name , func (t * testing.T ) {
128- val := convert (t , tt .qv , protos .DBType_CLICKHOUSE , tt .nullable )
129- ts , ok := val .(time.Time )
130- require .Truef (t , ok , "expected time.Time, got %T" , val )
131- if tt .isDate {
132- // Compare only the date part, since dates are encoded as whole days.
133- assert .Equal (t , tt .expected .Format ("2006-01-02" ), ts .UTC ().Format ("2006-01-02" ))
134- } else {
135- assert .Truef (t , ts .Equal (tt .expected ), "expected %s, got %s" , tt .expected , ts )
136- }
137- })
138- }
139-
140- // Non-ClickHouse targets must not touch out-of-range values: they pass through untouched.
141- t .Run ("other_dwh_no_change" , func (t * testing.T ) {
142- val := convert (t , types.QValueTimestamp {Val : aboveRange }, protos .DBType_POSTGRES , false )
143- ts , ok := val .(time.Time )
144- require .Truef (t , ok , "expected time.Time, got %T" , val )
145- assert .True (t , ts .Equal (aboveRange ))
146- })
147- }
148-
14980func TestAvroQValueSize (t * testing.T ) {
15081 ctx := context .Background ()
15182 env := map [string ]string {
0 commit comments