diff --git a/contrib/babelfishpg_common/src/datetime.c b/contrib/babelfishpg_common/src/datetime.c index 0ca3680be9..8fda2a7d77 100644 --- a/contrib/babelfishpg_common/src/datetime.c +++ b/contrib/babelfishpg_common/src/datetime.c @@ -1308,6 +1308,8 @@ timestamp_diff(PG_FUNCTION_ARGS) int32 seconddiff; int32 millisecdiff; int32 microsecdiff; + int32 days_in_timestamp1; + int32 days_in_timestamp2; struct pg_tm tt1, *tm1 = &tt1; fsec_t fsec1; @@ -1330,16 +1332,16 @@ timestamp_diff(PG_FUNCTION_ARGS) type = DecodeUnits(0, lowunits, &val); // Decode units does not handle doy properly - if(strncmp(lowunits, "doy", 3) == 0) { + if(strlen(lowunits) == 3 && strncmp(lowunits, "doy", 3) == 0) { type = UNITS; val = DTK_DOY; } - if(strncmp(lowunits, "nanosecond", 11) == 0) { + if(strlen(lowunits) == 10 && strncmp(lowunits, "nanosecond", 10) == 0) { type = UNITS; val = DTK_NANO; } - if(strncmp(lowunits, "weekday", 7) == 0) { + if(strlen(lowunits) == 7 && strncmp(lowunits, "weekday", 7) == 0) { type = UNITS; val = DTK_DAY; } @@ -1354,6 +1356,21 @@ timestamp_diff(PG_FUNCTION_ARGS) yeardiff = tm2->tm_year - tm1->tm_year; monthdiff = tm2->tm_mon - tm1->tm_mon; diff = (yeardiff * 12 + monthdiff) / 3; + /* Calculate if quarter boundary is crossed for the remaining months */ + if (monthdiff % 3 > 0) + { + if (yeardiff >= 0 && ((tm1->tm_mon - 1) % 3 > (tm2->tm_mon - 1) % 3)) + diff++; + else if (yeardiff < 0 && ((tm1->tm_mon - 1) % 3 < (tm2->tm_mon - 1) % 3)) + diff--; + } + else if (monthdiff % 3 < 0) + { + if (yeardiff > 0 && ((tm1->tm_mon - 1) % 3 > (tm2->tm_mon - 1) % 3)) + diff++; + else if (yeardiff <= 0 && ((tm1->tm_mon - 1) % 3 < (tm2->tm_mon - 1) % 3)) + diff--; + } break; case DTK_MONTH: yeardiff = tm2->tm_year - tm1->tm_year; @@ -1361,10 +1378,18 @@ timestamp_diff(PG_FUNCTION_ARGS) diff = yeardiff * 12 + monthdiff; break; case DTK_WEEK: - daydiff = days_in_date(tm2->tm_mday, tm2->tm_mon, tm2->tm_year) - days_in_date(tm1->tm_mday, tm1->tm_mon, tm1->tm_year); + days_in_timestamp1 = days_in_date(tm1->tm_mday, tm1->tm_mon, tm1->tm_year); + days_in_timestamp2 = days_in_date(tm2->tm_mday, tm2->tm_mon, tm2->tm_year); + daydiff = days_in_timestamp2 - days_in_timestamp1; diff = daydiff / 7; - if(daydiff % 7 >= 4) - diff++; + /* Calculate if saturday-sunday boundary is crossed for the remaining days */ + if (abs(daydiff) % 7 > ((Max(days_in_timestamp1, days_in_timestamp2) - 1) % 7)) + { + if (daydiff < 0) + diff--; + else + diff++; + } break; case DTK_DAY: case DTK_DOY: @@ -1452,7 +1477,7 @@ timestamp_diff(PG_FUNCTION_ARGS) if(overflow) { ereport(ERROR, (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE), - errmsg("The datediff function resulted in an overflow. The number of dateparts separating two date/time instances is too large. Try to use datediff with a less precise datepart"))); + errmsg("The %s function resulted in an overflow. The number of dateparts separating two date/time instances is too large. Try to use %s with a less precise datepart.", "datediff", "datediff"))); } PG_RETURN_INT32(diff); @@ -1479,6 +1504,8 @@ timestamp_diff_big(PG_FUNCTION_ARGS) int64 seconddiff; int64 millisecdiff; int64 microsecdiff; + int64 days_in_timestamp1; + int64 days_in_timestamp2; struct pg_tm tt1, *tm1 = &tt1; fsec_t fsec1; @@ -1501,15 +1528,15 @@ timestamp_diff_big(PG_FUNCTION_ARGS) type = DecodeUnits(0, lowunits, &val); // Decode units does not handle doy or nano properly - if(strncmp(lowunits, "doy", 3) == 0) { + if(strlen(lowunits) == 3 && strncmp(lowunits, "doy", 3) == 0) { type = UNITS; val = DTK_DOY; } - if(strncmp(lowunits, "nanosecond", 11) == 0) { + if(strlen(lowunits) == 10 && strncmp(lowunits, "nanosecond", 10) == 0) { type = UNITS; val = DTK_NANO; } - if(strncmp(lowunits, "weekday", 7) == 0) { + if(strlen(lowunits) == 7 && strncmp(lowunits, "weekday", 7) == 0) { type = UNITS; val = DTK_DAY; } @@ -1525,6 +1552,21 @@ timestamp_diff_big(PG_FUNCTION_ARGS) yeardiff = tm2->tm_year - tm1->tm_year; monthdiff = tm2->tm_mon - tm1->tm_mon; diff = (yeardiff * 12 + monthdiff) / 3; + /* Calculate if quarter boundary is crossed for the remaining months */ + if (monthdiff % 3 > 0) + { + if (yeardiff >= 0 && ((tm1->tm_mon - 1) % 3 > (tm2->tm_mon - 1) % 3)) + diff++; + else if (yeardiff < 0 && ((tm1->tm_mon - 1) % 3 < (tm2->tm_mon - 1) % 3)) + diff--; + } + else if (monthdiff % 3 < 0) + { + if (yeardiff > 0 && ((tm1->tm_mon - 1) % 3 > (tm2->tm_mon - 1) % 3)) + diff++; + else if (yeardiff <= 0 && ((tm1->tm_mon - 1) % 3 < (tm2->tm_mon - 1) % 3)) + diff--; + } break; case DTK_MONTH: yeardiff = tm2->tm_year - tm1->tm_year; @@ -1532,10 +1574,18 @@ timestamp_diff_big(PG_FUNCTION_ARGS) diff = yeardiff * 12 + monthdiff; break; case DTK_WEEK: - daydiff = days_in_date(tm2->tm_mday, tm2->tm_mon, tm2->tm_year) - days_in_date(tm1->tm_mday, tm1->tm_mon, tm1->tm_year); + days_in_timestamp1 = days_in_date(tm1->tm_mday, tm1->tm_mon, tm1->tm_year); + days_in_timestamp2 = days_in_date(tm2->tm_mday, tm2->tm_mon, tm2->tm_year); + daydiff = days_in_timestamp2 - days_in_timestamp1; diff = daydiff / 7; - if(daydiff % 7 >= 4) - diff++; + /* Calculate if saturday-sunday boundary is crossed for the remaining days */ + if (abs(daydiff) % 7 > ((Max(days_in_timestamp1, days_in_timestamp2) - 1) % 7)) + { + if (daydiff < 0) + diff--; + else + diff++; + } break; case DTK_DAY: case DTK_DOY: @@ -1617,12 +1667,12 @@ timestamp_diff_big(PG_FUNCTION_ARGS) if(!validDateDiff) { ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("\'%s\' is not a recognized %s option", lowunits, "datediff"))); + errmsg("\'%s\' is not a recognized %s option", lowunits, "datediff_big"))); } if(overflow) { ereport(ERROR, (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE), - errmsg("The datediff function resulted in an overflow. The number of dateparts separating two date/time instances is too large. Try to use datediff with a less precise datepart"))); + errmsg("The %s function resulted in an overflow. The number of dateparts separating two date/time instances is too large. Try to use %s with a less precise datepart.", "datediff_big", "datediff_big"))); } PG_RETURN_INT64(diff); @@ -1728,15 +1778,15 @@ dateadd_datetime(PG_FUNCTION_ARGS) { type = DecodeUnits(0, lowunits, &val); - if(strncmp(lowunits, "doy", 3) == 0 || strncmp(lowunits, "dayofyear", 9) == 0) { + if((strlen(lowunits) == 3 && strncmp(lowunits, "doy", 3) == 0) || (strlen(lowunits) == 9 && strncmp(lowunits, "dayofyear", 9) == 0)) { type = UNITS; val = DTK_DOY; } - if(strncmp(lowunits, "nanosecond", 11) == 0) { + if(strlen(lowunits) == 10 && strncmp(lowunits, "nanosecond", 10) == 0) { type = UNITS; val = DTK_NANO; } - if(strncmp(lowunits, "weekday", 7) == 0) { + if(strlen(lowunits) == 7 && strncmp(lowunits, "weekday", 7) == 0) { type = UNITS; val = DTK_DAY; } diff --git a/contrib/babelfishpg_tds/error_mapping.txt b/contrib/babelfishpg_tds/error_mapping.txt index cf1e84ccd0..60fd4551eb 100644 --- a/contrib/babelfishpg_tds/error_mapping.txt +++ b/contrib/babelfishpg_tds/error_mapping.txt @@ -181,7 +181,7 @@ XX000 ERRCODE_INTERNAL_ERROR "The table-valued parameter \"%s\" must be declared 0A000 ERRCODE_FEATURE_NOT_SUPPORTED "Column name or number of supplied values does not match table definition." SQL_ERROR_213 16 42501 ERRCODE_INSUFFICIENT_PRIVILEGE "Only members of the sysadmin role can execute this stored procedure." SQL_ERROR_15003 16 42809 ERRCODE_WRONG_OBJECT_TYPE "The target \"%s\" of the OUTPUT INTO clause cannot be a view or common table expression." SQL_ERROR_330 16 -22008 ERRCODE_DATETIME_VALUE_OUT_OF_RANGE "The datediff function resulted in an overflow. The number of dateparts separating two date/time instances is too large. Try to use datediff with a less precise datepart" SQL_ERROR_535 16 +22008 ERRCODE_DATETIME_VALUE_OUT_OF_RANGE "The %s function resulted in an overflow. The number of dateparts separating two date/time instances is too large. Try to use %s with a less precise datepart." SQL_ERROR_535 16 22023 ERRCODE_INVALID_PARAMETER_VALUE "\'%s\' is not a recognized %s option" SQL_ERROR_155 15 22023 ERRCODE_INVALID_PARAMETER_VALUE "The datepart %s is not supported by date function %s for data type %s." SQL_ERROR_9810 16 22008 ERRCODE_DATETIME_VALUE_OUT_OF_RANGE "Adding a value to a \'%s\' column caused an overflow." SQL_ERROR_517 16 diff --git a/test/JDBC/expected/BABEL-2347.out b/test/JDBC/expected/BABEL-2347.out index 11724986c8..bd54e38097 100644 --- a/test/JDBC/expected/BABEL-2347.out +++ b/test/JDBC/expected/BABEL-2347.out @@ -132,7 +132,7 @@ SELECT DATEDIFF(quarter, @date1, @date2) as quarter_diff go ~~START~~ int -0 +1 ~~END~~ @@ -144,7 +144,7 @@ SELECT DATEDIFF(qq, @date1, @date2) as qq_diff go ~~START~~ int -0 +1 ~~END~~ @@ -241,7 +241,7 @@ SELECT DATEDIFF(quarter, @date1, @date2) as quarter_diff go ~~START~~ int -0 +1 ~~END~~ @@ -253,7 +253,7 @@ SELECT DATEDIFF(qq, @date1, @date2) as qq_diff go ~~START~~ int -0 +1 ~~END~~ diff --git a/test/JDBC/expected/BABEL-2812-vu-verify.out b/test/JDBC/expected/BABEL-2812-vu-verify.out index 7752d63442..4df1dbbd64 100644 --- a/test/JDBC/expected/BABEL-2812-vu-verify.out +++ b/test/JDBC/expected/BABEL-2812-vu-verify.out @@ -325,7 +325,7 @@ SELECT * FROM babel_2812_vu_v38 GO ~~ERROR (Code: 535)~~ -~~ERROR (Message: The datediff function resulted in an overflow. The number of dateparts separating two date/time instances is too large. Try to use datediff with a less precise datepart)~~ +~~ERROR (Message: The datediff function resulted in an overflow. The number of dateparts separating two date/time instances is too large. Try to use datediff with a less precise datepart.)~~ -- smaller interval for millisecond SELECT * FROM babel_2812_vu_v39 @@ -340,7 +340,7 @@ SELECT * FROM babel_2812_vu_v40 GO ~~ERROR (Code: 535)~~ -~~ERROR (Message: The datediff function resulted in an overflow. The number of dateparts separating two date/time instances is too large. Try to use datediff with a less precise datepart)~~ +~~ERROR (Message: The datediff function resulted in an overflow. The number of dateparts separating two date/time instances is too large. Try to use datediff with a less precise datepart.)~~ -- microsecond and nanosecond can only handle diff of 0 for date type SELECT * FROM babel_2812_vu_v41 diff --git a/test/JDBC/expected/TestErrorHelperFunctions.out b/test/JDBC/expected/TestErrorHelperFunctions.out index ff2ce1f34c..7daf229fdf 100644 --- a/test/JDBC/expected/TestErrorHelperFunctions.out +++ b/test/JDBC/expected/TestErrorHelperFunctions.out @@ -204,7 +204,7 @@ XX000#!#The table-valued parameter "%s" must be declared with the READONLY optio 0A000#!#Column name or number of supplied values does not match table definition.#!##!#213 42501#!#Only members of the sysadmin role can execute this stored procedure.#!##!#15003 42809#!#The target "%s" of the OUTPUT INTO clause cannot be a view or common table expression.#!##!#330 -22008#!#The datediff function resulted in an overflow. The number of dateparts separating two date/time instances is too large. Try to use datediff with a less precise datepart#!##!#535 +22008#!#The %s function resulted in an overflow. The number of dateparts separating two date/time instances is too large. Try to use %s with a less precise datepart.#!##!#535 22023#!#'%s' is not a recognized %s option#!##!#155 22023#!#The datepart %s is not supported by date function %s for data type %s.#!##!#9810 22008#!#Adding a value to a '%s' column caused an overflow.#!##!#517 diff --git a/test/JDBC/expected/babel_function.out b/test/JDBC/expected/babel_function.out index 01f5cf3e3c..41d3979e82 100644 --- a/test/JDBC/expected/babel_function.out +++ b/test/JDBC/expected/babel_function.out @@ -1369,7 +1369,7 @@ select datediff(week,CAST('2037-03-01 23:30:05.523'AS sys.datetime),CAST('2036-0 GO ~~START~~ int --52 +-53 ~~END~~ select datediff(hour, CAST('2037-03-01 23:30:05.523'AS sys.datetime), CAST('2036-02-28 23:30:05.523'AS sys.datetime)); @@ -1426,7 +1426,7 @@ select datediff(quarter,CAST('2016-12-26 23:30:05.523456'AS datetime2), CAST('20 GO ~~START~~ int -6 +7 ~~END~~ select datediff(hour, CAST('2016-12-26 23:30:05'AS smalldatetime), CAST('2016-12-28 21:29:05'AS smalldatetime)); diff --git a/test/JDBC/expected/datediff-vu-verify.out b/test/JDBC/expected/datediff-vu-verify.out index 1ea3659990..16436bb257 100644 --- a/test/JDBC/expected/datediff-vu-verify.out +++ b/test/JDBC/expected/datediff-vu-verify.out @@ -102,7 +102,7 @@ exec datediff_p12 GO ~~ERROR (Code: 535)~~ -~~ERROR (Message: The datediff function resulted in an overflow. The number of dateparts separating two date/time instances is too large. Try to use datediff with a less precise datepart)~~ +~~ERROR (Message: The datediff function resulted in an overflow. The number of dateparts separating two date/time instances is too large. Try to use datediff with a less precise datepart.)~~ -- 1200000000000 @@ -167,7 +167,7 @@ SELECT DATEDIFF(nanosecond, cast('1900-01-01 01:01:20.98' as datetime), cast('20 go ~~ERROR (Code: 535)~~ -~~ERROR (Message: The datediff function resulted in an overflow. The number of dateparts separating two date/time instances is too large. Try to use datediff with a less precise datepart)~~ +~~ERROR (Message: The datediff function resulted in an overflow. The number of dateparts separating two date/time instances is too large. Try to use datediff with a less precise datepart.)~~ if (@@trancount > 0) select cast('compile time error' as text) else select cast('runtime error' as text) @@ -180,3 +180,927 @@ compile time error if (@@trancount > 0) rollback tran GO + +Declare @runForDate datetime = '01/22/2012'; +Declare @evaluationDate datetime = DATEADD(DAY,-1,@runForDate); +Select DATEDIFF(wk,7,@evaluationDate) +GO +~~START~~ +int +5845 +~~END~~ + + +-- Basic Functionality +SELECT DATEDIFF(week, CAST('2023-01-01' AS DATE), CAST('2023-01-01' AS DATE)) AS SameDate; +GO +~~START~~ +int +0 +~~END~~ + + +SELECT DATEDIFF(week, CAST('2023-01-01' AS DATETIME), CAST('2023-01-02' AS DATETIME)) AS ConsecutiveDaysSameWeek; +GO +~~START~~ +int +0 +~~END~~ + + +SELECT DATEDIFF(week, CAST('2023-01-01' AS DATE), CAST('2022-12-25' AS DATE)) AS DifferentWeeks; +GO +~~START~~ +int +-1 +~~END~~ + + +SELECT DATEDIFF(week, CAST('2010-01-01' AS DATE), CAST('2009-12-19' AS DATE)) AS DifferentWeeks; +GO +~~START~~ +int +-2 +~~END~~ + + +SELECT DATEDIFF(quarter, CAST('2023-01-01' AS DATE), CAST('2023-01-31' AS DATE)) AS SameQuarter; +GO +~~START~~ +int +0 +~~END~~ + + +SELECT DATEDIFF(quarter, CAST('2023-01-01' AS DATETIME), CAST('2023-02-01' AS DATETIME)) AS ConsecutiveMonths; +GO +~~START~~ +int +0 +~~END~~ + + +SELECT DATEDIFF(quarter, CAST('2023-02-01' AS DATETIME), CAST('2023-01-01' AS DATETIME)) AS ConsecutiveMonths; +GO +~~START~~ +int +0 +~~END~~ + + +SELECT DATEDIFF(quarter, CAST('2023-01-01' AS DATE), CAST('2023-07-25' AS DATE)) AS DifferentQuarters; +GO +~~START~~ +int +2 +~~END~~ + + +SELECT DATEDIFF(quarter, CAST('2010-01-01' AS DATE), CAST('2011-12-19' AS DATE)) AS DifferentQuarters; +GO +~~START~~ +int +7 +~~END~~ + + +-- No boundary crossed +SELECT DATEDIFF(week, CAST('2023-01-01' AS DATE), CAST('2023-01-07' AS DATE)) AS NoBoundaryCrossed; +GO +~~START~~ +int +0 +~~END~~ + + +SELECT DATEDIFF(week, CAST('2023-01-07' AS DATE), CAST('2023-01-01' AS DATE)) AS NoBoundaryCrossed; +GO +~~START~~ +int +0 +~~END~~ + + +SELECT DATEDIFF(quarter, CAST('2023-01-01' AS DATE), CAST('2023-03-31' AS DATE)) AS NoBoundaryCrossed; +GO +~~START~~ +int +0 +~~END~~ + + +-- One boundary crossed +SELECT DATEDIFF(week, CAST('2023-01-07' AS DATETIME), CAST('2023-01-08' AS DATETIME)) AS OneBoundaryCrossed; +GO +~~START~~ +int +1 +~~END~~ + + +SELECT DATEDIFF(wk, CAST('2023-01-07' AS DATETIME), CAST('2023-01-08' AS DATETIME)) AS OneBoundaryCrossed; +GO +~~START~~ +int +1 +~~END~~ + + +SELECT DATEDIFF(week, CAST('2023-01-08' AS DATETIME), CAST('2023-01-07' AS DATETIME)) AS OneBoundaryCrossed; +GO +~~START~~ +int +-1 +~~END~~ + + +SELECT DATEDIFF(quarter, CAST('2023-01-01' AS DATETIME), CAST('2023-04-01' AS DATETIME)) AS OneBoundaryCrossed; +GO +~~START~~ +int +1 +~~END~~ + + +SELECT DATEDIFF(quarter, CAST('2023-04-01' AS DATETIME), CAST('2023-01-01' AS DATETIME)) AS OneBoundaryCrossed; +GO +~~START~~ +int +-1 +~~END~~ + + +SELECT DATEDIFF(qq, CAST('2023-01-01' AS DATETIME), CAST('2022-12-31' AS DATETIME)) AS OneBoundaryCrossed; +GO +~~START~~ +int +-1 +~~END~~ + + +SELECT DATEDIFF(quarter, CAST('2022-12-31' AS DATETIME), CAST('2023-01-01' AS DATETIME)) AS OneBoundaryCrossed; +GO +~~START~~ +int +1 +~~END~~ + + +-- Multiple boundaries crossed +SELECT DATEDIFF(week, CAST('2023-01-07' AS DATE), CAST('2023-01-22' AS DATE)) AS MultipleBoundariesCrossed; +GO +~~START~~ +int +3 +~~END~~ + + +SELECT DATEDIFF(ww, CAST('2023-01-07' AS DATE), CAST('2023-01-22' AS DATE)) AS MultipleBoundariesCrossed; +GO +~~START~~ +int +3 +~~END~~ + + +SELECT DATEDIFF(week, CAST('2023-01-22' AS DATE), CAST('2023-01-07' AS DATE)) AS MultipleBoundariesCrossed; +GO +~~START~~ +int +-3 +~~END~~ + + +SELECT DATEDIFF(quarter, CAST('2023-01-07' AS DATE), CAST('2023-01-22' AS DATE)) AS MultipleBoundariesCrossed; +GO +~~START~~ +int +0 +~~END~~ + + +SELECT DATEDIFF(q, CAST('2023-01-07' AS DATE), CAST('2023-01-22' AS DATE)) AS MultipleBoundariesCrossed; +GO +~~START~~ +int +0 +~~END~~ + + +SELECT DATEDIFF(q, CAST('2023-01-22' AS DATE), CAST('2023-01-07' AS DATE)) AS MultipleBoundariesCrossed; +GO +~~START~~ +int +0 +~~END~~ + + +SELECT DATEDIFF(q, CAST('2023-05-22' AS DATE), CAST('2023-06-07' AS DATE)) AS MultipleBoundariesCrossed; +GO +~~START~~ +int +0 +~~END~~ + + +SELECT DATEDIFF(quarter, CAST('2023-06-22' AS DATE), CAST('2023-05-07' AS DATE)) AS MultipleBoundariesCrossed; +GO +~~START~~ +int +0 +~~END~~ + + +SELECT DATEDIFF(quarter, CAST('2023-06-22' AS DATE), CAST('2023-07-07' AS DATE)) AS MultipleBoundariesCrossed; +GO +~~START~~ +int +1 +~~END~~ + + +SELECT DATEDIFF(quarter, CAST('2023-07-22' AS DATE), CAST('2023-06-07' AS DATE)) AS MultipleBoundariesCrossed; +GO +~~START~~ +int +-1 +~~END~~ + + +SELECT DATEDIFF(quarter, CAST('2023-01-22' AS DATE), CAST('2024-01-07' AS DATE)) AS MultipleBoundariesCrossed; +GO +~~START~~ +int +4 +~~END~~ + + +SELECT DATEDIFF(quarter, CAST('2024-01-22' AS DATE), CAST('2023-01-07' AS DATE)) AS MultipleBoundariesCrossed; +GO +~~START~~ +int +-4 +~~END~~ + + +SELECT DATEDIFF(quarter, CAST('2023-01-22' AS DATE), CAST('2024-04-07' AS DATE)) AS MultipleBoundariesCrossed; +GO +~~START~~ +int +5 +~~END~~ + + +SELECT DATEDIFF(quarter, CAST('2024-01-22' AS DATE), CAST('2023-04-07' AS DATE)) AS MultipleBoundariesCrossed; +GO +~~START~~ +int +-3 +~~END~~ + + +-- Time-sensitive crossing +SELECT DATEDIFF(week, CAST('2023-01-07 23:59' AS DATETIME), CAST('2023-01-08 00:00' AS DATETIME)) AS TimeSensitiveBoundary; +GO +~~START~~ +int +1 +~~END~~ + + +SELECT DATEDIFF(week, CAST('2023-01-08 00:00' AS DATETIME), CAST('2023-01-07 23:59' AS DATETIME)) AS TimeSensitiveBoundary; +GO +~~START~~ +int +-1 +~~END~~ + + +SELECT DATEDIFF(quarter, CAST('2023-09-30 23:59' AS DATETIME), CAST('2023-10-01 00:00' AS DATETIME)) AS TimeSensitiveBoundary; +GO +~~START~~ +int +1 +~~END~~ + + +SELECT DATEDIFF(quarter, CAST('2023-10-01 00:00' AS DATETIME), CAST('2023-09-30 23:59' AS DATETIME)) AS TimeSensitiveBoundary; +GO +~~START~~ +int +-1 +~~END~~ + + +-- Overlapping across years +SELECT DATEDIFF(week, CAST('2022-12-31' AS DATE), CAST('2023-01-08' AS DATE)) AS YearBoundaryCrossed; +GO +~~START~~ +int +2 +~~END~~ + + +SELECT DATEDIFF(quarter, CAST('2022-12-31' AS DATE), CAST('2023-01-08' AS DATE)) AS YearBoundaryCrossed; +GO +~~START~~ +int +1 +~~END~~ + + +-- Week starts on Sunday +SELECT DATEDIFF(week, CAST('2023-01-01' AS DATE), CAST('2023-01-08' AS DATE)) AS WeekStartsOnSunday; +GO +~~START~~ +int +1 +~~END~~ + + +-- Week ends on Saturday +SELECT DATEDIFF(week, CAST('2023-01-01' AS DATETIME), CAST('2023-01-14' AS DATETIME)) AS WeekEndsOnSaturday; +GO +~~START~~ +int +1 +~~END~~ + + +-- Multiple weeks with no overlap +SELECT DATEDIFF(week, CAST('2023-01-01' AS DATE), CAST('2023-01-28' AS DATE)) AS MultipleWeeksNoOverlap; +GO +~~START~~ +int +3 +~~END~~ + + +-- Start and end at exact boundaries +SELECT DATEDIFF(week, CAST('2023-01-01 00:00:00' AS DATETIME), CAST('2023-01-08 00:00:00' AS DATETIME)) AS ExactBoundary; +GO +~~START~~ +int +1 +~~END~~ + + +SELECT DATEDIFF(quarter, CAST('2023-01-01 00:00:00' AS DATETIME), CAST('2023-04-01 00:00:00' AS DATETIME)) AS ExactBoundary; +GO +~~START~~ +int +1 +~~END~~ + + +-- Start and end with fractional seconds +SELECT DATEDIFF(week, CAST('2023-01-01 23:59:59.999999' AS DATETIME2), CAST('2023-01-08 00:00:00.000000' AS DATETIME2)) AS FractionalSecondsPrecision; +GO +~~START~~ +int +1 +~~END~~ + + +-- Leap Year +SELECT DATEDIFF(week, CAST('2020-02-28' AS DATETIME), CAST('2020-03-01' AS DATETIME)) AS AcrossLeapDay; +GO +~~START~~ +int +1 +~~END~~ + + +SELECT DATEDIFF(week, CAST('2020-02-29' AS DATE), CAST('2020-03-07' AS DATE)) AS WeekWithLeapDay; +GO +~~START~~ +int +1 +~~END~~ + + +-- Negative Intervals +SELECT DATEDIFF(week, CAST('2023-01-08' AS DATE), CAST('2023-01-01' AS DATE)) AS NegativeInterval; +GO +~~START~~ +int +-1 +~~END~~ + + +SELECT DATEDIFF(week, CAST('2023-01-08 12:00' AS DATETIME), CAST('2023-01-01 12:00' AS DATETIME)) AS NegativeWithTime; +GO +~~START~~ +int +-1 +~~END~~ + + +SELECT DATEDIFF(week, CAST('9999-01-01' AS DATE), CAST('0001-01-01' AS DATE)) AS Date_ReverseRange; +GO +~~START~~ +int +-521670 +~~END~~ + + +SELECT DATEDIFF(week, CAST('9999-01-01' AS DATETIME2), CAST('0001-01-01' AS DATETIME2)) AS Datetime2_ReverseRange; +GO +~~START~~ +int +-521670 +~~END~~ + + +-- Boundary Conditions +SELECT DATEDIFF(week, CAST('2023-01-01' AS DATETIME), CAST('2023-01-07' AS DATETIME)) AS SameWeekBoundary; +GO +~~START~~ +int +0 +~~END~~ + + +SELECT DATEDIFF(week, CAST('2023-01-07' AS DATE), CAST('2023-01-08' AS DATE)) AS WeekResetBoundary; +GO +~~START~~ +int +1 +~~END~~ + + +-- Across Years +SELECT DATEDIFF(week, CAST('2022-12-31' AS DATETIME), CAST('2023-01-01' AS DATETIME)) AS SameWeekAcrossYears; +GO +~~START~~ +int +1 +~~END~~ + + +SELECT DATEDIFF(week, CAST('2022-12-31' AS DATE), CAST('2023-01-08' AS DATE)) AS DifferentWeeksAcrossYears; +GO +~~START~~ +int +2 +~~END~~ + + +-- Null Inputs +SELECT DATEDIFF(week, NULL, CAST('2023-01-01' AS DATE)) AS NullStartDate; +GO +~~START~~ +int + +~~END~~ + + +SELECT DATEDIFF(week, CAST('2023-01-01' AS DATETIME), NULL) AS NullEndDate; +GO +~~START~~ +int + +~~END~~ + + +SELECT DATEDIFF(week, NULL, NULL) AS BothNull; +GO +~~START~~ +int + +~~END~~ + + +SELECT DATEDIFF(quarter, NULL, CAST('2023-01-01' AS DATE)) AS NullStartDate; +GO +~~START~~ +int + +~~END~~ + + +SELECT DATEDIFF(quarter, CAST('2023-01-01' AS DATETIME), NULL) AS NullEndDate; +GO +~~START~~ +int + +~~END~~ + + +SELECT DATEDIFF(quarter, NULL, NULL) AS BothNull; +GO +~~START~~ +int + +~~END~~ + + +-- Invalid Inputs +SELECT DATEDIFF(week, CAST('InvalidDate' AS DATE), CAST('2023-01-01' AS DATE)) AS InvalidStartDate; +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: invalid input syntax for type date: "InvalidDate")~~ + + +SELECT DATEDIFF(week, CAST('2023-01-01' AS DATETIME), CAST('InvalidDate' AS DATETIME)) AS InvalidEndDate; +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: invalid input syntax for type datetime: "InvalidDate")~~ + + +SELECT DATEDIFF(quarter, CAST('InvalidDate' AS DATE), CAST('2023-01-01' AS DATE)) AS InvalidStartDate; +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: invalid input syntax for type date: "InvalidDate")~~ + + +SELECT DATEDIFF(quarter, CAST('2023-01-01' AS DATETIME), CAST('InvalidDate' AS DATETIME)) AS InvalidEndDate; +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: invalid input syntax for type datetime: "InvalidDate")~~ + + +-- Large Date Ranges +SELECT DATEDIFF(week, CAST('1923-01-01' AS DATE), CAST('2023-01-01' AS DATE)) AS CenturyDifference; +GO +~~START~~ +int +5218 +~~END~~ + + +SELECT DATEDIFF(week, CAST('0001-01-01' AS DATETIME), CAST('2023-01-01' AS DATETIME)) AS MillenniaDifference; +GO +~~ERROR (Code: 517)~~ + +~~ERROR (Message: data out of range for datetime)~~ + + +SELECT DATEDIFF(quarter, CAST('1923-01-01' AS DATE), CAST('2023-01-01' AS DATE)) AS CenturyDifference; +GO +~~START~~ +int +400 +~~END~~ + + +SELECT DATEDIFF(quarter, CAST('0001-01-01' AS DATETIME), CAST('2023-01-01' AS DATETIME)) AS MillenniaDifference; +GO +~~ERROR (Code: 517)~~ + +~~ERROR (Message: data out of range for datetime)~~ + + +-- Boundary Testing +SELECT DATEDIFF(week, CAST('0001-01-01' AS DATE), CAST('9999-12-31' AS DATE)) AS Date_FullRange; +GO +~~START~~ +int +521722 +~~END~~ + + +SELECT DATEDIFF(week, CAST('1753-01-01' AS DATETIME), CAST('9999-12-31' AS DATETIME)) AS Datetime_FullRange; +GO +~~START~~ +int +430307 +~~END~~ + + +SELECT DATEDIFF(week, CAST('0001-01-01' AS DATETIME), CAST('9999-12-31' AS DATETIME)) AS Datetime_FullRange_Error; +GO +~~ERROR (Code: 517)~~ + +~~ERROR (Message: data out of range for datetime)~~ + + +SELECT DATEDIFF(week, CAST('0001-01-01 00:00:00.000000' AS DATETIME2), CAST('9999-12-31 23:59:59.999999' AS DATETIME2)) AS Datetime2_FullRange; +GO +~~START~~ +int +521722 +~~END~~ + + +SELECT DATEDIFF(week, CAST('1900-01-01 00:00:00' AS SMALLDATETIME), CAST('2079-06-06 23:59:59' AS SMALLDATETIME)) AS Smalldatetime_FullRange; +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: data out of range for smalldatetime)~~ + + +SELECT DATEDIFF(week, CAST('1753-01-01 00:00:00' AS SMALLDATETIME), CAST('2079-06-06 23:59:59' AS SMALLDATETIME)) AS Smalldatetime_FullRange_Error; +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: data out of range for smalldatetime)~~ + + +SELECT DATEDIFF(week, CAST('1900-01-01 00:00:00' AS SMALLDATETIME), CAST('9999-12-31 23:59:59' AS SMALLDATETIME)) AS Smalldatetime_FullRange_Error; +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: data out of range for smalldatetime)~~ + + +SELECT DATEDIFF(week, CAST('0001-01-01 00:00:00.000000 +00:00' AS DATETIMEOFFSET), CAST('9999-12-31 23:59:59.999999 +00:00' AS DATETIMEOFFSET)) AS DatetimeOffset_FullRange; +GO +~~START~~ +int +521722 +~~END~~ + + +SELECT DATEDIFF(week, CAST('12:00:00' AS TIME), CAST('18:00:00' AS TIME)) AS TimeDiff; +GO +~~START~~ +int +0 +~~END~~ + + +SELECT DATEDIFF(week, CAST('12:00:00' AS TIME), CAST('2024-01-01' AS DATE)) AS TimeToDateDiff; +GO +~~START~~ +int +6470 +~~END~~ + + +SELECT DATEDIFF(week, CAST('2024-01-01' AS DATE), CAST('12:00:00' AS TIME)) AS DateToTimeDiff; +GO +~~START~~ +int +-6470 +~~END~~ + + +SELECT DATEDIFF(quarter, CAST('0001-01-01' AS DATE), CAST('9999-12-31' AS DATE)) AS Date_FullRange; +GO +~~START~~ +int +39995 +~~END~~ + + +SELECT DATEDIFF(quarter, CAST('1753-01-01' AS DATETIME), CAST('9999-12-31' AS DATETIME)) AS Datetime_FullRange; +GO +~~START~~ +int +32987 +~~END~~ + + +SELECT DATEDIFF(quarter, CAST('0001-01-01' AS DATETIME), CAST('9999-12-31' AS DATETIME)) AS Datetime_FullRange_Error; +GO +~~ERROR (Code: 517)~~ + +~~ERROR (Message: data out of range for datetime)~~ + + +SELECT DATEDIFF(quarter, CAST('0001-01-01 00:00:00.000000' AS DATETIME2), CAST('9999-12-31 23:59:59.999999' AS DATETIME2)) AS Datetime2_FullRange; +GO +~~START~~ +int +39995 +~~END~~ + + +SELECT DATEDIFF(quarter, CAST('1900-01-01 00:00:00' AS SMALLDATETIME), CAST('2079-06-06 23:59:59' AS SMALLDATETIME)) AS Smalldatetime_FullRange; +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: data out of range for smalldatetime)~~ + + +SELECT DATEDIFF(quarter, CAST('1753-01-01 00:00:00' AS SMALLDATETIME), CAST('2079-06-06 23:59:59' AS SMALLDATETIME)) AS Smalldatetime_FullRange_Error; +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: data out of range for smalldatetime)~~ + + +SELECT DATEDIFF(quarter, CAST('1900-01-01 00:00:00' AS SMALLDATETIME), CAST('9999-12-31 23:59:59' AS SMALLDATETIME)) AS Smalldatetime_FullRange_Error; +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: data out of range for smalldatetime)~~ + + +SELECT DATEDIFF(quarter, CAST('0001-01-01 00:00:00.000000 +00:00' AS DATETIMEOFFSET), CAST('9999-12-31 23:59:59.999999 +00:00' AS DATETIMEOFFSET)) AS DatetimeOffset_FullRange; +GO +~~START~~ +int +39995 +~~END~~ + + +SELECT DATEDIFF(quarter, CAST('12:00:00' AS TIME), CAST('18:00:00' AS TIME)) AS TimeDiff; +GO +~~START~~ +int +0 +~~END~~ + + +SELECT DATEDIFF(quarter, CAST('12:00:00' AS TIME), CAST('2024-01-01' AS DATE)) AS TimeToDateDiff; +GO +~~START~~ +int +496 +~~END~~ + + +SELECT DATEDIFF(quarter, CAST('2024-01-01' AS DATE), CAST('12:00:00' AS TIME)) AS DateToTimeDiff; +GO +~~START~~ +int +-496 +~~END~~ + + +-- Will be fixed under BABEL-5492 +SELECT DATEDIFF(week, CAST('0001-01-01' AS DATE), CAST('9999-01-01 23:59:59' AS DATETIME)) AS DateToDatetime; +GO +~~START~~ +int +~~ERROR (Code: 517)~~ + +~~ERROR (Message: data out of range for datetime)~~ + + +SELECT DATEDIFF(quarter, CAST('0001-01-01' AS DATE), CAST('9999-01-01 23:59:59' AS DATETIME)) AS DateToDatetime; +GO +~~START~~ +int +~~ERROR (Code: 517)~~ + +~~ERROR (Message: data out of range for datetime)~~ + + +-- Mixed-Type Testing +SELECT DATEDIFF(week, CAST('1753-01-01 00:00:00' AS DATETIME), CAST('9999-01-01 23:59:59.999' AS DATETIME2)) AS DatetimeToDatetime2; +GO +~~START~~ +int +430255 +~~END~~ + + +SELECT DATEDIFF(week, CAST('0001-01-01 00:00:00+00:00' AS DATETIMEOFFSET), CAST('2079-06-06' AS SMALLDATETIME)) AS DatetimeOffsetToSmalldatetime; +GO +~~START~~ +int +108447 +~~END~~ + + +SELECT DATEDIFF(week, CAST('1753-01-01 00:00:00' AS DATETIME2), CAST('1900-01-01' AS DATE)) AS Datetime2ToDate; +GO +~~START~~ +int +7670 +~~END~~ + + +SELECT DATEDIFF(week, CAST('0001-01-01 00:00:00+00:00' AS DATETIMEOFFSET), CAST('1753-01-01 00:00:00' AS DATETIME2)) AS DatetimeOffsetTodatetime2; +GO +~~START~~ +int +91415 +~~END~~ + + +SELECT DATEDIFF(quarter, CAST('1753-01-01 00:00:00' AS DATETIME), CAST('9999-01-01 23:59:59.999' AS DATETIME2)) AS DatetimeToDatetime2; +GO +~~START~~ +int +32984 +~~END~~ + + +SELECT DATEDIFF(quarter, CAST('0001-01-01 00:00:00+00:00' AS DATETIMEOFFSET), CAST('2079-06-06' AS SMALLDATETIME)) AS DatetimeOffsetToSmalldatetime; +GO +~~START~~ +int +8313 +~~END~~ + + +SELECT DATEDIFF(quarter, CAST('1753-01-01 00:00:00' AS DATETIME2), CAST('1900-01-01' AS DATE)) AS Datetime2ToDate; +GO +~~START~~ +int +588 +~~END~~ + + +SELECT DATEDIFF(quarter, CAST('0001-01-01 00:00:00+00:00' AS DATETIMEOFFSET), CAST('1753-01-01 00:00:00' AS DATETIME2)) AS DatetimeOffsetTodatetime2; +GO +~~START~~ +int +7008 +~~END~~ + + +-- Test Cases for Different Time Zones in DATETIMEOFFSET +SELECT DATEDIFF(week, '2023-01-01 00:00:00+00:00', '2023-01-08 00:00:00+05:30') AS SameTimeDifferentOffsets; +GO +~~START~~ +int +0 +~~END~~ + + +SELECT DATEDIFF(week, '2023-01-01 00:00:00+00:00', '2023-01-08 05:30:00+05:30') AS SameTimeDifferentOffsets; +GO +~~START~~ +int +1 +~~END~~ + + +SELECT DATEDIFF(week, '2023-01-01 00:00:00-05:00', '2023-01-01 00:00:00+01:00') AS StartEarlierDifferentZone; +GO +~~START~~ +int +-1 +~~END~~ + + +SELECT DATEDIFF(week, '2024-01-05 23:59:59+00:00', '2024-01-06 00:00:01+05:30') AS CrossWeekBoundary; +GO +~~START~~ +int +0 +~~END~~ + + +SELECT DATEDIFF(week, '2000-01-01 00:00:00+00:00', '2023-01-01 00:00:00+10:00') AS LargeIntervalDifferentOffsets; +GO +~~START~~ +int +1200 +~~END~~ + + +SELECT DATEDIFF(week, '2023-01-01 00:00:00+05:30', '2000-01-01 00:00:00+00:00') AS ReverseIntervalDifferentOffsets; +GO +~~START~~ +int +-1200 +~~END~~ + + +SELECT DATEDIFF(quarter, '2023-01-01 00:00:00+00:00', '2023-04-01 00:00:00+05:30') AS SameTimeDifferentOffsets; +GO +~~START~~ +int +0 +~~END~~ + + +SELECT DATEDIFF(quarter, '2023-01-01 00:00:00+00:00', '2023-04-01 05:30:00+05:30') AS SameTimeDifferentOffsets; +GO +~~START~~ +int +1 +~~END~~ + + +SELECT DATEDIFF(quarter, '2023-01-01 00:00:00-05:00', '2023-01-01 00:00:00+01:00') AS StartEarlierDifferentZone; +GO +~~START~~ +int +-1 +~~END~~ + + +SELECT DATEDIFF(quarter, '2023-12-31 23:59:59+00:00', '2024-01-01 00:00:01+05:30') AS CrossQuarterBoundary; +GO +~~START~~ +int +0 +~~END~~ + + +SELECT DATEDIFF(quarter, '2000-01-01 00:00:00+00:00', '2023-01-01 00:00:00+10:00') AS LargeIntervalDifferentOffsets; +GO +~~START~~ +int +91 +~~END~~ + + +SELECT DATEDIFF(quarter, '2023-01-01 00:00:00+05:30', '2000-01-01 00:00:00+00:00') AS ReverseIntervalDifferentOffsets; +GO +~~START~~ +int +-91 +~~END~~ + diff --git a/test/JDBC/expected/datediff_big-vu-verify.out b/test/JDBC/expected/datediff_big-vu-verify.out index 310c4dad30..3d0379a90f 100644 --- a/test/JDBC/expected/datediff_big-vu-verify.out +++ b/test/JDBC/expected/datediff_big-vu-verify.out @@ -10,7 +10,7 @@ SELECT * FROM datediff_big_vu_prepare_v2 GO ~~ERROR (Code: 535)~~ -~~ERROR (Message: The datediff function resulted in an overflow. The number of dateparts separating two date/time instances is too large. Try to use datediff with a less precise datepart)~~ +~~ERROR (Message: The datediff_big function resulted in an overflow. The number of dateparts separating two date/time instances is too large. Try to use datediff_big with a less precise datepart.)~~ SELECT * FROM datediff_big_vu_prepare_v3 @@ -33,7 +33,7 @@ SELECT * FROM datediff_big_vu_prepare_v5 GO ~~START~~ bigint#!#bigint#!#bigint#!#bigint#!#bigint#!#bigint#!#bigint#!#bigint#!#bigint#!#bigint#!#bigint#!#bigint -100#!#396#!#1189#!#36160#!#36160#!#5166#!#867840#!#52070401#!#3124224060#!#3124224060000#!#3124224060000000#!#3124224060000000000 +100#!#397#!#1189#!#36160#!#36160#!#5165#!#867840#!#52070401#!#3124224060#!#3124224060000#!#3124224060000000#!#3124224060000000000 ~~END~~ @@ -105,7 +105,7 @@ EXEC datediff_big_vu_prepare_p2 GO ~~ERROR (Code: 535)~~ -~~ERROR (Message: The datediff function resulted in an overflow. The number of dateparts separating two date/time instances is too large. Try to use datediff with a less precise datepart)~~ +~~ERROR (Message: The datediff_big function resulted in an overflow. The number of dateparts separating two date/time instances is too large. Try to use datediff_big with a less precise datepart.)~~ EXEC datediff_big_vu_prepare_p3 @@ -128,7 +128,7 @@ EXEC datediff_big_vu_prepare_p5 GO ~~START~~ bigint#!#bigint#!#bigint#!#bigint#!#bigint#!#bigint#!#bigint#!#bigint#!#bigint#!#bigint#!#bigint#!#bigint -100#!#396#!#1189#!#36160#!#36160#!#5166#!#867840#!#52070401#!#3124224060#!#3124224060000#!#3124224060000000#!#3124224060000000000 +100#!#397#!#1189#!#36160#!#36160#!#5165#!#867840#!#52070401#!#3124224060#!#3124224060000#!#3124224060000000#!#3124224060000000000 ~~END~~ @@ -202,7 +202,7 @@ SELECT DATEDIFF_BIG(fakeoption, cast('2023-01-01 01:01:20.98' as datetime), cast go ~~ERROR (Code: 155)~~ -~~ERROR (Message: 'fakeoption' is not a recognized datediff option)~~ +~~ERROR (Message: 'fakeoption' is not a recognized datediff_big option)~~ if (@@trancount > 0) select cast('compile time error' as text) else select cast('runtime error' as text) @@ -223,7 +223,7 @@ SELECT DATEDIFF_BIG(nanosecond, cast('1900-01-01 01:01:20.98' as datetime), cast go ~~ERROR (Code: 535)~~ -~~ERROR (Message: The datediff function resulted in an overflow. The number of dateparts separating two date/time instances is too large. Try to use datediff with a less precise datepart)~~ +~~ERROR (Message: The datediff_big function resulted in an overflow. The number of dateparts separating two date/time instances is too large. Try to use datediff_big with a less precise datepart.)~~ if (@@trancount > 0) select cast('compile time error' as text) else select cast('runtime error' as text) @@ -257,3 +257,927 @@ compile time error if (@@trancount > 0) rollback tran GO + +Declare @runForDate datetime = '01/22/2012'; +Declare @evaluationDate datetime = DATEADD(DAY,-1,@runForDate); +Select DATEDIFF_BIG(wk,7,@evaluationDate) +GO +~~START~~ +bigint +5845 +~~END~~ + + +-- Basic Functionality +SELECT DATEDIFF_BIG(week, CAST('2023-01-01' AS DATE), CAST('2023-01-01' AS DATE)) AS SameDate; +GO +~~START~~ +bigint +0 +~~END~~ + + +SELECT DATEDIFF_BIG(week, CAST('2023-01-01' AS DATETIME), CAST('2023-01-02' AS DATETIME)) AS ConsecutiveDaysSameWeek; +GO +~~START~~ +bigint +0 +~~END~~ + + +SELECT DATEDIFF_BIG(week, CAST('2023-01-01' AS DATE), CAST('2022-12-25' AS DATE)) AS DifferentWeeks; +GO +~~START~~ +bigint +-1 +~~END~~ + + +SELECT DATEDIFF_BIG(week, CAST('2010-01-01' AS DATE), CAST('2009-12-19' AS DATE)) AS DifferentWeeks; +GO +~~START~~ +bigint +-2 +~~END~~ + + +SELECT DATEDIFF_BIG(quarter, CAST('2023-01-01' AS DATE), CAST('2023-01-31' AS DATE)) AS SameQuarter; +GO +~~START~~ +bigint +0 +~~END~~ + + +SELECT DATEDIFF_BIG(quarter, CAST('2023-01-01' AS DATETIME), CAST('2023-02-01' AS DATETIME)) AS ConsecutiveMonths; +GO +~~START~~ +bigint +0 +~~END~~ + + +SELECT DATEDIFF_BIG(quarter, CAST('2023-02-01' AS DATETIME), CAST('2023-01-01' AS DATETIME)) AS ConsecutiveMonths; +GO +~~START~~ +bigint +0 +~~END~~ + + +SELECT DATEDIFF_BIG(quarter, CAST('2023-01-01' AS DATE), CAST('2023-07-25' AS DATE)) AS DifferentQuarters; +GO +~~START~~ +bigint +2 +~~END~~ + + +SELECT DATEDIFF_BIG(quarter, CAST('2010-01-01' AS DATE), CAST('2011-12-19' AS DATE)) AS DifferentQuarters; +GO +~~START~~ +bigint +7 +~~END~~ + + +-- No boundary crossed +SELECT DATEDIFF_BIG(week, CAST('2023-01-01' AS DATE), CAST('2023-01-07' AS DATE)) AS NoBoundaryCrossed; +GO +~~START~~ +bigint +0 +~~END~~ + + +SELECT DATEDIFF_BIG(week, CAST('2023-01-07' AS DATE), CAST('2023-01-01' AS DATE)) AS NoBoundaryCrossed; +GO +~~START~~ +bigint +0 +~~END~~ + + +SELECT DATEDIFF_BIG(quarter, CAST('2023-01-01' AS DATE), CAST('2023-03-31' AS DATE)) AS NoBoundaryCrossed; +GO +~~START~~ +bigint +0 +~~END~~ + + +-- One boundary crossed +SELECT DATEDIFF_BIG(week, CAST('2023-01-07' AS DATETIME), CAST('2023-01-08' AS DATETIME)) AS OneBoundaryCrossed; +GO +~~START~~ +bigint +1 +~~END~~ + + +SELECT DATEDIFF_BIG(wk, CAST('2023-01-07' AS DATETIME), CAST('2023-01-08' AS DATETIME)) AS OneBoundaryCrossed; +GO +~~START~~ +bigint +1 +~~END~~ + + +SELECT DATEDIFF_BIG(week, CAST('2023-01-08' AS DATETIME), CAST('2023-01-07' AS DATETIME)) AS OneBoundaryCrossed; +GO +~~START~~ +bigint +-1 +~~END~~ + + +SELECT DATEDIFF_BIG(quarter, CAST('2023-01-01' AS DATETIME), CAST('2023-04-01' AS DATETIME)) AS OneBoundaryCrossed; +GO +~~START~~ +bigint +1 +~~END~~ + + +SELECT DATEDIFF_BIG(quarter, CAST('2023-04-01' AS DATETIME), CAST('2023-01-01' AS DATETIME)) AS OneBoundaryCrossed; +GO +~~START~~ +bigint +-1 +~~END~~ + + +SELECT DATEDIFF_BIG(qq, CAST('2023-01-01' AS DATETIME), CAST('2022-12-31' AS DATETIME)) AS OneBoundaryCrossed; +GO +~~START~~ +bigint +-1 +~~END~~ + + +SELECT DATEDIFF_BIG(quarter, CAST('2022-12-31' AS DATETIME), CAST('2023-01-01' AS DATETIME)) AS OneBoundaryCrossed; +GO +~~START~~ +bigint +1 +~~END~~ + + +-- Multiple boundaries crossed +SELECT DATEDIFF_BIG(week, CAST('2023-01-07' AS DATE), CAST('2023-01-22' AS DATE)) AS MultipleBoundariesCrossed; +GO +~~START~~ +bigint +3 +~~END~~ + + +SELECT DATEDIFF_BIG(ww, CAST('2023-01-07' AS DATE), CAST('2023-01-22' AS DATE)) AS MultipleBoundariesCrossed; +GO +~~START~~ +bigint +3 +~~END~~ + + +SELECT DATEDIFF_BIG(week, CAST('2023-01-22' AS DATE), CAST('2023-01-07' AS DATE)) AS MultipleBoundariesCrossed; +GO +~~START~~ +bigint +-3 +~~END~~ + + +SELECT DATEDIFF_BIG(quarter, CAST('2023-01-07' AS DATE), CAST('2023-01-22' AS DATE)) AS MultipleBoundariesCrossed; +GO +~~START~~ +bigint +0 +~~END~~ + + +SELECT DATEDIFF_BIG(q, CAST('2023-01-07' AS DATE), CAST('2023-01-22' AS DATE)) AS MultipleBoundariesCrossed; +GO +~~START~~ +bigint +0 +~~END~~ + + +SELECT DATEDIFF_BIG(quarter, CAST('2023-01-22' AS DATE), CAST('2023-01-07' AS DATE)) AS MultipleBoundariesCrossed; +GO +~~START~~ +bigint +0 +~~END~~ + + +SELECT DATEDIFF_BIG(quarter, CAST('2023-05-22' AS DATE), CAST('2023-06-07' AS DATE)) AS MultipleBoundariesCrossed; +GO +~~START~~ +bigint +0 +~~END~~ + + +SELECT DATEDIFF_BIG(quarter, CAST('2023-06-22' AS DATE), CAST('2023-05-07' AS DATE)) AS MultipleBoundariesCrossed; +GO +~~START~~ +bigint +0 +~~END~~ + + +SELECT DATEDIFF_BIG(quarter, CAST('2023-06-22' AS DATE), CAST('2023-07-07' AS DATE)) AS MultipleBoundariesCrossed; +GO +~~START~~ +bigint +1 +~~END~~ + + +SELECT DATEDIFF_BIG(quarter, CAST('2023-07-22' AS DATE), CAST('2023-06-07' AS DATE)) AS MultipleBoundariesCrossed; +GO +~~START~~ +bigint +-1 +~~END~~ + + +SELECT DATEDIFF_BIG(quarter, CAST('2023-01-22' AS DATE), CAST('2024-01-07' AS DATE)) AS MultipleBoundariesCrossed; +GO +~~START~~ +bigint +4 +~~END~~ + + +SELECT DATEDIFF_BIG(quarter, CAST('2024-01-22' AS DATE), CAST('2023-01-07' AS DATE)) AS MultipleBoundariesCrossed; +GO +~~START~~ +bigint +-4 +~~END~~ + + +SELECT DATEDIFF_BIG(quarter, CAST('2023-01-22' AS DATE), CAST('2024-04-07' AS DATE)) AS MultipleBoundariesCrossed; +GO +~~START~~ +bigint +5 +~~END~~ + + +SELECT DATEDIFF_BIG(quarter, CAST('2024-01-22' AS DATE), CAST('2023-04-07' AS DATE)) AS MultipleBoundariesCrossed; +GO +~~START~~ +bigint +-3 +~~END~~ + + +-- Time-sensitive crossing +SELECT DATEDIFF_BIG(week, CAST('2023-01-07 23:59' AS DATETIME), CAST('2023-01-08 00:00' AS DATETIME)) AS TimeSensitiveBoundary; +GO +~~START~~ +bigint +1 +~~END~~ + + +SELECT DATEDIFF_BIG(week, CAST('2023-01-08 00:00' AS DATETIME), CAST('2023-01-07 23:59' AS DATETIME)) AS TimeSensitiveBoundary; +GO +~~START~~ +bigint +-1 +~~END~~ + + +SELECT DATEDIFF_BIG(quarter, CAST('2023-09-30 23:59' AS DATETIME), CAST('2023-10-01 00:00' AS DATETIME)) AS TimeSensitiveBoundary; +GO +~~START~~ +bigint +1 +~~END~~ + + +SELECT DATEDIFF_BIG(quarter, CAST('2023-10-01 00:00' AS DATETIME), CAST('2023-09-30 23:59' AS DATETIME)) AS TimeSensitiveBoundary; +GO +~~START~~ +bigint +-1 +~~END~~ + + +-- Overlapping across years +SELECT DATEDIFF_BIG(week, CAST('2022-12-31' AS DATE), CAST('2023-01-08' AS DATE)) AS YearBoundaryCrossed; +GO +~~START~~ +bigint +2 +~~END~~ + + +SELECT DATEDIFF_BIG(quarter, CAST('2022-12-31' AS DATE), CAST('2023-01-08' AS DATE)) AS YearBoundaryCrossed; +GO +~~START~~ +bigint +1 +~~END~~ + + +-- Week starts on Sunday +SELECT DATEDIFF_BIG(week, CAST('2023-01-01' AS DATE), CAST('2023-01-08' AS DATE)) AS WeekStartsOnSunday; +GO +~~START~~ +bigint +1 +~~END~~ + + +-- Week ends on Saturday +SELECT DATEDIFF_BIG(week, CAST('2023-01-01' AS DATETIME), CAST('2023-01-14' AS DATETIME)) AS WeekEndsOnSaturday; +GO +~~START~~ +bigint +1 +~~END~~ + + +-- Multiple weeks with no overlap +SELECT DATEDIFF_BIG(week, CAST('2023-01-01' AS DATE), CAST('2023-01-28' AS DATE)) AS MultipleWeeksNoOverlap; +GO +~~START~~ +bigint +3 +~~END~~ + + +-- Start and end at exact boundaries +SELECT DATEDIFF_BIG(week, CAST('2023-01-01 00:00:00' AS DATETIME), CAST('2023-01-08 00:00:00' AS DATETIME)) AS ExactBoundary; +GO +~~START~~ +bigint +1 +~~END~~ + + +SELECT DATEDIFF_BIG(quarter, CAST('2023-01-01 00:00:00' AS DATETIME), CAST('2023-04-01 00:00:00' AS DATETIME)) AS ExactBoundary; +GO +~~START~~ +bigint +1 +~~END~~ + + +-- Start and end with fractional seconds +SELECT DATEDIFF_BIG(week, CAST('2023-01-01 23:59:59.999999' AS DATETIME2), CAST('2023-01-08 00:00:00.000000' AS DATETIME2)) AS FractionalSecondsPrecision; +GO +~~START~~ +bigint +1 +~~END~~ + + +-- Leap Year +SELECT DATEDIFF_BIG(week, CAST('2020-02-28' AS DATETIME), CAST('2020-03-01' AS DATETIME)) AS AcrossLeapDay; +GO +~~START~~ +bigint +1 +~~END~~ + + +SELECT DATEDIFF_BIG(week, CAST('2020-02-29' AS DATE), CAST('2020-03-07' AS DATE)) AS WeekWithLeapDay; +GO +~~START~~ +bigint +1 +~~END~~ + + +-- Negative Intervals +SELECT DATEDIFF_BIG(week, CAST('2023-01-08' AS DATE), CAST('2023-01-01' AS DATE)) AS NegativeInterval; +GO +~~START~~ +bigint +-1 +~~END~~ + + +SELECT DATEDIFF_BIG(week, CAST('2023-01-08 12:00' AS DATETIME), CAST('2023-01-01 12:00' AS DATETIME)) AS NegativeWithTime; +GO +~~START~~ +bigint +-1 +~~END~~ + + +SELECT DATEDIFF_BIG(week, CAST('9999-01-01' AS DATE), CAST('0001-01-01' AS DATE)) AS Date_ReverseRange; +GO +~~START~~ +bigint +-521670 +~~END~~ + + +SELECT DATEDIFF_BIG(week, CAST('9999-01-01' AS DATETIME2), CAST('0001-01-01' AS DATETIME2)) AS Datetime2_ReverseRange; +GO +~~START~~ +bigint +-521670 +~~END~~ + + +-- Boundary Conditions +SELECT DATEDIFF_BIG(week, CAST('2023-01-01' AS DATETIME), CAST('2023-01-07' AS DATETIME)) AS SameWeekBoundary; +GO +~~START~~ +bigint +0 +~~END~~ + + +SELECT DATEDIFF_BIG(week, CAST('2023-01-07' AS DATE), CAST('2023-01-08' AS DATE)) AS WeekResetBoundary; +GO +~~START~~ +bigint +1 +~~END~~ + + +-- Across Years +SELECT DATEDIFF_BIG(week, CAST('2022-12-31' AS DATETIME), CAST('2023-01-01' AS DATETIME)) AS SameWeekAcrossYears; +GO +~~START~~ +bigint +1 +~~END~~ + + +SELECT DATEDIFF_BIG(week, CAST('2022-12-31' AS DATE), CAST('2023-01-08' AS DATE)) AS DifferentWeeksAcrossYears; +GO +~~START~~ +bigint +2 +~~END~~ + + +-- Null Inputs +SELECT DATEDIFF_BIG(week, NULL, CAST('2023-01-01' AS DATE)) AS NullStartDate; +GO +~~START~~ +bigint + +~~END~~ + + +SELECT DATEDIFF_BIG(week, CAST('2023-01-01' AS DATETIME), NULL) AS NullEndDate; +GO +~~START~~ +bigint + +~~END~~ + + +SELECT DATEDIFF_BIG(week, NULL, NULL) AS BothNull; +GO +~~START~~ +bigint + +~~END~~ + + +SELECT DATEDIFF_BIG(quarter, NULL, CAST('2023-01-01' AS DATE)) AS NullStartDate; +GO +~~START~~ +bigint + +~~END~~ + + +SELECT DATEDIFF_BIG(quarter, CAST('2023-01-01' AS DATETIME), NULL) AS NullEndDate; +GO +~~START~~ +bigint + +~~END~~ + + +SELECT DATEDIFF_BIG(quarter, NULL, NULL) AS BothNull; +GO +~~START~~ +bigint + +~~END~~ + + +-- Invalid Inputs +SELECT DATEDIFF_BIG(week, CAST('InvalidDate' AS DATE), CAST('2023-01-01' AS DATE)) AS InvalidStartDate; +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: invalid input syntax for type date: "InvalidDate")~~ + + +SELECT DATEDIFF_BIG(week, CAST('2023-01-01' AS DATETIME), CAST('InvalidDate' AS DATETIME)) AS InvalidEndDate; +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: invalid input syntax for type datetime: "InvalidDate")~~ + + +SELECT DATEDIFF_BIG(quarter, CAST('InvalidDate' AS DATE), CAST('2023-01-01' AS DATE)) AS InvalidStartDate; +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: invalid input syntax for type date: "InvalidDate")~~ + + +SELECT DATEDIFF_BIG(quarter, CAST('2023-01-01' AS DATETIME), CAST('InvalidDate' AS DATETIME)) AS InvalidEndDate; +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: invalid input syntax for type datetime: "InvalidDate")~~ + + +-- Large Date Ranges +SELECT DATEDIFF_BIG(week, CAST('1923-01-01' AS DATE), CAST('2023-01-01' AS DATE)) AS CenturyDifference; +GO +~~START~~ +bigint +5218 +~~END~~ + + +SELECT DATEDIFF_BIG(week, CAST('0001-01-01' AS DATETIME), CAST('2023-01-01' AS DATETIME)) AS MillenniaDifference; +GO +~~ERROR (Code: 517)~~ + +~~ERROR (Message: data out of range for datetime)~~ + + +SELECT DATEDIFF_BIG(quarter, CAST('1923-01-01' AS DATE), CAST('2023-01-01' AS DATE)) AS CenturyDifference; +GO +~~START~~ +bigint +400 +~~END~~ + + +SELECT DATEDIFF_BIG(quarter, CAST('0001-01-01' AS DATETIME), CAST('2023-01-01' AS DATETIME)) AS MillenniaDifference; +GO +~~ERROR (Code: 517)~~ + +~~ERROR (Message: data out of range for datetime)~~ + + +-- Boundary Testing +SELECT DATEDIFF_BIG(week, CAST('0001-01-01' AS DATE), CAST('9999-12-31' AS DATE)) AS Date_FullRange; +GO +~~START~~ +bigint +521722 +~~END~~ + + +SELECT DATEDIFF_BIG(week, CAST('1753-01-01' AS DATETIME), CAST('9999-12-31' AS DATETIME)) AS Datetime_FullRange; +GO +~~START~~ +bigint +430307 +~~END~~ + + +SELECT DATEDIFF_BIG(week, CAST('0001-01-01' AS DATETIME), CAST('9999-12-31' AS DATETIME)) AS Datetime_FullRange_Error; +GO +~~ERROR (Code: 517)~~ + +~~ERROR (Message: data out of range for datetime)~~ + + +SELECT DATEDIFF_BIG(week, CAST('0001-01-01 00:00:00.000000' AS DATETIME2), CAST('9999-12-31 23:59:59.999999' AS DATETIME2)) AS Datetime2_FullRange; +GO +~~START~~ +bigint +521722 +~~END~~ + + +SELECT DATEDIFF_BIG(week, CAST('1900-01-01 00:00:00' AS SMALLDATETIME), CAST('2079-06-06 23:59:59' AS SMALLDATETIME)) AS Smalldatetime_FullRange; +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: data out of range for smalldatetime)~~ + + +SELECT DATEDIFF_BIG(week, CAST('1753-01-01 00:00:00' AS SMALLDATETIME), CAST('2079-06-06 23:59:59' AS SMALLDATETIME)) AS Smalldatetime_FullRange_Error; +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: data out of range for smalldatetime)~~ + + +SELECT DATEDIFF_BIG(week, CAST('1900-01-01 00:00:00' AS SMALLDATETIME), CAST('9999-12-31 23:59:59' AS SMALLDATETIME)) AS Smalldatetime_FullRange_Error; +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: data out of range for smalldatetime)~~ + + +SELECT DATEDIFF_BIG(week, CAST('0001-01-01 00:00:00.000000 +00:00' AS DATETIMEOFFSET), CAST('9999-12-31 23:59:59.999999 +00:00' AS DATETIMEOFFSET)) AS DatetimeOffset_FullRange; +GO +~~START~~ +bigint +521722 +~~END~~ + + +SELECT DATEDIFF_BIG(week, CAST('12:00:00' AS TIME), CAST('18:00:00' AS TIME)) AS TimeDiff; +GO +~~START~~ +bigint +0 +~~END~~ + + +SELECT DATEDIFF_BIG(week, CAST('12:00:00' AS TIME), CAST('2024-01-01' AS DATE)) AS TimeToDateDiff; +GO +~~START~~ +bigint +6470 +~~END~~ + + +SELECT DATEDIFF_BIG(week, CAST('2024-01-01' AS DATE), CAST('12:00:00' AS TIME)) AS DateToTimeDiff; +GO +~~START~~ +bigint +-6470 +~~END~~ + + +SELECT DATEDIFF_BIG(quarter, CAST('0001-01-01' AS DATE), CAST('9999-12-31' AS DATE)) AS Date_FullRange; +GO +~~START~~ +bigint +39995 +~~END~~ + + +SELECT DATEDIFF_BIG(quarter, CAST('1753-01-01' AS DATETIME), CAST('9999-12-31' AS DATETIME)) AS Datetime_FullRange; +GO +~~START~~ +bigint +32987 +~~END~~ + + +SELECT DATEDIFF_BIG(quarter, CAST('0001-01-01' AS DATETIME), CAST('9999-12-31' AS DATETIME)) AS Datetime_FullRange_Error; +GO +~~ERROR (Code: 517)~~ + +~~ERROR (Message: data out of range for datetime)~~ + + +SELECT DATEDIFF_BIG(quarter, CAST('0001-01-01 00:00:00.000000' AS DATETIME2), CAST('9999-12-31 23:59:59.999999' AS DATETIME2)) AS Datetime2_FullRange; +GO +~~START~~ +bigint +39995 +~~END~~ + + +SELECT DATEDIFF_BIG(quarter, CAST('1900-01-01 00:00:00' AS SMALLDATETIME), CAST('2079-06-06 23:59:59' AS SMALLDATETIME)) AS Smalldatetime_FullRange; +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: data out of range for smalldatetime)~~ + + +SELECT DATEDIFF_BIG(quarter, CAST('1753-01-01 00:00:00' AS SMALLDATETIME), CAST('2079-06-06 23:59:59' AS SMALLDATETIME)) AS Smalldatetime_FullRange_Error; +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: data out of range for smalldatetime)~~ + + +SELECT DATEDIFF_BIG(quarter, CAST('1900-01-01 00:00:00' AS SMALLDATETIME), CAST('9999-12-31 23:59:59' AS SMALLDATETIME)) AS Smalldatetime_FullRange_Error; +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: data out of range for smalldatetime)~~ + + +SELECT DATEDIFF_BIG(quarter, CAST('0001-01-01 00:00:00.000000 +00:00' AS DATETIMEOFFSET), CAST('9999-12-31 23:59:59.999999 +00:00' AS DATETIMEOFFSET)) AS DatetimeOffset_FullRange; +GO +~~START~~ +bigint +39995 +~~END~~ + + +SELECT DATEDIFF_BIG(quarter, CAST('12:00:00' AS TIME), CAST('18:00:00' AS TIME)) AS TimeDiff; +GO +~~START~~ +bigint +0 +~~END~~ + + +SELECT DATEDIFF_BIG(quarter, CAST('12:00:00' AS TIME), CAST('2024-01-01' AS DATE)) AS TimeToDateDiff; +GO +~~START~~ +bigint +496 +~~END~~ + + +SELECT DATEDIFF_BIG(quarter, CAST('2024-01-01' AS DATE), CAST('12:00:00' AS TIME)) AS DateToTimeDiff; +GO +~~START~~ +bigint +-496 +~~END~~ + + +-- Will be fixed under BABEL-5492 +SELECT DATEDIFF_BIG(week, CAST('0001-01-01' AS DATE), CAST('9999-01-01 23:59:59' AS DATETIME)) AS DateToDatetime; +GO +~~START~~ +bigint +~~ERROR (Code: 517)~~ + +~~ERROR (Message: data out of range for datetime)~~ + + +SELECT DATEDIFF_BIG(quarter, CAST('0001-01-01' AS DATE), CAST('9999-01-01 23:59:59' AS DATETIME)) AS DateToDatetime; +GO +~~START~~ +bigint +~~ERROR (Code: 517)~~ + +~~ERROR (Message: data out of range for datetime)~~ + + +-- Mixed-Type Testing +SELECT DATEDIFF_BIG(week, CAST('1753-01-01 00:00:00' AS DATETIME), CAST('9999-01-01 23:59:59.999' AS DATETIME2)) AS DatetimeToDatetime2; +GO +~~START~~ +bigint +430255 +~~END~~ + + +SELECT DATEDIFF_BIG(week, CAST('0001-01-01 00:00:00+00:00' AS DATETIMEOFFSET), CAST('2079-06-06' AS SMALLDATETIME)) AS DatetimeOffsetToSmalldatetime; +GO +~~START~~ +bigint +108447 +~~END~~ + + +SELECT DATEDIFF_BIG(week, CAST('1753-01-01 00:00:00' AS DATETIME2), CAST('1900-01-01' AS DATE)) AS Datetime2ToDate; +GO +~~START~~ +bigint +7670 +~~END~~ + + +SELECT DATEDIFF_BIG(week, CAST('0001-01-01 00:00:00+00:00' AS DATETIMEOFFSET), CAST('1753-01-01 00:00:00' AS DATETIME2)) AS DatetimeOffsetTodatetime2; +GO +~~START~~ +bigint +91415 +~~END~~ + + +SELECT DATEDIFF_BIG(quarter, CAST('1753-01-01 00:00:00' AS DATETIME), CAST('9999-01-01 23:59:59.999' AS DATETIME2)) AS DatetimeToDatetime2; +GO +~~START~~ +bigint +32984 +~~END~~ + + +SELECT DATEDIFF_BIG(quarter, CAST('0001-01-01 00:00:00+00:00' AS DATETIMEOFFSET), CAST('2079-06-06' AS SMALLDATETIME)) AS DatetimeOffsetToSmalldatetime; +GO +~~START~~ +bigint +8313 +~~END~~ + + +SELECT DATEDIFF_BIG(quarter, CAST('1753-01-01 00:00:00' AS DATETIME2), CAST('1900-01-01' AS DATE)) AS Datetime2ToDate; +GO +~~START~~ +bigint +588 +~~END~~ + + +SELECT DATEDIFF_BIG(quarter, CAST('0001-01-01 00:00:00+00:00' AS DATETIMEOFFSET), CAST('1753-01-01 00:00:00' AS DATETIME2)) AS DatetimeOffsetTodatetime2; +GO +~~START~~ +bigint +7008 +~~END~~ + + +-- Test Cases for Different Time Zones in DATETIMEOFFSET +SELECT DATEDIFF_BIG(week, '2023-01-01 00:00:00+00:00', '2023-01-08 00:00:00+05:30') AS SameTimeDifferentOffsets; +GO +~~START~~ +bigint +0 +~~END~~ + + +SELECT DATEDIFF_BIG(week, '2023-01-01 00:00:00+00:00', '2023-01-08 05:30:00+05:30') AS SameTimeDifferentOffsets; +GO +~~START~~ +bigint +1 +~~END~~ + + +SELECT DATEDIFF_BIG(week, '2023-01-01 00:00:00-05:00', '2023-01-01 00:00:00+01:00') AS StartEarlierDifferentZone; +GO +~~START~~ +bigint +-1 +~~END~~ + + +SELECT DATEDIFF_BIG(week, '2024-01-05 23:59:59+00:00', '2024-01-06 00:00:01+05:30') AS CrossWeekBoundary; +GO +~~START~~ +bigint +0 +~~END~~ + + +SELECT DATEDIFF_BIG(week, '2000-01-01 00:00:00+00:00', '2023-01-01 00:00:00+10:00') AS LargeIntervalDifferentOffsets; +GO +~~START~~ +bigint +1200 +~~END~~ + + +SELECT DATEDIFF_BIG(week, '2023-01-01 00:00:00+05:30', '2000-01-01 00:00:00+00:00') AS ReverseIntervalDifferentOffsets; +GO +~~START~~ +bigint +-1200 +~~END~~ + + +SELECT DATEDIFF_BIG(quarter, '2023-01-01 00:00:00+00:00', '2023-04-01 00:00:00+05:30') AS SameTimeDifferentOffsets; +GO +~~START~~ +bigint +0 +~~END~~ + + +SELECT DATEDIFF_BIG(quarter, '2023-01-01 00:00:00+00:00', '2023-04-01 05:30:00+05:30') AS SameTimeDifferentOffsets; +GO +~~START~~ +bigint +1 +~~END~~ + + +SELECT DATEDIFF_BIG(quarter, '2023-01-01 00:00:00-05:00', '2023-01-01 00:00:00+01:00') AS StartEarlierDifferentZone; +GO +~~START~~ +bigint +-1 +~~END~~ + + +SELECT DATEDIFF_BIG(quarter, '2023-12-31 23:59:59+00:00', '2024-01-01 00:00:01+05:30') AS CrossQuarterBoundary; +GO +~~START~~ +bigint +0 +~~END~~ + + +SELECT DATEDIFF_BIG(quarter, '2000-01-01 00:00:00+00:00', '2023-01-01 00:00:00+10:00') AS LargeIntervalDifferentOffsets; +GO +~~START~~ +bigint +91 +~~END~~ + + +SELECT DATEDIFF_BIG(quarter, '2023-01-01 00:00:00+05:30', '2000-01-01 00:00:00+00:00') AS ReverseIntervalDifferentOffsets; +GO +~~START~~ +bigint +-91 +~~END~~ + diff --git a/test/JDBC/expected/non_default_server_collation/chinese_prc_ci_as/babel_function.out b/test/JDBC/expected/non_default_server_collation/chinese_prc_ci_as/babel_function.out index 018c7e6f4e..30b1ce1931 100644 --- a/test/JDBC/expected/non_default_server_collation/chinese_prc_ci_as/babel_function.out +++ b/test/JDBC/expected/non_default_server_collation/chinese_prc_ci_as/babel_function.out @@ -1369,7 +1369,7 @@ select datediff(week,CAST('2037-03-01 23:30:05.523'AS sys.datetime),CAST('2036-0 GO ~~START~~ int --52 +-53 ~~END~~ select datediff(hour, CAST('2037-03-01 23:30:05.523'AS sys.datetime), CAST('2036-02-28 23:30:05.523'AS sys.datetime)); @@ -1426,7 +1426,7 @@ select datediff(quarter,CAST('2016-12-26 23:30:05.523456'AS datetime2), CAST('20 GO ~~START~~ int -6 +7 ~~END~~ select datediff(hour, CAST('2016-12-26 23:30:05'AS smalldatetime), CAST('2016-12-28 21:29:05'AS smalldatetime)); diff --git a/test/JDBC/input/dateFunctions/datediff-vu-verify.sql b/test/JDBC/input/dateFunctions/datediff-vu-verify.sql index 2792eef63c..72378e0636 100644 --- a/test/JDBC/input/dateFunctions/datediff-vu-verify.sql +++ b/test/JDBC/input/dateFunctions/datediff-vu-verify.sql @@ -83,3 +83,369 @@ GO if (@@trancount > 0) rollback tran GO + +Declare @runForDate datetime = '01/22/2012'; +Declare @evaluationDate datetime = DATEADD(DAY,-1,@runForDate); +Select DATEDIFF(wk,7,@evaluationDate) +GO + +-- Basic Functionality +SELECT DATEDIFF(week, CAST('2023-01-01' AS DATE), CAST('2023-01-01' AS DATE)) AS SameDate; +GO + +SELECT DATEDIFF(week, CAST('2023-01-01' AS DATETIME), CAST('2023-01-02' AS DATETIME)) AS ConsecutiveDaysSameWeek; +GO + +SELECT DATEDIFF(week, CAST('2023-01-01' AS DATE), CAST('2022-12-25' AS DATE)) AS DifferentWeeks; +GO + +SELECT DATEDIFF(week, CAST('2010-01-01' AS DATE), CAST('2009-12-19' AS DATE)) AS DifferentWeeks; +GO + +SELECT DATEDIFF(quarter, CAST('2023-01-01' AS DATE), CAST('2023-01-31' AS DATE)) AS SameQuarter; +GO + +SELECT DATEDIFF(quarter, CAST('2023-01-01' AS DATETIME), CAST('2023-02-01' AS DATETIME)) AS ConsecutiveMonths; +GO + +SELECT DATEDIFF(quarter, CAST('2023-02-01' AS DATETIME), CAST('2023-01-01' AS DATETIME)) AS ConsecutiveMonths; +GO + +SELECT DATEDIFF(quarter, CAST('2023-01-01' AS DATE), CAST('2023-07-25' AS DATE)) AS DifferentQuarters; +GO + +SELECT DATEDIFF(quarter, CAST('2010-01-01' AS DATE), CAST('2011-12-19' AS DATE)) AS DifferentQuarters; +GO + +-- No boundary crossed +SELECT DATEDIFF(week, CAST('2023-01-01' AS DATE), CAST('2023-01-07' AS DATE)) AS NoBoundaryCrossed; +GO + +SELECT DATEDIFF(week, CAST('2023-01-07' AS DATE), CAST('2023-01-01' AS DATE)) AS NoBoundaryCrossed; +GO + +SELECT DATEDIFF(quarter, CAST('2023-01-01' AS DATE), CAST('2023-03-31' AS DATE)) AS NoBoundaryCrossed; +GO + +-- One boundary crossed +SELECT DATEDIFF(week, CAST('2023-01-07' AS DATETIME), CAST('2023-01-08' AS DATETIME)) AS OneBoundaryCrossed; +GO + +SELECT DATEDIFF(wk, CAST('2023-01-07' AS DATETIME), CAST('2023-01-08' AS DATETIME)) AS OneBoundaryCrossed; +GO + +SELECT DATEDIFF(week, CAST('2023-01-08' AS DATETIME), CAST('2023-01-07' AS DATETIME)) AS OneBoundaryCrossed; +GO + +SELECT DATEDIFF(quarter, CAST('2023-01-01' AS DATETIME), CAST('2023-04-01' AS DATETIME)) AS OneBoundaryCrossed; +GO + +SELECT DATEDIFF(quarter, CAST('2023-04-01' AS DATETIME), CAST('2023-01-01' AS DATETIME)) AS OneBoundaryCrossed; +GO + +SELECT DATEDIFF(qq, CAST('2023-01-01' AS DATETIME), CAST('2022-12-31' AS DATETIME)) AS OneBoundaryCrossed; +GO + +SELECT DATEDIFF(quarter, CAST('2022-12-31' AS DATETIME), CAST('2023-01-01' AS DATETIME)) AS OneBoundaryCrossed; +GO + +-- Multiple boundaries crossed +SELECT DATEDIFF(week, CAST('2023-01-07' AS DATE), CAST('2023-01-22' AS DATE)) AS MultipleBoundariesCrossed; +GO + +SELECT DATEDIFF(ww, CAST('2023-01-07' AS DATE), CAST('2023-01-22' AS DATE)) AS MultipleBoundariesCrossed; +GO + +SELECT DATEDIFF(week, CAST('2023-01-22' AS DATE), CAST('2023-01-07' AS DATE)) AS MultipleBoundariesCrossed; +GO + +SELECT DATEDIFF(quarter, CAST('2023-01-07' AS DATE), CAST('2023-01-22' AS DATE)) AS MultipleBoundariesCrossed; +GO + +SELECT DATEDIFF(q, CAST('2023-01-07' AS DATE), CAST('2023-01-22' AS DATE)) AS MultipleBoundariesCrossed; +GO + +SELECT DATEDIFF(q, CAST('2023-01-22' AS DATE), CAST('2023-01-07' AS DATE)) AS MultipleBoundariesCrossed; +GO + +SELECT DATEDIFF(q, CAST('2023-05-22' AS DATE), CAST('2023-06-07' AS DATE)) AS MultipleBoundariesCrossed; +GO + +SELECT DATEDIFF(quarter, CAST('2023-06-22' AS DATE), CAST('2023-05-07' AS DATE)) AS MultipleBoundariesCrossed; +GO + +SELECT DATEDIFF(quarter, CAST('2023-06-22' AS DATE), CAST('2023-07-07' AS DATE)) AS MultipleBoundariesCrossed; +GO + +SELECT DATEDIFF(quarter, CAST('2023-07-22' AS DATE), CAST('2023-06-07' AS DATE)) AS MultipleBoundariesCrossed; +GO + +SELECT DATEDIFF(quarter, CAST('2023-01-22' AS DATE), CAST('2024-01-07' AS DATE)) AS MultipleBoundariesCrossed; +GO + +SELECT DATEDIFF(quarter, CAST('2024-01-22' AS DATE), CAST('2023-01-07' AS DATE)) AS MultipleBoundariesCrossed; +GO + +SELECT DATEDIFF(quarter, CAST('2023-01-22' AS DATE), CAST('2024-04-07' AS DATE)) AS MultipleBoundariesCrossed; +GO + +SELECT DATEDIFF(quarter, CAST('2024-01-22' AS DATE), CAST('2023-04-07' AS DATE)) AS MultipleBoundariesCrossed; +GO + +-- Time-sensitive crossing +SELECT DATEDIFF(week, CAST('2023-01-07 23:59' AS DATETIME), CAST('2023-01-08 00:00' AS DATETIME)) AS TimeSensitiveBoundary; +GO + +SELECT DATEDIFF(week, CAST('2023-01-08 00:00' AS DATETIME), CAST('2023-01-07 23:59' AS DATETIME)) AS TimeSensitiveBoundary; +GO + +SELECT DATEDIFF(quarter, CAST('2023-09-30 23:59' AS DATETIME), CAST('2023-10-01 00:00' AS DATETIME)) AS TimeSensitiveBoundary; +GO + +SELECT DATEDIFF(quarter, CAST('2023-10-01 00:00' AS DATETIME), CAST('2023-09-30 23:59' AS DATETIME)) AS TimeSensitiveBoundary; +GO + +-- Overlapping across years +SELECT DATEDIFF(week, CAST('2022-12-31' AS DATE), CAST('2023-01-08' AS DATE)) AS YearBoundaryCrossed; +GO + +SELECT DATEDIFF(quarter, CAST('2022-12-31' AS DATE), CAST('2023-01-08' AS DATE)) AS YearBoundaryCrossed; +GO + +-- Week starts on Sunday +SELECT DATEDIFF(week, CAST('2023-01-01' AS DATE), CAST('2023-01-08' AS DATE)) AS WeekStartsOnSunday; +GO + +-- Week ends on Saturday +SELECT DATEDIFF(week, CAST('2023-01-01' AS DATETIME), CAST('2023-01-14' AS DATETIME)) AS WeekEndsOnSaturday; +GO + +-- Multiple weeks with no overlap +SELECT DATEDIFF(week, CAST('2023-01-01' AS DATE), CAST('2023-01-28' AS DATE)) AS MultipleWeeksNoOverlap; +GO + +-- Start and end at exact boundaries +SELECT DATEDIFF(week, CAST('2023-01-01 00:00:00' AS DATETIME), CAST('2023-01-08 00:00:00' AS DATETIME)) AS ExactBoundary; +GO + +SELECT DATEDIFF(quarter, CAST('2023-01-01 00:00:00' AS DATETIME), CAST('2023-04-01 00:00:00' AS DATETIME)) AS ExactBoundary; +GO + +-- Start and end with fractional seconds +SELECT DATEDIFF(week, CAST('2023-01-01 23:59:59.999999' AS DATETIME2), CAST('2023-01-08 00:00:00.000000' AS DATETIME2)) AS FractionalSecondsPrecision; +GO + +-- Leap Year +SELECT DATEDIFF(week, CAST('2020-02-28' AS DATETIME), CAST('2020-03-01' AS DATETIME)) AS AcrossLeapDay; +GO + +SELECT DATEDIFF(week, CAST('2020-02-29' AS DATE), CAST('2020-03-07' AS DATE)) AS WeekWithLeapDay; +GO + +-- Negative Intervals +SELECT DATEDIFF(week, CAST('2023-01-08' AS DATE), CAST('2023-01-01' AS DATE)) AS NegativeInterval; +GO + +SELECT DATEDIFF(week, CAST('2023-01-08 12:00' AS DATETIME), CAST('2023-01-01 12:00' AS DATETIME)) AS NegativeWithTime; +GO + +SELECT DATEDIFF(week, CAST('9999-01-01' AS DATE), CAST('0001-01-01' AS DATE)) AS Date_ReverseRange; +GO + +SELECT DATEDIFF(week, CAST('9999-01-01' AS DATETIME2), CAST('0001-01-01' AS DATETIME2)) AS Datetime2_ReverseRange; +GO + +-- Boundary Conditions +SELECT DATEDIFF(week, CAST('2023-01-01' AS DATETIME), CAST('2023-01-07' AS DATETIME)) AS SameWeekBoundary; +GO + +SELECT DATEDIFF(week, CAST('2023-01-07' AS DATE), CAST('2023-01-08' AS DATE)) AS WeekResetBoundary; +GO + +-- Across Years +SELECT DATEDIFF(week, CAST('2022-12-31' AS DATETIME), CAST('2023-01-01' AS DATETIME)) AS SameWeekAcrossYears; +GO + +SELECT DATEDIFF(week, CAST('2022-12-31' AS DATE), CAST('2023-01-08' AS DATE)) AS DifferentWeeksAcrossYears; +GO + +-- Null Inputs +SELECT DATEDIFF(week, NULL, CAST('2023-01-01' AS DATE)) AS NullStartDate; +GO + +SELECT DATEDIFF(week, CAST('2023-01-01' AS DATETIME), NULL) AS NullEndDate; +GO + +SELECT DATEDIFF(week, NULL, NULL) AS BothNull; +GO + +SELECT DATEDIFF(quarter, NULL, CAST('2023-01-01' AS DATE)) AS NullStartDate; +GO + +SELECT DATEDIFF(quarter, CAST('2023-01-01' AS DATETIME), NULL) AS NullEndDate; +GO + +SELECT DATEDIFF(quarter, NULL, NULL) AS BothNull; +GO + +-- Invalid Inputs +SELECT DATEDIFF(week, CAST('InvalidDate' AS DATE), CAST('2023-01-01' AS DATE)) AS InvalidStartDate; +GO + +SELECT DATEDIFF(week, CAST('2023-01-01' AS DATETIME), CAST('InvalidDate' AS DATETIME)) AS InvalidEndDate; +GO + +SELECT DATEDIFF(quarter, CAST('InvalidDate' AS DATE), CAST('2023-01-01' AS DATE)) AS InvalidStartDate; +GO + +SELECT DATEDIFF(quarter, CAST('2023-01-01' AS DATETIME), CAST('InvalidDate' AS DATETIME)) AS InvalidEndDate; +GO + +-- Large Date Ranges +SELECT DATEDIFF(week, CAST('1923-01-01' AS DATE), CAST('2023-01-01' AS DATE)) AS CenturyDifference; +GO + +SELECT DATEDIFF(week, CAST('0001-01-01' AS DATETIME), CAST('2023-01-01' AS DATETIME)) AS MillenniaDifference; +GO + +SELECT DATEDIFF(quarter, CAST('1923-01-01' AS DATE), CAST('2023-01-01' AS DATE)) AS CenturyDifference; +GO + +SELECT DATEDIFF(quarter, CAST('0001-01-01' AS DATETIME), CAST('2023-01-01' AS DATETIME)) AS MillenniaDifference; +GO + +-- Boundary Testing +SELECT DATEDIFF(week, CAST('0001-01-01' AS DATE), CAST('9999-12-31' AS DATE)) AS Date_FullRange; +GO + +SELECT DATEDIFF(week, CAST('1753-01-01' AS DATETIME), CAST('9999-12-31' AS DATETIME)) AS Datetime_FullRange; +GO + +SELECT DATEDIFF(week, CAST('0001-01-01' AS DATETIME), CAST('9999-12-31' AS DATETIME)) AS Datetime_FullRange_Error; +GO + +SELECT DATEDIFF(week, CAST('0001-01-01 00:00:00.000000' AS DATETIME2), CAST('9999-12-31 23:59:59.999999' AS DATETIME2)) AS Datetime2_FullRange; +GO + +SELECT DATEDIFF(week, CAST('1900-01-01 00:00:00' AS SMALLDATETIME), CAST('2079-06-06 23:59:59' AS SMALLDATETIME)) AS Smalldatetime_FullRange; +GO + +SELECT DATEDIFF(week, CAST('1753-01-01 00:00:00' AS SMALLDATETIME), CAST('2079-06-06 23:59:59' AS SMALLDATETIME)) AS Smalldatetime_FullRange_Error; +GO + +SELECT DATEDIFF(week, CAST('1900-01-01 00:00:00' AS SMALLDATETIME), CAST('9999-12-31 23:59:59' AS SMALLDATETIME)) AS Smalldatetime_FullRange_Error; +GO + +SELECT DATEDIFF(week, CAST('0001-01-01 00:00:00.000000 +00:00' AS DATETIMEOFFSET), CAST('9999-12-31 23:59:59.999999 +00:00' AS DATETIMEOFFSET)) AS DatetimeOffset_FullRange; +GO + +SELECT DATEDIFF(week, CAST('12:00:00' AS TIME), CAST('18:00:00' AS TIME)) AS TimeDiff; +GO + +SELECT DATEDIFF(week, CAST('12:00:00' AS TIME), CAST('2024-01-01' AS DATE)) AS TimeToDateDiff; +GO + +SELECT DATEDIFF(week, CAST('2024-01-01' AS DATE), CAST('12:00:00' AS TIME)) AS DateToTimeDiff; +GO + +SELECT DATEDIFF(quarter, CAST('0001-01-01' AS DATE), CAST('9999-12-31' AS DATE)) AS Date_FullRange; +GO + +SELECT DATEDIFF(quarter, CAST('1753-01-01' AS DATETIME), CAST('9999-12-31' AS DATETIME)) AS Datetime_FullRange; +GO + +SELECT DATEDIFF(quarter, CAST('0001-01-01' AS DATETIME), CAST('9999-12-31' AS DATETIME)) AS Datetime_FullRange_Error; +GO + +SELECT DATEDIFF(quarter, CAST('0001-01-01 00:00:00.000000' AS DATETIME2), CAST('9999-12-31 23:59:59.999999' AS DATETIME2)) AS Datetime2_FullRange; +GO + +SELECT DATEDIFF(quarter, CAST('1900-01-01 00:00:00' AS SMALLDATETIME), CAST('2079-06-06 23:59:59' AS SMALLDATETIME)) AS Smalldatetime_FullRange; +GO + +SELECT DATEDIFF(quarter, CAST('1753-01-01 00:00:00' AS SMALLDATETIME), CAST('2079-06-06 23:59:59' AS SMALLDATETIME)) AS Smalldatetime_FullRange_Error; +GO + +SELECT DATEDIFF(quarter, CAST('1900-01-01 00:00:00' AS SMALLDATETIME), CAST('9999-12-31 23:59:59' AS SMALLDATETIME)) AS Smalldatetime_FullRange_Error; +GO + +SELECT DATEDIFF(quarter, CAST('0001-01-01 00:00:00.000000 +00:00' AS DATETIMEOFFSET), CAST('9999-12-31 23:59:59.999999 +00:00' AS DATETIMEOFFSET)) AS DatetimeOffset_FullRange; +GO + +SELECT DATEDIFF(quarter, CAST('12:00:00' AS TIME), CAST('18:00:00' AS TIME)) AS TimeDiff; +GO + +SELECT DATEDIFF(quarter, CAST('12:00:00' AS TIME), CAST('2024-01-01' AS DATE)) AS TimeToDateDiff; +GO + +SELECT DATEDIFF(quarter, CAST('2024-01-01' AS DATE), CAST('12:00:00' AS TIME)) AS DateToTimeDiff; +GO + +-- Will be fixed under BABEL-5492 +SELECT DATEDIFF(week, CAST('0001-01-01' AS DATE), CAST('9999-01-01 23:59:59' AS DATETIME)) AS DateToDatetime; +GO + +SELECT DATEDIFF(quarter, CAST('0001-01-01' AS DATE), CAST('9999-01-01 23:59:59' AS DATETIME)) AS DateToDatetime; +GO + +-- Mixed-Type Testing +SELECT DATEDIFF(week, CAST('1753-01-01 00:00:00' AS DATETIME), CAST('9999-01-01 23:59:59.999' AS DATETIME2)) AS DatetimeToDatetime2; +GO + +SELECT DATEDIFF(week, CAST('0001-01-01 00:00:00+00:00' AS DATETIMEOFFSET), CAST('2079-06-06' AS SMALLDATETIME)) AS DatetimeOffsetToSmalldatetime; +GO + +SELECT DATEDIFF(week, CAST('1753-01-01 00:00:00' AS DATETIME2), CAST('1900-01-01' AS DATE)) AS Datetime2ToDate; +GO + +SELECT DATEDIFF(week, CAST('0001-01-01 00:00:00+00:00' AS DATETIMEOFFSET), CAST('1753-01-01 00:00:00' AS DATETIME2)) AS DatetimeOffsetTodatetime2; +GO + +SELECT DATEDIFF(quarter, CAST('1753-01-01 00:00:00' AS DATETIME), CAST('9999-01-01 23:59:59.999' AS DATETIME2)) AS DatetimeToDatetime2; +GO + +SELECT DATEDIFF(quarter, CAST('0001-01-01 00:00:00+00:00' AS DATETIMEOFFSET), CAST('2079-06-06' AS SMALLDATETIME)) AS DatetimeOffsetToSmalldatetime; +GO + +SELECT DATEDIFF(quarter, CAST('1753-01-01 00:00:00' AS DATETIME2), CAST('1900-01-01' AS DATE)) AS Datetime2ToDate; +GO + +SELECT DATEDIFF(quarter, CAST('0001-01-01 00:00:00+00:00' AS DATETIMEOFFSET), CAST('1753-01-01 00:00:00' AS DATETIME2)) AS DatetimeOffsetTodatetime2; +GO + +-- Test Cases for Different Time Zones in DATETIMEOFFSET +SELECT DATEDIFF(week, '2023-01-01 00:00:00+00:00', '2023-01-08 00:00:00+05:30') AS SameTimeDifferentOffsets; +GO + +SELECT DATEDIFF(week, '2023-01-01 00:00:00+00:00', '2023-01-08 05:30:00+05:30') AS SameTimeDifferentOffsets; +GO + +SELECT DATEDIFF(week, '2023-01-01 00:00:00-05:00', '2023-01-01 00:00:00+01:00') AS StartEarlierDifferentZone; +GO + +SELECT DATEDIFF(week, '2024-01-05 23:59:59+00:00', '2024-01-06 00:00:01+05:30') AS CrossWeekBoundary; +GO + +SELECT DATEDIFF(week, '2000-01-01 00:00:00+00:00', '2023-01-01 00:00:00+10:00') AS LargeIntervalDifferentOffsets; +GO + +SELECT DATEDIFF(week, '2023-01-01 00:00:00+05:30', '2000-01-01 00:00:00+00:00') AS ReverseIntervalDifferentOffsets; +GO + +SELECT DATEDIFF(quarter, '2023-01-01 00:00:00+00:00', '2023-04-01 00:00:00+05:30') AS SameTimeDifferentOffsets; +GO + +SELECT DATEDIFF(quarter, '2023-01-01 00:00:00+00:00', '2023-04-01 05:30:00+05:30') AS SameTimeDifferentOffsets; +GO + +SELECT DATEDIFF(quarter, '2023-01-01 00:00:00-05:00', '2023-01-01 00:00:00+01:00') AS StartEarlierDifferentZone; +GO + +SELECT DATEDIFF(quarter, '2023-12-31 23:59:59+00:00', '2024-01-01 00:00:01+05:30') AS CrossQuarterBoundary; +GO + +SELECT DATEDIFF(quarter, '2000-01-01 00:00:00+00:00', '2023-01-01 00:00:00+10:00') AS LargeIntervalDifferentOffsets; +GO + +SELECT DATEDIFF(quarter, '2023-01-01 00:00:00+05:30', '2000-01-01 00:00:00+00:00') AS ReverseIntervalDifferentOffsets; +GO diff --git a/test/JDBC/input/functions/datediff_big-vu-verify.sql b/test/JDBC/input/functions/datediff_big-vu-verify.sql index b969588987..69e01d5644 100644 --- a/test/JDBC/input/functions/datediff_big-vu-verify.sql +++ b/test/JDBC/input/functions/datediff_big-vu-verify.sql @@ -107,4 +107,370 @@ if (@@trancount > 0) select cast('compile time error' as text) else select cast( GO if (@@trancount > 0) rollback tran -GO \ No newline at end of file +GO + +Declare @runForDate datetime = '01/22/2012'; +Declare @evaluationDate datetime = DATEADD(DAY,-1,@runForDate); +Select DATEDIFF_BIG(wk,7,@evaluationDate) +GO + +-- Basic Functionality +SELECT DATEDIFF_BIG(week, CAST('2023-01-01' AS DATE), CAST('2023-01-01' AS DATE)) AS SameDate; +GO + +SELECT DATEDIFF_BIG(week, CAST('2023-01-01' AS DATETIME), CAST('2023-01-02' AS DATETIME)) AS ConsecutiveDaysSameWeek; +GO + +SELECT DATEDIFF_BIG(week, CAST('2023-01-01' AS DATE), CAST('2022-12-25' AS DATE)) AS DifferentWeeks; +GO + +SELECT DATEDIFF_BIG(week, CAST('2010-01-01' AS DATE), CAST('2009-12-19' AS DATE)) AS DifferentWeeks; +GO + +SELECT DATEDIFF_BIG(quarter, CAST('2023-01-01' AS DATE), CAST('2023-01-31' AS DATE)) AS SameQuarter; +GO + +SELECT DATEDIFF_BIG(quarter, CAST('2023-01-01' AS DATETIME), CAST('2023-02-01' AS DATETIME)) AS ConsecutiveMonths; +GO + +SELECT DATEDIFF_BIG(quarter, CAST('2023-02-01' AS DATETIME), CAST('2023-01-01' AS DATETIME)) AS ConsecutiveMonths; +GO + +SELECT DATEDIFF_BIG(quarter, CAST('2023-01-01' AS DATE), CAST('2023-07-25' AS DATE)) AS DifferentQuarters; +GO + +SELECT DATEDIFF_BIG(quarter, CAST('2010-01-01' AS DATE), CAST('2011-12-19' AS DATE)) AS DifferentQuarters; +GO + +-- No boundary crossed +SELECT DATEDIFF_BIG(week, CAST('2023-01-01' AS DATE), CAST('2023-01-07' AS DATE)) AS NoBoundaryCrossed; +GO + +SELECT DATEDIFF_BIG(week, CAST('2023-01-07' AS DATE), CAST('2023-01-01' AS DATE)) AS NoBoundaryCrossed; +GO + +SELECT DATEDIFF_BIG(quarter, CAST('2023-01-01' AS DATE), CAST('2023-03-31' AS DATE)) AS NoBoundaryCrossed; +GO + +-- One boundary crossed +SELECT DATEDIFF_BIG(week, CAST('2023-01-07' AS DATETIME), CAST('2023-01-08' AS DATETIME)) AS OneBoundaryCrossed; +GO + +SELECT DATEDIFF_BIG(wk, CAST('2023-01-07' AS DATETIME), CAST('2023-01-08' AS DATETIME)) AS OneBoundaryCrossed; +GO + +SELECT DATEDIFF_BIG(week, CAST('2023-01-08' AS DATETIME), CAST('2023-01-07' AS DATETIME)) AS OneBoundaryCrossed; +GO + +SELECT DATEDIFF_BIG(quarter, CAST('2023-01-01' AS DATETIME), CAST('2023-04-01' AS DATETIME)) AS OneBoundaryCrossed; +GO + +SELECT DATEDIFF_BIG(quarter, CAST('2023-04-01' AS DATETIME), CAST('2023-01-01' AS DATETIME)) AS OneBoundaryCrossed; +GO + +SELECT DATEDIFF_BIG(qq, CAST('2023-01-01' AS DATETIME), CAST('2022-12-31' AS DATETIME)) AS OneBoundaryCrossed; +GO + +SELECT DATEDIFF_BIG(quarter, CAST('2022-12-31' AS DATETIME), CAST('2023-01-01' AS DATETIME)) AS OneBoundaryCrossed; +GO + +-- Multiple boundaries crossed +SELECT DATEDIFF_BIG(week, CAST('2023-01-07' AS DATE), CAST('2023-01-22' AS DATE)) AS MultipleBoundariesCrossed; +GO + +SELECT DATEDIFF_BIG(ww, CAST('2023-01-07' AS DATE), CAST('2023-01-22' AS DATE)) AS MultipleBoundariesCrossed; +GO + +SELECT DATEDIFF_BIG(week, CAST('2023-01-22' AS DATE), CAST('2023-01-07' AS DATE)) AS MultipleBoundariesCrossed; +GO + +SELECT DATEDIFF_BIG(quarter, CAST('2023-01-07' AS DATE), CAST('2023-01-22' AS DATE)) AS MultipleBoundariesCrossed; +GO + +SELECT DATEDIFF_BIG(q, CAST('2023-01-07' AS DATE), CAST('2023-01-22' AS DATE)) AS MultipleBoundariesCrossed; +GO + +SELECT DATEDIFF_BIG(quarter, CAST('2023-01-22' AS DATE), CAST('2023-01-07' AS DATE)) AS MultipleBoundariesCrossed; +GO + +SELECT DATEDIFF_BIG(quarter, CAST('2023-05-22' AS DATE), CAST('2023-06-07' AS DATE)) AS MultipleBoundariesCrossed; +GO + +SELECT DATEDIFF_BIG(quarter, CAST('2023-06-22' AS DATE), CAST('2023-05-07' AS DATE)) AS MultipleBoundariesCrossed; +GO + +SELECT DATEDIFF_BIG(quarter, CAST('2023-06-22' AS DATE), CAST('2023-07-07' AS DATE)) AS MultipleBoundariesCrossed; +GO + +SELECT DATEDIFF_BIG(quarter, CAST('2023-07-22' AS DATE), CAST('2023-06-07' AS DATE)) AS MultipleBoundariesCrossed; +GO + +SELECT DATEDIFF_BIG(quarter, CAST('2023-01-22' AS DATE), CAST('2024-01-07' AS DATE)) AS MultipleBoundariesCrossed; +GO + +SELECT DATEDIFF_BIG(quarter, CAST('2024-01-22' AS DATE), CAST('2023-01-07' AS DATE)) AS MultipleBoundariesCrossed; +GO + +SELECT DATEDIFF_BIG(quarter, CAST('2023-01-22' AS DATE), CAST('2024-04-07' AS DATE)) AS MultipleBoundariesCrossed; +GO + +SELECT DATEDIFF_BIG(quarter, CAST('2024-01-22' AS DATE), CAST('2023-04-07' AS DATE)) AS MultipleBoundariesCrossed; +GO + +-- Time-sensitive crossing +SELECT DATEDIFF_BIG(week, CAST('2023-01-07 23:59' AS DATETIME), CAST('2023-01-08 00:00' AS DATETIME)) AS TimeSensitiveBoundary; +GO + +SELECT DATEDIFF_BIG(week, CAST('2023-01-08 00:00' AS DATETIME), CAST('2023-01-07 23:59' AS DATETIME)) AS TimeSensitiveBoundary; +GO + +SELECT DATEDIFF_BIG(quarter, CAST('2023-09-30 23:59' AS DATETIME), CAST('2023-10-01 00:00' AS DATETIME)) AS TimeSensitiveBoundary; +GO + +SELECT DATEDIFF_BIG(quarter, CAST('2023-10-01 00:00' AS DATETIME), CAST('2023-09-30 23:59' AS DATETIME)) AS TimeSensitiveBoundary; +GO + +-- Overlapping across years +SELECT DATEDIFF_BIG(week, CAST('2022-12-31' AS DATE), CAST('2023-01-08' AS DATE)) AS YearBoundaryCrossed; +GO + +SELECT DATEDIFF_BIG(quarter, CAST('2022-12-31' AS DATE), CAST('2023-01-08' AS DATE)) AS YearBoundaryCrossed; +GO + +-- Week starts on Sunday +SELECT DATEDIFF_BIG(week, CAST('2023-01-01' AS DATE), CAST('2023-01-08' AS DATE)) AS WeekStartsOnSunday; +GO + +-- Week ends on Saturday +SELECT DATEDIFF_BIG(week, CAST('2023-01-01' AS DATETIME), CAST('2023-01-14' AS DATETIME)) AS WeekEndsOnSaturday; +GO + +-- Multiple weeks with no overlap +SELECT DATEDIFF_BIG(week, CAST('2023-01-01' AS DATE), CAST('2023-01-28' AS DATE)) AS MultipleWeeksNoOverlap; +GO + +-- Start and end at exact boundaries +SELECT DATEDIFF_BIG(week, CAST('2023-01-01 00:00:00' AS DATETIME), CAST('2023-01-08 00:00:00' AS DATETIME)) AS ExactBoundary; +GO + +SELECT DATEDIFF_BIG(quarter, CAST('2023-01-01 00:00:00' AS DATETIME), CAST('2023-04-01 00:00:00' AS DATETIME)) AS ExactBoundary; +GO + +-- Start and end with fractional seconds +SELECT DATEDIFF_BIG(week, CAST('2023-01-01 23:59:59.999999' AS DATETIME2), CAST('2023-01-08 00:00:00.000000' AS DATETIME2)) AS FractionalSecondsPrecision; +GO + +-- Leap Year +SELECT DATEDIFF_BIG(week, CAST('2020-02-28' AS DATETIME), CAST('2020-03-01' AS DATETIME)) AS AcrossLeapDay; +GO + +SELECT DATEDIFF_BIG(week, CAST('2020-02-29' AS DATE), CAST('2020-03-07' AS DATE)) AS WeekWithLeapDay; +GO + +-- Negative Intervals +SELECT DATEDIFF_BIG(week, CAST('2023-01-08' AS DATE), CAST('2023-01-01' AS DATE)) AS NegativeInterval; +GO + +SELECT DATEDIFF_BIG(week, CAST('2023-01-08 12:00' AS DATETIME), CAST('2023-01-01 12:00' AS DATETIME)) AS NegativeWithTime; +GO + +SELECT DATEDIFF_BIG(week, CAST('9999-01-01' AS DATE), CAST('0001-01-01' AS DATE)) AS Date_ReverseRange; +GO + +SELECT DATEDIFF_BIG(week, CAST('9999-01-01' AS DATETIME2), CAST('0001-01-01' AS DATETIME2)) AS Datetime2_ReverseRange; +GO + +-- Boundary Conditions +SELECT DATEDIFF_BIG(week, CAST('2023-01-01' AS DATETIME), CAST('2023-01-07' AS DATETIME)) AS SameWeekBoundary; +GO + +SELECT DATEDIFF_BIG(week, CAST('2023-01-07' AS DATE), CAST('2023-01-08' AS DATE)) AS WeekResetBoundary; +GO + +-- Across Years +SELECT DATEDIFF_BIG(week, CAST('2022-12-31' AS DATETIME), CAST('2023-01-01' AS DATETIME)) AS SameWeekAcrossYears; +GO + +SELECT DATEDIFF_BIG(week, CAST('2022-12-31' AS DATE), CAST('2023-01-08' AS DATE)) AS DifferentWeeksAcrossYears; +GO + +-- Null Inputs +SELECT DATEDIFF_BIG(week, NULL, CAST('2023-01-01' AS DATE)) AS NullStartDate; +GO + +SELECT DATEDIFF_BIG(week, CAST('2023-01-01' AS DATETIME), NULL) AS NullEndDate; +GO + +SELECT DATEDIFF_BIG(week, NULL, NULL) AS BothNull; +GO + +SELECT DATEDIFF_BIG(quarter, NULL, CAST('2023-01-01' AS DATE)) AS NullStartDate; +GO + +SELECT DATEDIFF_BIG(quarter, CAST('2023-01-01' AS DATETIME), NULL) AS NullEndDate; +GO + +SELECT DATEDIFF_BIG(quarter, NULL, NULL) AS BothNull; +GO + +-- Invalid Inputs +SELECT DATEDIFF_BIG(week, CAST('InvalidDate' AS DATE), CAST('2023-01-01' AS DATE)) AS InvalidStartDate; +GO + +SELECT DATEDIFF_BIG(week, CAST('2023-01-01' AS DATETIME), CAST('InvalidDate' AS DATETIME)) AS InvalidEndDate; +GO + +SELECT DATEDIFF_BIG(quarter, CAST('InvalidDate' AS DATE), CAST('2023-01-01' AS DATE)) AS InvalidStartDate; +GO + +SELECT DATEDIFF_BIG(quarter, CAST('2023-01-01' AS DATETIME), CAST('InvalidDate' AS DATETIME)) AS InvalidEndDate; +GO + +-- Large Date Ranges +SELECT DATEDIFF_BIG(week, CAST('1923-01-01' AS DATE), CAST('2023-01-01' AS DATE)) AS CenturyDifference; +GO + +SELECT DATEDIFF_BIG(week, CAST('0001-01-01' AS DATETIME), CAST('2023-01-01' AS DATETIME)) AS MillenniaDifference; +GO + +SELECT DATEDIFF_BIG(quarter, CAST('1923-01-01' AS DATE), CAST('2023-01-01' AS DATE)) AS CenturyDifference; +GO + +SELECT DATEDIFF_BIG(quarter, CAST('0001-01-01' AS DATETIME), CAST('2023-01-01' AS DATETIME)) AS MillenniaDifference; +GO + +-- Boundary Testing +SELECT DATEDIFF_BIG(week, CAST('0001-01-01' AS DATE), CAST('9999-12-31' AS DATE)) AS Date_FullRange; +GO + +SELECT DATEDIFF_BIG(week, CAST('1753-01-01' AS DATETIME), CAST('9999-12-31' AS DATETIME)) AS Datetime_FullRange; +GO + +SELECT DATEDIFF_BIG(week, CAST('0001-01-01' AS DATETIME), CAST('9999-12-31' AS DATETIME)) AS Datetime_FullRange_Error; +GO + +SELECT DATEDIFF_BIG(week, CAST('0001-01-01 00:00:00.000000' AS DATETIME2), CAST('9999-12-31 23:59:59.999999' AS DATETIME2)) AS Datetime2_FullRange; +GO + +SELECT DATEDIFF_BIG(week, CAST('1900-01-01 00:00:00' AS SMALLDATETIME), CAST('2079-06-06 23:59:59' AS SMALLDATETIME)) AS Smalldatetime_FullRange; +GO + +SELECT DATEDIFF_BIG(week, CAST('1753-01-01 00:00:00' AS SMALLDATETIME), CAST('2079-06-06 23:59:59' AS SMALLDATETIME)) AS Smalldatetime_FullRange_Error; +GO + +SELECT DATEDIFF_BIG(week, CAST('1900-01-01 00:00:00' AS SMALLDATETIME), CAST('9999-12-31 23:59:59' AS SMALLDATETIME)) AS Smalldatetime_FullRange_Error; +GO + +SELECT DATEDIFF_BIG(week, CAST('0001-01-01 00:00:00.000000 +00:00' AS DATETIMEOFFSET), CAST('9999-12-31 23:59:59.999999 +00:00' AS DATETIMEOFFSET)) AS DatetimeOffset_FullRange; +GO + +SELECT DATEDIFF_BIG(week, CAST('12:00:00' AS TIME), CAST('18:00:00' AS TIME)) AS TimeDiff; +GO + +SELECT DATEDIFF_BIG(week, CAST('12:00:00' AS TIME), CAST('2024-01-01' AS DATE)) AS TimeToDateDiff; +GO + +SELECT DATEDIFF_BIG(week, CAST('2024-01-01' AS DATE), CAST('12:00:00' AS TIME)) AS DateToTimeDiff; +GO + +SELECT DATEDIFF_BIG(quarter, CAST('0001-01-01' AS DATE), CAST('9999-12-31' AS DATE)) AS Date_FullRange; +GO + +SELECT DATEDIFF_BIG(quarter, CAST('1753-01-01' AS DATETIME), CAST('9999-12-31' AS DATETIME)) AS Datetime_FullRange; +GO + +SELECT DATEDIFF_BIG(quarter, CAST('0001-01-01' AS DATETIME), CAST('9999-12-31' AS DATETIME)) AS Datetime_FullRange_Error; +GO + +SELECT DATEDIFF_BIG(quarter, CAST('0001-01-01 00:00:00.000000' AS DATETIME2), CAST('9999-12-31 23:59:59.999999' AS DATETIME2)) AS Datetime2_FullRange; +GO + +SELECT DATEDIFF_BIG(quarter, CAST('1900-01-01 00:00:00' AS SMALLDATETIME), CAST('2079-06-06 23:59:59' AS SMALLDATETIME)) AS Smalldatetime_FullRange; +GO + +SELECT DATEDIFF_BIG(quarter, CAST('1753-01-01 00:00:00' AS SMALLDATETIME), CAST('2079-06-06 23:59:59' AS SMALLDATETIME)) AS Smalldatetime_FullRange_Error; +GO + +SELECT DATEDIFF_BIG(quarter, CAST('1900-01-01 00:00:00' AS SMALLDATETIME), CAST('9999-12-31 23:59:59' AS SMALLDATETIME)) AS Smalldatetime_FullRange_Error; +GO + +SELECT DATEDIFF_BIG(quarter, CAST('0001-01-01 00:00:00.000000 +00:00' AS DATETIMEOFFSET), CAST('9999-12-31 23:59:59.999999 +00:00' AS DATETIMEOFFSET)) AS DatetimeOffset_FullRange; +GO + +SELECT DATEDIFF_BIG(quarter, CAST('12:00:00' AS TIME), CAST('18:00:00' AS TIME)) AS TimeDiff; +GO + +SELECT DATEDIFF_BIG(quarter, CAST('12:00:00' AS TIME), CAST('2024-01-01' AS DATE)) AS TimeToDateDiff; +GO + +SELECT DATEDIFF_BIG(quarter, CAST('2024-01-01' AS DATE), CAST('12:00:00' AS TIME)) AS DateToTimeDiff; +GO + +-- Will be fixed under BABEL-5492 +SELECT DATEDIFF_BIG(week, CAST('0001-01-01' AS DATE), CAST('9999-01-01 23:59:59' AS DATETIME)) AS DateToDatetime; +GO + +SELECT DATEDIFF_BIG(quarter, CAST('0001-01-01' AS DATE), CAST('9999-01-01 23:59:59' AS DATETIME)) AS DateToDatetime; +GO + +-- Mixed-Type Testing +SELECT DATEDIFF_BIG(week, CAST('1753-01-01 00:00:00' AS DATETIME), CAST('9999-01-01 23:59:59.999' AS DATETIME2)) AS DatetimeToDatetime2; +GO + +SELECT DATEDIFF_BIG(week, CAST('0001-01-01 00:00:00+00:00' AS DATETIMEOFFSET), CAST('2079-06-06' AS SMALLDATETIME)) AS DatetimeOffsetToSmalldatetime; +GO + +SELECT DATEDIFF_BIG(week, CAST('1753-01-01 00:00:00' AS DATETIME2), CAST('1900-01-01' AS DATE)) AS Datetime2ToDate; +GO + +SELECT DATEDIFF_BIG(week, CAST('0001-01-01 00:00:00+00:00' AS DATETIMEOFFSET), CAST('1753-01-01 00:00:00' AS DATETIME2)) AS DatetimeOffsetTodatetime2; +GO + +SELECT DATEDIFF_BIG(quarter, CAST('1753-01-01 00:00:00' AS DATETIME), CAST('9999-01-01 23:59:59.999' AS DATETIME2)) AS DatetimeToDatetime2; +GO + +SELECT DATEDIFF_BIG(quarter, CAST('0001-01-01 00:00:00+00:00' AS DATETIMEOFFSET), CAST('2079-06-06' AS SMALLDATETIME)) AS DatetimeOffsetToSmalldatetime; +GO + +SELECT DATEDIFF_BIG(quarter, CAST('1753-01-01 00:00:00' AS DATETIME2), CAST('1900-01-01' AS DATE)) AS Datetime2ToDate; +GO + +SELECT DATEDIFF_BIG(quarter, CAST('0001-01-01 00:00:00+00:00' AS DATETIMEOFFSET), CAST('1753-01-01 00:00:00' AS DATETIME2)) AS DatetimeOffsetTodatetime2; +GO + +-- Test Cases for Different Time Zones in DATETIMEOFFSET +SELECT DATEDIFF_BIG(week, '2023-01-01 00:00:00+00:00', '2023-01-08 00:00:00+05:30') AS SameTimeDifferentOffsets; +GO + +SELECT DATEDIFF_BIG(week, '2023-01-01 00:00:00+00:00', '2023-01-08 05:30:00+05:30') AS SameTimeDifferentOffsets; +GO + +SELECT DATEDIFF_BIG(week, '2023-01-01 00:00:00-05:00', '2023-01-01 00:00:00+01:00') AS StartEarlierDifferentZone; +GO + +SELECT DATEDIFF_BIG(week, '2024-01-05 23:59:59+00:00', '2024-01-06 00:00:01+05:30') AS CrossWeekBoundary; +GO + +SELECT DATEDIFF_BIG(week, '2000-01-01 00:00:00+00:00', '2023-01-01 00:00:00+10:00') AS LargeIntervalDifferentOffsets; +GO + +SELECT DATEDIFF_BIG(week, '2023-01-01 00:00:00+05:30', '2000-01-01 00:00:00+00:00') AS ReverseIntervalDifferentOffsets; +GO + +SELECT DATEDIFF_BIG(quarter, '2023-01-01 00:00:00+00:00', '2023-04-01 00:00:00+05:30') AS SameTimeDifferentOffsets; +GO + +SELECT DATEDIFF_BIG(quarter, '2023-01-01 00:00:00+00:00', '2023-04-01 05:30:00+05:30') AS SameTimeDifferentOffsets; +GO + +SELECT DATEDIFF_BIG(quarter, '2023-01-01 00:00:00-05:00', '2023-01-01 00:00:00+01:00') AS StartEarlierDifferentZone; +GO + +SELECT DATEDIFF_BIG(quarter, '2023-12-31 23:59:59+00:00', '2024-01-01 00:00:01+05:30') AS CrossQuarterBoundary; +GO + +SELECT DATEDIFF_BIG(quarter, '2000-01-01 00:00:00+00:00', '2023-01-01 00:00:00+10:00') AS LargeIntervalDifferentOffsets; +GO + +SELECT DATEDIFF_BIG(quarter, '2023-01-01 00:00:00+05:30', '2000-01-01 00:00:00+00:00') AS ReverseIntervalDifferentOffsets; +GO