From 44fb4f562fc98e274c0a7d30fd6fba7b7b0737ca Mon Sep 17 00:00:00 2001 From: Cloud User Date: Fri, 19 Feb 2016 15:31:30 +0000 Subject: [PATCH] JIRA TRAFODION-1825. Fix for core caused by input datetime values. --- core/sql/cli/CliExpExchange.cpp | 2 + core/sql/exp/exp_datetime.cpp | 30 ++-- .../{EXPECTED022.LINUX => EXPECTED022.SB} | 134 +++++++++++++++--- core/sql/regress/executor/TEST022 | 12 ++ core/sql/sqlci/Param.cpp | 8 +- core/sql/sqlci/SqlCmd.cpp | 37 ++++- 6 files changed, 186 insertions(+), 37 deletions(-) rename core/sql/regress/executor/{EXPECTED022.LINUX => EXPECTED022.SB} (98%) mode change 100755 => 100644 diff --git a/core/sql/cli/CliExpExchange.cpp b/core/sql/cli/CliExpExchange.cpp index 24853a3975..b313040dee 100644 --- a/core/sql/cli/CliExpExchange.cpp +++ b/core/sql/cli/CliExpExchange.cpp @@ -4095,6 +4095,8 @@ InputOutputExpr::inputValues(atp_struct *atp, sourceType = REC_BYTE_F_ASCII; sourcePrecision = 0; // TBD $$$$ add source max chars later sourceScale = SQLCHARSETCODE_ISO88591; // assume target charset is ASCII-compatible + + convFlags |= CONV_NO_HADOOP_DATE_FIX; } } else if ((sourceType == targetType) && diff --git a/core/sql/exp/exp_datetime.cpp b/core/sql/exp/exp_datetime.cpp index a1cff3cef0..781f2dd15d 100644 --- a/core/sql/exp/exp_datetime.cpp +++ b/core/sql/exp/exp_datetime.cpp @@ -1759,6 +1759,7 @@ scanField(char *&src, ULng32 flags) { NABoolean noDatetimeValidation = (flags & CONV_NO_DATETIME_VALIDATION) != 0; + NABoolean noHadoopDateFix = (flags & CONV_NO_HADOOP_DATE_FIX) != 0; // The maximum lengths of the various fields. Since the value of // REC_DATE_YEAR is 1, the first entry is just a place holder. @@ -1846,10 +1847,17 @@ scanField(char *&src, // if (len < maxLens[field] && field != REC_DATE_FRACTION_MP) { - // An unknown character was encountered in the string. - // - ExRaiseSqlError(heap, diagsArea, EXE_CONVERT_STRING_ERROR); - return FALSE; + if ((NOT noHadoopDateFix) && + (field >= REC_DATE_HOUR)) { + // extend with zeroes + value = 0; + } + else { + // An unknown character was encountered in the string. + // + ExRaiseSqlError(heap, diagsArea, EXE_CONVERT_STRING_ERROR); + return FALSE; + } } else if (src < srcEnd && isDigit8859_1(*src)) { return FALSE; } @@ -1879,7 +1887,6 @@ ExpDatetime::convAsciiToDatetime(char *srcData, { NABoolean noDatetimeValidation = (flags & CONV_NO_DATETIME_VALIDATION) != 0; - NABoolean noHadoopDateFix = (flags & CONV_NO_HADOOP_DATE_FIX) != 0; // skip leading and trailing blanks and adjust srcData and srcLen // accordingly @@ -1908,19 +1915,6 @@ ExpDatetime::convAsciiToDatetime(char *srcData, srcLen--; } - char hadoopDateFix[20]; - if ((srcLen == 10) && - (NOT noHadoopDateFix)) - { - memcpy(hadoopDateFix, srcData, 10); - hadoopDateFix[10] = '\0'; - strcat(hadoopDateFix, " 00:00:00"); - srcLen = 19; - srcData = hadoopDateFix; - - dstEndField = REC_DATE_SECOND; - } - // Indicates if an " AM" or " PM" strings appears at the end of the // source. // 0 - means no AM/PM indicator diff --git a/core/sql/regress/executor/EXPECTED022.LINUX b/core/sql/regress/executor/EXPECTED022.SB old mode 100755 new mode 100644 similarity index 98% rename from core/sql/regress/executor/EXPECTED022.LINUX rename to core/sql/regress/executor/EXPECTED022.SB index 87d83125e5..cbe4b2fdc4 --- a/core/sql/regress/executor/EXPECTED022.LINUX +++ b/core/sql/regress/executor/EXPECTED022.SB @@ -746,6 +746,41 @@ 23:11:06.12 +--- 1 row(s) selected. +>> +>>select cast('2010-01-01' as timestamp(3)) from t022t1; + +(EXPR) +----------------------- + +2010-01-01 00:00:00.000 + +--- 1 row(s) selected. +>>select cast('2010-01-01 10' as timestamp) from t022t1; + +(EXPR) +-------------------------- + +2010-01-01 10:00:00.000000 + +--- 1 row(s) selected. +>> +>>create table if not exists t022dtime(a date not null, b time, c timestamp); + +--- SQL operation complete. +>>prepare s from upsert into t022dtime values (?, ?, ?); + +--- SQL command prepared. +>>execute s using '2010-01-01', '10:10:10', '2010-01-01 10:10:10.123'; + +--- 1 row(s) inserted. +>>select * from t022dtime; + +A B C +---------- -------- -------------------------- + +2010-01-01 10:10:10 2010-01-01 10:10:10.123000 + --- 1 row(s) selected. >> >>-- negative cases @@ -793,6 +828,22 @@ *** ERROR[8415] The provided DATE, TIME, or TIMESTAMP is not valid and cannot be converted. --- 0 row(s) selected. +>>select cast ('23:11:06' as timestamp) from t022t1; + +*** ERROR[8415] The provided DATE, TIME, or TIMESTAMP is not valid and cannot be converted. + +--- 0 row(s) selected. +>>select cast('2010-01-01' as time) from t022t1; + +*** ERROR[8415] The provided DATE, TIME, or TIMESTAMP is not valid and cannot be converted. + +--- 0 row(s) selected. +>>select timestamp'2010-01-01 10' from t022t1; + +*** ERROR[3047] The timestamp '2010-01-01 10' is not valid. + +*** ERROR[8822] The statement was not prepared. + >> >>-- Prove these cases work since they're used in the succeeding negative tests. >> @@ -2669,7 +2720,7 @@ A B *** ERROR[8415] The provided DATE, TIME, or TIMESTAMP is not valid and cannot be converted. -*** ERROR[15015] PARAM ?p (value 11/20/1997 15:15:08.123456 am) cannot be converted to type TIMESTAMP(3). +*** ERROR[15015] PARAM ?p (value 11/20/1997 15:15:08.123456 am) cannot be converted to type TIMESTAMP(6). --- 0 row(s) inserted. >> @@ -2681,7 +2732,7 @@ A B *** ERROR[8415] The provided DATE, TIME, or TIMESTAMP is not valid and cannot be converted. -*** ERROR[15015] PARAM ?p (value 2100-01-01:ab:00:47.250000) cannot be converted to type TIMESTAMP(3). +*** ERROR[15015] PARAM ?p (value 2100-01-01:ab:00:47.250000) cannot be converted to type TIMESTAMP(6). --- 0 row(s) inserted. >> @@ -2691,7 +2742,7 @@ A B *** ERROR[8415] The provided DATE, TIME, or TIMESTAMP is not valid and cannot be converted. -*** ERROR[15015] PARAM ?p (value 1998-03-12 03:15:08.123456 pm) cannot be converted to type TIMESTAMP(3). +*** ERROR[15015] PARAM ?p (value 1998-03-12 03:15:08.123456 pm) cannot be converted to type TIMESTAMP(6). --- 0 row(s) inserted. >> @@ -2701,7 +2752,7 @@ A B *** ERROR[8415] The provided DATE, TIME, or TIMESTAMP is not valid and cannot be converted. -*** ERROR[15015] PARAM ?p (value 1996-05-23 16:15:08.123 am) cannot be converted to type TIMESTAMP(3). +*** ERROR[15015] PARAM ?p (value 1996-05-23 16:15:08.123 am) cannot be converted to type TIMESTAMP(6). --- 0 row(s) inserted. >> @@ -2776,7 +2827,7 @@ C1 *** ERROR[8415] The provided DATE, TIME, or TIMESTAMP is not valid and cannot be converted. -*** ERROR[15015] PARAM ?p (value 00:a1:00) cannot be converted to type TIMESTAMP(2). +*** ERROR[15015] PARAM ?p (value 00:a1:00) cannot be converted to type TIME(0). --- 0 row(s) inserted. >> @@ -2786,7 +2837,7 @@ C1 *** ERROR[8415] The provided DATE, TIME, or TIMESTAMP is not valid and cannot be converted. -*** ERROR[15015] PARAM ?p (value 14:59:59 am) cannot be converted to type TIMESTAMP(2). +*** ERROR[15015] PARAM ?p (value 14:59:59 am) cannot be converted to type TIME(0). --- 0 row(s) inserted. >> @@ -2796,7 +2847,7 @@ C1 *** ERROR[8415] The provided DATE, TIME, or TIMESTAMP is not valid and cannot be converted. -*** ERROR[15015] PARAM ?p (value 11:60:59 am) cannot be converted to type TIMESTAMP(2). +*** ERROR[15015] PARAM ?p (value 11:60:59 am) cannot be converted to type TIME(0). --- 0 row(s) inserted. >> @@ -4168,7 +4219,7 @@ Hello (EXPR) (EXPR) (EXPR) ------------- ------------- -------------------------- -10:13:14.0000 10:13:14.0000 2016-02-03 06:33:46.601880 +10:13:14.0000 10:13:14.0000 2016-02-19 15:24:29.239482 --- 1 row(s) selected. >>--test on precision of time @@ -5428,6 +5479,41 @@ lkjihgfedc ? ? 23:11:06.12 +--- 1 row(s) selected. +>> +>>select cast('2010-01-01' as timestamp(3)) from t022t1; + +(EXPR) +----------------------- + +2010-01-01 00:00:00.000 + +--- 1 row(s) selected. +>>select cast('2010-01-01 10' as timestamp) from t022t1; + +(EXPR) +-------------------------- + +2010-01-01 10:00:00.000000 + +--- 1 row(s) selected. +>> +>>create table if not exists t022dtime(a date not null, b time, c timestamp); + +--- SQL operation complete. +>>prepare s from upsert into t022dtime values (?, ?, ?); + +--- SQL command prepared. +>>execute s using '2010-01-01', '10:10:10', '2010-01-01 10:10:10.123'; + +--- 1 row(s) inserted. +>>select * from t022dtime; + +A B C +---------- -------- -------------------------- + +2010-01-01 10:10:10 2010-01-01 10:10:10.123000 + --- 1 row(s) selected. >> >>-- negative cases @@ -5475,6 +5561,22 @@ lkjihgfedc ? ? *** ERROR[8415] The provided DATE, TIME, or TIMESTAMP is not valid and cannot be converted. --- 0 row(s) selected. +>>select cast ('23:11:06' as timestamp) from t022t1; + +*** ERROR[8415] The provided DATE, TIME, or TIMESTAMP is not valid and cannot be converted. + +--- 0 row(s) selected. +>>select cast('2010-01-01' as time) from t022t1; + +*** ERROR[8415] The provided DATE, TIME, or TIMESTAMP is not valid and cannot be converted. + +--- 0 row(s) selected. +>>select timestamp'2010-01-01 10' from t022t1; + +*** ERROR[3047] The timestamp '2010-01-01 10' is not valid. + +*** ERROR[8822] The statement was not prepared. + >> >>-- Prove these cases work since they're used in the succeeding negative tests. >> @@ -7351,7 +7453,7 @@ A B *** ERROR[8415] The provided DATE, TIME, or TIMESTAMP is not valid and cannot be converted. -*** ERROR[15015] PARAM ?p (value 11/20/1997 15:15:08.123456 am) cannot be converted to type TIMESTAMP(3). +*** ERROR[15015] PARAM ?p (value 11/20/1997 15:15:08.123456 am) cannot be converted to type TIMESTAMP(6). --- 0 row(s) inserted. >> @@ -7363,7 +7465,7 @@ A B *** ERROR[8415] The provided DATE, TIME, or TIMESTAMP is not valid and cannot be converted. -*** ERROR[15015] PARAM ?p (value 2100-01-01:ab:00:47.250000) cannot be converted to type TIMESTAMP(3). +*** ERROR[15015] PARAM ?p (value 2100-01-01:ab:00:47.250000) cannot be converted to type TIMESTAMP(6). --- 0 row(s) inserted. >> @@ -7373,7 +7475,7 @@ A B *** ERROR[8415] The provided DATE, TIME, or TIMESTAMP is not valid and cannot be converted. -*** ERROR[15015] PARAM ?p (value 1998-03-12 03:15:08.123456 pm) cannot be converted to type TIMESTAMP(3). +*** ERROR[15015] PARAM ?p (value 1998-03-12 03:15:08.123456 pm) cannot be converted to type TIMESTAMP(6). --- 0 row(s) inserted. >> @@ -7383,7 +7485,7 @@ A B *** ERROR[8415] The provided DATE, TIME, or TIMESTAMP is not valid and cannot be converted. -*** ERROR[15015] PARAM ?p (value 1996-05-23 16:15:08.123 am) cannot be converted to type TIMESTAMP(3). +*** ERROR[15015] PARAM ?p (value 1996-05-23 16:15:08.123 am) cannot be converted to type TIMESTAMP(6). --- 0 row(s) inserted. >> @@ -7458,7 +7560,7 @@ C1 *** ERROR[8415] The provided DATE, TIME, or TIMESTAMP is not valid and cannot be converted. -*** ERROR[15015] PARAM ?p (value 00:a1:00) cannot be converted to type TIMESTAMP(2). +*** ERROR[15015] PARAM ?p (value 00:a1:00) cannot be converted to type TIME(0). --- 0 row(s) inserted. >> @@ -7468,7 +7570,7 @@ C1 *** ERROR[8415] The provided DATE, TIME, or TIMESTAMP is not valid and cannot be converted. -*** ERROR[15015] PARAM ?p (value 14:59:59 am) cannot be converted to type TIMESTAMP(2). +*** ERROR[15015] PARAM ?p (value 14:59:59 am) cannot be converted to type TIME(0). --- 0 row(s) inserted. >> @@ -7478,7 +7580,7 @@ C1 *** ERROR[8415] The provided DATE, TIME, or TIMESTAMP is not valid and cannot be converted. -*** ERROR[15015] PARAM ?p (value 11:60:59 am) cannot be converted to type TIMESTAMP(2). +*** ERROR[15015] PARAM ?p (value 11:60:59 am) cannot be converted to type TIME(0). --- 0 row(s) inserted. >> @@ -8850,7 +8952,7 @@ Hello (EXPR) (EXPR) (EXPR) ------------- ------------- -------------------------- -10:13:14.0000 10:13:14.0000 2016-02-03 06:36:01.915955 +10:13:14.0000 10:13:14.0000 2016-02-19 15:26:59.794585 --- 1 row(s) selected. >>--test on precision of time diff --git a/core/sql/regress/executor/TEST022 b/core/sql/regress/executor/TEST022 index e82f0cb9d5..9628ceed2b 100755 --- a/core/sql/regress/executor/TEST022 +++ b/core/sql/regress/executor/TEST022 @@ -81,6 +81,7 @@ drop table $$TEST_SCHEMA$$.t022a7; drop table t022fltcmp; drop table t022bug cascade; ?ifMX +drop table t022dtime; ------------------------------------------------------------------------------- ?section test @@ -220,6 +221,14 @@ select cast('10:11:12.123+05:00' as time) from t022t1; select time '23:11:06.123' from t022t1; select cast ('23:11:06.123' as time(2)) from t022t1; +select cast('2010-01-01' as timestamp(3)) from t022t1; +select cast('2010-01-01 10' as timestamp) from t022t1; + +create table if not exists t022dtime(a date not null, b time, c timestamp); +prepare s from upsert into t022dtime values (?, ?, ?); +execute s using '2010-01-01', '10:10:10', '2010-01-01 10:10:10.123'; +select * from t022dtime; + -- negative cases select cast('2016-01-29Z' as date) from t022t1; select cast('2016-01-29+05:00' as date) from t022t1; @@ -229,6 +238,9 @@ select date '2016-01-29+05:00' from t022t1; select time '25:11:11' from t022t1; select time '23:11:11.1234567' from t022t1; select cast ('23:11:61' as time) from t022t1; +select cast ('23:11:06' as timestamp) from t022t1; +select cast('2010-01-01' as time) from t022t1; +select timestamp'2010-01-01 10' from t022t1; -- Prove these cases work since they're used in the succeeding negative tests. diff --git a/core/sql/sqlci/Param.cpp b/core/sql/sqlci/Param.cpp index fcc950f640..2e7f634e39 100644 --- a/core/sql/sqlci/Param.cpp +++ b/core/sql/sqlci/Param.cpp @@ -426,6 +426,9 @@ short Param::convertValue(SqlciEnv * sqlci_env, short targetType, short VCLenSize = 0; converted_value = new char[targetLen + 1]; + UInt32 flags = 0; + flags |= CONV_NO_HADOOP_DATE_FIX; + #pragma nowarn(1506) // warning elimination ex_expr::exp_return_type ok = convDoIt(value, sourceLen, @@ -440,7 +443,10 @@ short Param::convertValue(SqlciEnv * sqlci_env, short targetType, VCLen, VCLenSize, 0, - &diags); + &diags, + CONV_UNKNOWN, + NULL, + flags); if ( ok != ex_expr::EXPR_OK) { diff --git a/core/sql/sqlci/SqlCmd.cpp b/core/sql/sqlci/SqlCmd.cpp index 6c09c0d503..c21531cc29 100644 --- a/core/sql/sqlci/SqlCmd.cpp +++ b/core/sql/sqlci/SqlCmd.cpp @@ -1628,10 +1628,43 @@ short SqlCmd::doDescribeInput(SqlciEnv * sqlci_env, , 0 , 0 ); - + + rec_datetime_field dtStartField = REC_DATE_YEAR; + rec_datetime_field dtEndField = REC_DATE_SECOND; + if (datatype == REC_DATETIME) + { + Lng32 dtCode; + retcode = SQL_EXEC_GetDescItem(input_desc, entry, + SQLDESC_DATETIME_CODE, + &dtCode, 0, 0, 0, 0); + HandleCLIError(retcode, sqlci_env); + + // this will get fractional precision + retcode = SQL_EXEC_GetDescItem(input_desc, entry, + SQLDESC_PRECISION, + &precision, 0, 0, 0, 0); + HandleCLIError(retcode, sqlci_env); + + if (dtCode == REC_DTCODE_DATE) + { + dtStartField = REC_DATE_YEAR; + dtEndField = REC_DATE_DAY; + } + else if (dtCode == REC_DTCODE_TIME) + { + dtStartField = REC_DATE_HOUR; + dtEndField = REC_DATE_SECOND; + } + else if (dtCode == REC_DTCODE_TIMESTAMP) + { + dtStartField = REC_DATE_YEAR; + dtEndField = REC_DATE_SECOND; + } + } + NAType::convertTypeToText(tgttype, datatype, length, precision, scale, - REC_DATE_YEAR, REC_DATE_SECOND, + dtStartField, dtEndField, (short)precision, SQLInterval::DEFAULT_LEADING_PRECISION, FALSE/*upshift*/,