2222import io .dingodb .expr .common .timezone .core .DateTimeType ;
2323import io .dingodb .expr .common .timezone .core .DingoDateTime ;
2424import io .dingodb .expr .common .timezone .core .SimpleTimeZoneConfig ;
25- import io .dingodb .expr .common .timezone .operations .ArithmeticOperations ;
2625import io .dingodb .expr .common .timezone .operations .ExtractionOperations ;
2726import io .dingodb .expr .common .timezone .operations .FormattingOperations ;
2827import io .dingodb .expr .common .timezone .operations .OperationResult ;
2928import lombok .Getter ;
3029
3130import java .time .Instant ;
3231import java .time .LocalDate ;
32+ import java .time .LocalDateTime ;
33+ import java .time .LocalTime ;
3334import java .time .ZoneId ;
35+ import java .time .ZonedDateTime ;
3436import java .time .format .DateTimeFormatter ;
3537import java .time .temporal .ChronoUnit ;
3638
@@ -60,6 +62,18 @@ public Object processDateTime(Object input, DateTimeType inputType,
6062 if (input == null || inputType == null ) {
6163 return null ;
6264 }
65+ // Fast path: same type, non-TZ-sensitive SQL types — no conversion needed
66+ if (inputType == outputType ) {
67+ if (input instanceof java .sql .Date && inputType == DateTimeType .DATE ) {
68+ return input ;
69+ }
70+ if (input instanceof java .sql .Time && inputType == DateTimeType .TIME ) {
71+ return input ;
72+ }
73+ if (input instanceof java .sql .Timestamp && inputType == DateTimeType .TIMESTAMP ) {
74+ return input ;
75+ }
76+ }
6377 try {
6478 DingoDateTime internal = tierProcessor .convertInput (input , inputType );
6579
@@ -134,29 +148,50 @@ public ZoneId getStorageZone() {
134148 }
135149
136150 public DingoDateTime dateAdd (DingoDateTime dateTime , long amount , ChronoUnit unit ) {
137- ArithmeticOperations .AddOperation operation = new ArithmeticOperations .AddOperation (unit , amount );
138-
139- OperationResult result = (OperationResult ) operation .execute (new DingoDateTime []{dateTime }, getOutputZone ());
140-
141- if (result .isSuccess () && result .getValue () instanceof DingoDateTime ) {
142- return (DingoDateTime ) result .getValue ();
151+ if (dateTime .isTimeZoneSensitive ()) {
152+ DingoDateTime .DingoTimestampTZ tzValue = (DingoDateTime .DingoTimestampTZ ) dateTime ;
153+ ZonedDateTime zdt = tzValue .getUtcValue ().atZone (tzValue .getOriginalZone ());
154+ return new DingoDateTime .DingoTimestampTZ (zdt .plus (amount , unit ).toInstant (), tzValue .getOriginalZone ());
143155 }
144-
145- throw new DateTimeProcessingException ("Date add operation failed: "
146- + (result .getErrorMessage () != null ? result .getErrorMessage () : "Unknown error" ));
156+ Object value = dateTime .getValue ();
157+ if (value instanceof LocalDate ) {
158+ return new DingoDateTime .DingoLocalDate (((LocalDate ) value ).plus (amount , unit ));
159+ } else if (value instanceof LocalDateTime ) {
160+ return new DingoDateTime .DingoLocalDateTime (((LocalDateTime ) value ).plus (amount , unit ));
161+ } else if (value instanceof LocalTime ) {
162+ return new DingoDateTime .DingoLocalTime (((LocalTime ) value ).plus (amount , unit ));
163+ }
164+ throw new DateTimeProcessingException ("Unsupported type for add: " + value .getClass ());
147165 }
148166
149167 public DingoDateTime dateSubtract (DingoDateTime dateTime , long amount , ChronoUnit unit ) {
150- ArithmeticOperations .SubtractOperation operation = new ArithmeticOperations .SubtractOperation (unit , amount );
168+ if (dateTime .isTimeZoneSensitive ()) {
169+ DingoDateTime .DingoTimestampTZ tzValue = (DingoDateTime .DingoTimestampTZ ) dateTime ;
170+ ZonedDateTime zdt = tzValue .getUtcValue ().atZone (tzValue .getOriginalZone ());
171+ return new DingoDateTime .DingoTimestampTZ (zdt .minus (amount , unit ).toInstant (), tzValue .getOriginalZone ());
172+ }
173+ Object value = dateTime .getValue ();
174+ if (value instanceof LocalDate ) {
175+ return new DingoDateTime .DingoLocalDate (((LocalDate ) value ).minus (amount , unit ));
176+ } else if (value instanceof LocalDateTime ) {
177+ return new DingoDateTime .DingoLocalDateTime (((LocalDateTime ) value ).minus (amount , unit ));
178+ } else if (value instanceof LocalTime ) {
179+ return new DingoDateTime .DingoLocalTime (((LocalTime ) value ).minus (amount , unit ));
180+ }
181+ throw new DateTimeProcessingException ("Unsupported type for subtract: " + value .getClass ());
182+ }
151183
152- OperationResult result = (OperationResult ) operation .execute (new DingoDateTime []{dateTime }, getOutputZone ());
184+ // -------------------------------------------------------------------------
185+ // Type-specialized extraction fast paths — bypass the full pipeline
186+ // for non-timezone-sensitive java.sql types (Date, Timestamp).
187+ // -------------------------------------------------------------------------
153188
154- if ( result . isSuccess () && result . getValue () instanceof DingoDateTime ) {
155- return ( DingoDateTime ) result . getValue ();
156- }
189+ public Integer extractYear ( java . sql . Date value ) {
190+ return value == null ? null : value . toLocalDate (). getYear ();
191+ }
157192
158- throw new DateTimeProcessingException ( "Date subtract operation failed: "
159- + ( result . getErrorMessage () != null ? result . getErrorMessage () : "Unknown error" ) );
193+ public Integer extractYear ( java . sql . Timestamp value ) {
194+ return value == null ? null : value . toLocalDateTime (). getYear ( );
160195 }
161196
162197 public Integer extractYear (Object input ) {
@@ -178,6 +213,14 @@ public Integer extractYear(Object input) {
178213 + (result .getErrorMessage () != null ? result .getErrorMessage () : "Unknown error" ));
179214 }
180215
216+ public Integer extractMonth (java .sql .Date value ) {
217+ return value == null ? null : value .toLocalDate ().getMonthValue ();
218+ }
219+
220+ public Integer extractMonth (java .sql .Timestamp value ) {
221+ return value == null ? null : value .toLocalDateTime ().getMonthValue ();
222+ }
223+
181224 public Integer extractMonth (Object input ) {
182225 ExtractionOperations .ExtractFieldOperation operation = ExtractionOperations .month ();
183226 DateTimeType inputType = inferInputType (input );
@@ -198,6 +241,14 @@ public Integer extractMonth(Object input) {
198241 + (result .getErrorMessage () != null ? result .getErrorMessage () : "Unknown error" ));
199242 }
200243
244+ public Integer extractDay (java .sql .Date value ) {
245+ return value == null ? null : value .toLocalDate ().getDayOfMonth ();
246+ }
247+
248+ public Integer extractDay (java .sql .Timestamp value ) {
249+ return value == null ? null : value .toLocalDateTime ().getDayOfMonth ();
250+ }
251+
201252 public Integer extractDay (Object input ) {
202253 ExtractionOperations .ExtractFieldOperation operation = ExtractionOperations .dayOfMonth ();
203254 DateTimeType inputType = inferInputType (input );
@@ -218,6 +269,14 @@ public Integer extractDay(Object input) {
218269 + (result .getErrorMessage () != null ? result .getErrorMessage () : "Unknown error" ));
219270 }
220271
272+ public Integer extractQuarter (java .sql .Date value ) {
273+ return value == null ? null : (value .toLocalDate ().getMonthValue () - 1 ) / 3 + 1 ;
274+ }
275+
276+ public Integer extractQuarter (java .sql .Timestamp value ) {
277+ return value == null ? null : (value .toLocalDateTime ().getMonthValue () - 1 ) / 3 + 1 ;
278+ }
279+
221280 public Integer extractQuarter (Object input ) {
222281 ExtractionOperations .ExtractQuarterOperation operation = ExtractionOperations .quarter ();
223282 DateTimeType inputType = inferInputType (input );
@@ -238,6 +297,20 @@ public Integer extractQuarter(Object input) {
238297 + (result .getErrorMessage () != null ? result .getErrorMessage () : "Unknown error" ));
239298 }
240299
300+ public Integer extractWeek (java .sql .Date value ) {
301+ if (value == null ) {
302+ return null ;
303+ }
304+ return value .toLocalDate ().get (java .time .temporal .IsoFields .WEEK_OF_WEEK_BASED_YEAR );
305+ }
306+
307+ public Integer extractWeek (java .sql .Timestamp value ) {
308+ if (value == null ) {
309+ return null ;
310+ }
311+ return value .toLocalDateTime ().get (java .time .temporal .IsoFields .WEEK_OF_WEEK_BASED_YEAR );
312+ }
313+
241314 public Integer extractWeek (Object input ) {
242315 ExtractionOperations .ExtractFieldOperation operation = ExtractionOperations .week ();
243316 DateTimeType inputType = inferInputType (input );
@@ -259,6 +332,18 @@ public Integer extractWeek(Object input) {
259332 + (result .getErrorMessage () != null ? result .getErrorMessage () : "Unknown error" ));
260333 }
261334
335+ public Integer extractHour (java .sql .Date value ) {
336+ return 0 ;
337+ }
338+
339+ public Integer extractHour (java .sql .Timestamp value ) {
340+ return value == null ? 0 : value .toLocalDateTime ().getHour ();
341+ }
342+
343+ public Integer extractHour (java .sql .Time value ) {
344+ return value == null ? 0 : value .toLocalTime ().getHour ();
345+ }
346+
262347 public Integer extractHour (Object input ) {
263348 ExtractionOperations .ExtractFieldOperation operation = ExtractionOperations .hour ();
264349 DateTimeType inputType = inferInputType (input );
@@ -276,6 +361,18 @@ public Integer extractHour(Object input) {
276361 + (result .getErrorMessage () != null ? result .getErrorMessage () : "Unknown error" ));
277362 }
278363
364+ public Integer extractMinute (java .sql .Date value ) {
365+ return 0 ;
366+ }
367+
368+ public Integer extractMinute (java .sql .Timestamp value ) {
369+ return value == null ? 0 : value .toLocalDateTime ().getMinute ();
370+ }
371+
372+ public Integer extractMinute (java .sql .Time value ) {
373+ return value == null ? 0 : value .toLocalTime ().getMinute ();
374+ }
375+
279376 public Integer extractMinute (Object input ) {
280377 ExtractionOperations .ExtractFieldOperation operation = ExtractionOperations .minute ();
281378 DateTimeType inputType = inferInputType (input );
@@ -293,6 +390,18 @@ public Integer extractMinute(Object input) {
293390 + (result .getErrorMessage () != null ? result .getErrorMessage () : "Unknown error" ));
294391 }
295392
393+ public Integer extractSecond (java .sql .Date value ) {
394+ return 0 ;
395+ }
396+
397+ public Integer extractSecond (java .sql .Timestamp value ) {
398+ return value == null ? 0 : value .toLocalDateTime ().getSecond ();
399+ }
400+
401+ public Integer extractSecond (java .sql .Time value ) {
402+ return value == null ? 0 : value .toLocalTime ().getSecond ();
403+ }
404+
296405 public Integer extractSecond (Object input ) {
297406 ExtractionOperations .ExtractFieldOperation operation = ExtractionOperations .second ();
298407 DateTimeType inputType = inferInputType (input );
@@ -310,6 +419,17 @@ public Integer extractSecond(Object input) {
310419 + (result .getErrorMessage () != null ? result .getErrorMessage () : "Unknown error" ));
311420 }
312421
422+ public Integer extractMillisecond (java .sql .Date value ) {
423+ return 0 ;
424+ }
425+
426+ public Integer extractMillisecond (java .sql .Timestamp value ) {
427+ if (value == null ) {
428+ return 0 ;
429+ }
430+ return value .toLocalDateTime ().getNano () / 1_000_000 ;
431+ }
432+
313433 public Integer extractMillisecond (Object input ) {
314434 ExtractionOperations .ExtractFieldOperation operation = ExtractionOperations .millisecond ();
315435 DateTimeType inputType = inferInputType (input );
0 commit comments