Skip to content

Commit

Permalink
Fix issue with convert function when converting string to date, datet…
Browse files Browse the repository at this point in the history
…imeoffset, datetime2, datetime, smalldatetime or time (#2622)

For converting string to datetime2, datetimeoffset and smalldatetime using convert function, we are directly using cast function which will convert the string to given type with default style. Added support to use corresponding SQL helper functions defined which will fix this issue.

For conversion of string to date, datetime, smalldatetime and time using convert function, there are helper functions defined but are unable to handle all the supported datetime string literals. Refactored these definitions and fixed this issue.

For conversion of string to datetime2 and datetimeoffset using convert function, there are no helper functions defined which handles this conversion as there are for conversion of string to date, datetime, smalldatetime and time. Added definitions to handle these datatypes as well.

Function sys.babelfish_get_microsecs_from_fractsecs() is unable to handle the edge case where fractional seconds get overflowed after rounding it to given scale. Function babelfish_get_timeunit_from_string only returns HOURS, MINUTES, SECONDS and FRACTSECONDS from a given time string. Extended this function to return OFFHOURS, OFFMINUTES and OFFSIGN to get details of timeoffset from time string.

Cherry-picked from: #2613

Issues Resolved: BABEL-4896

Signed-off-by: Rohit Bhagat rohitbgt@amazon.com
  • Loading branch information
rohit01010 committed May 28, 2024
1 parent c48a326 commit 3d6bc8f
Show file tree
Hide file tree
Showing 143 changed files with 83,533 additions and 739 deletions.
2,165 changes: 1,557 additions & 608 deletions contrib/babelfishpg_tsql/sql/sys_function_helpers.sql

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions contrib/babelfishpg_tsql/sql/sys_functions.sql
Original file line number Diff line number Diff line change
Expand Up @@ -4032,8 +4032,8 @@ BEGIN
ELSE
-- Round datetime to fixed bins (e.g. .000, .003, .007)
IF date_arg_datatype = 'sys.datetime'::regtype THEN
date := sys.babelfish_conv_string_to_datetime('DATETIME', date::TEXT)::sys.datetime;
origin := sys.babelfish_conv_string_to_datetime('DATETIME', origin::TEXT)::sys.datetime;
date := sys.babelfish_conv_string_to_datetime_v2('DATETIME', date::TEXT)::sys.datetime;
origin := sys.babelfish_conv_string_to_datetime_v2('DATETIME', origin::TEXT)::sys.datetime;
END IF;
-- when datepart is {year, quarter, month} make use of AGE() function to find number of buckets
IF datepart IN ('year', 'quarter', 'month') THEN
Expand Down
5,253 changes: 5,253 additions & 0 deletions contrib/babelfishpg_tsql/sql/upgrades/babelfishpg_tsql--3.5.0--3.6.0.sql

Large diffs are not rendered by default.

57 changes: 53 additions & 4 deletions contrib/babelfishpg_tsql/src/backend_parser/gram-tsql-epilogue.y.c
Original file line number Diff line number Diff line change
Expand Up @@ -196,11 +196,60 @@ TsqlFunctionConvert(TypeName *typename, Node *arg, Node *style, bool try, int lo
result = (Node *) makeFuncCall(TsqlSystemFuncName("babelfish_conv_helper_to_date"), args, COERCE_EXPLICIT_CALL, location);

else if (type_oid == TIMEOID)
result = (Node *) makeFuncCall(TsqlSystemFuncName("babelfish_conv_helper_to_time"), args, COERCE_EXPLICIT_CALL, location);

{
Node *helperFuncCall;
helperFuncCall = (Node *) makeFuncCall(TsqlSystemFuncName("babelfish_conv_helper_to_time"), lcons(makeIntConst(typmod, location), args), COERCE_EXPLICIT_CALL, location);

/*
* add a type cast on top of the CONVERT helper function
* so typmod can be applied
*/
result = makeTypeCast(helperFuncCall, typename, location);
}
else if (type_oid == typenameTypeId(NULL, makeTypeName("datetime")))
result = (Node *) makeFuncCall(TsqlSystemFuncName("babelfish_conv_helper_to_datetime"), args, COERCE_EXPLICIT_CALL, location);

{
Node *helperFuncCall;
helperFuncCall = (Node *) makeFuncCall(TsqlSystemFuncName("babelfish_conv_helper_to_datetime"), lcons(makeIntConst(typmod, location), args), COERCE_EXPLICIT_CALL, location);

/*
* add a type cast on top of the CONVERT helper function
* so typmod can be applied
*/
result = makeTypeCast(helperFuncCall, typename, location);
}
else if (type_oid == typenameTypeId(NULL, makeTypeName("datetime2")))
{
Node *helperFuncCall;
helperFuncCall = (Node *) makeFuncCall(TsqlSystemFuncName("babelfish_conv_helper_to_datetime2"), lcons(makeIntConst(typmod, location), args), COERCE_EXPLICIT_CALL, location);

/*
* add a type cast on top of the CONVERT helper function
* so typmod can be applied
*/
result = makeTypeCast(helperFuncCall, typename, location);
}
else if (type_oid == typenameTypeId(NULL, makeTypeName("datetimeoffset")))
{
Node *helperFuncCall;
helperFuncCall = (Node *) makeFuncCall(TsqlSystemFuncName("babelfish_conv_helper_to_datetimeoffset"), lcons(makeIntConst(typmod, location), args), COERCE_EXPLICIT_CALL, location);

/*
* add a type cast on top of the CONVERT helper function
* so typmod can be applied
*/
result = makeTypeCast(helperFuncCall, typename, location);
}
else if (type_oid == typenameTypeId(NULL, makeTypeName("smalldatetime")))
{
Node *helperFuncCall;
helperFuncCall = (Node *) makeFuncCall(TsqlSystemFuncName("babelfish_conv_helper_to_smalldatetime"), lcons(makeIntConst(typmod, location), args), COERCE_EXPLICIT_CALL, location);

/*
* add a type cast on top of the CONVERT helper function
* so typmod can be applied
*/
result = makeTypeCast(helperFuncCall, typename, location);
}
else if ((strcmp(typename_string, "varchar") == 0) || (strcmp(typename_string, "nvarchar") == 0) ||
(strcmp(typename_string, "bpchar") == 0) || (strcmp(typename_string, "nchar") == 0))
{
Expand Down
Loading

0 comments on commit 3d6bc8f

Please sign in to comment.