diff --git a/legend-engine-core/legend-engine-core-base/legend-engine-core-language-pure/legend-engine-language-pure-compiler/src/main/java/org/finos/legend/engine/language/pure/compiler/toPureGraph/handlers/Handlers.java b/legend-engine-core/legend-engine-core-base/legend-engine-core-language-pure/legend-engine-language-pure-compiler/src/main/java/org/finos/legend/engine/language/pure/compiler/toPureGraph/handlers/Handlers.java index b60c83458d9..574b8f3e984 100644 --- a/legend-engine-core/legend-engine-core-base/legend-engine-core-language-pure/legend-engine-language-pure-compiler/src/main/java/org/finos/legend/engine/language/pure/compiler/toPureGraph/handlers/Handlers.java +++ b/legend-engine-core/legend-engine-core-base/legend-engine-core-language-pure/legend-engine-language-pure-compiler/src/main/java/org/finos/legend/engine/language/pure/compiler/toPureGraph/handlers/Handlers.java @@ -1450,6 +1450,7 @@ private void registerDates() h("meta::pure::functions::date::year_Date_$0_1$__Integer_$0_1$_", false, ps -> res("Integer", "zeroOne"), ps -> typeZeroOne(ps.get(0), DATE))); register("meta::pure::functions::date::adjust_Date_1__Integer_1__DurationUnit_1__Date_1_", true, ps -> res("Date", "one")); + register("meta::pure::functions::date::convertTimeZone_DateTime_1__String_1__String_1__String_1_", false, ps -> res("String", "one")); register(m(m(h("meta::pure::functions::date::date_Integer_1__Date_1_", true, ps -> res("Date", "one"), ps -> ps.size() == 1)), m(h("meta::pure::functions::date::date_Integer_1__Integer_1__Date_1_", true, ps -> res("Date", "one"), ps -> ps.size() == 2)), @@ -2450,6 +2451,7 @@ private Map buildDispatch() map.put("meta::pure::functions::constraints::warn_Boolean_1__String_1__Boolean_1_", (List ps) -> ps.size() == 2 && isOne(ps.get(0)._multiplicity()) && ("Nil".equals(ps.get(0)._genericType()._rawType()._name()) || "Boolean".equals(ps.get(0)._genericType()._rawType()._name())) && isOne(ps.get(1)._multiplicity()) && ("Nil".equals(ps.get(1)._genericType()._rawType()._name()) || "String".equals(ps.get(1)._genericType()._rawType()._name()))); map.put("meta::pure::functions::date::add_StrictDate_1__Duration_1__StrictDate_1_", (List ps) -> ps.size() == 2 && isOne(ps.get(0)._multiplicity()) && ("Nil".equals(ps.get(0)._genericType()._rawType()._name()) || "StrictDate".equals(ps.get(0)._genericType()._rawType()._name())) && isOne(ps.get(1)._multiplicity()) && ("Nil".equals(ps.get(1)._genericType()._rawType()._name()) || "Duration".equals(ps.get(1)._genericType()._rawType()._name()))); map.put("meta::pure::functions::date::adjust_Date_1__Integer_1__DurationUnit_1__Date_1_", (List ps) -> ps.size() == 3 && isOne(ps.get(0)._multiplicity()) && Sets.immutable.with("Nil", "Date", "StrictDate", "DateTime", "LatestDate").contains(ps.get(0)._genericType()._rawType()._name()) && isOne(ps.get(1)._multiplicity()) && ("Nil".equals(ps.get(1)._genericType()._rawType()._name()) || "Integer".equals(ps.get(1)._genericType()._rawType()._name())) && isOne(ps.get(2)._multiplicity()) && ("Nil".equals(ps.get(2)._genericType()._rawType()._name()) || "DurationUnit".equals(ps.get(2)._genericType()._rawType()._name()))); + map.put("meta::pure::functions::date::convertTimeZone_DateTime_1__String_1__String_1__String_1_", (List ps) -> ps.size() == 3 && isOne(ps.get(0)._multiplicity()) && ("Nil".equals(ps.get(0)._genericType()._rawType()._name()) || "DateTime".equals(ps.get(0)._genericType()._rawType()._name())) && isOne(ps.get(1)._multiplicity()) && ("Nil".equals(ps.get(1)._genericType()._rawType()._name()) || "String".equals(ps.get(1)._genericType()._rawType()._name())) && isOne(ps.get(2)._multiplicity()) && ("Nil".equals(ps.get(2)._genericType()._rawType()._name()) || "String".equals(ps.get(2)._genericType()._rawType()._name()))); map.put("meta::pure::functions::date::dateDiff_Date_$0_1$__Date_$0_1$__DurationUnit_1__Integer_$0_1$_", (List ps) -> ps.size() == 3 && matchZeroOne(ps.get(0)._multiplicity()) && Sets.immutable.with("Nil", "Date", "StrictDate", "DateTime", "LatestDate").contains(ps.get(0)._genericType()._rawType()._name()) && matchZeroOne(ps.get(1)._multiplicity()) && Sets.immutable.with("Nil", "Date", "StrictDate", "DateTime", "LatestDate").contains(ps.get(1)._genericType()._rawType()._name()) && isOne(ps.get(2)._multiplicity()) && ("Nil".equals(ps.get(2)._genericType()._rawType()._name()) || "DurationUnit".equals(ps.get(2)._genericType()._rawType()._name()))); map.put("meta::pure::functions::date::dateDiff_Date_1__Date_1__DurationUnit_1__Integer_1_", (List ps) -> ps.size() == 3 && isOne(ps.get(0)._multiplicity()) && Sets.immutable.with("Nil", "Date", "StrictDate", "DateTime", "LatestDate").contains(ps.get(0)._genericType()._rawType()._name()) && isOne(ps.get(1)._multiplicity()) && Sets.immutable.with("Nil", "Date", "StrictDate", "DateTime", "LatestDate").contains(ps.get(1)._genericType()._rawType()._name()) && isOne(ps.get(2)._multiplicity()) && ("Nil".equals(ps.get(2)._genericType()._rawType()._name()) || "DurationUnit".equals(ps.get(2)._genericType()._rawType()._name()))); map.put("meta::pure::functions::date::datePart_Date_$0_1$__Date_$0_1$_", (List ps) -> ps.size() == 1 && matchZeroOne(ps.get(0)._multiplicity()) && Sets.immutable.with("Nil", "Date", "StrictDate", "DateTime", "LatestDate").contains(ps.get(0)._genericType()._rawType()._name())); diff --git a/legend-engine-core/legend-engine-core-pure/legend-engine-pure-code-compiled-core/src/main/resources/core/pure/corefunctions/dateExtension.pure b/legend-engine-core/legend-engine-core-pure/legend-engine-pure-code-compiled-core/src/main/resources/core/pure/corefunctions/dateExtension.pure index cbd65834de6..486b1972a4c 100644 --- a/legend-engine-core/legend-engine-core-pure/legend-engine-pure-code-compiled-core/src/main/resources/core/pure/corefunctions/dateExtension.pure +++ b/legend-engine-core/legend-engine-core-pure/legend-engine-pure-code-compiled-core/src/main/resources/core/pure/corefunctions/dateExtension.pure @@ -471,6 +471,14 @@ function meta::pure::functions::date::systemDefaultTimeZones():String[*] ['GMT', 'UTC'] } +function {doc.doc ='Adjust the timezone of a date time and format the time to the specifid format'} +meta::pure::functions::date::convertTimeZone(time:DateTime[1], targetZone:String[1],targetFormat:String[1]):String[1] +{ + format( '%t{['+$targetZone+']'+$targetFormat+'}' ,$time); +} + + + function meta::pure::functions::date::hasYear(d:Date[1]):Boolean[1] { true; @@ -641,5 +649,5 @@ function meta::pure::functions::date::toEpochValue(d:Date[1], unit:DurationUnit[ function meta::pure::functions::date::validateDateTimeFormat(dateTimeFormat:String[1]):Boolean[1] { // Supported Formats : yyyy, yyyy-M, yyyy-MM, yyyy-MM-d, yyyy-M-d, yyyy-MM-dd, yyyy/mm/dd, yyyyMMdd, yyyyMd, yyMd, dd/MM/yyyy, MM/dd/yyyy, MM/dd/yyyy "at" hh:mma z, yyyy-MM-dd HH:mm:ss, yyyy-MM-dd h:mm:ssa, yyyy-MM-dd HH:mm:ss.SSS, yyyy-MM-dd HH:mm:ss.SSSX, yyyy-MM-dd HH:mm:ss.SSSZ, yyyy-MM-dd HH:mm:ss.SSS z, yyyy-MM-dd HH:mm:ss.SSSS z, yyyy-MM-dd"T"HH:mm:ss, yyyy-MM-dd"T"HH:mm:ssZ, yyyy-MM-dd"T"HH:mm:ss.SSS, yyyy-MM-dd"T"HH:mm:ss.SSSZ, yyyy-MM-dd"T"HH:mm:ss.SSSSZ, yy-MM-dd"T"HH:mm:ss."000000", , 'yyyy-MM-dd"T"HH:mm:ss."000000"X', [EST]yyyy-MM-dd HH:mm:ss.SSSZ, [CST]yyyy-MM-dd HH:mm:ss.SSS z, [CET]yyyy-MM-dd HH:mm:ss.SSSX, [EST]yyyy-MM-dd and other timezones - $dateTimeFormat->matches('(\\[[A-Z][A-Z]([ACDKLMNORSTUVW])?([DSWT])?([T])?\\])?(MM/dd/|dd/MM/)?(?:y{4}|y{2})(([-/])?[mM]{1,2}(([-/])?(d{1,2}) *((\"T\")?(H{2}|h{1}):m{2}:s{2}.?((?:S{3,4} *[zZX]?|\"000000\"))?)?)?)? *(\"at\")? *(h{2}:m{2}a)? *[zZxX]?'); + $dateTimeFormat->matches('(\\[[A-Z][A-Z]([ACDKLMNORSTUVW])?([DSWT])?([T])?\\])?(MM/dd/|dd/MM/)?(?:y{4}|y{2})(([-/])?[mM]{1,2}(([-/])?(d{1,2}) *((\"T\"|T)?(H{2}|h{1}):m{2}:s{2}.?((?:S{3,4} *[zZX]?|\"000000\"))?)?)?)? *(\"at\")? *(h{2}:m{2}a)? *[zZxX]?'); } diff --git a/legend-engine-core/legend-engine-core-pure/legend-engine-pure-code-compiled-core/src/main/resources/core/pure/corefunctions/tests/date/testDate.pure b/legend-engine-core/legend-engine-core-pure/legend-engine-pure-code-compiled-core/src/main/resources/core/pure/corefunctions/tests/date/testDate.pure index e4bd32161e5..db2e0e02420 100644 --- a/legend-engine-core/legend-engine-core-pure/legend-engine-pure-code-compiled-core/src/main/resources/core/pure/corefunctions/tests/date/testDate.pure +++ b/legend-engine-core/legend-engine-core-pure/legend-engine-pure-code-compiled-core/src/main/resources/core/pure/corefunctions/tests/date/testDate.pure @@ -27,3 +27,10 @@ function <> meta::pure::functions::date::tests::testValidateDateTimeF let invalidFormats = ['yyy', 'yyyyy-M', 'yyyy-MMM', 'yyyy-MM-ddd', 'dd/mm/yyyy', 'MM/ddyy', 'MM/dd/yyyy "at" hh:ma z', 'yyyy-MMM-dd HH:mm:ss', 'yyyy-MM-dd hh:mm:ssa', 'yyyy-MM-dd HH:mm:ss.SSZ', 'yyyy-MM-dd HH:mm:ss.SZ', 'yyyy-MM-dd"TT"HH:mm:ss', 'yyyy-MM-dd"T"HH:mm:sss.SSS', 'yyyy-MM-dd""HH:mm:ss.SSSZ', 'yyyy-MM-dd"T"HH:mm:ss.SSSSSZ', 'yy-MM-dd"T"HH:mm:ss."00"', '(EST)yyyy-MM-dd']; assert($invalidFormats->map(format | validateDateTimeFormat($format))->assertNotContains(true)); } + + +function <> meta::pure::functions::date::tests::testconvertTimeZone():Boolean[1] +{ + assertEquals('2024-08-15T11:33:42.054-0400', convertTimeZone(%2024-08-15T15:33:42.054+0000,'America/New_York','yyyy-MM-dd"T"HH:mm:ss.SSSZ')); +} + \ No newline at end of file diff --git a/legend-engine-core/legend-engine-core-pure/legend-engine-pure-code-compiled-core/src/main/resources/core/pure/router/routing/router_routing.pure b/legend-engine-core/legend-engine-core-pure/legend-engine-pure-code-compiled-core/src/main/resources/core/pure/router/routing/router_routing.pure index 234fa16c7e8..3698befe0ac 100644 --- a/legend-engine-core/legend-engine-core-pure/legend-engine-pure-code-compiled-core/src/main/resources/core/pure/router/routing/router_routing.pure +++ b/legend-engine-core/legend-engine-core-pure/legend-engine-pure-code-compiled-core/src/main/resources/core/pure/router/routing/router_routing.pure @@ -921,7 +921,8 @@ function meta::pure::router::routing::shouldStopFunctions(extensions:meta::pure: sort_T_m__T_m_, sort_T_m__Function_$0_1$__T_m_, sortBy_T_m__Function_$0_1$__T_m_, - sort_T_m__Function_$0_1$__Function_$0_1$__T_m_ + sort_T_m__Function_$0_1$__Function_$0_1$__T_m_, + meta::pure::functions::date::convertTimeZone_DateTime_1__String_1__String_1__String_1_ ]->concatenate($extensions.routerExtensions().shouldStopRouting) } diff --git a/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-dbExtension/legend-engine-xt-relationalStore-memsql/legend-engine-xt-relationalStore-memsql-pure/src/main/resources/core_relational_memsql/relational/sqlQueryToString/memSQLExtension.pure b/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-dbExtension/legend-engine-xt-relationalStore-memsql/legend-engine-xt-relationalStore-memsql-pure/src/main/resources/core_relational_memsql/relational/sqlQueryToString/memSQLExtension.pure index 630dedb5675..67113b44441 100644 --- a/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-dbExtension/legend-engine-xt-relationalStore-memsql/legend-engine-xt-relationalStore-memsql-pure/src/main/resources/core_relational_memsql/relational/sqlQueryToString/memSQLExtension.pure +++ b/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-dbExtension/legend-engine-xt-relationalStore-memsql/legend-engine-xt-relationalStore-memsql-pure/src/main/resources/core_relational_memsql/relational/sqlQueryToString/memSQLExtension.pure @@ -141,7 +141,9 @@ function <> meta::relational::functions::sqlQueryToString::memsq dynaFnToSql('toString', $allStates, ^ToSql(format='cast(%s as char)')), dynaFnToSql('toTimestamp', $allStates, ^ToSql(format='%s', transform={p:String[2] | $p->transformToTimestampMemSQL()})), dynaFnToSql('year', $allStates, ^ToSql(format='year(%s)')), - dynaFnToSql('weekOfYear', $allStates, ^ToSql(format='weekofyear(%s)')) + dynaFnToSql('weekOfYear', $allStates, ^ToSql(format='weekofyear(%s)')), + dynaFnToSql('convertTimeZone', $allStates, ^ToSql(format='%s', contextAwareTransform={p:String[3],s:SqlGenerationContext[1] | $p->transformConvertTimeZone($s)})) + ]; } @@ -179,6 +181,17 @@ function <> meta::relational::functions::sqlQueryToString::memsq let timestampFormat = $params->at(1); 'to_timestamp('+$params->at(0)+','+$timestampFormat+')'; } +function <> meta::relational::functions::sqlQueryToString::memsql::transformConvertTimeZone(params:String[3],context:SqlGenerationContext[1]):String[1] +{ + let sourceTZ = if($context.dbConfig.dbTimeZone->isEmpty(),|'GMT',|$context.dbConfig.dbTimeZone->toOne()); + let unWrappedfmt = $params->at(2)->substring(1, $params->at(2)->length()-1); + assert($unWrappedfmt->validateDateTimeFormat(),'Found an invalid date format'); + let formatpairs = meta::relational::functions::sqlQueryToString::default::defaultJavaToSQLTimeParts(); + let msqlDate = $formatpairs->fold( {sub, date| $date->toOne()->replace($sub.first,$sub.second)},$params->at(2)); + format('TO_CHAR(CONVERT_TZ(%s,\'%s\',%s),%s)',[$params->at(0),$sourceTZ,$params->at(1),$msqlDate]); +} + + function <> meta::relational::functions::sqlQueryToString::memsql::generateDateDiffExpressionForMemSQL(params:String[*]):String[1] { diff --git a/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-dbExtension/legend-engine-xt-relationalStore-memsql/legend-engine-xt-relationalStore-memsql-pure/src/main/resources/core_relational_memsql/relational/tests/mapping/sqlFunction/testSqlFunctionsInMapping.pure b/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-dbExtension/legend-engine-xt-relationalStore-memsql/legend-engine-xt-relationalStore-memsql-pure/src/main/resources/core_relational_memsql/relational/tests/mapping/sqlFunction/testSqlFunctionsInMapping.pure index a02ba4f6546..42f7c66a4e1 100644 --- a/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-dbExtension/legend-engine-xt-relationalStore-memsql/legend-engine-xt-relationalStore-memsql-pure/src/main/resources/core_relational_memsql/relational/tests/mapping/sqlFunction/testSqlFunctionsInMapping.pure +++ b/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-dbExtension/legend-engine-xt-relationalStore-memsql/legend-engine-xt-relationalStore-memsql-pure/src/main/resources/core_relational_memsql/relational/tests/mapping/sqlFunction/testSqlFunctionsInMapping.pure @@ -147,3 +147,13 @@ function <> meta::relational::memsql::tests::mapping::sqlFunction::ba meta::relational::runtime::DatabaseType.MemSQL, meta::relational::extension::relationalExtensions()); assertEquals('select cast(to_base64(`root`.alphaNumericString) as char) as `res1`, cast(from_base64(cast(to_base64(`root`.alphaNumericString) as char)) as char) as `res2` from dataTable as `root`', $s); } + + + +function <> meta::relational::memsql::tests::mapping::sqlFunction::convertTZ::testConvertTZ():Boolean[1] +{ + let s = toSQLString(|SqlFunctionDemo.all()->project([s | $s.convertTimeZone,s|$s.dateTime->convertTimeZone('EST','yyyy-MM-ddTHH:mm:ss.SSS')], ['tzm','tzQuery']), + testMapping, + meta::relational::runtime::DatabaseType.MemSQL, meta::relational::extension::relationalExtensions()); + assertEquals('select TO_CHAR(CONVERT_TZ(`root`.dateTime,\'GMT\',\'EST\'),\'YYYY-MM-DD HH24:MI:SS\') as `tzm`, TO_CHAR(CONVERT_TZ(`root`.dateTime,\'GMT\',\'EST\'),\'YYYY-MM-DDTHH24:MI:SS.FF3\') as `tzQuery` from dataTable as `root`',$s); +} diff --git a/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-dbExtension/legend-engine-xt-relationalStore-snowflake/legend-engine-xt-relationalStore-snowflake-pure/src/main/resources/core_relational_snowflake/relational/sqlQueryToString/snowflakeExtension.pure b/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-dbExtension/legend-engine-xt-relationalStore-snowflake/legend-engine-xt-relationalStore-snowflake-pure/src/main/resources/core_relational_snowflake/relational/sqlQueryToString/snowflakeExtension.pure index b43c2d1ecec..161b81dc835 100644 --- a/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-dbExtension/legend-engine-xt-relationalStore-snowflake/legend-engine-xt-relationalStore-snowflake-pure/src/main/resources/core_relational_snowflake/relational/sqlQueryToString/snowflakeExtension.pure +++ b/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-dbExtension/legend-engine-xt-relationalStore-snowflake/legend-engine-xt-relationalStore-snowflake-pure/src/main/resources/core_relational_snowflake/relational/sqlQueryToString/snowflakeExtension.pure @@ -191,7 +191,11 @@ function <> meta::relational::functions::sqlQueryToString::snowf dynaFnToSql('toString', $allStates, ^ToSql(format='cast(%s as varchar)')), dynaFnToSql('toTimestamp', $allStates, ^ToSql(format='%s' , transform={p:String[2] | $p->transformToTimestampSnowflake()})), dynaFnToSql('weekOfYear', $allStates, ^ToSql(format='WEEKOFYEAR(%s)')), - dynaFnToSql('year', $allStates, ^ToSql(format='year(%s)')) + dynaFnToSql('year', $allStates, ^ToSql(format='year(%s)')), + dynaFnToSql('convertTimeZone', $allStates, ^ToSql(format='%s', contextAwareTransform={p:String[3],s:SqlGenerationContext[1] | $p->transformConvertTimeZone($s)})) + + + ]; } @@ -404,6 +408,21 @@ function meta::relational::functions::sqlQueryToString::snowflake::preAndFinally ); } + + +function <> meta::relational::functions::sqlQueryToString::snowflake::transformConvertTimeZone(params:String[3],context:SqlGenerationContext[1]):String[1] +{ + let unWrappedfmt = $params->at(2)->substring(1, $params->at(2)->length()-1); $unWrappedfmt->println(); + assert($unWrappedfmt->validateDateTimeFormat(),'Found an invalid date format'); + let formatpairs = meta::relational::functions::sqlQueryToString::default::defaultJavaToSQLTimeParts(); + let format = $formatpairs->fold( {sub, date| $date->toOne()->replace($sub.first,$sub.second)},$params->at(2)); + format('TO_CHAR(CONVERT_TIMEZONE(%s,%s),%s)',[$params->at(0),$params->at(1),$format]); +} + + + + + function <> meta::relational::functions::sqlQueryToString::snowflake::snowflakeReservedWords():String[*] { // Based on https://docs.snowflake.com/en/sql-reference/reserved-keywords @@ -494,4 +513,3 @@ function <> meta::relational::functions::sqlQueryToString::snowf ] } - diff --git a/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-dbExtension/legend-engine-xt-relationalStore-snowflake/legend-engine-xt-relationalStore-snowflake-pure/src/main/resources/core_relational_snowflake/relational/tests/testSnowflakeSqlFunctionsInMapping.pure b/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-dbExtension/legend-engine-xt-relationalStore-snowflake/legend-engine-xt-relationalStore-snowflake-pure/src/main/resources/core_relational_snowflake/relational/tests/testSnowflakeSqlFunctionsInMapping.pure index 3c8de678423..74a28a479ef 100644 --- a/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-dbExtension/legend-engine-xt-relationalStore-snowflake/legend-engine-xt-relationalStore-snowflake-pure/src/main/resources/core_relational_snowflake/relational/tests/testSnowflakeSqlFunctionsInMapping.pure +++ b/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-dbExtension/legend-engine-xt-relationalStore-snowflake/legend-engine-xt-relationalStore-snowflake-pure/src/main/resources/core_relational_snowflake/relational/tests/testSnowflakeSqlFunctionsInMapping.pure @@ -195,4 +195,12 @@ function <> meta::relational::tests::mapping::function::snowflake::te testMapping, meta::relational::runtime::DatabaseType.Snowflake, meta::relational::extension::relationalExtensions()); assertEquals('select to_boolean(\'true\') as "bolValue" from dataTable as "root"',$s); -} \ No newline at end of file +} + +function <> meta::relational::tests::mapping::function::snowflake::testConvertTimeZone():Boolean[1] +{ + let s = toSQLString(|SqlFunctionDemo.all()->project([s | $s.convertTimeZone,s|$s.dateTime->convertTimeZone('EST','yyyy-MM-ddTHH:mm:ss')], ['tzm','tzQuery']), + testMapping, + meta::relational::runtime::DatabaseType.Snowflake, meta::relational::extension::relationalExtensions()); + assertEquals('select TO_CHAR(CONVERT_TIMEZONE("root".dateTime,\'EST\'),\'YYYY-MM-DD HH24:MI:SS\') as "tzm", TO_CHAR(CONVERT_TIMEZONE("root".dateTime,\'EST\'),\'YYYY-MM-DDTHH24:MI:SS\') as "tzQuery" from dataTable as "root"',$s); +} diff --git a/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-execution/legend-engine-xt-relationalStore-executionPlan-connection/src/main/java/org/finos/legend/engine/plan/execution/stores/relational/LegendH2Extensions.java b/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-execution/legend-engine-xt-relationalStore-executionPlan-connection/src/main/java/org/finos/legend/engine/plan/execution/stores/relational/LegendH2Extensions.java index 64105801d39..4bd73ab001b 100644 --- a/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-execution/legend-engine-xt-relationalStore-executionPlan-connection/src/main/java/org/finos/legend/engine/plan/execution/stores/relational/LegendH2Extensions.java +++ b/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-execution/legend-engine-xt-relationalStore-executionPlan-connection/src/main/java/org/finos/legend/engine/plan/execution/stores/relational/LegendH2Extensions.java @@ -22,6 +22,7 @@ import org.apache.commons.text.similarity.LevenshteinDistance; import org.finos.legend.engine.shared.core.ObjectMapperFactory; import org.h2.tools.SimpleResultSet; +import org.h2.util.DateTimeUtils; import org.h2.value.Value; import org.h2.value.ValueArray; import org.h2.value.ValueBigint; @@ -30,6 +31,7 @@ import org.h2.value.ValueInteger; import org.h2.value.ValueNull; import org.h2.value.ValueReal; +import org.h2.value.ValueTimestamp; import org.h2.value.ValueVarchar; import java.math.BigDecimal; @@ -37,6 +39,10 @@ import java.sql.Connection; import java.sql.ResultSet; import java.sql.Types; +import java.time.LocalDateTime; +import java.time.LocalTime; +import java.time.ZoneId; +import java.time.ZonedDateTime; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; @@ -331,4 +337,19 @@ public static Value legend_h2_extension_jaro_winkler_similarity(Value string1, V return ValueDouble.get(new JaroWinklerSimilarity().apply(string1.getString(), string2.getString())); } + + public static Value legend_h2_extension_convertTimeZone(Value string1, Value string2) + { + if (string1 == ValueNull.INSTANCE || string2 == ValueNull.INSTANCE) + { + return ValueNull.INSTANCE; + } + String targetTimezone = string2.getString(); + LocalDateTime localDateTime = LocalDateTime.parse(((ValueTimestamp) string1).getISOString()); + ZonedDateTime utcTime = localDateTime.atZone(ZoneId.of("UTC")); + ZonedDateTime targetTime = utcTime.withZoneSameInstant(ZoneId.of(targetTimezone)); + LocalTime time = targetTime.toLocalTime(); + return DateTimeUtils.parseTimestamp(targetTime.toLocalDateTime().toString(),null,false); + + } } diff --git a/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-execution/legend-engine-xt-relationalStore-executionPlan-connection/src/main/java/org/finos/legend/engine/plan/execution/stores/relational/connection/authentication/strategy/DefaultH2AuthenticationStrategy.java b/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-execution/legend-engine-xt-relationalStore-executionPlan-connection/src/main/java/org/finos/legend/engine/plan/execution/stores/relational/connection/authentication/strategy/DefaultH2AuthenticationStrategy.java index db24c8d92ed..455ec6c21df 100644 --- a/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-execution/legend-engine-xt-relationalStore-executionPlan-connection/src/main/java/org/finos/legend/engine/plan/execution/stores/relational/connection/authentication/strategy/DefaultH2AuthenticationStrategy.java +++ b/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-execution/legend-engine-xt-relationalStore-executionPlan-connection/src/main/java/org/finos/legend/engine/plan/execution/stores/relational/connection/authentication/strategy/DefaultH2AuthenticationStrategy.java @@ -110,7 +110,9 @@ private static List getLegendH2ExtensionSQLs() "CREATE ALIAS IF NOT EXISTS legend_h2_extension_flatten_array FOR \"org.finos.legend.engine.plan.execution.stores.relational.LegendH2Extensions.legend_h2_extension_flatten_array\";", "CREATE ALIAS IF NOT EXISTS legend_h2_extension_split_part FOR \"org.finos.legend.engine.plan.execution.stores.relational.LegendH2Extensions.legend_h2_extension_split_part\";", "CREATE ALIAS IF NOT EXISTS legend_h2_extension_edit_distance FOR \"org.finos.legend.engine.plan.execution.stores.relational.LegendH2Extensions.legend_h2_extension_edit_distance\";", - "CREATE ALIAS IF NOT EXISTS legend_h2_extension_jaro_winkler_similarity FOR \"org.finos.legend.engine.plan.execution.stores.relational.LegendH2Extensions.legend_h2_extension_jaro_winkler_similarity\";" + "CREATE ALIAS IF NOT EXISTS legend_h2_extension_jaro_winkler_similarity FOR \"org.finos.legend.engine.plan.execution.stores.relational.LegendH2Extensions.legend_h2_extension_jaro_winkler_similarity\";", + "CREATE ALIAS IF NOT EXISTS legend_h2_extension_convertTimeZone FOR \"org.finos.legend.engine.plan.execution.stores.relational.LegendH2Extensions.legend_h2_extension_convertTimeZone\";" + ); } @@ -127,7 +129,9 @@ private static List getLegendH2_1_4_200_ExtensionSQLs() "CREATE ALIAS IF NOT EXISTS legend_h2_extension_flatten_array FOR \"org.finos.legend.engine.plan.execution.stores.relational.LegendH2Extensions_1_4_200.legend_h2_extension_flatten_array\";", "CREATE ALIAS IF NOT EXISTS legend_h2_extension_split_part FOR \"org.finos.legend.engine.plan.execution.stores.relational.LegendH2Extensions_1_4_200.legend_h2_extension_split_part\";", "CREATE ALIAS IF NOT EXISTS legend_h2_extension_edit_distance FOR \"org.finos.legend.engine.plan.execution.stores.relational.LegendH2Extensions_1_4_200.legend_h2_extension_edit_distance\";", - "CREATE ALIAS IF NOT EXISTS legend_h2_extension_jaro_winkler_similarity FOR \"org.finos.legend.engine.plan.execution.stores.relational.LegendH2Extensions_1_4_200.legend_h2_extension_jaro_winkler_similarity\";" + "CREATE ALIAS IF NOT EXISTS legend_h2_extension_jaro_winkler_similarity FOR \"org.finos.legend.engine.plan.execution.stores.relational.LegendH2Extensions_1_4_200.legend_h2_extension_jaro_winkler_similarity\";", + "CREATE ALIAS IF NOT EXISTS legend_h2_extension_convertTimeZone FOR \"org.finos.legend.engine.plan.execution.stores.relational.LegendH2Extensions_1_4_200.legend_h2_extension_convertTimeZone\";" + ); } } diff --git a/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-execution/legend-engine-xt-relationalStore-h2-1.4.200-execution/src/main/java/org/finos/legend/engine/plan/execution/stores/relational/LegendH2Extensions_1_4_200.java b/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-execution/legend-engine-xt-relationalStore-h2-1.4.200-execution/src/main/java/org/finos/legend/engine/plan/execution/stores/relational/LegendH2Extensions_1_4_200.java index 19aa050c097..3a8dbc64a23 100644 --- a/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-execution/legend-engine-xt-relationalStore-h2-1.4.200-execution/src/main/java/org/finos/legend/engine/plan/execution/stores/relational/LegendH2Extensions_1_4_200.java +++ b/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-execution/legend-engine-xt-relationalStore-h2-1.4.200-execution/src/main/java/org/finos/legend/engine/plan/execution/stores/relational/LegendH2Extensions_1_4_200.java @@ -23,6 +23,7 @@ import org.apache.commons.text.similarity.LevenshteinDistance; import org.finos.legend.engine.shared.core.ObjectMapperFactory; import org.h2.tools.SimpleResultSet; +import org.h2.util.DateTimeUtils; import org.h2.value.Value; import org.h2.value.ValueArray; import org.h2.value.ValueBoolean; @@ -38,6 +39,11 @@ import java.sql.Connection; import java.sql.ResultSet; import java.sql.Types; +import java.time.LocalDateTime; +import java.time.LocalTime; +import java.time.ZoneId; +import java.time.ZonedDateTime; +import java.time.format.DateTimeFormatter; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; @@ -343,4 +349,18 @@ public static Value legend_h2_extension_jaro_winkler_similarity(Value string1, V return ValueDouble.get(new JaroWinklerSimilarity().apply(string1.getString(), string2.getString())); } + + public static Value legend_h2_extension_convertTimeZone(Value string1, Value string2) + { + if (string1 == ValueNull.INSTANCE || string2 == ValueNull.INSTANCE) + { + return ValueNull.INSTANCE; + } + String targetTimezone = string2.getString(); + LocalDateTime localDateTime = LocalDateTime.parse(string1.getString(),DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")); + ZonedDateTime utcTime = localDateTime.atZone(ZoneId.of("UTC")); + ZonedDateTime targetTime = utcTime.withZoneSameInstant(ZoneId.of(targetTimezone)); + LocalTime time = targetTime.toLocalTime(); + return DateTimeUtils.parseTimestamp(targetTime.toLocalDateTime().toString(),null,false); + } } diff --git a/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-generation/legend-engine-xt-relationalStore-pure/src/main/resources/core_relational/relational/pureToSQLQuery/pureToSQLQuery.pure b/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-generation/legend-engine-xt-relationalStore-pure/src/main/resources/core_relational/relational/pureToSQLQuery/pureToSQLQuery.pure index 86c43ca0435..c8ffa354969 100644 --- a/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-generation/legend-engine-xt-relationalStore-pure/src/main/resources/core_relational/relational/pureToSQLQuery/pureToSQLQuery.pure +++ b/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-generation/legend-engine-xt-relationalStore-pure/src/main/resources/core_relational/relational/pureToSQLQuery/pureToSQLQuery.pure @@ -8329,6 +8329,8 @@ function meta::relational::functions::pureToSqlQuery::getSupportedFunctions():Ma ^PureFunctionToRelationalFunctionPair(first=meta::pure::functions::date::previousDayOfWeek_DayOfWeek_1__Date_1_,second=meta::relational::functions::pureToSqlQuery::processDynaFunction_FunctionExpression_1__PropertyMapping_MANY__SelectWithCursor_1__Map_1__State_1__JoinType_1__String_1__List_1__DebugContext_1__Extension_MANY__RelationalOperationElement_1_), ^PureFunctionToRelationalFunctionPair(first=meta::pure::functions::date::previousDayOfWeek_Date_1__DayOfWeek_1__Date_1_,second=meta::relational::functions::pureToSqlQuery::processDynaFunction_FunctionExpression_1__PropertyMapping_MANY__SelectWithCursor_1__Map_1__State_1__JoinType_1__String_1__List_1__DebugContext_1__Extension_MANY__RelationalOperationElement_1_), ^PureFunctionToRelationalFunctionPair(first=meta::pure::functions::date::dayOfMonth_Date_1__Integer_1_,second=meta::relational::functions::pureToSqlQuery::processDynaFunction_FunctionExpression_1__PropertyMapping_MANY__SelectWithCursor_1__Map_1__State_1__JoinType_1__String_1__List_1__DebugContext_1__Extension_MANY__RelationalOperationElement_1_), + ^PureFunctionToRelationalFunctionPair(first=meta::pure::functions::date::convertTimeZone_DateTime_1__String_1__String_1__String_1_,second=meta::relational::functions::pureToSqlQuery::processDynaFunction_FunctionExpression_1__PropertyMapping_MANY__SelectWithCursor_1__Map_1__State_1__JoinType_1__String_1__List_1__DebugContext_1__Extension_MANY__RelationalOperationElement_1_), + ^PureFunctionToRelationalFunctionPair(first=meta::pure::functions::string::ascii_String_1__Integer_1_,second=meta::relational::functions::pureToSqlQuery::processDynaFunction_FunctionExpression_1__PropertyMapping_MANY__SelectWithCursor_1__Map_1__State_1__JoinType_1__String_1__List_1__DebugContext_1__Extension_MANY__RelationalOperationElement_1_), ^PureFunctionToRelationalFunctionPair(first=meta::pure::functions::string::char_Integer_1__String_1_,second=meta::relational::functions::pureToSqlQuery::processDynaFunction_FunctionExpression_1__PropertyMapping_MANY__SelectWithCursor_1__Map_1__State_1__JoinType_1__String_1__List_1__DebugContext_1__Extension_MANY__RelationalOperationElement_1_), ^PureFunctionToRelationalFunctionPair(first=meta::pure::functions::string::startsWith_String_1__String_1__Boolean_1_,second=meta::relational::functions::pureToSqlQuery::processDynaFunction_FunctionExpression_1__PropertyMapping_MANY__SelectWithCursor_1__Map_1__State_1__JoinType_1__String_1__List_1__DebugContext_1__Extension_MANY__RelationalOperationElement_1_), @@ -8358,6 +8360,7 @@ function meta::relational::functions::pureToSqlQuery::getSupportedFunctions():Ma ^PureFunctionToRelationalFunctionPair(first=meta::pure::functions::string::repeatString_String_$0_1$__Integer_1__String_$0_1$_,second=meta::relational::functions::pureToSqlQuery::processDynaFunction_FunctionExpression_1__PropertyMapping_MANY__SelectWithCursor_1__Map_1__State_1__JoinType_1__String_1__List_1__DebugContext_1__Extension_MANY__RelationalOperationElement_1_), ^PureFunctionToRelationalFunctionPair(first=meta::pure::functions::string::reverseString_String_1__String_1_,second=meta::relational::functions::pureToSqlQuery::processDynaFunction_FunctionExpression_1__PropertyMapping_MANY__SelectWithCursor_1__Map_1__State_1__JoinType_1__String_1__List_1__DebugContext_1__Extension_MANY__RelationalOperationElement_1_), ^PureFunctionToRelationalFunctionPair(first=meta::pure::functions::string::splitPart_String_$0_1$__String_1__Integer_1__String_$0_1$_,second=meta::relational::functions::pureToSqlQuery::processSplitPart_FunctionExpression_1__PropertyMapping_MANY__SelectWithCursor_1__Map_1__State_1__JoinType_1__String_1__List_1__DebugContext_1__Extension_MANY__RelationalOperationElement_1_), + ^PureFunctionToRelationalFunctionPair(first=meta::pure::functions::math::abs_Integer_1__Integer_1_,second=meta::relational::functions::pureToSqlQuery::processDynaFunction_FunctionExpression_1__PropertyMapping_MANY__SelectWithCursor_1__Map_1__State_1__JoinType_1__String_1__List_1__DebugContext_1__Extension_MANY__RelationalOperationElement_1_), ^PureFunctionToRelationalFunctionPair(first=meta::pure::functions::math::abs_Number_1__Number_1_,second=meta::relational::functions::pureToSqlQuery::processDynaFunction_FunctionExpression_1__PropertyMapping_MANY__SelectWithCursor_1__Map_1__State_1__JoinType_1__String_1__List_1__DebugContext_1__Extension_MANY__RelationalOperationElement_1_), ^PureFunctionToRelationalFunctionPair(first=meta::pure::functions::math::abs_Float_1__Float_1_,second=meta::relational::functions::pureToSqlQuery::processDynaFunction_FunctionExpression_1__PropertyMapping_MANY__SelectWithCursor_1__Map_1__State_1__JoinType_1__String_1__List_1__DebugContext_1__Extension_MANY__RelationalOperationElement_1_), diff --git a/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-generation/legend-engine-xt-relationalStore-pure/src/main/resources/core_relational/relational/sqlQueryToString/dbExtension.pure b/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-generation/legend-engine-xt-relationalStore-pure/src/main/resources/core_relational/relational/sqlQueryToString/dbExtension.pure index e397bdbe8b7..984984e5f86 100644 --- a/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-generation/legend-engine-xt-relationalStore-pure/src/main/resources/core_relational/relational/sqlQueryToString/dbExtension.pure +++ b/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-generation/legend-engine-xt-relationalStore-pure/src/main/resources/core_relational/relational/sqlQueryToString/dbExtension.pure @@ -906,7 +906,12 @@ Class meta::relational::functions::sqlQueryToString::DynaFunctionToSql toSql(parameters:RelationalOperationElement[*], sgcs:SqlGenerationContext[*]) { let processedParams = $parameters->zip($sgcs)->map(p | $p.first->processOperation($p.second)); - let params = if($this.toSql.transform->isEmpty(), | $processedParams, | $this.toSql.transform->toOne()->eval($processedParams)); + let params = if($this.toSql.transform->isEmpty() && $this.toSql.contextAwareTransform->isEmpty() , + | $processedParams, + | if($this.toSql.transform->isNotEmpty() , + |$this.toSql.transform->toOne()->eval($processedParams), + | $this.toSql.contextAwareTransform->toOne()->eval($processedParams,$sgcs->at(0))) + ); format($this.toSql.format, $params); }:String[1]; @@ -920,6 +925,8 @@ Class meta::relational::functions::sqlQueryToString::ToSql format:String[1]; transform:meta::pure::metamodel::function::Function<{String[*]->String[*]}>[0..1]; parametersWithinWhenClause : Boolean[*]; + contextAwareTransform:meta::pure::metamodel::function::Function<{String[*],SqlGenerationContext[1]->String[*]}>[0..1]; + } Enum meta::relational::functions::sqlQueryToString::DynaFunctionRegistry @@ -948,6 +955,7 @@ Enum meta::relational::functions::sqlQueryToString::DynaFunctionRegistry convertDate, convertDateTime, convertVarchar128, + convertTimeZone, cos, cot, count, diff --git a/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-generation/legend-engine-xt-relationalStore-pure/src/main/resources/core_relational/relational/sqlQueryToString/dbSpecific/h2/h2Extension1_4_200.pure b/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-generation/legend-engine-xt-relationalStore-pure/src/main/resources/core_relational/relational/sqlQueryToString/dbSpecific/h2/h2Extension1_4_200.pure index ca3135465b4..dba9e48118e 100644 --- a/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-generation/legend-engine-xt-relationalStore-pure/src/main/resources/core_relational/relational/sqlQueryToString/dbSpecific/h2/h2Extension1_4_200.pure +++ b/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-generation/legend-engine-xt-relationalStore-pure/src/main/resources/core_relational/relational/sqlQueryToString/dbSpecific/h2/h2Extension1_4_200.pure @@ -139,10 +139,21 @@ function <> meta::relational::functions::sqlQueryToString::h2::v dynaFnToSql('toString', $allStates, ^ToSql(format='cast(%s as varchar)')), dynaFnToSql('toTimestamp', $allStates, ^ToSql(format='%s', transform={p:String[2] | $p->transformToTimestampH2()})), dynaFnToSql('weekOfYear', $allStates, ^ToSql(format='week(%s)')), - dynaFnToSql('year', $allStates, ^ToSql(format='year(%s)')) + dynaFnToSql('year', $allStates, ^ToSql(format='year(%s)')), + dynaFnToSql('convertTimeZone', $allStates, ^ToSql(format='%s', transform={p:String[3] | $p->transformConvertTimeZone()})) + ]; } +function <> meta::relational::functions::sqlQueryToString::h2::v1_4_200::transformConvertTimeZone(params:String[3]):String[1] +{ + let unWrappedfmt = $params->at(2)->substring(1, $params->at(2)->length()-1); + assert($unWrappedfmt->validateDateTimeFormat(),'Found an invalid date format'); + let formatpairs = meta::relational::functions::sqlQueryToString::default::defaultJavaToSQLTimeParts(); + let datefmt = $formatpairs->fold( {sub, date| $date->toOne()->replace($sub.first,$sub.second)},$params->at(2)); + format('TO_CHAR(legend_h2_extension_convertTimeZone(%s,%s),%s)',[$params->at(0),$params->at(1),$datefmt]); +} + function <> meta::relational::functions::sqlQueryToString::h2::v1_4_200::processUpsertSQLQueryForH2(upsertQuery: UpsertSQLQuery[1], sgc: SqlGenerationContext[1]): String[1] { // Map of Column to Literals of VarPlaceHolder diff --git a/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-generation/legend-engine-xt-relationalStore-pure/src/main/resources/core_relational/relational/sqlQueryToString/dbSpecific/h2/h2Extension2_1_214.pure b/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-generation/legend-engine-xt-relationalStore-pure/src/main/resources/core_relational/relational/sqlQueryToString/dbSpecific/h2/h2Extension2_1_214.pure index 91749156000..8292a836d88 100644 --- a/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-generation/legend-engine-xt-relationalStore-pure/src/main/resources/core_relational/relational/sqlQueryToString/dbSpecific/h2/h2Extension2_1_214.pure +++ b/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-generation/legend-engine-xt-relationalStore-pure/src/main/resources/core_relational/relational/sqlQueryToString/dbSpecific/h2/h2Extension2_1_214.pure @@ -252,10 +252,21 @@ function <> meta::relational::functions::sqlQueryToString::h2::v dynaFnToSql('toFloat', $allStates, ^ToSql(format='cast(%s as double precision)')), dynaFnToSql('toTimestamp', $allStates, ^ToSql(format='%s', transform={p:String[2] | $p->transformToTimestampH2()})), dynaFnToSql('weekOfYear', $allStates, ^ToSql(format='week(%s)')), - dynaFnToSql('year', $allStates, ^ToSql(format='year(%s)')) + dynaFnToSql('year', $allStates, ^ToSql(format='year(%s)')), + dynaFnToSql('convertTimeZone', $allStates, ^ToSql(format='%s', transform={p:String[3] | $p->transformConvertTimeZone()})) + ]; } + +function <> meta::relational::functions::sqlQueryToString::h2::v2_1_214::transformConvertTimeZone(params:String[3]):String[1] +{ + let unWrappedfmt = $params->at(2)->substring(1, $params->at(2)->length()-1); + assert($unWrappedfmt->validateDateTimeFormat(),'Found an invalid date format'); + let formatpairs = meta::relational::functions::sqlQueryToString::default::defaultJavaToSQLTimeParts(); + let datefmt = $formatpairs->fold( {sub, date| $date->toOne()->replace($sub.first,$sub.second)},$params->at(2)); + format('TO_CHAR(legend_h2_extension_convertTimeZone(\'%s\',%s),%s)',[$params->at(0),$params->at(1),$datefmt]); +} function <> meta::relational::functions::sqlQueryToString::h2::v2_1_214::processUpsertSQLQueryForH2(upsertQuery: UpsertSQLQuery[1], sgc: SqlGenerationContext[1]): String[1] { // Map of Column to Literals of VarPlaceHolder diff --git a/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-generation/legend-engine-xt-relationalStore-pure/src/main/resources/core_relational/relational/sqlQueryToString/extensionDefaults.pure b/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-generation/legend-engine-xt-relationalStore-pure/src/main/resources/core_relational/relational/sqlQueryToString/extensionDefaults.pure index d4f3ea5eebb..d9330f8f85d 100644 --- a/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-generation/legend-engine-xt-relationalStore-pure/src/main/resources/core_relational/relational/sqlQueryToString/extensionDefaults.pure +++ b/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-generation/legend-engine-xt-relationalStore-pure/src/main/resources/core_relational/relational/sqlQueryToString/extensionDefaults.pure @@ -769,3 +769,21 @@ function meta::relational::functions::sqlQueryToString::default::escapeLikeExprD ->replace('_', '\\_') ->replace('%', '\\%'); } + + +function meta::relational::functions::sqlQueryToString::default::defaultJavaToSQLTimeParts():Pair[*] +{ + let formatSubs = [ + pair('yyyy', 'YYYY'), // Year + pair('dd', 'DD'), // Day in month padded + pair('HH', 'I1'), // Hour in day (0-23) padded + pair('H', 'FMHH24'), // Hour in day (0-23) + pair('hh', 'I2'), // Hour in day (0-12) padded + pair('h', 'FMHH12'), // Hour in day (0-12) + pair('mm', 'MI'), // Minute in hour + pair('SSS','FF3'), + pair('ss', 'SS'), // Second in minute + pair('I1', 'HH24'), //replace intermediate placeholders + pair('I2', 'HH12') + ]; +} diff --git a/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-generation/legend-engine-xt-relationalStore-pure/src/main/resources/core_relational/relational/tests/mapping/sqlFunction/testSqlFunctionsInMapping.pure b/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-generation/legend-engine-xt-relationalStore-pure/src/main/resources/core_relational/relational/tests/mapping/sqlFunction/testSqlFunctionsInMapping.pure index d75ce2da4bf..089b309a679 100644 --- a/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-generation/legend-engine-xt-relationalStore-pure/src/main/resources/core_relational/relational/tests/mapping/sqlFunction/testSqlFunctionsInMapping.pure +++ b/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-generation/legend-engine-xt-relationalStore-pure/src/main/resources/core_relational/relational/tests/mapping/sqlFunction/testSqlFunctionsInMapping.pure @@ -716,6 +716,7 @@ Class meta::relational::tests::mapping::sqlFunction::model::domain::SqlFunctionD dateTime: DateTime[1]; adjustDate: DateTime[1]; toBoolean: Boolean[1]; + convertTimeZone: String[1]; } Class meta::relational::tests::mapping::sqlFunction::model::domain::SqlFunctionDemoForPresto @@ -828,7 +829,8 @@ Mapping meta::relational::tests::mapping::sqlFunction::model::mapping::testMappi dateTime: dateTime, adjustDate: adjust(dateTime, -7, 'DAYS'), - toBoolean: parseBoolean('true') + toBoolean: parseBoolean('true'), + convertTimeZone: convertTimeZone( dateTime,'EST','yyyy-MM-dd HH:mm:ss') ) }