From 38f01c6e75c611fdf8df4ea6ad2e8f0deda426b7 Mon Sep 17 00:00:00 2001 From: Ziqi Li Date: Wed, 22 Sep 2021 16:19:24 -0700 Subject: [PATCH 01/29] Changed adding default timezone offset to TIME WITH TIME ZONE from parsing phase to evaluating phase. --- .../src/java/org/partiql/examples/Test.java | 29 ++++++ .../org/partiql/type-domains/partiql.ion | 2 +- .../partiql/lang/ast/ExprNodeToStatement.kt | 1 + .../partiql/lang/ast/StatementToExprNode.kt | 1 + lang/src/org/partiql/lang/ast/ast.kt | 7 +- .../lang/ast/passes/AstRewriterBase.kt | 1 + .../partiql/lang/eval/EvaluatingCompiler.kt | 6 +- lang/src/org/partiql/lang/syntax/SqlParser.kt | 53 +++++------ .../lang/syntax/SqlParserDateTimeTests.kt | 93 +++++++++---------- 9 files changed, 111 insertions(+), 82 deletions(-) create mode 100644 examples/src/java/org/partiql/examples/Test.java diff --git a/examples/src/java/org/partiql/examples/Test.java b/examples/src/java/org/partiql/examples/Test.java new file mode 100644 index 0000000000..3f795f77ed --- /dev/null +++ b/examples/src/java/org/partiql/examples/Test.java @@ -0,0 +1,29 @@ +package org.partiql.examples; + +import com.amazon.ion.IonSystem; +import com.amazon.ion.system.IonSystemBuilder; +import org.partiql.lang.CompilerPipeline; +import org.partiql.lang.eval.EvaluationSession; +import org.partiql.lang.eval.ExprValue; +import org.partiql.lang.eval.Expression; + +import java.time.LocalTime; +import java.time.OffsetTime; +import java.time.format.DateTimeFormatter; + +public class Test { + public static void main (String[] args){ +// final IonSystem ion = IonSystemBuilder.standard().build(); +// final CompilerPipeline pipeline = CompilerPipeline.standard(ion); +// final EvaluationSession session = EvaluationSession.standard(); +// final String query = "1 + 1"; +// Expression e = pipeline.compile(query); +// ExprValue result = e.eval(session); +// +// System.out.println(result); + + //OffsetTime time1 = OffsetTime.parse("10:15:30", DateTimeFormatter.ISO_TIME); + LocalTime time2 = LocalTime.parse("10:15:30-05:30", DateTimeFormatter.ISO_TIME); + //System.out.println (time1.getOffset()); + } +} diff --git a/lang/resources/org/partiql/type-domains/partiql.ion b/lang/resources/org/partiql/type-domains/partiql.ion index 3fa2d52dfd..ea2a469651 100644 --- a/lang/resources/org/partiql/type-domains/partiql.ion +++ b/lang/resources/org/partiql/type-domains/partiql.ion @@ -125,7 +125,7 @@ // end of sum expr // Time - (product time_value hour::int minute::int second::int nano::int precision::int tz_minutes::(? int)) + (product time_value hour::int minute::int second::int nano::int precision::int with_time_zone::bool tz_minutes::(? int)) // A "step" within a path expression; that is the components of the expression following the root. (sum path_step diff --git a/lang/src/org/partiql/lang/ast/ExprNodeToStatement.kt b/lang/src/org/partiql/lang/ast/ExprNodeToStatement.kt index c16c4b40aa..f4fc15e303 100644 --- a/lang/src/org/partiql/lang/ast/ExprNodeToStatement.kt +++ b/lang/src/org/partiql/lang/ast/ExprNodeToStatement.kt @@ -183,6 +183,7 @@ fun ExprNode.toAstExpr(): PartiqlAst.Expr { node.second.toLong(), node.nano.toLong(), node.precision.toLong(), + node.with_time_zone, node.tz_minutes?.toLong() ) ) diff --git a/lang/src/org/partiql/lang/ast/StatementToExprNode.kt b/lang/src/org/partiql/lang/ast/StatementToExprNode.kt index a61c360d91..a341b78338 100644 --- a/lang/src/org/partiql/lang/ast/StatementToExprNode.kt +++ b/lang/src/org/partiql/lang/ast/StatementToExprNode.kt @@ -201,6 +201,7 @@ private class StatementTransformer(val ion: IonSystem) { value.second.value.toInt(), value.nano.value.toInt(), value.precision.value.toInt(), + value.withTimeZone.value, value.tzMinutes?.value?.toInt(), metas ) diff --git a/lang/src/org/partiql/lang/ast/ast.kt b/lang/src/org/partiql/lang/ast/ast.kt index 7d18914aac..a0dcb32d08 100644 --- a/lang/src/org/partiql/lang/ast/ast.kt +++ b/lang/src/org/partiql/lang/ast/ast.kt @@ -1020,8 +1020,10 @@ sealed class DateTimeType : ExprNode() { * @param second represents the second value. * @param nano represents the fractional part of the second up to the nanoseconds' precision. * @param precision is an optional parameter which, if specified, represents the precision of the fractional second. - * @param tz_minutes is the optional time zone in minutes which can be specified with "WITH TIME ZONE". - * If [tz_minutes] is null, that means the time zone is undefined. + * @param with_time_zone is a boolean to decide whether the time has a time zone. + * True represents 'TIME WITH TIME ZONE', while false represents 'TIME WITHOUT TIME ZONE'. + * @param tz_minutes is the optional time zone in minutes if the time has an explicitly specified time zone. + * The value should be null in case of 'TIME WITHOUT TIME ZONE' or in case that the time zone is not specified for 'TIME WITH TIME ZONE'. */ data class Time( val hour: Int, @@ -1029,6 +1031,7 @@ sealed class DateTimeType : ExprNode() { val second: Int, val nano: Int, val precision: Int, + val with_time_zone: Boolean, val tz_minutes: Int? = null, override val metas: MetaContainer ) : DateTimeType() { diff --git a/lang/src/org/partiql/lang/ast/passes/AstRewriterBase.kt b/lang/src/org/partiql/lang/ast/passes/AstRewriterBase.kt index 35f6837bce..670e6c459e 100644 --- a/lang/src/org/partiql/lang/ast/passes/AstRewriterBase.kt +++ b/lang/src/org/partiql/lang/ast/passes/AstRewriterBase.kt @@ -458,6 +458,7 @@ open class AstRewriterBase : AstRewriter { node.second, node.nano, node.precision, + node.with_time_zone, node.tz_minutes, rewriteMetas(node) ) diff --git a/lang/src/org/partiql/lang/eval/EvaluatingCompiler.kt b/lang/src/org/partiql/lang/eval/EvaluatingCompiler.kt index f1f814e1a2..be3b28fe1a 100644 --- a/lang/src/org/partiql/lang/eval/EvaluatingCompiler.kt +++ b/lang/src/org/partiql/lang/eval/EvaluatingCompiler.kt @@ -28,6 +28,7 @@ import org.partiql.lang.eval.time.Time import org.partiql.lang.eval.visitors.PartiqlAstSanityValidator import org.partiql.lang.syntax.SqlParser import org.partiql.lang.util.* +import org.partiql.lang.util.DEFAULT_TIMEZONE_OFFSET import java.math.* import java.util.* import kotlin.collections.* @@ -1999,9 +2000,10 @@ internal class EvaluatingCompiler( } private fun compileTime(node: DateTimeType.Time) : ThunkEnv { - val (hour, minute, second, nano, precision, tz_minutes, metas) = node + val (hour, minute, second, nano, precision, with_time_zone, tz_minutes, metas) = node return thunkFactory.thunkEnv(metas) { - valueFactory.newTime(Time.of(hour, minute, second, nano, precision, tz_minutes)) + // Add the default time zone if the type 'TIME WITH TIME ZONE' does not have an explicitly specified time zone. + valueFactory.newTime(Time.of(hour, minute, second, nano, precision, if (with_time_zone && tz_minutes == null) DEFAULT_TIMEZONE_OFFSET.totalMinutes else tz_minutes)) } } diff --git a/lang/src/org/partiql/lang/syntax/SqlParser.kt b/lang/src/org/partiql/lang/syntax/SqlParser.kt index b25da01a4a..950e0faebc 100644 --- a/lang/src/org/partiql/lang/syntax/SqlParser.kt +++ b/lang/src/org/partiql/lang/syntax/SqlParser.kt @@ -34,6 +34,7 @@ import java.time.format.DateTimeFormatter.* import java.time.* import java.time.format.DateTimeFormatter import java.time.format.DateTimeParseException +import java.time.temporal.Temporal /** @@ -700,13 +701,19 @@ class SqlParser(private val ion: IonSystem) : Parser { val timeString = token!!.text!! val precision = children[0].token!!.value!!.numberValue().toInt() val time = LocalTime.parse(timeString, DateTimeFormatter.ISO_TIME) - DateTimeType.Time(time.hour, time.minute, time.second, time.nano, precision, null, metas) + DateTimeType.Time(time.hour, time.minute, time.second, time.nano, precision, false, null, metas) } TIME_WITH_TIME_ZONE -> { val timeString = token!!.text!! val precision = children[0].token?.value?.numberValue()?.toInt() - val time = OffsetTime.parse(timeString) - DateTimeType.Time(time.hour, time.minute, time.second, time.nano, precision!!, time.offset.totalSeconds/60, metas) + try { + val time = OffsetTime.parse(timeString) + DateTimeType.Time(time.hour, time.minute, time.second, time.nano, precision!!, true, time.offset.totalSeconds/60, metas) + } catch (e: DateTimeParseException) { + // In case time zone not explicitly specified + val time = LocalTime.parse(timeString) + DateTimeType.Time(time.hour, time.minute, time.second, time.nano, precision!!, true, null, metas) + } } else -> unsupported("Unsupported syntax for $type", PARSE_UNSUPPORTED_SYNTAX) } @@ -2374,10 +2381,10 @@ class SqlParser(private val ion: IonSystem) : Parser { var rem = this - // Parses the time string without the time zone offset. - fun tryLocalTimeParsing(time: String?) { + // Parses the time string with or without the time zone offset. + fun tryTimeParsing(time: String?, formatter: DateTimeFormatter, parse: (String?, DateTimeFormatter) -> Temporal) { try { - LocalTime.parse(time, DateTimeFormatter.ISO_TIME) + parse(time, formatter) } catch (e: DateTimeParseException) { rem.head.err(e.localizedMessage, PARSE_INVALID_TIME_STRING) @@ -2389,7 +2396,7 @@ class SqlParser(private val ion: IonSystem) : Parser { rem = precision.remaining // 2. Check for optional "with time zone" tokens and store the boolean - val (remainingAfterOptionalTimeZone, isTimeZoneSpecified) = rem.checkForOptionalTimeZone() + val (remainingAfterOptionalTimeZone, withTimeZone) = rem.checkForOptionalTimeZone() rem = remainingAfterOptionalTimeZone val timeStringToken = rem.head @@ -2407,35 +2414,23 @@ class SqlParser(private val ion: IonSystem) : Parser { rem.head.err("Invalid format for time string. Expected format is \"TIME [(p)] [WITH TIME ZONE] HH:MM:SS[.ddddd...][+|-HH:MM]\"", PARSE_INVALID_TIME_STRING) } - var newTimeString = timeString - when(isTimeZoneSpecified) { - false -> tryLocalTimeParsing(timeString) - true -> try { - OffsetTime.parse(timeString, DateTimeFormatter.ISO_TIME) - } catch (e: DateTimeParseException) { - // The exception thrown here is because of the invalid time or time zone offset specified in the timestring. - // The valid time zone offsets are in the range of [-18:00 - 18:00] - if (timeWithoutTimeZoneRegex.matches(timeString)) { - // Fall back on parsing a string without a time zone offset only if the offset is not specified. - // Add default timezone offset in that case. - tryLocalTimeParsing(timeString) - newTimeString = timeString + DEFAULT_TIMEZONE_OFFSET.getOffsetHHmm() - } - else { - rem.head.err(e.localizedMessage, PARSE_INVALID_TIME_STRING) - } - } - } + // For time with time zone, if the time zone is not explicitly specified, we still consider it as valid. + // We will add the default time zone to it later in the evaluation phase. + if (!withTimeZone || timeWithoutTimeZoneRegex.matches(timeString)) + tryTimeParsing (timeString, DateTimeFormatter.ISO_TIME, LocalTime::parse) + else + tryTimeParsing (timeString, DateTimeFormatter.ISO_TIME, OffsetTime::parse) + // Extract the precision from the time string representation if the precision is not specified. // For e.g., TIME '23:12:12.12300' should have precision of 5. // The source span here is just the filler value and does not reflect the actual source location of the precision // as it does not exists in case the precision is unspecified. val precisionOfValue = precision.token ?: - Token(LITERAL, ion.newInt(getPrecisionFromTimeString(newTimeString)), timeStringToken.span) + Token(LITERAL, ion.newInt(getPrecisionFromTimeString(timeString)), timeStringToken.span) return ParseNode( - if (isTimeZoneSpecified) TIME_WITH_TIME_ZONE else TIME, - rem.head!!.copy(value = ion.newString(newTimeString)), + if (withTimeZone) TIME_WITH_TIME_ZONE else TIME, + rem.head!!.copy(value = ion.newString(timeString)), listOf(precision.copy(token = precisionOfValue)), rem.tail) } diff --git a/lang/test/org/partiql/lang/syntax/SqlParserDateTimeTests.kt b/lang/test/org/partiql/lang/syntax/SqlParserDateTimeTests.kt index 874515399b..5e08621897 100644 --- a/lang/test/org/partiql/lang/syntax/SqlParserDateTimeTests.kt +++ b/lang/test/org/partiql/lang/syntax/SqlParserDateTimeTests.kt @@ -8,13 +8,10 @@ import org.partiql.lang.domains.id import java.util.* import org.partiql.lang.errors.ErrorCode import org.partiql.lang.errors.Property -import org.partiql.lang.util.DEFAULT_TIMEZONE_OFFSET import org.partiql.lang.util.to class SqlParserDateTimeTests : SqlParserTestBase() { - private val defaultTimeZoneOffset = (DEFAULT_TIMEZONE_OFFSET.totalSeconds / 60).toLong() - data class DateTimeTestCase(val source: String, val skipTest: Boolean = false, val block: PartiqlAst.Builder.() -> PartiqlAst.PartiqlAstNode) private data class Date(val year: Int, val month: Int, val day: Int) @@ -57,140 +54,140 @@ class SqlParserDateTimeTests : SqlParserTestBase() { ) }, DateTimeTestCase("TIME '02:30:59'") { - litTime(timeValue(2, 30, 59, 0, 0, null)) + litTime(timeValue(2, 30, 59, 0, 0, false, null)) }, DateTimeTestCase("TIME (3) '12:59:31'") { - litTime(timeValue(12, 59, 31, 0, 3, null)) + litTime(timeValue(12, 59, 31, 0, 3, false, null)) }, DateTimeTestCase("TIME '23:59:59.9999'") { - litTime(timeValue(23, 59, 59, 999900000, 4, null)) + litTime(timeValue(23, 59, 59, 999900000, 4, false, null)) }, DateTimeTestCase("TIME (7) '23:59:59.123456789'") { - litTime(timeValue(23, 59, 59, 123456789, 7, null)) + litTime(timeValue(23, 59, 59, 123456789, 7, false, null)) }, DateTimeTestCase("TIME (9) '23:59:59.123456789'") { - litTime(timeValue(23, 59, 59, 123456789, 9, null)) + litTime(timeValue(23, 59, 59, 123456789, 9, false, null)) }, DateTimeTestCase("TIME (0) '23:59:59.123456789'") { - litTime(timeValue(23, 59, 59, 123456789, 0, null)) + litTime(timeValue(23, 59, 59, 123456789, 0, false, null)) }, DateTimeTestCase("TIME '02:30:59-05:30'") { - litTime(timeValue(2, 30, 59, 0, 0, null)) + litTime(timeValue(2, 30, 59, 0, 0, false, null)) }, DateTimeTestCase("TIME '02:30:59+05:30'") { - litTime(timeValue(2, 30, 59, 0, 0, null)) + litTime(timeValue(2, 30, 59, 0, 0, false, null)) }, DateTimeTestCase("TIME '02:30:59-14:39'") { - litTime(timeValue(2, 30, 59, 0, 0, null)) + litTime(timeValue(2, 30, 59, 0, 0, false, null)) }, DateTimeTestCase("TIME '02:30:59+00:00'") { - litTime(timeValue(2, 30, 59, 0, 0, null)) + litTime(timeValue(2, 30, 59, 0, 0, false, null)) }, DateTimeTestCase("TIME '02:30:59-00:00'") { - litTime(timeValue(2, 30, 59, 0, 0, null)) + litTime(timeValue(2, 30, 59, 0, 0, false, null)) }, DateTimeTestCase("TIME (3) '12:59:31+10:30'") { - litTime(timeValue(12, 59, 31, 0, 3, null)) + litTime(timeValue(12, 59, 31, 0, 3, false, null)) }, DateTimeTestCase("TIME (0) '00:00:00+00:00'") { - litTime(timeValue(0, 0, 0, 0, 0, null)) + litTime(timeValue(0, 0, 0, 0, 0, false, null)) }, DateTimeTestCase("TIME (0) '00:00:00-00:00'") { - litTime(timeValue(0, 0, 0, 0, 0, null)) + litTime(timeValue(0, 0, 0, 0, 0, false, null)) }, DateTimeTestCase("TIME '23:59:59.9999-11:59'") { - litTime(timeValue(23, 59, 59, 999900000, 4, null)) + litTime(timeValue(23, 59, 59, 999900000, 4, false, null)) }, DateTimeTestCase("TIME '23:59:59.99990-11:59'") { - litTime(timeValue(23, 59, 59, 999900000, 5, null)) + litTime(timeValue(23, 59, 59, 999900000, 5, false, null)) }, DateTimeTestCase("TIME (5) '23:59:59.9999-11:59'") { - litTime(timeValue(23, 59, 59, 999900000, 5, null)) + litTime(timeValue(23, 59, 59, 999900000, 5, false, null)) }, DateTimeTestCase("TIME (7) '23:59:59.123456789+01:00'") { - litTime(timeValue(23, 59, 59, 123456789, 7, null)) + litTime(timeValue(23, 59, 59, 123456789, 7, false, null)) }, DateTimeTestCase("TIME (9) '23:59:59.123456789-14:50'") { - litTime(timeValue(23, 59, 59, 123456789, 9, null)) + litTime(timeValue(23, 59, 59, 123456789, 9, false, null)) }, DateTimeTestCase("TIME (0) '23:59:59.123456789-18:00'") { - litTime(timeValue(23, 59, 59, 123456789, 0, null)) + litTime(timeValue(23, 59, 59, 123456789, 0, false, null)) }, DateTimeTestCase("TIME WITH TIME ZONE '02:30:59'") { - litTime(timeValue(2, 30, 59, 0, 0, defaultTimeZoneOffset)) + litTime(timeValue(2, 30, 59, 0, 0, true, null)) }, DateTimeTestCase("TIME (3) WITH TIME ZONE '12:59:31'") { - litTime(timeValue(12, 59, 31, 0, 3, defaultTimeZoneOffset)) + litTime(timeValue(12, 59, 31, 0, 3, true, null)) }, DateTimeTestCase("TIME WITH TIME ZONE '23:59:59.9999'") { - litTime(timeValue(23, 59, 59, 999900000, 4, defaultTimeZoneOffset)) + litTime(timeValue(23, 59, 59, 999900000, 4, true, null)) }, DateTimeTestCase("TIME (7) WITH TIME ZONE '23:59:59.123456789'") { - litTime(timeValue(23, 59, 59, 123456789, 7, defaultTimeZoneOffset)) + litTime(timeValue(23, 59, 59, 123456789, 7, true, null)) }, DateTimeTestCase("TIME (9) WITH TIME ZONE '23:59:59.123456789'") { - litTime(timeValue(23, 59, 59, 123456789, 9, defaultTimeZoneOffset)) + litTime(timeValue(23, 59, 59, 123456789, 9, true, null)) }, DateTimeTestCase("TIME (0) WITH TIME ZONE '23:59:59.123456789'") { - litTime(timeValue(23, 59, 59, 123456789, 0, defaultTimeZoneOffset)) + litTime(timeValue(23, 59, 59, 123456789, 0, true, null)) }, DateTimeTestCase("TIME (0) WITH TIME ZONE '00:00:00+00:00'") { - litTime(timeValue(0, 0, 0, 0, 0, 0)) + litTime(timeValue(0, 0, 0, 0, 0, true, 0)) }, DateTimeTestCase("TIME (0) WITH TIME ZONE '00:00:00.0000-00:00'") { - litTime(timeValue(0, 0, 0, 0, 0, 0)) + litTime(timeValue(0, 0, 0, 0, 0, true, 0)) }, DateTimeTestCase("TIME WITH TIME ZONE '02:30:59.1234500-05:30'") { - litTime(timeValue(2, 30, 59, 123450000, 7, -330)) + litTime(timeValue(2, 30, 59, 123450000, 7, true, -330)) }, DateTimeTestCase("TIME WITH TIME ZONE '02:30:59+05:30'") { - litTime(timeValue(2, 30, 59, 0, 0, 330)) + litTime(timeValue(2, 30, 59, 0, 0, true, 330)) }, DateTimeTestCase("TIME WITH TIME ZONE '02:30:59-14:39'") { - litTime(timeValue(2, 30, 59, 0, 0, -879)) + litTime(timeValue(2, 30, 59, 0, 0, true, -879)) }, DateTimeTestCase("TIME WITH TIME ZONE '23:59:59.9999-11:59'") { - litTime(timeValue(23, 59, 59, 999900000, 4, -719)) + litTime(timeValue(23, 59, 59, 999900000, 4, true, -719)) }, DateTimeTestCase("TIME WITH TIME ZONE '23:59:59.99990-11:59'") { - litTime(timeValue(23, 59, 59, 999900000, 5, -719)) + litTime(timeValue(23, 59, 59, 999900000, 5, true, -719)) }, DateTimeTestCase("TIME (5) WITH TIME ZONE '23:59:59.9999-11:59'") { - litTime(timeValue(23, 59, 59, 999900000, 5, -719)) + litTime(timeValue(23, 59, 59, 999900000, 5, true, -719)) }, DateTimeTestCase("TIME (7) WITH TIME ZONE '23:59:59.123456789+01:00'") { - litTime(timeValue(23, 59, 59, 123456789, 7, 60)) + litTime(timeValue(23, 59, 59, 123456789, 7, true, 60)) }, DateTimeTestCase("TIME (9) WITH TIME ZONE '23:59:59.123456789-14:50'") { - litTime(timeValue(23, 59, 59, 123456789, 9, -890)) + litTime(timeValue(23, 59, 59, 123456789, 9, true, -890)) }, DateTimeTestCase("TIME (0) WITH TIME ZONE '23:59:59.123456789-18:00'") { - litTime(timeValue(23, 59, 59, 123456789, 0, -1080)) + litTime(timeValue(23, 59, 59, 123456789, 0, true, -1080)) }, // TODO: These tests should pass. Check https://github.com/partiql/partiql-lang-kotlin/issues/395 DateTimeTestCase("TIME '23:59:59.1234567890'", skipTest = true) { - litTime(timeValue(23, 59, 59, 123456789, 9, null)) + litTime(timeValue(23, 59, 59, 123456789, 9, false, null)) }, DateTimeTestCase("TIME '23:59:59.1234567899'", skipTest = true) { - litTime(timeValue(23, 59, 59, 123456790, 9, null)) + litTime(timeValue(23, 59, 59, 123456790, 9, false, null)) }, DateTimeTestCase("TIME '23:59:59.1234567890+18:00'", skipTest = true) { - litTime(timeValue(23, 59, 59, 123456789, 9, null)) + litTime(timeValue(23, 59, 59, 123456789, 9, false, null)) }, DateTimeTestCase("TIME '23:59:59.1234567899+18:00'", skipTest = true) { - litTime(timeValue(23, 59, 59, 123456790, 9, null)) + litTime(timeValue(23, 59, 59, 123456790, 9, false, null)) }, DateTimeTestCase("TIME WITH TIME ZONE '23:59:59.1234567890'", skipTest = true) { - litTime(timeValue(23, 59, 59, 123456789, 9, defaultTimeZoneOffset)) + litTime(timeValue(23, 59, 59, 123456789, 9, true, null)) }, DateTimeTestCase("TIME WITH TIME ZONE '23:59:59.1234567899'", skipTest = true) { - litTime(timeValue(23, 59, 59, 123456790, 9, defaultTimeZoneOffset)) + litTime(timeValue(23, 59, 59, 123456790, 9, true, null)) }, DateTimeTestCase("TIME WITH TIME ZONE '23:59:59.1234567890+18:00'", skipTest = true) { - litTime(timeValue(23, 59, 59, 123456789, 9, 1080)) + litTime(timeValue(23, 59, 59, 123456789, 9, true, 1080)) }, DateTimeTestCase("TIME WITH TIME ZONE '23:59:59.1234567899+18:00'", skipTest = true) { - litTime(timeValue(23, 59, 59, 123456790, 9, 1080)) + litTime(timeValue(23, 59, 59, 123456790, 9, true, 1080)) } ) From ea06c692cf5ce030be661b6b0eac391798a7f68b Mon Sep 17 00:00:00 2001 From: Ziqi Li Date: Wed, 22 Sep 2021 17:45:48 -0700 Subject: [PATCH 02/29] Remove unnecessary files --- .../src/java/org/partiql/examples/Test.java | 29 ------------------- 1 file changed, 29 deletions(-) delete mode 100644 examples/src/java/org/partiql/examples/Test.java diff --git a/examples/src/java/org/partiql/examples/Test.java b/examples/src/java/org/partiql/examples/Test.java deleted file mode 100644 index 3f795f77ed..0000000000 --- a/examples/src/java/org/partiql/examples/Test.java +++ /dev/null @@ -1,29 +0,0 @@ -package org.partiql.examples; - -import com.amazon.ion.IonSystem; -import com.amazon.ion.system.IonSystemBuilder; -import org.partiql.lang.CompilerPipeline; -import org.partiql.lang.eval.EvaluationSession; -import org.partiql.lang.eval.ExprValue; -import org.partiql.lang.eval.Expression; - -import java.time.LocalTime; -import java.time.OffsetTime; -import java.time.format.DateTimeFormatter; - -public class Test { - public static void main (String[] args){ -// final IonSystem ion = IonSystemBuilder.standard().build(); -// final CompilerPipeline pipeline = CompilerPipeline.standard(ion); -// final EvaluationSession session = EvaluationSession.standard(); -// final String query = "1 + 1"; -// Expression e = pipeline.compile(query); -// ExprValue result = e.eval(session); -// -// System.out.println(result); - - //OffsetTime time1 = OffsetTime.parse("10:15:30", DateTimeFormatter.ISO_TIME); - LocalTime time2 = LocalTime.parse("10:15:30-05:30", DateTimeFormatter.ISO_TIME); - //System.out.println (time1.getOffset()); - } -} From 9728308288b64583cf181234fad62b081b1b74e0 Mon Sep 17 00:00:00 2001 From: Ziqi Li Date: Wed, 22 Sep 2021 17:53:13 -0700 Subject: [PATCH 03/29] Modified comments --- lang/src/org/partiql/lang/ast/ast.kt | 4 ++-- lang/src/org/partiql/lang/eval/EvaluatingCompiler.kt | 2 +- lang/src/org/partiql/lang/syntax/SqlParser.kt | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lang/src/org/partiql/lang/ast/ast.kt b/lang/src/org/partiql/lang/ast/ast.kt index a0dcb32d08..ddc8428bef 100644 --- a/lang/src/org/partiql/lang/ast/ast.kt +++ b/lang/src/org/partiql/lang/ast/ast.kt @@ -1021,9 +1021,9 @@ sealed class DateTimeType : ExprNode() { * @param nano represents the fractional part of the second up to the nanoseconds' precision. * @param precision is an optional parameter which, if specified, represents the precision of the fractional second. * @param with_time_zone is a boolean to decide whether the time has a time zone. - * True represents 'TIME WITH TIME ZONE', while false represents 'TIME WITHOUT TIME ZONE'. + * True represents "TIME WITH TIME ZONE", while false represents "TIME WITHOUT TIME ZONE". * @param tz_minutes is the optional time zone in minutes if the time has an explicitly specified time zone. - * The value should be null in case of 'TIME WITHOUT TIME ZONE' or in case that the time zone is not specified for 'TIME WITH TIME ZONE'. + * The value should be null in case of "TIME WITHOUT TIME ZONE" or in case that the time zone is not specified for 'TIME WITH TIME ZONE'. */ data class Time( val hour: Int, diff --git a/lang/src/org/partiql/lang/eval/EvaluatingCompiler.kt b/lang/src/org/partiql/lang/eval/EvaluatingCompiler.kt index be3b28fe1a..c3c9a1991e 100644 --- a/lang/src/org/partiql/lang/eval/EvaluatingCompiler.kt +++ b/lang/src/org/partiql/lang/eval/EvaluatingCompiler.kt @@ -2002,7 +2002,7 @@ internal class EvaluatingCompiler( private fun compileTime(node: DateTimeType.Time) : ThunkEnv { val (hour, minute, second, nano, precision, with_time_zone, tz_minutes, metas) = node return thunkFactory.thunkEnv(metas) { - // Add the default time zone if the type 'TIME WITH TIME ZONE' does not have an explicitly specified time zone. + // Add the default time zone if the type "TIME WITH TIME ZONE" does not have an explicitly specified time zone. valueFactory.newTime(Time.of(hour, minute, second, nano, precision, if (with_time_zone && tz_minutes == null) DEFAULT_TIMEZONE_OFFSET.totalMinutes else tz_minutes)) } } diff --git a/lang/src/org/partiql/lang/syntax/SqlParser.kt b/lang/src/org/partiql/lang/syntax/SqlParser.kt index 950e0faebc..1acea81baa 100644 --- a/lang/src/org/partiql/lang/syntax/SqlParser.kt +++ b/lang/src/org/partiql/lang/syntax/SqlParser.kt @@ -2414,7 +2414,7 @@ class SqlParser(private val ion: IonSystem) : Parser { rem.head.err("Invalid format for time string. Expected format is \"TIME [(p)] [WITH TIME ZONE] HH:MM:SS[.ddddd...][+|-HH:MM]\"", PARSE_INVALID_TIME_STRING) } - // For time with time zone, if the time zone is not explicitly specified, we still consider it as valid. + // For "TIME WITH TIME ZONE", if the time zone is not explicitly specified, we still consider it as valid. // We will add the default time zone to it later in the evaluation phase. if (!withTimeZone || timeWithoutTimeZoneRegex.matches(timeString)) tryTimeParsing (timeString, DateTimeFormatter.ISO_TIME, LocalTime::parse) From 49d23b1066ba516e8b9d45ebed6d8fbf58369c03 Mon Sep 17 00:00:00 2001 From: Ziqi Li Date: Sun, 26 Sep 2021 22:30:39 -0700 Subject: [PATCH 04/29] Fix issue 410 --- .../src/java/org/partiql/examples/Test.java | 24 +++++++++++++++++++ .../partiql/lang/eval/EvaluatingCompiler.kt | 6 ++--- .../partiql/lang/eval/EvaluationSession.kt | 13 ++++++++-- .../partiql/lang/eval/time/TimeExtensions.kt | 8 ------- 4 files changed, 38 insertions(+), 13 deletions(-) create mode 100644 examples/src/java/org/partiql/examples/Test.java diff --git a/examples/src/java/org/partiql/examples/Test.java b/examples/src/java/org/partiql/examples/Test.java new file mode 100644 index 0000000000..4a3e0507d8 --- /dev/null +++ b/examples/src/java/org/partiql/examples/Test.java @@ -0,0 +1,24 @@ +package org.partiql.examples; + +import com.amazon.ion.IonSystem; +import com.amazon.ion.Timestamp; +import com.amazon.ion.system.IonSystemBuilder; +import org.partiql.lang.CompilerPipeline; +import org.partiql.lang.eval.Bindings; +import org.partiql.lang.eval.EvaluationSession; +import org.partiql.lang.eval.ExprValue; +import org.partiql.lang.eval.Expression; + +import java.util.TimeZone; + +public class Test { + public static void main (String[] args){ + final IonSystem ion = IonSystemBuilder.standard().build(); + final CompilerPipeline pipeline = CompilerPipeline.standard(ion); + final Expression selectAndFilter = pipeline.compile( + "SELECT ? as b1, f.bar FROM foo f WHERE f.bar = ?"); + final EvaluationSession session = EvaluationSession.standard(); + + System.out.println(Timestamp.nowZ()); + } +} diff --git a/lang/src/org/partiql/lang/eval/EvaluatingCompiler.kt b/lang/src/org/partiql/lang/eval/EvaluatingCompiler.kt index c3c9a1991e..e9847f9d42 100644 --- a/lang/src/org/partiql/lang/eval/EvaluatingCompiler.kt +++ b/lang/src/org/partiql/lang/eval/EvaluatingCompiler.kt @@ -28,8 +28,8 @@ import org.partiql.lang.eval.time.Time import org.partiql.lang.eval.visitors.PartiqlAstSanityValidator import org.partiql.lang.syntax.SqlParser import org.partiql.lang.util.* -import org.partiql.lang.util.DEFAULT_TIMEZONE_OFFSET import java.math.* +import java.time.ZoneOffset import java.util.* import kotlin.collections.* @@ -1999,11 +1999,11 @@ internal class EvaluatingCompiler( return thunkFactory.thunkEnv(metas) { value } } - private fun compileTime(node: DateTimeType.Time) : ThunkEnv { + private fun compileTime(node: DateTimeType.Time, defaultTimezoneOffset: ZoneOffset) : ThunkEnv { val (hour, minute, second, nano, precision, with_time_zone, tz_minutes, metas) = node return thunkFactory.thunkEnv(metas) { // Add the default time zone if the type "TIME WITH TIME ZONE" does not have an explicitly specified time zone. - valueFactory.newTime(Time.of(hour, minute, second, nano, precision, if (with_time_zone && tz_minutes == null) DEFAULT_TIMEZONE_OFFSET.totalMinutes else tz_minutes)) + valueFactory.newTime(Time.of(hour, minute, second, nano, precision, if (with_time_zone && tz_minutes == null) defaultTimezoneOffset.totalMinutes else tz_minutes)) } } diff --git a/lang/src/org/partiql/lang/eval/EvaluationSession.kt b/lang/src/org/partiql/lang/eval/EvaluationSession.kt index e9406d3151..2e85b096c3 100644 --- a/lang/src/org/partiql/lang/eval/EvaluationSession.kt +++ b/lang/src/org/partiql/lang/eval/EvaluationSession.kt @@ -15,6 +15,7 @@ package org.partiql.lang.eval import com.amazon.ion.* +import java.time.ZoneOffset /** * Evaluation Session. Holds user defined constants used during evaluation. Each value has a default value that can @@ -26,7 +27,8 @@ import com.amazon.ion.* */ class EvaluationSession private constructor(val globals: Bindings, val parameters: List, - val now: Timestamp) { + val now: Timestamp, + val defaultTimezoneOffest: ZoneOffset) { companion object { /** * Java style builder to construct a new [EvaluationSession]. Uses the default value for any non specified field @@ -68,8 +70,15 @@ class EvaluationSession private constructor(val globals: Bindings, return this } + private var defaultTimezoneOffest: ZoneOffset = ZoneOffset.UTC + fun defaultTimezoneOffset(value: ZoneOffset): Builder { + defaultTimezoneOffest = value + return this + } + fun build(): EvaluationSession = EvaluationSession(now = now ?: Timestamp.nowZ(), parameters = parameters, - globals = globals) + globals = globals, + defaultTimezoneOffest = defaultTimezoneOffest) } } diff --git a/lang/src/org/partiql/lang/eval/time/TimeExtensions.kt b/lang/src/org/partiql/lang/eval/time/TimeExtensions.kt index 865d1587f6..788ea58801 100644 --- a/lang/src/org/partiql/lang/eval/time/TimeExtensions.kt +++ b/lang/src/org/partiql/lang/eval/time/TimeExtensions.kt @@ -18,14 +18,6 @@ internal val genericTimeRegex = Regex("\\d\\d:\\d\\d:\\d\\d(\\.\\d*)?([+|-]\\d\\ */ internal val DATE_PATTERN_REGEX = Regex("\\d\\d\\d\\d-\\d\\d-\\d\\d") -/** - * If the default timezone offset is not provided with [CompileOptions], it defaults to [ZoneOffset.UTC]. - * (The option to specify default timezone offset will be available once [#410](https://github.com/partiql/partiql-lang-kotlin/issues/410) is resolved) - * - * If timezone offset is not specified explicitly (when using `TIME WITH TIME ZONE`), the default time zone offset is used. - */ -internal val DEFAULT_TIMEZONE_OFFSET = ZoneOffset.UTC - /** * Returns the string representation of the [ZoneOffset] in HH:mm format. */ From 82147af774b27586c2ba54b752cb8367609863b0 Mon Sep 17 00:00:00 2001 From: Ziqi Li Date: Tue, 28 Sep 2021 09:57:01 -0700 Subject: [PATCH 05/29] Provide an option in EvaluationSession to configure default timezone. --- .../src/java/org/partiql/examples/Test.java | 24 - .../partiql/lang/eval/EvaluatingCompiler.kt | 13 +- .../partiql/lang/eval/EvaluationSession.kt | 8 +- .../partiql/lang/eval/ExprValueExtensions.kt | 7 +- .../lang/eval/EvaluatingCompilerCastTest.kt | 1556 +++++++++-------- .../eval/EvaluatingCompilerDateTimeTests.kt | 12 +- .../lang/eval/EvaluationSessionTest.kt | 23 +- 7 files changed, 903 insertions(+), 740 deletions(-) delete mode 100644 examples/src/java/org/partiql/examples/Test.java diff --git a/examples/src/java/org/partiql/examples/Test.java b/examples/src/java/org/partiql/examples/Test.java deleted file mode 100644 index 4a3e0507d8..0000000000 --- a/examples/src/java/org/partiql/examples/Test.java +++ /dev/null @@ -1,24 +0,0 @@ -package org.partiql.examples; - -import com.amazon.ion.IonSystem; -import com.amazon.ion.Timestamp; -import com.amazon.ion.system.IonSystemBuilder; -import org.partiql.lang.CompilerPipeline; -import org.partiql.lang.eval.Bindings; -import org.partiql.lang.eval.EvaluationSession; -import org.partiql.lang.eval.ExprValue; -import org.partiql.lang.eval.Expression; - -import java.util.TimeZone; - -public class Test { - public static void main (String[] args){ - final IonSystem ion = IonSystemBuilder.standard().build(); - final CompilerPipeline pipeline = CompilerPipeline.standard(ion); - final Expression selectAndFilter = pipeline.compile( - "SELECT ? as b1, f.bar FROM foo f WHERE f.bar = ?"); - final EvaluationSession session = EvaluationSession.standard(); - - System.out.println(Timestamp.nowZ()); - } -} diff --git a/lang/src/org/partiql/lang/eval/EvaluatingCompiler.kt b/lang/src/org/partiql/lang/eval/EvaluatingCompiler.kt index 2d35ac6f9d..8a9bcb6636 100644 --- a/lang/src/org/partiql/lang/eval/EvaluatingCompiler.kt +++ b/lang/src/org/partiql/lang/eval/EvaluatingCompiler.kt @@ -28,7 +28,6 @@ import org.partiql.lang.eval.time.Time import org.partiql.lang.eval.visitors.PartiqlAstSanityValidator import org.partiql.lang.syntax.SqlParser import org.partiql.lang.util.* -import org.partiql.lang.util.DEFAULT_TIMEZONE_OFFSET import java.math.* import java.time.ZoneOffset import java.util.* @@ -812,7 +811,7 @@ internal class EvaluatingCompiler( val locationMeta = metas.sourceLocationMeta thunkFactory.thunkEnv(metas) { env -> val valueToCast = expThunk(env) - valueToCast.cast(dataType, valueFactory, locationMeta) + valueToCast.cast(dataType, valueFactory, locationMeta, env) } } } @@ -2000,13 +1999,6 @@ internal class EvaluatingCompiler( return thunkFactory.thunkEnv(metas) { value } } -<<<<<<< HEAD - private fun compileTime(node: DateTimeType.Time, defaultTimezoneOffset: ZoneOffset) : ThunkEnv { - val (hour, minute, second, nano, precision, with_time_zone, tz_minutes, metas) = node - return thunkFactory.thunkEnv(metas) { - // Add the default time zone if the type "TIME WITH TIME ZONE" does not have an explicitly specified time zone. - valueFactory.newTime(Time.of(hour, minute, second, nano, precision, if (with_time_zone && tz_minutes == null) defaultTimezoneOffset.totalMinutes else tz_minutes)) -======= private fun compileTime(node: DateTimeType.Time) : ThunkEnv { val (hour, minute, second, nano, precision, with_time_zone, tz_minutes, metas) = node return thunkFactory.thunkEnv(metas) { @@ -2018,10 +2010,9 @@ internal class EvaluatingCompiler( second, nano, precision, - if (with_time_zone && tz_minutes == null) DEFAULT_TIMEZONE_OFFSET.totalMinutes else tz_minutes + if (with_time_zone && tz_minutes == null) it.session.defaultTimezoneOffset.totalMinutes else tz_minutes ) ) ->>>>>>> 630139666d83c3fcfcd51adbeca9740e7276ee39 } } diff --git a/lang/src/org/partiql/lang/eval/EvaluationSession.kt b/lang/src/org/partiql/lang/eval/EvaluationSession.kt index 2e85b096c3..f98dee46ea 100644 --- a/lang/src/org/partiql/lang/eval/EvaluationSession.kt +++ b/lang/src/org/partiql/lang/eval/EvaluationSession.kt @@ -28,7 +28,7 @@ import java.time.ZoneOffset class EvaluationSession private constructor(val globals: Bindings, val parameters: List, val now: Timestamp, - val defaultTimezoneOffest: ZoneOffset) { + val defaultTimezoneOffset: ZoneOffset) { companion object { /** * Java style builder to construct a new [EvaluationSession]. Uses the default value for any non specified field @@ -70,15 +70,15 @@ class EvaluationSession private constructor(val globals: Bindings, return this } - private var defaultTimezoneOffest: ZoneOffset = ZoneOffset.UTC + private var defaultTimezoneOffset: ZoneOffset = ZoneOffset.UTC fun defaultTimezoneOffset(value: ZoneOffset): Builder { - defaultTimezoneOffest = value + defaultTimezoneOffset = value return this } fun build(): EvaluationSession = EvaluationSession(now = now ?: Timestamp.nowZ(), parameters = parameters, globals = globals, - defaultTimezoneOffest = defaultTimezoneOffest) + defaultTimezoneOffset = defaultTimezoneOffset) } } diff --git a/lang/src/org/partiql/lang/eval/ExprValueExtensions.kt b/lang/src/org/partiql/lang/eval/ExprValueExtensions.kt index 48037f4cd2..c04a3d3847 100644 --- a/lang/src/org/partiql/lang/eval/ExprValueExtensions.kt +++ b/lang/src/org/partiql/lang/eval/ExprValueExtensions.kt @@ -227,7 +227,8 @@ private val genericTimeRegex = Regex("\\d\\d:\\d\\d:\\d\\d(\\.\\d*)?([+|-]\\d\\d fun ExprValue.cast( targetDataType: DataType, valueFactory: ExprValueFactory, - locationMeta: SourceLocationMeta? + locationMeta: SourceLocationMeta?, + env: Environment ): ExprValue { val targetSqlDataType = targetDataType.sqlDataType @@ -362,7 +363,7 @@ fun ExprValue.cast( type == TIME -> { val time = timeValue() val timeZoneOffset = when (targetSqlDataType) { - SqlDataType.TIME_WITH_TIME_ZONE -> time.zoneOffset?: DEFAULT_TIMEZONE_OFFSET + SqlDataType.TIME_WITH_TIME_ZONE -> time.zoneOffset?: env.session.defaultTimezoneOffset else -> null } return valueFactory.newTime( @@ -405,7 +406,7 @@ fun ExprValue.cast( // Note that the [genericTimeRegex] has a group to extract the zone offset. val zoneOffsetString = matcher.group(2) - val zoneOffset = zoneOffsetString?.let { ZoneOffset.of(it) } ?: DEFAULT_TIMEZONE_OFFSET + val zoneOffset = zoneOffsetString?.let { ZoneOffset.of(it) } ?: env.session.defaultTimezoneOffset return valueFactory.newTime( Time.of( diff --git a/lang/test/org/partiql/lang/eval/EvaluatingCompilerCastTest.kt b/lang/test/org/partiql/lang/eval/EvaluatingCompilerCastTest.kt index 032f429097..cf85cdba58 100644 --- a/lang/test/org/partiql/lang/eval/EvaluatingCompilerCastTest.kt +++ b/lang/test/org/partiql/lang/eval/EvaluatingCompilerCastTest.kt @@ -21,14 +21,15 @@ import junitparams.Parameters import junitparams.naming.TestCaseName import org.junit.Test import org.partiql.lang.syntax.ParserException -import org.partiql.lang.util.DEFAULT_TIMEZONE_OFFSET import org.partiql.lang.util.getOffsetHHmm +import java.time.ZoneOffset class EvaluatingCompilerCastTest : EvaluatorTestBase() { private val allTypeNames = ExprValueType.values().flatMap { it.sqlTextNames } // cast as NULL is tested by castMissingAsNull fun parametersForCastMissing() = allTypeNames - "NULL" + @Test @Parameters @TestCaseName("CAST(MISSING AS {0})") @@ -47,6 +48,7 @@ class EvaluatingCompilerCastTest : EvaluatorTestBase() { // cast as MISSING is tested by castNullAsMissing fun parametersForCastNull() = allTypeNames - "MISSING" + @Test @Parameters @TestCaseName("CAST(NULL AS {0})") @@ -69,7 +71,13 @@ class EvaluatingCompilerCastTest : EvaluatorTestBase() { * @param expectedErrorCode The expected error code of any [EvaluationException] or `null` when no exception * is to be expected. */ - data class CastCase(val source: String, val type: String, val expected: String?, val expectedErrorCode: ErrorCode?) { + data class CastCase( + val source: String, + val type: String, + val expected: String?, + val expectedErrorCode: ErrorCode?, + val session: EvaluationSession = EvaluationSession.standard() + ) { val expression = "CAST($source AS $type)" override fun toString(): String = expression } @@ -84,10 +92,17 @@ class EvaluatingCompilerCastTest : EvaluatorTestBase() { */ fun case(source: String, type: String, expected: String) = CastCase(source, type, expected, null) + /** + * Function to create explicit CAST( to ) CastCase with EvaluationSession. + */ + fun case(source: String, type: String, expected: String, session: EvaluationSession) = + CastCase(source, type, expected, null, session) + /** * Function to create explicit CAST( to ) CastCase throwing error. */ - fun case(source: String, type: String, expectedErrorCode: ErrorCode) = CastCase(source, type, null, expectedErrorCode) + fun case(source: String, type: String, expectedErrorCode: ErrorCode) = + CastCase(source, type, null, expectedErrorCode) /** Partial application of the source expression and the expected error code without type. */ fun case(source: String, expectedErrorCode: ErrorCode): (String) -> CastCase = { @@ -96,675 +111,693 @@ class EvaluatingCompilerCastTest : EvaluatorTestBase() { /** For each partial case, apply each of the given types to generate a concrete cast case. */ fun List<(String) -> CastCase>.types(types: List): List = - this.flatMap { partial -> types.map { type -> partial(type) } } + this.flatMap { partial -> types.map { type -> partial(type) } } fun parametersForCast() = + listOf( + listOf( + // booleans + case("TRUE AND FALSE", "false"), + case("`true`", "true"), + // numbers + case("5", "true"), + case("`0e0`", "false"), + case("1.1", "true"), + // timestamp + case("`2007-10-10T`", EVALUATOR_INVALID_CAST), + // text + case("'hello'", EVALUATOR_CAST_FAILED), + case("'TrUe'", "true"), + case("""`"FALSE"`""", "false"), + case("""`'true'`""", "true"), + // lob + case("""`{{""}}`""", EVALUATOR_INVALID_CAST), + case("""`{{"goodbye"}}`""", EVALUATOR_INVALID_CAST), + case("""`{{"false"}}`""", EVALUATOR_INVALID_CAST), + case("""`{{"true"}}`""", EVALUATOR_INVALID_CAST), + case("`{{}}`", EVALUATOR_INVALID_CAST), + case("`{{Z29vZGJ5ZQ==}}`", EVALUATOR_INVALID_CAST), // goodbye + case("`{{ZmFsc2U=}}`", EVALUATOR_INVALID_CAST), // false + case("`{{dHJ1ZQ==}}`", EVALUATOR_INVALID_CAST), // true + // list + case("`[]`", EVALUATOR_INVALID_CAST), + case("`[true]`", EVALUATOR_INVALID_CAST), + case("`[false]`", EVALUATOR_INVALID_CAST), + case("`[true, false]`", EVALUATOR_INVALID_CAST), + // sexp + case("`()`", EVALUATOR_INVALID_CAST), + case("`(true)`", EVALUATOR_INVALID_CAST), + case("`(false)`", EVALUATOR_INVALID_CAST), + // struct + case("`{}`", EVALUATOR_INVALID_CAST), + case("{}", EVALUATOR_INVALID_CAST), + case("`{a:true}`", EVALUATOR_INVALID_CAST), + case("{'b':true}", EVALUATOR_INVALID_CAST), + // bag + case("<<>>", EVALUATOR_INVALID_CAST), + case("<>", EVALUATOR_INVALID_CAST), + case("<>", EVALUATOR_INVALID_CAST) + ).types(BOOL.sqlTextNames), + listOf( + // booleans + case("TRUE AND FALSE", "0"), + case("`true`", "1"), + // numbers + case("5", "5"), + case(" 5 ", "5"), + case("`0e0`", "0"), + case("1.1", "1"), + case("1.9", "1"), + case("-20.1", "-20"), + case("-20.9", "-20"), + // timestamp + case("`2007-10-10T`", EVALUATOR_INVALID_CAST), + // text + case("'hello'", EVALUATOR_CAST_FAILED), + case("'1234A'", EVALUATOR_CAST_FAILED), // Invalid ION value + case("'20'", "20"), + case("'020'", "20"), + case("'+20'", "20"), + case("'+020'", "20"), + case("'-20'", "-20"), + case("'-020'", "-20"), + case("'0'", "0"), + case("'00'", "0"), + case("'+0'", "0"), + case("'+00'", "0"), + case("'-0'", "0"), + case("'-00'", "0"), + case("'0xA'", "10"), + case("'0XA'", "10"), + case("'0x0A'", "10"), + case("'+0xA'", "10"), + case("'+0x0A'", "10"), + case("'-0xA'", "-10"), + case("'-0x0A'", "-10"), + case("'0b10'", "2"), + case("'0B10'", "2"), + case("'0b010'", "2"), + case("'+0b10'", "2"), + case("'+0b010'", "2"), + case("'-0b10'", "-2"), + case("'-0b010'", "-2"), + case("""`"1000"`""", "1000"), + case("""`'2e100'`""", EVALUATOR_CAST_FAILED), + case("""`'2d100'`""", EVALUATOR_CAST_FAILED), + case("'00xA'", EVALUATOR_CAST_FAILED), + case("'00b10'", EVALUATOR_CAST_FAILED), + // lob + case("""`{{""}}`""", EVALUATOR_INVALID_CAST), + case("""`{{"0"}}`""", EVALUATOR_INVALID_CAST), + case("""`{{"1.0"}}`""", EVALUATOR_INVALID_CAST), + case("""`{{"2e10"}}`""", EVALUATOR_INVALID_CAST), + case("`{{}}`", EVALUATOR_INVALID_CAST), + case("`{{MA==}}`", EVALUATOR_INVALID_CAST), // 0 + case("`{{MS4w}}`", EVALUATOR_INVALID_CAST), // 1.0 + case("`{{MmUxMA==}}`", EVALUATOR_INVALID_CAST), // 2e10 + // list + case("`[]`", EVALUATOR_INVALID_CAST), + case("`[1]`", EVALUATOR_INVALID_CAST), + case("`[-2, 0]`", EVALUATOR_INVALID_CAST), + // sexp + case("`()`", EVALUATOR_INVALID_CAST), + case("`(1)`", EVALUATOR_INVALID_CAST), + case("`(0)`", EVALUATOR_INVALID_CAST), + // struct + case("`{}`", EVALUATOR_INVALID_CAST), + case("{}", EVALUATOR_INVALID_CAST), + case("`{a:12}`", EVALUATOR_INVALID_CAST), + case("{'b':-4}", EVALUATOR_INVALID_CAST), + // bag + case("<<>>", EVALUATOR_INVALID_CAST), + case("<<14>>", EVALUATOR_INVALID_CAST), + case("<<20>>", EVALUATOR_INVALID_CAST) + ).types(INT.sqlTextNames), + listOf( + // booleans + case("TRUE AND FALSE", "0e0"), + case("`true`", "1e0"), + // numbers + case("5", "5e0"), + case(" 5 ", "5e0"), + case("`0e0`", "0e0"), + case("1.1", "1.1e0"), + case("-20.1", "-20.1e0"), + // timestamp + case("`2007-10-10T`", EVALUATOR_INVALID_CAST), + // text + case("'hello'", EVALUATOR_CAST_FAILED), + case("'-20'", "-20e0"), + case("""`"1000"`""", "1000e0"), + case("""`'2e100'`""", "2e100"), + case("""`'2d100'`""", EVALUATOR_CAST_FAILED), + // lob + case("""`{{""}}`""", EVALUATOR_INVALID_CAST), + case("""`{{"0"}}`""", EVALUATOR_INVALID_CAST), + case("""`{{"1.0"}}`""", EVALUATOR_INVALID_CAST), + case("""`{{"2e10"}}`""", EVALUATOR_INVALID_CAST), + case("`{{}}`", EVALUATOR_INVALID_CAST), + case("`{{MA==}}`", EVALUATOR_INVALID_CAST), // 0 + case("`{{MS4w}}`", EVALUATOR_INVALID_CAST), // 1.0 + case("`{{MmUxMA==}}`", EVALUATOR_INVALID_CAST), // 2e10 + // list + case("`[]`", EVALUATOR_INVALID_CAST), + case("`[1e0]`", EVALUATOR_INVALID_CAST), + case("`[-2e0, 0e0]`", EVALUATOR_INVALID_CAST), + // sexp + case("`()`", EVALUATOR_INVALID_CAST), + case("`(1e0)`", EVALUATOR_INVALID_CAST), + case("`(0e0)`", EVALUATOR_INVALID_CAST), + // struct + case("`{}`", EVALUATOR_INVALID_CAST), + case("{}", EVALUATOR_INVALID_CAST), + case("`{a:12e0}`", EVALUATOR_INVALID_CAST), + case("{'b':`-4e0`}", EVALUATOR_INVALID_CAST), + // bag + case("<<>>", EVALUATOR_INVALID_CAST), + case("<<`14e0`>>", EVALUATOR_INVALID_CAST), + case("<<`20e0`>>", EVALUATOR_INVALID_CAST) + ).types(FLOAT.sqlTextNames), + listOf( + // booleans + case("TRUE AND FALSE", "0d0"), + case("`true`", "1d0"), + // numbers + case("5", "5d0"), + case("5 ", "5d0"), + case("`0e0`", "0."), // TODO formalize this behavior + case("`1e0`", "1."), // TODO formalize this behavior + case("1.1", "1.1d0"), + case("-20.1", "-20.1d0"), + // timestamp + case("`2007-10-10T`", EVALUATOR_INVALID_CAST), + // text + case("'hello'", EVALUATOR_CAST_FAILED), + case("'-20'", "-20d0"), + case("""`"1000"`""", "1000d0"), + case("""`'2e100'`""", "2d100"), + case("""`'2d100'`""", EVALUATOR_CAST_FAILED), + // lob + case("""`{{""}}`""", EVALUATOR_INVALID_CAST), + case("""`{{"0"}}`""", EVALUATOR_INVALID_CAST), + case("""`{{"1.0"}}`""", EVALUATOR_INVALID_CAST), + case("""`{{"2e10"}}`""", EVALUATOR_INVALID_CAST), + case("`{{}}`", EVALUATOR_INVALID_CAST), + case("`{{MA==}}`", EVALUATOR_INVALID_CAST), // 0 + case("`{{MS4w}}`", EVALUATOR_INVALID_CAST), // 1.0 + case("`{{MmUxMA==}}`", EVALUATOR_INVALID_CAST), // 2e10 + // list + case("`[]`", EVALUATOR_INVALID_CAST), + case("`[1d0]`", EVALUATOR_INVALID_CAST), + case("`[-2d0, 0d0]`", EVALUATOR_INVALID_CAST), + // sexp + case("`()`", EVALUATOR_INVALID_CAST), + case("`(1d0)`", EVALUATOR_INVALID_CAST), + case("`(0d0)`", EVALUATOR_INVALID_CAST), + // struct + case("`{}`", EVALUATOR_INVALID_CAST), + case("{}", EVALUATOR_INVALID_CAST), + case("`{a:12d0}`", EVALUATOR_INVALID_CAST), + case("{'b':`-4d0`}", EVALUATOR_INVALID_CAST), + // bag + case("<<>>", EVALUATOR_INVALID_CAST), + case("<<`14d0`>>", EVALUATOR_INVALID_CAST), + case("<<`20d0`>>", EVALUATOR_INVALID_CAST) + ).types(DECIMAL.sqlTextNames), + listOf( + // booleans + case("TRUE AND FALSE", EVALUATOR_INVALID_CAST), + case("`true`", EVALUATOR_INVALID_CAST), + // numbers + case("5", EVALUATOR_INVALID_CAST), + case("`0e0`", EVALUATOR_INVALID_CAST), + case("1.1", EVALUATOR_INVALID_CAST), + case("-20.1", EVALUATOR_INVALID_CAST), + // timestamp + case("`2007-10-10T`", "\$partiql_date::2007-10-10"), + case("`2007-02-23T12:14Z`", "\$partiql_date::2007-02-23"), + case("`2007-02-23T12:14:33.079Z`", "\$partiql_date::2007-02-23"), + case("`2007-02-23T12:14:33.079-08:00`", "\$partiql_date::2007-02-23"), + case("`2007-02T`", "\$partiql_date::2007-02-01"), + case("`2007T`", "\$partiql_date::2007-01-01"), + // text + case("'hello'", EVALUATOR_CAST_FAILED), + case("'2016-03-01T01:12:12Z'", EVALUATOR_CAST_FAILED), + case("""`"2001-01-01"`""", "\$partiql_date::2001-01-01"), + case("""`"+20212-02-01"`""", EVALUATOR_CAST_FAILED), + case("""`"20212-02-01"`""", EVALUATOR_CAST_FAILED), + case("""`'2000T'`""", EVALUATOR_CAST_FAILED), + case("""`'1999-04T'`""", EVALUATOR_CAST_FAILED), + // lob + case("""`{{""}}`""", EVALUATOR_INVALID_CAST), + case("`{{}}`", EVALUATOR_INVALID_CAST), + // list + case("`[]`", EVALUATOR_INVALID_CAST), + // sexp + case("`()`", EVALUATOR_INVALID_CAST), + // struct + case("`{}`", EVALUATOR_INVALID_CAST), + // bag + case("<<>>", EVALUATOR_INVALID_CAST) + ).types(DATE.sqlTextNames), + // Find more coverage for the "Cast as Time" tests in `castDateAndTime`. + listOf( + // booleans + case("TRUE AND FALSE", EVALUATOR_INVALID_CAST), + case("`true`", EVALUATOR_INVALID_CAST), + // numbers + case("5", EVALUATOR_INVALID_CAST), + case("`0e0`", EVALUATOR_INVALID_CAST), + case("1.1", EVALUATOR_INVALID_CAST), + case("-20.1", EVALUATOR_INVALID_CAST), + // timestamp + case( + "`2007-10-10T`", + "\$partiql_time::{hour:0,minute:0,second:0.,timezone_hour:null.int,timezone_minute:null.int}" + ), + case( + "`2007-02-23T12:14Z`", + "\$partiql_time::{hour:12,minute:14,second:0.,timezone_hour:null.int,timezone_minute:null.int}" + ), + case( + "`2007-02-23T12:14:33.079Z`", + "\$partiql_time::{hour:12,minute:14,second:33.079,timezone_hour:null.int,timezone_minute:null.int}" + ), + case( + "`2007-02-23T12:14:33.079-08:00`", + "\$partiql_time::{hour:12,minute:14,second:33.079,timezone_hour:null.int,timezone_minute:null.int}" + ), + case( + "`2007-02T`", + "\$partiql_time::{hour:0,minute:0,second:0.,timezone_hour:null.int,timezone_minute:null.int}" + ), + case( + "`2007T`", + "\$partiql_time::{hour:0,minute:0,second:0.,timezone_hour:null.int,timezone_minute:null.int}" + ), + // text + case("'hello'", EVALUATOR_CAST_FAILED), + case("'2016-03-01T01:12:12Z'", EVALUATOR_CAST_FAILED), + case("""`"23:2:12.12345"`""", EVALUATOR_CAST_FAILED), + case("""`"+20212-02-01"`""", EVALUATOR_CAST_FAILED), + case("""`"20212-02-01"`""", EVALUATOR_CAST_FAILED), + case("""`'2000T'`""", EVALUATOR_CAST_FAILED), + case("""`'1999-04T'`""", EVALUATOR_CAST_FAILED), + // lob + case("""`{{""}}`""", EVALUATOR_INVALID_CAST), + case("`{{}}`", EVALUATOR_INVALID_CAST), + // list + case("`[]`", EVALUATOR_INVALID_CAST), + // sexp + case("`()`", EVALUATOR_INVALID_CAST), + // struct + case("`{}`", EVALUATOR_INVALID_CAST), + // bag + case("<<>>", EVALUATOR_INVALID_CAST) + ).types(TIME.sqlTextNames), listOf( - listOf( - // booleans - case("TRUE AND FALSE", "false"), - case("`true`", "true"), - // numbers - case("5", "true"), - case("`0e0`", "false"), - case("1.1", "true"), - // timestamp - case("`2007-10-10T`", EVALUATOR_INVALID_CAST), - // text - case("'hello'", EVALUATOR_CAST_FAILED), - case("'TrUe'", "true"), - case("""`"FALSE"`""", "false"), - case("""`'true'`""", "true"), - // lob - case("""`{{""}}`""", EVALUATOR_INVALID_CAST), - case("""`{{"goodbye"}}`""", EVALUATOR_INVALID_CAST), - case("""`{{"false"}}`""", EVALUATOR_INVALID_CAST), - case("""`{{"true"}}`""", EVALUATOR_INVALID_CAST), - case("`{{}}`", EVALUATOR_INVALID_CAST), - case("`{{Z29vZGJ5ZQ==}}`", EVALUATOR_INVALID_CAST), // goodbye - case("`{{ZmFsc2U=}}`", EVALUATOR_INVALID_CAST), // false - case("`{{dHJ1ZQ==}}`", EVALUATOR_INVALID_CAST), // true - // list - case("`[]`", EVALUATOR_INVALID_CAST), - case("`[true]`", EVALUATOR_INVALID_CAST), - case("`[false]`", EVALUATOR_INVALID_CAST), - case("`[true, false]`", EVALUATOR_INVALID_CAST), - // sexp - case("`()`", EVALUATOR_INVALID_CAST), - case("`(true)`", EVALUATOR_INVALID_CAST), - case("`(false)`", EVALUATOR_INVALID_CAST), - // struct - case("`{}`", EVALUATOR_INVALID_CAST), - case("{}", EVALUATOR_INVALID_CAST), - case("`{a:true}`", EVALUATOR_INVALID_CAST), - case("{'b':true}", EVALUATOR_INVALID_CAST), - // bag - case("<<>>", EVALUATOR_INVALID_CAST), - case("<>", EVALUATOR_INVALID_CAST), - case("<>", EVALUATOR_INVALID_CAST) - ).types(BOOL.sqlTextNames), - listOf( - // booleans - case("TRUE AND FALSE", "0"), - case("`true`", "1"), - // numbers - case("5", "5"), - case(" 5 ", "5"), - case("`0e0`", "0"), - case("1.1", "1"), - case("1.9", "1"), - case("-20.1", "-20"), - case("-20.9", "-20"), - // timestamp - case("`2007-10-10T`", EVALUATOR_INVALID_CAST), - // text - case("'hello'", EVALUATOR_CAST_FAILED), - case("'1234A'", EVALUATOR_CAST_FAILED), // Invalid ION value - case("'20'", "20"), - case("'020'", "20"), - case("'+20'", "20"), - case("'+020'", "20"), - case("'-20'", "-20"), - case("'-020'", "-20"), - case("'0'", "0"), - case("'00'", "0"), - case("'+0'", "0"), - case("'+00'", "0"), - case("'-0'", "0"), - case("'-00'", "0"), - case("'0xA'", "10"), - case("'0XA'", "10"), - case("'0x0A'", "10"), - case("'+0xA'", "10"), - case("'+0x0A'", "10"), - case("'-0xA'", "-10"), - case("'-0x0A'", "-10"), - case("'0b10'", "2"), - case("'0B10'", "2"), - case("'0b010'", "2"), - case("'+0b10'", "2"), - case("'+0b010'", "2"), - case("'-0b10'", "-2"), - case("'-0b010'", "-2"), - case("""`"1000"`""", "1000"), - case("""`'2e100'`""", EVALUATOR_CAST_FAILED), - case("""`'2d100'`""", EVALUATOR_CAST_FAILED), - case("'00xA'", EVALUATOR_CAST_FAILED), - case("'00b10'", EVALUATOR_CAST_FAILED), - // lob - case("""`{{""}}`""", EVALUATOR_INVALID_CAST), - case("""`{{"0"}}`""", EVALUATOR_INVALID_CAST), - case("""`{{"1.0"}}`""", EVALUATOR_INVALID_CAST), - case("""`{{"2e10"}}`""", EVALUATOR_INVALID_CAST), - case("`{{}}`", EVALUATOR_INVALID_CAST), - case("`{{MA==}}`", EVALUATOR_INVALID_CAST), // 0 - case("`{{MS4w}}`", EVALUATOR_INVALID_CAST), // 1.0 - case("`{{MmUxMA==}}`", EVALUATOR_INVALID_CAST), // 2e10 - // list - case("`[]`", EVALUATOR_INVALID_CAST), - case("`[1]`", EVALUATOR_INVALID_CAST), - case("`[-2, 0]`", EVALUATOR_INVALID_CAST), - // sexp - case("`()`", EVALUATOR_INVALID_CAST), - case("`(1)`", EVALUATOR_INVALID_CAST), - case("`(0)`", EVALUATOR_INVALID_CAST), - // struct - case("`{}`", EVALUATOR_INVALID_CAST), - case("{}", EVALUATOR_INVALID_CAST), - case("`{a:12}`", EVALUATOR_INVALID_CAST), - case("{'b':-4}", EVALUATOR_INVALID_CAST), - // bag - case("<<>>", EVALUATOR_INVALID_CAST), - case("<<14>>", EVALUATOR_INVALID_CAST), - case("<<20>>", EVALUATOR_INVALID_CAST) - ).types(INT.sqlTextNames), - listOf( - // booleans - case("TRUE AND FALSE", "0e0"), - case("`true`", "1e0"), - // numbers - case("5", "5e0"), - case(" 5 ", "5e0"), - case("`0e0`", "0e0"), - case("1.1", "1.1e0"), - case("-20.1", "-20.1e0"), - // timestamp - case("`2007-10-10T`", EVALUATOR_INVALID_CAST), - // text - case("'hello'", EVALUATOR_CAST_FAILED), - case("'-20'", "-20e0"), - case("""`"1000"`""", "1000e0"), - case("""`'2e100'`""", "2e100"), - case("""`'2d100'`""", EVALUATOR_CAST_FAILED), - // lob - case("""`{{""}}`""", EVALUATOR_INVALID_CAST), - case("""`{{"0"}}`""", EVALUATOR_INVALID_CAST), - case("""`{{"1.0"}}`""", EVALUATOR_INVALID_CAST), - case("""`{{"2e10"}}`""", EVALUATOR_INVALID_CAST), - case("`{{}}`", EVALUATOR_INVALID_CAST), - case("`{{MA==}}`", EVALUATOR_INVALID_CAST), // 0 - case("`{{MS4w}}`", EVALUATOR_INVALID_CAST), // 1.0 - case("`{{MmUxMA==}}`", EVALUATOR_INVALID_CAST), // 2e10 - // list - case("`[]`", EVALUATOR_INVALID_CAST), - case("`[1e0]`", EVALUATOR_INVALID_CAST), - case("`[-2e0, 0e0]`", EVALUATOR_INVALID_CAST), - // sexp - case("`()`", EVALUATOR_INVALID_CAST), - case("`(1e0)`", EVALUATOR_INVALID_CAST), - case("`(0e0)`", EVALUATOR_INVALID_CAST), - // struct - case("`{}`", EVALUATOR_INVALID_CAST), - case("{}", EVALUATOR_INVALID_CAST), - case("`{a:12e0}`", EVALUATOR_INVALID_CAST), - case("{'b':`-4e0`}", EVALUATOR_INVALID_CAST), - // bag - case("<<>>", EVALUATOR_INVALID_CAST), - case("<<`14e0`>>", EVALUATOR_INVALID_CAST), - case("<<`20e0`>>", EVALUATOR_INVALID_CAST) - ).types(FLOAT.sqlTextNames), - listOf( - // booleans - case("TRUE AND FALSE", "0d0"), - case("`true`", "1d0"), - // numbers - case("5", "5d0"), - case("5 ", "5d0"), - case("`0e0`", "0."), // TODO formalize this behavior - case("`1e0`", "1."), // TODO formalize this behavior - case("1.1", "1.1d0"), - case("-20.1", "-20.1d0"), - // timestamp - case("`2007-10-10T`", EVALUATOR_INVALID_CAST), - // text - case("'hello'", EVALUATOR_CAST_FAILED), - case("'-20'", "-20d0"), - case("""`"1000"`""", "1000d0"), - case("""`'2e100'`""", "2d100"), - case("""`'2d100'`""", EVALUATOR_CAST_FAILED), - // lob - case("""`{{""}}`""", EVALUATOR_INVALID_CAST), - case("""`{{"0"}}`""", EVALUATOR_INVALID_CAST), - case("""`{{"1.0"}}`""", EVALUATOR_INVALID_CAST), - case("""`{{"2e10"}}`""", EVALUATOR_INVALID_CAST), - case("`{{}}`", EVALUATOR_INVALID_CAST), - case("`{{MA==}}`", EVALUATOR_INVALID_CAST), // 0 - case("`{{MS4w}}`", EVALUATOR_INVALID_CAST), // 1.0 - case("`{{MmUxMA==}}`", EVALUATOR_INVALID_CAST), // 2e10 - // list - case("`[]`", EVALUATOR_INVALID_CAST), - case("`[1d0]`", EVALUATOR_INVALID_CAST), - case("`[-2d0, 0d0]`", EVALUATOR_INVALID_CAST), - // sexp - case("`()`", EVALUATOR_INVALID_CAST), - case("`(1d0)`", EVALUATOR_INVALID_CAST), - case("`(0d0)`", EVALUATOR_INVALID_CAST), - // struct - case("`{}`", EVALUATOR_INVALID_CAST), - case("{}", EVALUATOR_INVALID_CAST), - case("`{a:12d0}`", EVALUATOR_INVALID_CAST), - case("{'b':`-4d0`}", EVALUATOR_INVALID_CAST), - // bag - case("<<>>", EVALUATOR_INVALID_CAST), - case("<<`14d0`>>", EVALUATOR_INVALID_CAST), - case("<<`20d0`>>", EVALUATOR_INVALID_CAST) - ).types(DECIMAL.sqlTextNames), - listOf( - // booleans - case("TRUE AND FALSE", EVALUATOR_INVALID_CAST), - case("`true`", EVALUATOR_INVALID_CAST), - // numbers - case("5", EVALUATOR_INVALID_CAST), - case("`0e0`", EVALUATOR_INVALID_CAST), - case("1.1", EVALUATOR_INVALID_CAST), - case("-20.1", EVALUATOR_INVALID_CAST), - // timestamp - case("`2007-10-10T`", "\$partiql_date::2007-10-10"), - case("`2007-02-23T12:14Z`", "\$partiql_date::2007-02-23"), - case("`2007-02-23T12:14:33.079Z`", "\$partiql_date::2007-02-23"), - case("`2007-02-23T12:14:33.079-08:00`", "\$partiql_date::2007-02-23"), - case("`2007-02T`", "\$partiql_date::2007-02-01"), - case("`2007T`", "\$partiql_date::2007-01-01"), - // text - case("'hello'", EVALUATOR_CAST_FAILED), - case("'2016-03-01T01:12:12Z'", EVALUATOR_CAST_FAILED), - case("""`"2001-01-01"`""", "\$partiql_date::2001-01-01"), - case("""`"+20212-02-01"`""", EVALUATOR_CAST_FAILED), - case("""`"20212-02-01"`""", EVALUATOR_CAST_FAILED), - case("""`'2000T'`""", EVALUATOR_CAST_FAILED), - case("""`'1999-04T'`""", EVALUATOR_CAST_FAILED), - // lob - case("""`{{""}}`""", EVALUATOR_INVALID_CAST), - case("`{{}}`", EVALUATOR_INVALID_CAST), - // list - case("`[]`", EVALUATOR_INVALID_CAST), - // sexp - case("`()`", EVALUATOR_INVALID_CAST), - // struct - case("`{}`", EVALUATOR_INVALID_CAST), - // bag - case("<<>>", EVALUATOR_INVALID_CAST) - ).types(DATE.sqlTextNames), - // Find more coverage for the "Cast as Time" tests in `castDateAndTime`. - listOf( - // booleans - case("TRUE AND FALSE", EVALUATOR_INVALID_CAST), - case("`true`", EVALUATOR_INVALID_CAST), - // numbers - case("5", EVALUATOR_INVALID_CAST), - case("`0e0`", EVALUATOR_INVALID_CAST), - case("1.1", EVALUATOR_INVALID_CAST), - case("-20.1", EVALUATOR_INVALID_CAST), - // timestamp - case("`2007-10-10T`", "\$partiql_time::{hour:0,minute:0,second:0.,timezone_hour:null.int,timezone_minute:null.int}"), - case("`2007-02-23T12:14Z`", "\$partiql_time::{hour:12,minute:14,second:0.,timezone_hour:null.int,timezone_minute:null.int}"), - case("`2007-02-23T12:14:33.079Z`", "\$partiql_time::{hour:12,minute:14,second:33.079,timezone_hour:null.int,timezone_minute:null.int}"), - case("`2007-02-23T12:14:33.079-08:00`", "\$partiql_time::{hour:12,minute:14,second:33.079,timezone_hour:null.int,timezone_minute:null.int}"), - case("`2007-02T`", "\$partiql_time::{hour:0,minute:0,second:0.,timezone_hour:null.int,timezone_minute:null.int}"), - case("`2007T`", "\$partiql_time::{hour:0,minute:0,second:0.,timezone_hour:null.int,timezone_minute:null.int}"), - // text - case("'hello'", EVALUATOR_CAST_FAILED), - case("'2016-03-01T01:12:12Z'", EVALUATOR_CAST_FAILED), - case("""`"23:2:12.12345"`""", EVALUATOR_CAST_FAILED), - case("""`"+20212-02-01"`""", EVALUATOR_CAST_FAILED), - case("""`"20212-02-01"`""", EVALUATOR_CAST_FAILED), - case("""`'2000T'`""", EVALUATOR_CAST_FAILED), - case("""`'1999-04T'`""", EVALUATOR_CAST_FAILED), - // lob - case("""`{{""}}`""", EVALUATOR_INVALID_CAST), - case("`{{}}`", EVALUATOR_INVALID_CAST), - // list - case("`[]`", EVALUATOR_INVALID_CAST), - // sexp - case("`()`", EVALUATOR_INVALID_CAST), - // struct - case("`{}`", EVALUATOR_INVALID_CAST), - // bag - case("<<>>", EVALUATOR_INVALID_CAST) - ).types(TIME.sqlTextNames), - listOf( - // booleans - case("TRUE AND FALSE", EVALUATOR_INVALID_CAST), - case("`true`", EVALUATOR_INVALID_CAST), - // numbers - case("5", EVALUATOR_INVALID_CAST), - case("`0e0`", EVALUATOR_INVALID_CAST), - case("1.1", EVALUATOR_INVALID_CAST), - case("-20.1", EVALUATOR_INVALID_CAST), - // timestamp - case("`2007-10-10T`", "2007-10-10T"), - // text - case("'hello'", EVALUATOR_CAST_FAILED), - case("'2016-03-01T01:12:12Z'", "2016-03-01T01:12:12Z"), - case("""`"2001-01-01"`""", "2001-01-01T"), - case("""`'2000T'`""", "2000T"), - case("""`'1999-04T'`""", "1999-04T"), - // lob - case("""`{{""}}`""", EVALUATOR_INVALID_CAST), - case("`{{}}`", EVALUATOR_INVALID_CAST), - // list - case("`[]`", EVALUATOR_INVALID_CAST), - // sexp - case("`()`", EVALUATOR_INVALID_CAST), - // struct - case("`{}`", EVALUATOR_INVALID_CAST), - // bag - case("<<>>", EVALUATOR_INVALID_CAST) - ).types(TIMESTAMP.sqlTextNames), - listOf( - // booleans - case("TRUE AND FALSE", "'false'"), - case("`true`", "'true'"), - // numbers - case("5", "'5'"), - case("`0e0`", "'0.0'"), - case("1.1", "'1.1'"), - case("-20.1", "'-20.1'"), - // timestamp - case("`2007-10-10T`", "'2007-10-10'"), - // text - case("'hello'", "'hello'"), - case("'-20'", "'-20'"), - case("""`"1000"`""", "'1000'"), - case("""`'2e100'`""", "'2e100'"), - case("""`'2d100'`""", "'2d100'"), - // lob - case("""`{{""}}`""", EVALUATOR_INVALID_CAST), - case("""`{{"0"}}`""", EVALUATOR_INVALID_CAST), - case("""`{{"1.0"}}`""", EVALUATOR_INVALID_CAST), - case("""`{{"2e10"}}`""", EVALUATOR_INVALID_CAST), - case("`{{}}`", EVALUATOR_INVALID_CAST), - case("`{{MA==}}`", EVALUATOR_INVALID_CAST), // 0 - case("`{{MS4w}}`", EVALUATOR_INVALID_CAST), // 1.0 - case("`{{MmUxMA==}}`", EVALUATOR_INVALID_CAST), // 2e10 - // list - case("`[]`", EVALUATOR_INVALID_CAST), - case("['hello']", EVALUATOR_INVALID_CAST), - case("`[-2d0, 0d0]`", EVALUATOR_INVALID_CAST), - // sexp - case("`()`", EVALUATOR_INVALID_CAST), - case("`(1d0)`", EVALUATOR_INVALID_CAST), - case("`(0d0)`", EVALUATOR_INVALID_CAST), - // struct - case("`{}`", EVALUATOR_INVALID_CAST), - case("{}", EVALUATOR_INVALID_CAST), - case("`{a:12d0}`", EVALUATOR_INVALID_CAST), - case("{'b':`-4d0`}", EVALUATOR_INVALID_CAST), - // bag - case("<<>>", EVALUATOR_INVALID_CAST), - case("<<`14d0`>>", EVALUATOR_INVALID_CAST), - case("<<`20d0`>>", EVALUATOR_INVALID_CAST) - ).types(SYMBOL.sqlTextNames), - listOf( - // booleans - case("TRUE AND FALSE", "\"false\""), - case("`true`", "\"true\""), - // numbers - case("5", "\"5\""), - case("`0e0`", "\"0.0\""), - case("1.1", "\"1.1\""), - case("-20.1", "\"-20.1\""), - // timestamp - case("`2007-10-10T`", "\"2007-10-10\""), - // text - case("'hello'", "\"hello\""), - case("'-20'", "\"-20\""), - case("""`"1000"`""", "\"1000\""), - case("""`'2e100'`""", "\"2e100\""), - case("""`'2d100'`""", "\"2d100\""), - // lob - case("""`{{""}}`""", EVALUATOR_INVALID_CAST), - case("""`{{"0"}}`""", EVALUATOR_INVALID_CAST), - case("""`{{"1.0"}}`""", EVALUATOR_INVALID_CAST), - case("""`{{"2e10"}}`""", EVALUATOR_INVALID_CAST), - case("`{{}}`", EVALUATOR_INVALID_CAST), - case("`{{MA==}}`", EVALUATOR_INVALID_CAST), // 0 - case("`{{MS4w}}`", EVALUATOR_INVALID_CAST), // 1.0 - case("`{{MmUxMA==}}`", EVALUATOR_INVALID_CAST), // 2e10 - // list - case("`[]`", EVALUATOR_INVALID_CAST), - case("['hello']", EVALUATOR_INVALID_CAST), - case("`[-2d0, 0d0]`", EVALUATOR_INVALID_CAST), - // sexp - case("`()`", EVALUATOR_INVALID_CAST), - case("`(1d0)`", EVALUATOR_INVALID_CAST), - case("`(0d0)`", EVALUATOR_INVALID_CAST), - // struct - case("`{}`", EVALUATOR_INVALID_CAST), - case("{}", EVALUATOR_INVALID_CAST), - case("`{a:12d0}`", EVALUATOR_INVALID_CAST), - case("{'b':`-4d0`}", EVALUATOR_INVALID_CAST), - // bag - case("<<>>", EVALUATOR_INVALID_CAST), - case("<<`14d0`>>", EVALUATOR_INVALID_CAST), - case("<<'a', <<'hello'>>>>", EVALUATOR_INVALID_CAST), - case("<<`20d0`>>", EVALUATOR_INVALID_CAST) - ).types(STRING.sqlTextNames), - listOf( - // booleans - case("TRUE AND FALSE", EVALUATOR_INVALID_CAST), - case("`true`", EVALUATOR_INVALID_CAST), - // numbers - case("5", EVALUATOR_INVALID_CAST), - case("`0e0`", EVALUATOR_INVALID_CAST), - case("1.1", EVALUATOR_INVALID_CAST), - case("-20.1", EVALUATOR_INVALID_CAST), - // timestamp - case("`2007-10-10T`", EVALUATOR_INVALID_CAST), - // text - case("'hello'", EVALUATOR_INVALID_CAST), - case("'-20'", EVALUATOR_INVALID_CAST), - case("""`"1000"`""", EVALUATOR_INVALID_CAST), - case("""`'2e100'`""", EVALUATOR_INVALID_CAST), - case("""`'2d100'`""", EVALUATOR_INVALID_CAST), - // lob - case("""`{{""}}`""", """{{""}}"""), - case("""`{{"0"}}`""", """{{"0"}}"""), - case("""`{{"1.0"}}`""", """{{"1.0"}}"""), - case("""`{{"2e10"}}`""", """{{"2e10"}}"""), - case("`{{}}`", """{{""}}"""), - case("`{{MA==}}`", """{{"0"}}"""), - case("`{{MS4w}}`", """{{"1.0"}}"""), - case("`{{MmUxMA==}}`", """{{"2e10"}}"""), - // list - case("`[]`", EVALUATOR_INVALID_CAST), - case("['hello']", EVALUATOR_INVALID_CAST), - case("`[-2d0, 0d0]`", EVALUATOR_INVALID_CAST), - // sexp - case("`()`", EVALUATOR_INVALID_CAST), - case("`(1d0)`", EVALUATOR_INVALID_CAST), - case("`(0d0)`", EVALUATOR_INVALID_CAST), - // struct - case("`{}`", EVALUATOR_INVALID_CAST), - case("{}", EVALUATOR_INVALID_CAST), - case("`{a:12d0}`", EVALUATOR_INVALID_CAST), - case("{'b':`-4d0`}", EVALUATOR_INVALID_CAST), - // bag - case("<<>>", EVALUATOR_INVALID_CAST), - case("<<`14d0`>>", EVALUATOR_INVALID_CAST), - case("<<`20d0`>>", EVALUATOR_INVALID_CAST) - ).types(CLOB.sqlTextNames), - listOf( - // booleans - case("TRUE AND FALSE", EVALUATOR_INVALID_CAST), - case("`true`", EVALUATOR_INVALID_CAST), - // numbers - case("5", EVALUATOR_INVALID_CAST), - case("`0e0`", EVALUATOR_INVALID_CAST), - case("1.1", EVALUATOR_INVALID_CAST), - case("-20.1", EVALUATOR_INVALID_CAST), - // timestamp - case("`2007-10-10T`", EVALUATOR_INVALID_CAST), - // text - case("'hello'", EVALUATOR_INVALID_CAST), - case("'-20'", EVALUATOR_INVALID_CAST), - case("""`"1000"`""", EVALUATOR_INVALID_CAST), - case("""`'2e100'`""", EVALUATOR_INVALID_CAST), - case("""`'2d100'`""", EVALUATOR_INVALID_CAST), - // lob - case("""`{{""}}`""", """{{}}"""), - case("""`{{"0"}}`""", """{{MA==}}"""), - case("""`{{"1.0"}}`""", """{{MS4w}}"""), - case("""`{{"2e10"}}`""", """{{MmUxMA==}}"""), - case("`{{}}`", """{{}}"""), - case("`{{MA==}}`", """{{MA==}}"""), // 0 - case("`{{MS4w}}`", """{{MS4w}}"""), // 1.0 - case("`{{MmUxMA==}}`", """{{MmUxMA==}}"""), // 2e10 - // list - case("`[]`", EVALUATOR_INVALID_CAST), - case("['hello']", EVALUATOR_INVALID_CAST), - case("`[-2d0, 0d0]`", EVALUATOR_INVALID_CAST), - // sexp - case("`()`", EVALUATOR_INVALID_CAST), - case("`(1d0)`", EVALUATOR_INVALID_CAST), - case("`(0d0)`", EVALUATOR_INVALID_CAST), - // struct - case("`{}`", EVALUATOR_INVALID_CAST), - case("{}", EVALUATOR_INVALID_CAST), - case("`{a:12d0}`", EVALUATOR_INVALID_CAST), - case("{'b':`-4d0`}", EVALUATOR_INVALID_CAST), - // bag - case("<<>>", EVALUATOR_INVALID_CAST), - case("<<`14d0`>>", EVALUATOR_INVALID_CAST), - case("<<`20d0`>>", EVALUATOR_INVALID_CAST) - ).types(BLOB.sqlTextNames), - listOf( - // booleans - case("TRUE AND FALSE", EVALUATOR_INVALID_CAST), - case("`true`", EVALUATOR_INVALID_CAST), - // numbers - case("5", EVALUATOR_INVALID_CAST), - case("`0e0`", EVALUATOR_INVALID_CAST), - case("1.1", EVALUATOR_INVALID_CAST), - case("-20.1", EVALUATOR_INVALID_CAST), - // timestamp - case("`2007-10-10T`", EVALUATOR_INVALID_CAST), - // text - case("'hello'", EVALUATOR_INVALID_CAST), - case("'-20'", EVALUATOR_INVALID_CAST), - case("""`"1000"`""", EVALUATOR_INVALID_CAST), - case("""`'2e100'`""", EVALUATOR_INVALID_CAST), - case("""`'2d100'`""", EVALUATOR_INVALID_CAST), - // lob - case("""`{{""}}`""", EVALUATOR_INVALID_CAST), - case("""`{{"0"}}`""", EVALUATOR_INVALID_CAST), - case("""`{{"1.0"}}`""", EVALUATOR_INVALID_CAST), - case("""`{{"2e10"}}`""", EVALUATOR_INVALID_CAST), - case("`{{}}`", EVALUATOR_INVALID_CAST), - case("`{{MA==}}`", EVALUATOR_INVALID_CAST), // 0 - case("`{{MS4w}}`", EVALUATOR_INVALID_CAST), // 1.0 - case("`{{MmUxMA==}}`", EVALUATOR_INVALID_CAST), // 2e10 - // list - case("`[]`", "[]"), - case("['hello']", "[\"hello\"]"), - case("`[-2d0, 0d0]`", "[-2d0, 0d0]"), - // sexp - case("`()`", "[]"), - case("`(1d0)`", "[1d0]"), - case("`(0d0)`", "[0d0]"), - // struct - case("`{}`", EVALUATOR_INVALID_CAST), - case("{}", EVALUATOR_INVALID_CAST), - case("`{a:12d0}`", EVALUATOR_INVALID_CAST), - case("{'b':`-4d0`}", EVALUATOR_INVALID_CAST), - // bag - case("<<>>", "[]"), // TODO bag verification - case("<<`14d0`>>", "[14d0]"), // TODO bag verification - case("<<`20d0`>>", "[20d0]") // TODO bag verification - ).types(LIST.sqlTextNames), - listOf( - // booleans - case("TRUE AND FALSE", EVALUATOR_INVALID_CAST), - case("`true`", EVALUATOR_INVALID_CAST), - // numbers - case("5", EVALUATOR_INVALID_CAST), - case("`0e0`", EVALUATOR_INVALID_CAST), - case("1.1", EVALUATOR_INVALID_CAST), - case("-20.1", EVALUATOR_INVALID_CAST), - // timestamp - case("`2007-10-10T`", EVALUATOR_INVALID_CAST), - // text - case("'hello'", EVALUATOR_INVALID_CAST), - case("'-20'", EVALUATOR_INVALID_CAST), - case("""`"1000"`""", EVALUATOR_INVALID_CAST), - case("""`'2e100'`""", EVALUATOR_INVALID_CAST), - case("""`'2d100'`""", EVALUATOR_INVALID_CAST), - // lob - case("""`{{""}}`""", EVALUATOR_INVALID_CAST), - case("""`{{"0"}}`""", EVALUATOR_INVALID_CAST), - case("""`{{"1.0"}}`""", EVALUATOR_INVALID_CAST), - case("""`{{"2e10"}}`""", EVALUATOR_INVALID_CAST), - case("`{{}}`", EVALUATOR_INVALID_CAST), - case("`{{MA==}}`", EVALUATOR_INVALID_CAST), // 0 - case("`{{MS4w}}`", EVALUATOR_INVALID_CAST), // 1.0 - case("`{{MmUxMA==}}`", EVALUATOR_INVALID_CAST), // 2e10 - // list - case("`[]`", "()"), - case("['hello']", "(\"hello\")"), - case("`[-2d0, 0d0]`", "(-2d0 0d0)"), - // sexp - case("`()`", "()"), - case("`(1d0)`", "(1d0)"), - case("`(0d0)`", "(0d0)"), - // struct - case("`{}`", EVALUATOR_INVALID_CAST), - case("{}", EVALUATOR_INVALID_CAST), - case("`{a:12d0}`", EVALUATOR_INVALID_CAST), - case("{'b':`-4d0`}", EVALUATOR_INVALID_CAST), - // bag - case("<<>>", "()"), - case("<<`14d0`>>", "(14d0)"), - case("<<`20d0`>>", "(20d0)") - ).types(SEXP.sqlTextNames), - listOf( - // booleans - case("TRUE AND FALSE", EVALUATOR_INVALID_CAST), - case("`true`", EVALUATOR_INVALID_CAST), - // numbers - case("5", EVALUATOR_INVALID_CAST), - case("`0e0`", EVALUATOR_INVALID_CAST), - case("1.1", EVALUATOR_INVALID_CAST), - case("-20.1", EVALUATOR_INVALID_CAST), - // timestamp - case("`2007-10-10T`", EVALUATOR_INVALID_CAST), - // text - case("'hello'", EVALUATOR_INVALID_CAST), - case("'-20'", EVALUATOR_INVALID_CAST), - case("""`"1000"`""", EVALUATOR_INVALID_CAST), - case("""`'2e100'`""", EVALUATOR_INVALID_CAST), - case("""`'2d100'`""", EVALUATOR_INVALID_CAST), - // lob - case("""`{{""}}`""", EVALUATOR_INVALID_CAST), - case("""`{{"0"}}`""", EVALUATOR_INVALID_CAST), - case("""`{{"1.0"}}`""", EVALUATOR_INVALID_CAST), - case("""`{{"2e10"}}`""", EVALUATOR_INVALID_CAST), - case("`{{}}`", EVALUATOR_INVALID_CAST), - case("`{{MA==}}`", EVALUATOR_INVALID_CAST), // 0 - case("`{{MS4w}}`", EVALUATOR_INVALID_CAST), // 1.0 - case("`{{MmUxMA==}}`", EVALUATOR_INVALID_CAST), // 2e10 - // list - case("`[]`", EVALUATOR_INVALID_CAST), - case("['hello']", EVALUATOR_INVALID_CAST), - case("`[-2d0, 0d0]`", EVALUATOR_INVALID_CAST), - // sexp - case("`()`", EVALUATOR_INVALID_CAST), - case("`(1d0)`", EVALUATOR_INVALID_CAST), - case("`(0d0)`", EVALUATOR_INVALID_CAST), - // struct - case("`{}`", "{}"), - case("{}", "{}"), - case("`{a:12d0}`", "{a:12d0}"), - case("{'b':`-4d0`}", "{b:-4d0}"), - // bag - case("<<>>", EVALUATOR_INVALID_CAST), - case("<<`14d0`>>", EVALUATOR_INVALID_CAST), - case("<<`20d0`>>", EVALUATOR_INVALID_CAST) - ).types(STRUCT.sqlTextNames), - listOf( - // booleans - case("TRUE AND FALSE", EVALUATOR_INVALID_CAST), - case("`true`", EVALUATOR_INVALID_CAST), - // numbers - case("5", EVALUATOR_INVALID_CAST), - case("`0e0`", EVALUATOR_INVALID_CAST), - case("1.1", EVALUATOR_INVALID_CAST), - case("-20.1", EVALUATOR_INVALID_CAST), - // timestamp - case("`2007-10-10T`", EVALUATOR_INVALID_CAST), - // text - case("'hello'", EVALUATOR_INVALID_CAST), - case("'-20'", EVALUATOR_INVALID_CAST), - case("""`"1000"`""", EVALUATOR_INVALID_CAST), - case("""`'2e100'`""", EVALUATOR_INVALID_CAST), - case("""`'2d100'`""", EVALUATOR_INVALID_CAST), - // lob - case("""`{{""}}`""", EVALUATOR_INVALID_CAST), - case("""`{{"0"}}`""", EVALUATOR_INVALID_CAST), - case("""`{{"1.0"}}`""", EVALUATOR_INVALID_CAST), - case("""`{{"2e10"}}`""", EVALUATOR_INVALID_CAST), - case("`{{}}`", EVALUATOR_INVALID_CAST), - case("`{{MA==}}`", EVALUATOR_INVALID_CAST), // 0 - case("`{{MS4w}}`", EVALUATOR_INVALID_CAST), // 1.0 - case("`{{MmUxMA==}}`", EVALUATOR_INVALID_CAST), // 2e10 - // list - case("`[]`", "[]"), // TODO bag verification - case("['hello']", "[\"hello\"]"), // TODO bag verification - case("`[-2d0, 0d0]`", "[-2d0, 0d0]"), // TODO bag verification - // sexp - case("`()`", "[]"), // TODO bag verification - case("`(1d0)`", "[1d0]"), // TODO bag verification - case("`(0d0)`", "[0d0]"), // TODO bag verification - // struct - case("`{}`", EVALUATOR_INVALID_CAST), - case("{}", EVALUATOR_INVALID_CAST), - case("`{a:12d0}`", EVALUATOR_INVALID_CAST), - case("{'b':`-4d0`}", EVALUATOR_INVALID_CAST), - // bag - case("<<>>", "[]"), // TODO bag verification - case("<<`14d0`>>", "[14d0]"), // TODO bag verification - case("<<`20d0`>>", "[20d0]") // TODO bag verification - ).types(BAG.sqlTextNames) - ).flatMap { it } + // booleans + case("TRUE AND FALSE", EVALUATOR_INVALID_CAST), + case("`true`", EVALUATOR_INVALID_CAST), + // numbers + case("5", EVALUATOR_INVALID_CAST), + case("`0e0`", EVALUATOR_INVALID_CAST), + case("1.1", EVALUATOR_INVALID_CAST), + case("-20.1", EVALUATOR_INVALID_CAST), + // timestamp + case("`2007-10-10T`", "2007-10-10T"), + // text + case("'hello'", EVALUATOR_CAST_FAILED), + case("'2016-03-01T01:12:12Z'", "2016-03-01T01:12:12Z"), + case("""`"2001-01-01"`""", "2001-01-01T"), + case("""`'2000T'`""", "2000T"), + case("""`'1999-04T'`""", "1999-04T"), + // lob + case("""`{{""}}`""", EVALUATOR_INVALID_CAST), + case("`{{}}`", EVALUATOR_INVALID_CAST), + // list + case("`[]`", EVALUATOR_INVALID_CAST), + // sexp + case("`()`", EVALUATOR_INVALID_CAST), + // struct + case("`{}`", EVALUATOR_INVALID_CAST), + // bag + case("<<>>", EVALUATOR_INVALID_CAST) + ).types(TIMESTAMP.sqlTextNames), + listOf( + // booleans + case("TRUE AND FALSE", "'false'"), + case("`true`", "'true'"), + // numbers + case("5", "'5'"), + case("`0e0`", "'0.0'"), + case("1.1", "'1.1'"), + case("-20.1", "'-20.1'"), + // timestamp + case("`2007-10-10T`", "'2007-10-10'"), + // text + case("'hello'", "'hello'"), + case("'-20'", "'-20'"), + case("""`"1000"`""", "'1000'"), + case("""`'2e100'`""", "'2e100'"), + case("""`'2d100'`""", "'2d100'"), + // lob + case("""`{{""}}`""", EVALUATOR_INVALID_CAST), + case("""`{{"0"}}`""", EVALUATOR_INVALID_CAST), + case("""`{{"1.0"}}`""", EVALUATOR_INVALID_CAST), + case("""`{{"2e10"}}`""", EVALUATOR_INVALID_CAST), + case("`{{}}`", EVALUATOR_INVALID_CAST), + case("`{{MA==}}`", EVALUATOR_INVALID_CAST), // 0 + case("`{{MS4w}}`", EVALUATOR_INVALID_CAST), // 1.0 + case("`{{MmUxMA==}}`", EVALUATOR_INVALID_CAST), // 2e10 + // list + case("`[]`", EVALUATOR_INVALID_CAST), + case("['hello']", EVALUATOR_INVALID_CAST), + case("`[-2d0, 0d0]`", EVALUATOR_INVALID_CAST), + // sexp + case("`()`", EVALUATOR_INVALID_CAST), + case("`(1d0)`", EVALUATOR_INVALID_CAST), + case("`(0d0)`", EVALUATOR_INVALID_CAST), + // struct + case("`{}`", EVALUATOR_INVALID_CAST), + case("{}", EVALUATOR_INVALID_CAST), + case("`{a:12d0}`", EVALUATOR_INVALID_CAST), + case("{'b':`-4d0`}", EVALUATOR_INVALID_CAST), + // bag + case("<<>>", EVALUATOR_INVALID_CAST), + case("<<`14d0`>>", EVALUATOR_INVALID_CAST), + case("<<`20d0`>>", EVALUATOR_INVALID_CAST) + ).types(SYMBOL.sqlTextNames), + listOf( + // booleans + case("TRUE AND FALSE", "\"false\""), + case("`true`", "\"true\""), + // numbers + case("5", "\"5\""), + case("`0e0`", "\"0.0\""), + case("1.1", "\"1.1\""), + case("-20.1", "\"-20.1\""), + // timestamp + case("`2007-10-10T`", "\"2007-10-10\""), + // text + case("'hello'", "\"hello\""), + case("'-20'", "\"-20\""), + case("""`"1000"`""", "\"1000\""), + case("""`'2e100'`""", "\"2e100\""), + case("""`'2d100'`""", "\"2d100\""), + // lob + case("""`{{""}}`""", EVALUATOR_INVALID_CAST), + case("""`{{"0"}}`""", EVALUATOR_INVALID_CAST), + case("""`{{"1.0"}}`""", EVALUATOR_INVALID_CAST), + case("""`{{"2e10"}}`""", EVALUATOR_INVALID_CAST), + case("`{{}}`", EVALUATOR_INVALID_CAST), + case("`{{MA==}}`", EVALUATOR_INVALID_CAST), // 0 + case("`{{MS4w}}`", EVALUATOR_INVALID_CAST), // 1.0 + case("`{{MmUxMA==}}`", EVALUATOR_INVALID_CAST), // 2e10 + // list + case("`[]`", EVALUATOR_INVALID_CAST), + case("['hello']", EVALUATOR_INVALID_CAST), + case("`[-2d0, 0d0]`", EVALUATOR_INVALID_CAST), + // sexp + case("`()`", EVALUATOR_INVALID_CAST), + case("`(1d0)`", EVALUATOR_INVALID_CAST), + case("`(0d0)`", EVALUATOR_INVALID_CAST), + // struct + case("`{}`", EVALUATOR_INVALID_CAST), + case("{}", EVALUATOR_INVALID_CAST), + case("`{a:12d0}`", EVALUATOR_INVALID_CAST), + case("{'b':`-4d0`}", EVALUATOR_INVALID_CAST), + // bag + case("<<>>", EVALUATOR_INVALID_CAST), + case("<<`14d0`>>", EVALUATOR_INVALID_CAST), + case("<<'a', <<'hello'>>>>", EVALUATOR_INVALID_CAST), + case("<<`20d0`>>", EVALUATOR_INVALID_CAST) + ).types(STRING.sqlTextNames), + listOf( + // booleans + case("TRUE AND FALSE", EVALUATOR_INVALID_CAST), + case("`true`", EVALUATOR_INVALID_CAST), + // numbers + case("5", EVALUATOR_INVALID_CAST), + case("`0e0`", EVALUATOR_INVALID_CAST), + case("1.1", EVALUATOR_INVALID_CAST), + case("-20.1", EVALUATOR_INVALID_CAST), + // timestamp + case("`2007-10-10T`", EVALUATOR_INVALID_CAST), + // text + case("'hello'", EVALUATOR_INVALID_CAST), + case("'-20'", EVALUATOR_INVALID_CAST), + case("""`"1000"`""", EVALUATOR_INVALID_CAST), + case("""`'2e100'`""", EVALUATOR_INVALID_CAST), + case("""`'2d100'`""", EVALUATOR_INVALID_CAST), + // lob + case("""`{{""}}`""", """{{""}}"""), + case("""`{{"0"}}`""", """{{"0"}}"""), + case("""`{{"1.0"}}`""", """{{"1.0"}}"""), + case("""`{{"2e10"}}`""", """{{"2e10"}}"""), + case("`{{}}`", """{{""}}"""), + case("`{{MA==}}`", """{{"0"}}"""), + case("`{{MS4w}}`", """{{"1.0"}}"""), + case("`{{MmUxMA==}}`", """{{"2e10"}}"""), + // list + case("`[]`", EVALUATOR_INVALID_CAST), + case("['hello']", EVALUATOR_INVALID_CAST), + case("`[-2d0, 0d0]`", EVALUATOR_INVALID_CAST), + // sexp + case("`()`", EVALUATOR_INVALID_CAST), + case("`(1d0)`", EVALUATOR_INVALID_CAST), + case("`(0d0)`", EVALUATOR_INVALID_CAST), + // struct + case("`{}`", EVALUATOR_INVALID_CAST), + case("{}", EVALUATOR_INVALID_CAST), + case("`{a:12d0}`", EVALUATOR_INVALID_CAST), + case("{'b':`-4d0`}", EVALUATOR_INVALID_CAST), + // bag + case("<<>>", EVALUATOR_INVALID_CAST), + case("<<`14d0`>>", EVALUATOR_INVALID_CAST), + case("<<`20d0`>>", EVALUATOR_INVALID_CAST) + ).types(CLOB.sqlTextNames), + listOf( + // booleans + case("TRUE AND FALSE", EVALUATOR_INVALID_CAST), + case("`true`", EVALUATOR_INVALID_CAST), + // numbers + case("5", EVALUATOR_INVALID_CAST), + case("`0e0`", EVALUATOR_INVALID_CAST), + case("1.1", EVALUATOR_INVALID_CAST), + case("-20.1", EVALUATOR_INVALID_CAST), + // timestamp + case("`2007-10-10T`", EVALUATOR_INVALID_CAST), + // text + case("'hello'", EVALUATOR_INVALID_CAST), + case("'-20'", EVALUATOR_INVALID_CAST), + case("""`"1000"`""", EVALUATOR_INVALID_CAST), + case("""`'2e100'`""", EVALUATOR_INVALID_CAST), + case("""`'2d100'`""", EVALUATOR_INVALID_CAST), + // lob + case("""`{{""}}`""", """{{}}"""), + case("""`{{"0"}}`""", """{{MA==}}"""), + case("""`{{"1.0"}}`""", """{{MS4w}}"""), + case("""`{{"2e10"}}`""", """{{MmUxMA==}}"""), + case("`{{}}`", """{{}}"""), + case("`{{MA==}}`", """{{MA==}}"""), // 0 + case("`{{MS4w}}`", """{{MS4w}}"""), // 1.0 + case("`{{MmUxMA==}}`", """{{MmUxMA==}}"""), // 2e10 + // list + case("`[]`", EVALUATOR_INVALID_CAST), + case("['hello']", EVALUATOR_INVALID_CAST), + case("`[-2d0, 0d0]`", EVALUATOR_INVALID_CAST), + // sexp + case("`()`", EVALUATOR_INVALID_CAST), + case("`(1d0)`", EVALUATOR_INVALID_CAST), + case("`(0d0)`", EVALUATOR_INVALID_CAST), + // struct + case("`{}`", EVALUATOR_INVALID_CAST), + case("{}", EVALUATOR_INVALID_CAST), + case("`{a:12d0}`", EVALUATOR_INVALID_CAST), + case("{'b':`-4d0`}", EVALUATOR_INVALID_CAST), + // bag + case("<<>>", EVALUATOR_INVALID_CAST), + case("<<`14d0`>>", EVALUATOR_INVALID_CAST), + case("<<`20d0`>>", EVALUATOR_INVALID_CAST) + ).types(BLOB.sqlTextNames), + listOf( + // booleans + case("TRUE AND FALSE", EVALUATOR_INVALID_CAST), + case("`true`", EVALUATOR_INVALID_CAST), + // numbers + case("5", EVALUATOR_INVALID_CAST), + case("`0e0`", EVALUATOR_INVALID_CAST), + case("1.1", EVALUATOR_INVALID_CAST), + case("-20.1", EVALUATOR_INVALID_CAST), + // timestamp + case("`2007-10-10T`", EVALUATOR_INVALID_CAST), + // text + case("'hello'", EVALUATOR_INVALID_CAST), + case("'-20'", EVALUATOR_INVALID_CAST), + case("""`"1000"`""", EVALUATOR_INVALID_CAST), + case("""`'2e100'`""", EVALUATOR_INVALID_CAST), + case("""`'2d100'`""", EVALUATOR_INVALID_CAST), + // lob + case("""`{{""}}`""", EVALUATOR_INVALID_CAST), + case("""`{{"0"}}`""", EVALUATOR_INVALID_CAST), + case("""`{{"1.0"}}`""", EVALUATOR_INVALID_CAST), + case("""`{{"2e10"}}`""", EVALUATOR_INVALID_CAST), + case("`{{}}`", EVALUATOR_INVALID_CAST), + case("`{{MA==}}`", EVALUATOR_INVALID_CAST), // 0 + case("`{{MS4w}}`", EVALUATOR_INVALID_CAST), // 1.0 + case("`{{MmUxMA==}}`", EVALUATOR_INVALID_CAST), // 2e10 + // list + case("`[]`", "[]"), + case("['hello']", "[\"hello\"]"), + case("`[-2d0, 0d0]`", "[-2d0, 0d0]"), + // sexp + case("`()`", "[]"), + case("`(1d0)`", "[1d0]"), + case("`(0d0)`", "[0d0]"), + // struct + case("`{}`", EVALUATOR_INVALID_CAST), + case("{}", EVALUATOR_INVALID_CAST), + case("`{a:12d0}`", EVALUATOR_INVALID_CAST), + case("{'b':`-4d0`}", EVALUATOR_INVALID_CAST), + // bag + case("<<>>", "[]"), // TODO bag verification + case("<<`14d0`>>", "[14d0]"), // TODO bag verification + case("<<`20d0`>>", "[20d0]") // TODO bag verification + ).types(LIST.sqlTextNames), + listOf( + // booleans + case("TRUE AND FALSE", EVALUATOR_INVALID_CAST), + case("`true`", EVALUATOR_INVALID_CAST), + // numbers + case("5", EVALUATOR_INVALID_CAST), + case("`0e0`", EVALUATOR_INVALID_CAST), + case("1.1", EVALUATOR_INVALID_CAST), + case("-20.1", EVALUATOR_INVALID_CAST), + // timestamp + case("`2007-10-10T`", EVALUATOR_INVALID_CAST), + // text + case("'hello'", EVALUATOR_INVALID_CAST), + case("'-20'", EVALUATOR_INVALID_CAST), + case("""`"1000"`""", EVALUATOR_INVALID_CAST), + case("""`'2e100'`""", EVALUATOR_INVALID_CAST), + case("""`'2d100'`""", EVALUATOR_INVALID_CAST), + // lob + case("""`{{""}}`""", EVALUATOR_INVALID_CAST), + case("""`{{"0"}}`""", EVALUATOR_INVALID_CAST), + case("""`{{"1.0"}}`""", EVALUATOR_INVALID_CAST), + case("""`{{"2e10"}}`""", EVALUATOR_INVALID_CAST), + case("`{{}}`", EVALUATOR_INVALID_CAST), + case("`{{MA==}}`", EVALUATOR_INVALID_CAST), // 0 + case("`{{MS4w}}`", EVALUATOR_INVALID_CAST), // 1.0 + case("`{{MmUxMA==}}`", EVALUATOR_INVALID_CAST), // 2e10 + // list + case("`[]`", "()"), + case("['hello']", "(\"hello\")"), + case("`[-2d0, 0d0]`", "(-2d0 0d0)"), + // sexp + case("`()`", "()"), + case("`(1d0)`", "(1d0)"), + case("`(0d0)`", "(0d0)"), + // struct + case("`{}`", EVALUATOR_INVALID_CAST), + case("{}", EVALUATOR_INVALID_CAST), + case("`{a:12d0}`", EVALUATOR_INVALID_CAST), + case("{'b':`-4d0`}", EVALUATOR_INVALID_CAST), + // bag + case("<<>>", "()"), + case("<<`14d0`>>", "(14d0)"), + case("<<`20d0`>>", "(20d0)") + ).types(SEXP.sqlTextNames), + listOf( + // booleans + case("TRUE AND FALSE", EVALUATOR_INVALID_CAST), + case("`true`", EVALUATOR_INVALID_CAST), + // numbers + case("5", EVALUATOR_INVALID_CAST), + case("`0e0`", EVALUATOR_INVALID_CAST), + case("1.1", EVALUATOR_INVALID_CAST), + case("-20.1", EVALUATOR_INVALID_CAST), + // timestamp + case("`2007-10-10T`", EVALUATOR_INVALID_CAST), + // text + case("'hello'", EVALUATOR_INVALID_CAST), + case("'-20'", EVALUATOR_INVALID_CAST), + case("""`"1000"`""", EVALUATOR_INVALID_CAST), + case("""`'2e100'`""", EVALUATOR_INVALID_CAST), + case("""`'2d100'`""", EVALUATOR_INVALID_CAST), + // lob + case("""`{{""}}`""", EVALUATOR_INVALID_CAST), + case("""`{{"0"}}`""", EVALUATOR_INVALID_CAST), + case("""`{{"1.0"}}`""", EVALUATOR_INVALID_CAST), + case("""`{{"2e10"}}`""", EVALUATOR_INVALID_CAST), + case("`{{}}`", EVALUATOR_INVALID_CAST), + case("`{{MA==}}`", EVALUATOR_INVALID_CAST), // 0 + case("`{{MS4w}}`", EVALUATOR_INVALID_CAST), // 1.0 + case("`{{MmUxMA==}}`", EVALUATOR_INVALID_CAST), // 2e10 + // list + case("`[]`", EVALUATOR_INVALID_CAST), + case("['hello']", EVALUATOR_INVALID_CAST), + case("`[-2d0, 0d0]`", EVALUATOR_INVALID_CAST), + // sexp + case("`()`", EVALUATOR_INVALID_CAST), + case("`(1d0)`", EVALUATOR_INVALID_CAST), + case("`(0d0)`", EVALUATOR_INVALID_CAST), + // struct + case("`{}`", "{}"), + case("{}", "{}"), + case("`{a:12d0}`", "{a:12d0}"), + case("{'b':`-4d0`}", "{b:-4d0}"), + // bag + case("<<>>", EVALUATOR_INVALID_CAST), + case("<<`14d0`>>", EVALUATOR_INVALID_CAST), + case("<<`20d0`>>", EVALUATOR_INVALID_CAST) + ).types(STRUCT.sqlTextNames), + listOf( + // booleans + case("TRUE AND FALSE", EVALUATOR_INVALID_CAST), + case("`true`", EVALUATOR_INVALID_CAST), + // numbers + case("5", EVALUATOR_INVALID_CAST), + case("`0e0`", EVALUATOR_INVALID_CAST), + case("1.1", EVALUATOR_INVALID_CAST), + case("-20.1", EVALUATOR_INVALID_CAST), + // timestamp + case("`2007-10-10T`", EVALUATOR_INVALID_CAST), + // text + case("'hello'", EVALUATOR_INVALID_CAST), + case("'-20'", EVALUATOR_INVALID_CAST), + case("""`"1000"`""", EVALUATOR_INVALID_CAST), + case("""`'2e100'`""", EVALUATOR_INVALID_CAST), + case("""`'2d100'`""", EVALUATOR_INVALID_CAST), + // lob + case("""`{{""}}`""", EVALUATOR_INVALID_CAST), + case("""`{{"0"}}`""", EVALUATOR_INVALID_CAST), + case("""`{{"1.0"}}`""", EVALUATOR_INVALID_CAST), + case("""`{{"2e10"}}`""", EVALUATOR_INVALID_CAST), + case("`{{}}`", EVALUATOR_INVALID_CAST), + case("`{{MA==}}`", EVALUATOR_INVALID_CAST), // 0 + case("`{{MS4w}}`", EVALUATOR_INVALID_CAST), // 1.0 + case("`{{MmUxMA==}}`", EVALUATOR_INVALID_CAST), // 2e10 + // list + case("`[]`", "[]"), // TODO bag verification + case("['hello']", "[\"hello\"]"), // TODO bag verification + case("`[-2d0, 0d0]`", "[-2d0, 0d0]"), // TODO bag verification + // sexp + case("`()`", "[]"), // TODO bag verification + case("`(1d0)`", "[1d0]"), // TODO bag verification + case("`(0d0)`", "[0d0]"), // TODO bag verification + // struct + case("`{}`", EVALUATOR_INVALID_CAST), + case("{}", EVALUATOR_INVALID_CAST), + case("`{a:12d0}`", EVALUATOR_INVALID_CAST), + case("{'b':`-4d0`}", EVALUATOR_INVALID_CAST), + // bag + case("<<>>", "[]"), // TODO bag verification + case("<<`14d0`>>", "[14d0]"), // TODO bag verification + case("<<`20d0`>>", "[20d0]") // TODO bag verification + ).types(BAG.sqlTextNames) + ).flatMap { it } @Test @Parameters @@ -784,6 +817,8 @@ class EvaluatingCompilerCastTest : EvaluatorTestBase() { else -> assertEval(castCase.expression, castCase.expected) } + private val defaultTimezoneOffset = ZoneOffset.UTC + fun parametersForCastDateAndTime() = listOf( listOf( case("DATE '2007-10-10'", "2007-10-10") @@ -797,21 +832,33 @@ class EvaluatingCompilerCastTest : EvaluatorTestBase() { listOf( // CAST(