Skip to content

Support empty string handling for date and time datatypes #3807

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: BABEL_5_X_DEV
Choose a base branch
from

Conversation

manisha-deshpande
Copy link
Contributor

@manisha-deshpande manisha-deshpande commented Jun 5, 2025

Overview

Add TSQL-compatible handling of empty string ('') for date and time types, defaulting to '1900-01-01' for date and time, similar to datetime, datetime2, datetimeoffset, smalldatetime.

Task: BABEL-3433

Description

In SQL Server, when an empty string ('') is cast to date or time datatype, it should be return a default value - '1900-01-01' for date and '00:00:00.0000000' for time. Currently, Babelfish raises a syntax error for these cases. This change improves TSQL compatibility by matching SQL Server's behavior for empty string handling in date and time datatypes, while maintaining existing behavior for non-empty inputs.

1> create table bug(dt date null, tm time(3) null);
2> insert into bug values ('', '');
go
Msg 33557097, Level 16, State 1, Server BABELFISH, Line 1
invalid input syntax for type date: ""
Msg 33557097, Level 16, State 1, Server BABELFISH, Line 1
invalid input syntax for type time: ""

Changes:

    • Added helper functions in babelfish_common's datetime.c for default value initialization:
  • initializeToDefaultDate() - Returns default date '1900-01-01'
  • initializeToDefaultTime() - Returns default time '00:00:00.0000000'
  • isEmptyOrWhitespace() - Checks if string is empty or contains only whitespace
  1. Modifying string to date/time conversion in two places:
  • varchar2date() and varchar2time() functions for CAST operations from varchar and nvarchar types
  • tsql_coerce_string_literal_hook for string literals
  1. Added comprehensive test coverage in the Babelfish JDBC test suite to verify empty string handling across different scenarios including direct casts, table insert operation, type conversions, and formatting functions.

Remaining items out of current scope:

BABEL-5923

  • Support for casts from char and nchar types to date and time datatypes. (Currently only supports varchar, nvarchar)
  • Extend whitespace handling for other datetime types.
  • Support tab space handling for all date time datatypes.

Issues Resolved

BABEL-3433: Support for empty input string handling in date and time datatypes

Test Scenarios Covered [+ BABEL_3433.sql]

  • Use case based -
CREATE TABLE date_testing(d DATE);
INSERT INTO date_testing VALUES('');
go
INSERT ...

create table time_testing ( ti TIME );
INSERT INTO time_testing VALUES('');
go
INSERT ...

** The insertion subsequently affects the existing FORMAT date function tests with various arguments for tables date_testing, time_testing.

select * from date_testing;
go
~~START~~
date
1900-01-01
...

select FORMAT(d, 'd','en-us') from date_testing;
GO
~~START~~
nvarchar
1/1/1900
...
  • Other date functions
select CONVERT(varchar(30), CAST('' AS date), 102);
go -- 1900.01.01
select TRY_CONVERT(varchar(30), CAST('' AS date), 102);
go -- 1900.01.01
select datepart(day, cast('' as date));
go -- 1
select datediff(year, CAST('1900-01-01'AS date), CAST(''AS date));
go -- 0
select DAY(CAST('' AS date));
go -- 1
select YEAR(CAST('' AS date));
go -- 1900

  • Additional cast to other date types
select CAST(CAST('' AS date) AS datetime)
go -- datetime 1900-01-01 00:00:00.0
select CAST(CAST('' AS time) AS datetime)
go -- datetime 1900-01-01 00:00:00.0
select CAST(CAST('' AS date) AS datetime2);
go -- datetime2 1900-01-01 00:00:00.0000000
select CAST(CAST('' AS time) AS datetime2);
go -- datetime2 1900-01-01 00:00:00.0000000
select CAST(CAST('' AS time) AS smalldatetime);
go -- smalldatetime 1900-01-01 00:00:00.0
select CAST(CAST('' AS date) AS smalldatetime);
go -- smalldatetime 1900-01-01 00:00:00.0
select CAST(CAST('' AS date) AS datetimeoffset);
go -- datetimeoffset 1900-01-01 00:00:00.0000000 +00:00
select CAST(CAST('' AS time) AS datetimeoffset);
go -- datetimeoffset 1900-01-01 00:00:00.0000000 +00:00

  • Boundary conditions -

  • Arbitrary inputs -

  • Negative test cases -

  • Minor version upgrade tests -

  • Major version upgrade tests -

  • Performance tests -

  • Tooling impact -

  • Client tests -

Check List

  • Commits are signed per the DCO using --signoff

By submitting this pull request, I confirm that my contribution is under the terms of the Apache 2.0 and PostgreSQL licenses, and grant any person obtaining a copy of the contribution permission to relicense all or a portion of my contribution to the PostgreSQL License solely to contribute all or a portion of my contribution to the PostgreSQL open source project.

For more information on following Developer Certificate of Origin and signing off your commits, please check here.

Add TSQL-compatible handling of empty string ('') for date and time
types, defaulting to '1900-01-01' for date and '00:00:00.0000000' for
time, similar to datetime, datetime2, datetimeoffset, smalldatetime.
Added empty string test cases in different scenarios including table
insert, direct cast, cast to other date types, and formatting functions.

Task: BABEL-3433
Signed-off-by: Manisha Deshpande <[email protected]>
@coveralls
Copy link
Collaborator

coveralls commented Jun 6, 2025

Pull Request Test Coverage Report for Build 15496457607

Details

  • 0 of 0 changed or added relevant lines in 0 files are covered.
  • 2 unchanged lines in 1 file lost coverage.
  • Overall coverage increased (+0.002%) to 75.456%

Files with Coverage Reduction New Missed Lines %
contrib/babelfishpg_tds/src/backend/tds/tdscomm.c 2 76.03%
Totals Coverage Status
Change from base Build 15464616681: 0.002%
Covered Lines: 48783
Relevant Lines: 64651

💛 - Coveralls

Task: BABEL-3433
Signed-off-by: Manisha Deshpande <[email protected]>
@manisha-deshpande manisha-deshpande marked this pull request as ready for review June 6, 2025 23:39
Copy link
Contributor

@RIC06X RIC06X left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@Anikait143
Copy link
Contributor

Please add following Test Cases:

  1. Tests with empty strings consisting of whitespapces/tabs/new lines.
  2. Declare/Select statements
  3. Insertion into table with date/time column
  4. Casts from string datatypes (empty string) to date/time.
  5. Test with Views

1. Add helper functions to initialize the default date and time variables
   and to check for strings with whitespaces.
2. Modify varchar2date() and varchar2time() to handle empty/whitespace
   casts from varchar types to date and time types.
3. Update tsql_coerce_string_literal_hook to handle empty/whitespace
   casts from string literals to date and time datatypes.
4. Default empty/whitespace strings to '1900-01-01' for date and
   '00:00:00.0000000' for time.

Task: BABEL-3433
Signed-off-by: Manisha Deshpande <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants