2121
2222import org .apache .arrow .driver .jdbc .utils .RootAllocatorTestExtension ;
2323import org .apache .arrow .memory .BufferAllocator ;
24+ import org .apache .arrow .vector .BaseFixedWidthVector ;
25+ import org .apache .arrow .vector .FieldVector ;
2426import org .apache .arrow .vector .TimeStampMicroTZVector ;
2527import org .apache .arrow .vector .TimeStampMicroVector ;
28+ import org .apache .arrow .vector .TimeStampMilliTZVector ;
2629import org .apache .arrow .vector .TimeStampMilliVector ;
2730import org .apache .arrow .vector .TimeStampNanoTZVector ;
2831import org .apache .arrow .vector .TimeStampNanoVector ;
@@ -42,130 +45,103 @@ public class TimestampAvaticaParameterConverterTest {
4245 public static RootAllocatorTestExtension rootAllocatorTestExtension =
4346 new RootAllocatorTestExtension ();
4447
45- // A known epoch millis value: 2024-11-03 12:45:09.869 UTC
46- private static final long EPOCH_MILLIS = 1730637909869L ;
48+ // 2024-11-03 12:45:09.869 UTC — fractional seconds exercise the SECOND truncation path
49+ private static final long TEST_EPOCH_MILLIS_WITH_FRACTIONAL_SECONDS = 1730637909869L ;
4750
4851 @ Test
49- public void testBindParameterMilliVector () {
50- BufferAllocator allocator = rootAllocatorTestExtension .getRootAllocator ();
51- ArrowType .Timestamp type = new ArrowType .Timestamp (TimeUnit .MILLISECOND , null );
52- TimestampAvaticaParameterConverter converter = new TimestampAvaticaParameterConverter (type );
53-
54- try (TimeStampMilliVector vector = new TimeStampMilliVector ("ts" , allocator )) {
55- vector .allocateNew (1 );
56- TypedValue typedValue =
57- TypedValue .ofLocal (ColumnMetaData .Rep .JAVA_SQL_TIMESTAMP , EPOCH_MILLIS );
58- assertTrue (converter .bindParameter (vector , typedValue , 0 ));
59- assertEquals (EPOCH_MILLIS , vector .get (0 ));
60- }
52+ public void testSecVector () {
53+ assertBindConvertsMillis (
54+ TimeUnit .SECOND , null , TEST_EPOCH_MILLIS_WITH_FRACTIONAL_SECONDS / 1_000L );
6155 }
6256
6357 @ Test
64- public void testBindParameterMicroVector () {
65- BufferAllocator allocator = rootAllocatorTestExtension .getRootAllocator ();
66- ArrowType .Timestamp type = new ArrowType .Timestamp (TimeUnit .MICROSECOND , null );
67- TimestampAvaticaParameterConverter converter = new TimestampAvaticaParameterConverter (type );
68-
69- try (TimeStampMicroVector vector = new TimeStampMicroVector ("ts" , allocator )) {
70- vector .allocateNew (1 );
71- TypedValue typedValue =
72- TypedValue .ofLocal (ColumnMetaData .Rep .JAVA_SQL_TIMESTAMP , EPOCH_MILLIS );
73- assertTrue (converter .bindParameter (vector , typedValue , 0 ));
74- // Millis should be converted to micros
75- assertEquals (EPOCH_MILLIS * 1_000L , vector .get (0 ));
76- }
58+ public void testMilliVector () {
59+ assertBindConvertsMillis (TimeUnit .MILLISECOND , null , TEST_EPOCH_MILLIS_WITH_FRACTIONAL_SECONDS );
7760 }
7861
7962 @ Test
80- public void testBindParameterNanoVector () {
81- BufferAllocator allocator = rootAllocatorTestExtension .getRootAllocator ();
82- ArrowType .Timestamp type = new ArrowType .Timestamp (TimeUnit .NANOSECOND , null );
83- TimestampAvaticaParameterConverter converter = new TimestampAvaticaParameterConverter (type );
84-
85- try (TimeStampNanoVector vector = new TimeStampNanoVector ("ts" , allocator )) {
86- vector .allocateNew (1 );
87- TypedValue typedValue =
88- TypedValue .ofLocal (ColumnMetaData .Rep .JAVA_SQL_TIMESTAMP , EPOCH_MILLIS );
89- assertTrue (converter .bindParameter (vector , typedValue , 0 ));
90- // Millis should be converted to nanos
91- assertEquals (EPOCH_MILLIS * 1_000_000L , vector .get (0 ));
92- }
63+ public void testMicroVector () {
64+ assertBindConvertsMillis (
65+ TimeUnit .MICROSECOND , null , TEST_EPOCH_MILLIS_WITH_FRACTIONAL_SECONDS * 1_000L );
9366 }
9467
9568 @ Test
96- public void testBindParameterSecVector () {
97- BufferAllocator allocator = rootAllocatorTestExtension . getRootAllocator ();
98- ArrowType . Timestamp type = new ArrowType . Timestamp ( TimeUnit .SECOND , null );
99- TimestampAvaticaParameterConverter converter = new TimestampAvaticaParameterConverter ( type );
69+ public void testNanoVector () {
70+ assertBindConvertsMillis (
71+ TimeUnit .NANOSECOND , null , TEST_EPOCH_MILLIS_WITH_FRACTIONAL_SECONDS * 1_000_000L );
72+ }
10073
101- try (TimeStampSecVector vector = new TimeStampSecVector ("ts" , allocator )) {
102- vector .allocateNew (1 );
103- TypedValue typedValue =
104- TypedValue .ofLocal (ColumnMetaData .Rep .JAVA_SQL_TIMESTAMP , EPOCH_MILLIS );
105- assertTrue (converter .bindParameter (vector , typedValue , 0 ));
106- // Millis should be converted to seconds
107- assertEquals (EPOCH_MILLIS / 1_000L , vector .get (0 ));
108- }
74+ @ Test
75+ public void testSecTZVector () {
76+ assertBindConvertsMillis (
77+ TimeUnit .SECOND , "UTC" , TEST_EPOCH_MILLIS_WITH_FRACTIONAL_SECONDS / 1_000L );
10978 }
11079
11180 @ Test
112- public void testBindParameterMicroTZVector () {
113- BufferAllocator allocator = rootAllocatorTestExtension . getRootAllocator ();
114- ArrowType . Timestamp type = new ArrowType . Timestamp ( TimeUnit .MICROSECOND , "UTC" );
115- TimestampAvaticaParameterConverter converter = new TimestampAvaticaParameterConverter ( type );
81+ public void testMicroTZVector () {
82+ assertBindConvertsMillis (
83+ TimeUnit .MICROSECOND , "UTC" , TEST_EPOCH_MILLIS_WITH_FRACTIONAL_SECONDS * 1_000L );
84+ }
11685
117- try (TimeStampMicroTZVector vector = new TimeStampMicroTZVector ("ts" , allocator , "UTC" )) {
118- vector .allocateNew (1 );
119- TypedValue typedValue =
120- TypedValue .ofLocal (ColumnMetaData .Rep .JAVA_SQL_TIMESTAMP , EPOCH_MILLIS );
121- assertTrue (converter .bindParameter (vector , typedValue , 0 ));
122- assertEquals (EPOCH_MILLIS * 1_000L , vector .get (0 ));
123- }
86+ @ Test
87+ public void testNanoTZVector () {
88+ assertBindConvertsMillis (
89+ TimeUnit .NANOSECOND , "UTC" , TEST_EPOCH_MILLIS_WITH_FRACTIONAL_SECONDS * 1_000_000L );
12490 }
12591
12692 @ Test
127- public void testBindParameterNanoTZVector () {
93+ public void testSecVectorTruncatesSubSecond () {
12894 BufferAllocator allocator = rootAllocatorTestExtension .getRootAllocator ();
129- ArrowType .Timestamp type = new ArrowType .Timestamp (TimeUnit .NANOSECOND , "UTC" );
95+ ArrowType .Timestamp type = new ArrowType .Timestamp (TimeUnit .SECOND , null );
13096 TimestampAvaticaParameterConverter converter = new TimestampAvaticaParameterConverter (type );
13197
132- try (TimeStampNanoTZVector vector = new TimeStampNanoTZVector ("ts" , allocator , "UTC" )) {
98+ try (TimeStampSecVector vector = new TimeStampSecVector ("ts" , allocator )) {
13399 vector .allocateNew (1 );
134- TypedValue typedValue =
135- TypedValue .ofLocal (ColumnMetaData .Rep .JAVA_SQL_TIMESTAMP , EPOCH_MILLIS );
100+ // 1999 millis should truncate to 1 second, not round to 2
101+ TypedValue typedValue = TypedValue .ofLocal (ColumnMetaData .Rep .JAVA_SQL_TIMESTAMP , 1999L );
136102 assertTrue (converter .bindParameter (vector , typedValue , 0 ));
137- assertEquals (EPOCH_MILLIS * 1_000_000L , vector .get (0 ));
103+ assertEquals (1L , vector .get (0 ));
138104 }
139105 }
140106
141- @ Test
142- public void testBindParameterSecTZVector () {
107+ private void assertBindConvertsMillis (TimeUnit unit , String tz , long expectedValue ) {
143108 BufferAllocator allocator = rootAllocatorTestExtension .getRootAllocator ();
144- ArrowType .Timestamp type = new ArrowType .Timestamp (TimeUnit . SECOND , "UTC" );
109+ ArrowType .Timestamp type = new ArrowType .Timestamp (unit , tz );
145110 TimestampAvaticaParameterConverter converter = new TimestampAvaticaParameterConverter (type );
146111
147- try (TimeStampSecTZVector vector = new TimeStampSecTZVector ( "ts" , allocator , "UTC" )) {
148- vector .allocateNew (1 );
112+ try (FieldVector vector = createTestTimestampVector ( unit , tz , allocator )) {
113+ (( BaseFixedWidthVector ) vector ) .allocateNew (1 );
149114 TypedValue typedValue =
150- TypedValue .ofLocal (ColumnMetaData .Rep .JAVA_SQL_TIMESTAMP , EPOCH_MILLIS );
115+ TypedValue .ofLocal (
116+ ColumnMetaData .Rep .JAVA_SQL_TIMESTAMP , TEST_EPOCH_MILLIS_WITH_FRACTIONAL_SECONDS );
151117 assertTrue (converter .bindParameter (vector , typedValue , 0 ));
152- assertEquals (EPOCH_MILLIS / 1_000L , vector .get (0 ));
118+ long actual = vector .getDataBuffer ().getLong (0 );
119+ assertEquals (expectedValue , actual );
153120 }
154121 }
155122
156- @ Test
157- public void testBindParameterSecVectorTruncatesSubSecond () {
158- BufferAllocator allocator = rootAllocatorTestExtension .getRootAllocator ();
159- ArrowType .Timestamp type = new ArrowType .Timestamp (TimeUnit .SECOND , null );
160- TimestampAvaticaParameterConverter converter = new TimestampAvaticaParameterConverter (type );
161-
162- try (TimeStampSecVector vector = new TimeStampSecVector ("ts" , allocator )) {
163- vector .allocateNew (1 );
164- // 1999 millis should truncate to 1 second, not round to 2
165- long millis = 1999L ;
166- TypedValue typedValue = TypedValue .ofLocal (ColumnMetaData .Rep .JAVA_SQL_TIMESTAMP , millis );
167- assertTrue (converter .bindParameter (vector , typedValue , 0 ));
168- assertEquals (1L , vector .get (0 ));
123+ private static FieldVector createTestTimestampVector (
124+ TimeUnit unit , String tz , BufferAllocator allocator ) {
125+ boolean hasTz = tz != null ;
126+ switch (unit ) {
127+ case SECOND :
128+ return hasTz
129+ ? new TimeStampSecTZVector ("ts" , allocator , tz )
130+ : new TimeStampSecVector ("ts" , allocator );
131+ case MILLISECOND :
132+ return hasTz
133+ ? new TimeStampMilliTZVector ("ts" , allocator , tz )
134+ : new TimeStampMilliVector ("ts" , allocator );
135+ case MICROSECOND :
136+ return hasTz
137+ ? new TimeStampMicroTZVector ("ts" , allocator , tz )
138+ : new TimeStampMicroVector ("ts" , allocator );
139+ case NANOSECOND :
140+ return hasTz
141+ ? new TimeStampNanoTZVector ("ts" , allocator , tz )
142+ : new TimeStampNanoVector ("ts" , allocator );
143+ default :
144+ throw new IllegalArgumentException ("Unsupported time unit: " + unit );
169145 }
170146 }
171147}
0 commit comments