From cdb7bd055950d0f56e70e77e7b1678a2d6fb25fc Mon Sep 17 00:00:00 2001 From: Rivers Zhang Date: Thu, 14 Aug 2025 15:28:44 -0400 Subject: [PATCH] Allowing omitting the "T" separator from a datetime string Our customers have issue using spark to create a dataframe on a datetime column, because spark interpolates the provided datetime string, but drops the "T" separator when filling the range. It seems that omitting the "T" character is fairly acceptable, and ISO 8601 does allow it to be omitted in a few cases. This is a very simple patch to allow it. Signed-off-by: Rivers Zhang --- db/types.c | 10 ++++++++-- tests/datetime.test/t25.expected | 6 ++++++ tests/datetime.test/t25.sql | 8 ++++++++ tests/udf.test/{nextval.req => nextval.0.req} | 0 .../{nextval.req.expected => nextval.0.req.expected} | 0 tests/udf.test/{nextval_1.req => nextval.1.req} | 0 .../{nextval_1.req.expected => nextval.1.req.expected} | 0 tests/udf.test/runit | 2 +- 8 files changed, 23 insertions(+), 3 deletions(-) create mode 100644 tests/datetime.test/t25.expected create mode 100644 tests/datetime.test/t25.sql rename tests/udf.test/{nextval.req => nextval.0.req} (100%) rename tests/udf.test/{nextval.req.expected => nextval.0.req.expected} (100%) rename tests/udf.test/{nextval_1.req => nextval.1.req} (100%) rename tests/udf.test/{nextval_1.req.expected => nextval.1.req.expected} (100%) diff --git a/db/types.c b/db/types.c index d3aa44668d..afef6190ee 100644 --- a/db/types.c +++ b/db/types.c @@ -7262,7 +7262,7 @@ static int _isISO8601(const char *str, int len) /* (month<1 || month>12)*/ \ \ /*get day*/ \ - day = getInt(in, len, &offset, <oken, 1, 2, "-T", &skipped); \ + day = getInt(in, len, &offset, <oken, 1, 2, "-T ", &skipped); \ if (!ltoken) \ return CONV_WRONG_MDAY; \ /*(day <1 || !is_valid_days(year, month, day))*/ \ @@ -7307,8 +7307,14 @@ static int _isISO8601(const char *str, int len) ss = 0; \ } else \ mm = 0; \ - } else \ + } else { \ hh = 0; \ + /* Need to compensate if the last separator is a space */ \ + /* Because we expect the timezone string to have a leading space */ \ + /* See a few lines above for the same logic in parsing the fraction */ \ + if (in[offset - 1] == ' ') \ + offset--; /*incremented afterwards*/ \ + } \ \ /* fill in the blanks*/ \ out->tm.tm_year = year - 1900; \ diff --git a/tests/datetime.test/t25.expected b/tests/datetime.test/t25.expected new file mode 100644 index 0000000000..bebede3163 --- /dev/null +++ b/tests/datetime.test/t25.expected @@ -0,0 +1,6 @@ +(rows inserted=1) +(rows inserted=1) +(d="1970-01-01T000000.000 UTC") +(d="1970-08-17T001501.000 UTC") +(epoch=0) +(epoch=19700101) diff --git a/tests/datetime.test/t25.sql b/tests/datetime.test/t25.sql new file mode 100644 index 0000000000..338cb96d75 --- /dev/null +++ b/tests/datetime.test/t25.sql @@ -0,0 +1,8 @@ +SET TIMEZONE UTC +DROP TABLE IF EXISTS t25 +CREATE TABLE t25(d datetime)$$ +INSERT INTO t25 VALUES("1970-01-01 00:00:00 UTC") +INSERT INTO t25 VALUES("19700101") +SELECT d FROM t25 +SELECT CAST(d AS INT) AS epoch FROM t25 +DROP TABLE t25 diff --git a/tests/udf.test/nextval.req b/tests/udf.test/nextval.0.req similarity index 100% rename from tests/udf.test/nextval.req rename to tests/udf.test/nextval.0.req diff --git a/tests/udf.test/nextval.req.expected b/tests/udf.test/nextval.0.req.expected similarity index 100% rename from tests/udf.test/nextval.req.expected rename to tests/udf.test/nextval.0.req.expected diff --git a/tests/udf.test/nextval_1.req b/tests/udf.test/nextval.1.req similarity index 100% rename from tests/udf.test/nextval_1.req rename to tests/udf.test/nextval.1.req diff --git a/tests/udf.test/nextval_1.req.expected b/tests/udf.test/nextval.1.req.expected similarity index 100% rename from tests/udf.test/nextval_1.req.expected rename to tests/udf.test/nextval.1.req.expected diff --git a/tests/udf.test/runit b/tests/udf.test/runit index 13eb2b19e9..a1b3baf411 100755 --- a/tests/udf.test/runit +++ b/tests/udf.test/runit @@ -1,6 +1,6 @@ #!/usr/bin/env bash set -x -for t in *.req; do +for t in `ls *.req | sort`; do cdb2sql --tabs --script --cdb2cfg ${CDB2_CONFIG} ${1} default - 2> ${t}.output 1>&2 < ${t} set -e diff ${t}.expected ${t}.output