From cdda855b6dbd16ffad8faed00574d8c680af8ba8 Mon Sep 17 00:00:00 2001
From: gs-jp1 <80327721+gs-jp1@users.noreply.github.com>
Date: Tue, 10 Oct 2023 09:29:38 +0100
Subject: [PATCH] Legend Engine - Assortment of changes (#2349)
1. refactor tests for simplified reading
2. autogenerate schema protocol models
3. grammar composer support tablesubquery
---
.../legend-engine-xt-sql-compiler/pom.xml | 16 +
.../sql/grammar/to/SQLGrammarComposer.java | 2 +-
.../test/roundtrip/TestSQLRoundTrip.java | 6 +
.../legend-engine-xt-sql-protocol/pom.xml | 16 +
...l_query_sql_schema_metamodel.protocol.json | 6 +
.../schema_metamodel.pure | 41 +
.../binding/fromPure/fromPure.pure | 4 +-
.../binding/fromPure/tests/testTranspile.pure | 1166 ++++++++---------
.../binding/model.pure | 100 --
.../binding/schema.pure | 58 +
.../legend-engine-xt-sql-query/pom.xml | 4 -
.../engine/query/sql/api/SQLExecutor.java | 293 +++++
.../query/sql/api/execute/SqlExecute.java | 287 +---
.../query/sql/api/execute/SqlExecuteTest.java | 103 +-
14 files changed, 1113 insertions(+), 989 deletions(-)
create mode 100644 legend-engine-xts-sql/legend-engine-xt-sql-protocol/src/main/resources/core_external_query_sql_schema_metamodel.protocol.json
create mode 100644 legend-engine-xts-sql/legend-engine-xt-sql-pure-metamodel/src/main/resources/core_external_query_sql_metamodel/schema_metamodel.pure
delete mode 100644 legend-engine-xts-sql/legend-engine-xt-sql-pure/src/main/resources/core_external_query_sql/binding/model.pure
create mode 100644 legend-engine-xts-sql/legend-engine-xt-sql-pure/src/main/resources/core_external_query_sql/binding/schema.pure
create mode 100644 legend-engine-xts-sql/legend-engine-xt-sql-query/src/main/java/org/finos/legend/engine/query/sql/api/SQLExecutor.java
diff --git a/legend-engine-xts-sql/legend-engine-xt-sql-compiler/pom.xml b/legend-engine-xts-sql/legend-engine-xt-sql-compiler/pom.xml
index 60b55bdd533..5beacacb8f2 100644
--- a/legend-engine-xts-sql/legend-engine-xt-sql-compiler/pom.xml
+++ b/legend-engine-xts-sql/legend-engine-xt-sql-compiler/pom.xml
@@ -52,6 +52,22 @@
test
+
+ Generate translator for protocol
+ generate-sources
+
+ java
+
+
+ true
+ org.finos.legend.engine.protocol.generation.GenerateMetamodelToProtocolTranslator
+
+ core_external_query_sql_schema_metamodel.protocol.json
+ ${project.build.directory}/generated-sources/
+
+ test
+
+
diff --git a/legend-engine-xts-sql/legend-engine-xt-sql-grammar/src/main/java/org/finos/legend/engine/language/sql/grammar/to/SQLGrammarComposer.java b/legend-engine-xts-sql/legend-engine-xt-sql-grammar/src/main/java/org/finos/legend/engine/language/sql/grammar/to/SQLGrammarComposer.java
index 1e6b49eb802..57aaa1af936 100644
--- a/legend-engine-xts-sql/legend-engine-xt-sql-grammar/src/main/java/org/finos/legend/engine/language/sql/grammar/to/SQLGrammarComposer.java
+++ b/legend-engine-xts-sql/legend-engine-xt-sql-grammar/src/main/java/org/finos/legend/engine/language/sql/grammar/to/SQLGrammarComposer.java
@@ -527,7 +527,7 @@ public String visit(TableFunction val)
@Override
public String visit(TableSubquery val)
{
- return null;
+ return "(" + visit(val.query) + ")";
}
@Override
diff --git a/legend-engine-xts-sql/legend-engine-xt-sql-grammar/src/test/java/org/finos/legend/engine/language/sql/grammar/test/roundtrip/TestSQLRoundTrip.java b/legend-engine-xts-sql/legend-engine-xt-sql-grammar/src/test/java/org/finos/legend/engine/language/sql/grammar/test/roundtrip/TestSQLRoundTrip.java
index 4c9901b5bb0..befce651ac1 100644
--- a/legend-engine-xts-sql/legend-engine-xt-sql-grammar/src/test/java/org/finos/legend/engine/language/sql/grammar/test/roundtrip/TestSQLRoundTrip.java
+++ b/legend-engine-xts-sql/legend-engine-xt-sql-grammar/src/test/java/org/finos/legend/engine/language/sql/grammar/test/roundtrip/TestSQLRoundTrip.java
@@ -288,6 +288,12 @@ public void testWithinGroup()
check("SELECT percentile_cont(0.1) WITHIN GROUP (ORDER BY a ASC) FROM myTable");
}
+ @Test
+ public void testNested()
+ {
+ check("SELECT * from (select col from myTable)");
+ }
+
private void fail(String sql, int start, int end, String message)
{
try
diff --git a/legend-engine-xts-sql/legend-engine-xt-sql-protocol/pom.xml b/legend-engine-xts-sql/legend-engine-xt-sql-protocol/pom.xml
index cd9d62c0365..e9bebe9d248 100644
--- a/legend-engine-xts-sql/legend-engine-xt-sql-protocol/pom.xml
+++ b/legend-engine-xts-sql/legend-engine-xt-sql-protocol/pom.xml
@@ -52,6 +52,22 @@
test
+
+ generate schema metamodel
+ generate-sources
+
+ java
+
+
+ true
+ org.finos.legend.engine.protocol.generation.GenerateMetaClasses
+
+ core_external_query_sql_schema_metamodel.protocol.json
+ ${project.build.directory}/generated-sources/
+
+ test
+
+
diff --git a/legend-engine-xts-sql/legend-engine-xt-sql-protocol/src/main/resources/core_external_query_sql_schema_metamodel.protocol.json b/legend-engine-xts-sql/legend-engine-xt-sql-protocol/src/main/resources/core_external_query_sql_schema_metamodel.protocol.json
new file mode 100644
index 00000000000..e973ac4b716
--- /dev/null
+++ b/legend-engine-xts-sql/legend-engine-xt-sql-protocol/src/main/resources/core_external_query_sql_schema_metamodel.protocol.json
@@ -0,0 +1,6 @@
+{
+ "purePackage": "meta::external::query::sql::schema::metamodel",
+ "javaPackage": "org.finos.legend.engine.protocol.sql.schema.metamodel",
+ "elementsToBeExcluded": [
+ ]
+}
\ No newline at end of file
diff --git a/legend-engine-xts-sql/legend-engine-xt-sql-pure-metamodel/src/main/resources/core_external_query_sql_metamodel/schema_metamodel.pure b/legend-engine-xts-sql/legend-engine-xt-sql-pure-metamodel/src/main/resources/core_external_query_sql_metamodel/schema_metamodel.pure
new file mode 100644
index 00000000000..495a29cf632
--- /dev/null
+++ b/legend-engine-xts-sql/legend-engine-xt-sql-pure-metamodel/src/main/resources/core_external_query_sql_metamodel/schema_metamodel.pure
@@ -0,0 +1,41 @@
+Class meta::external::query::sql::schema::metamodel::SchemaColumn
+{
+ <> name: String[1];
+}
+
+Class meta::external::query::sql::schema::metamodel::PrimitiveSchemaColumn extends meta::external::query::sql::schema::metamodel::SchemaColumn
+{
+ <> type: meta::external::query::sql::schema::metamodel::PrimitiveType[1];
+}
+
+Class meta::external::query::sql::schema::metamodel::EnumSchemaColumn extends meta::external::query::sql::schema::metamodel::SchemaColumn
+{
+ <> type: String[1];
+}
+
+
+Class meta::external::query::sql::schema::metamodel::Schema
+{
+ <> columns: meta::external::query::sql::schema::metamodel::SchemaColumn[*];
+ <> enums: meta::external::query::sql::schema::metamodel::Enum[*];
+}
+
+Enum meta::external::query::sql::schema::metamodel::PrimitiveType
+{
+ Boolean,
+ StrictDate,
+ Number,
+ String,
+ LatestDate,
+ Float,
+ DateTime,
+ Date,
+ Integer,
+ Decimal
+}
+
+Class meta::external::query::sql::schema::metamodel::Enum
+{
+ <> type: String[1];
+ <> values: String[*];
+}
\ No newline at end of file
diff --git a/legend-engine-xts-sql/legend-engine-xt-sql-pure/src/main/resources/core_external_query_sql/binding/fromPure/fromPure.pure b/legend-engine-xts-sql/legend-engine-xt-sql-pure/src/main/resources/core_external_query_sql/binding/fromPure/fromPure.pure
index 90bb05666b6..f451545280f 100644
--- a/legend-engine-xts-sql/legend-engine-xt-sql-pure/src/main/resources/core_external_query_sql/binding/fromPure/fromPure.pure
+++ b/legend-engine-xts-sql/legend-engine-xt-sql-pure/src/main/resources/core_external_query_sql/binding/fromPure/fromPure.pure
@@ -155,13 +155,13 @@ function meta::external::query::sql::transformation::queryToPure::getSchemaFromS
sources: SQLSource[*],
query: meta::external::query::sql::metamodel::Node[1],
extensions: meta::pure::extension::Extension[*]
- ): meta::external::query::sql::Schema[1]
+ ): meta::external::query::sql::schema::metamodel::Schema[1]
{
let sqlTransformContext = processRootQuery($sources, $query, $extensions);
getSchema($sqlTransformContext);
}
-function meta::external::query::sql::transformation::queryToPure::getSchema(context:SqlTransformContext[1]): meta::external::query::sql::Schema[1]
+function meta::external::query::sql::transformation::queryToPure::getSchema(context:SqlTransformContext[1]): meta::external::query::sql::schema::metamodel::Schema[1]
{
$context.columns()->meta::external::query::sql::tdsColsToSchema();
}
diff --git a/legend-engine-xts-sql/legend-engine-xt-sql-pure/src/main/resources/core_external_query_sql/binding/fromPure/tests/testTranspile.pure b/legend-engine-xts-sql/legend-engine-xt-sql-pure/src/main/resources/core_external_query_sql/binding/fromPure/tests/testTranspile.pure
index 6ce75ddc42d..1d745b94da8 100644
--- a/legend-engine-xts-sql/legend-engine-xt-sql-pure/src/main/resources/core_external_query_sql/binding/fromPure/tests/testTranspile.pure
+++ b/legend-engine-xts-sql/legend-engine-xt-sql-pure/src/main/resources/core_external_query_sql/binding/fromPure/tests/testTranspile.pure
@@ -19,6 +19,7 @@ import meta::external::query::sql::transformation::queryToPure::*;
import meta::external::query::sql::metamodel::*;
import meta::external::query::sql::transformation::queryToPure::tests::*;
import meta::external::query::sql::*;
+import meta::external::query::sql::schema::metamodel::*;
import meta::legend::service::metamodel::*;
import meta::pure::functions::meta::*;
import meta::pure::mapping::*;
@@ -27,34 +28,36 @@ import meta::pure::metamodel::serialization::grammar::*;
//SELECT
function <> meta::external::query::sql::transformation::queryToPure::tests::testSelectStar():Boolean[1]
{
- let sqlString = 'SELECT * FROM service."/service/service1"';
- let sqlTransformContext = $sqlString->processQuery();
- let expected = {| FlatInput.all()->project(
+ test(
+ 'SELECT * FROM service."/service/service1"',
+
+ {| FlatInput.all()->project(
[ x | $x.booleanIn, x | $x.integerIn, x | $x.floatIn, x | $x.decimalIn, x | $x.strictDateIn, x | $x.dateTimeIn, x | $x.stringIn ],
[ 'Boolean', 'Integer', 'Float', 'Decimal', 'StrictDate', 'DateTime', 'String' ])
- };
- assertLambdaAndJSONEquals($expected, $sqlTransformContext.lambda());
+ }
+ )
}
function <> meta::external::query::sql::transformation::queryToPure::tests::testSelectNull():Boolean[1]
{
- let sqlString = 'SELECT NULL FROM service."/service/service1"';
- let sqlTransformContext = $sqlString->processQuery();
- let expected = {| FlatInput.all()->project(
+ test(
+ 'SELECT NULL FROM service."/service/service1"',
+
+ {| FlatInput.all()->project(
[ x | $x.booleanIn, x | $x.integerIn, x | $x.floatIn, x | $x.decimalIn, x | $x.strictDateIn, x | $x.dateTimeIn, x | $x.stringIn ],
[ 'Boolean', 'Integer', 'Float', 'Decimal', 'StrictDate', 'DateTime', 'String' ])->project([
col(row:TDSRow[1] | []->cast(@String), 'NULL')
])
- };
- assertLambdaAndJSONEquals($expected, $sqlTransformContext.lambda());
+ }
+ );
}
function <> meta::external::query::sql::transformation::queryToPure::tests::testSelectStarFromJoinTable():Boolean[1]
{
- let sqlString = 'SELECT table1.* FROM service."/service/service1" "table1" LEFT OUTER JOIN (SELECT * FROM service."/service/service2") AS "table2" ON "table1"."Integer" = "table2"."Integer"';
+ test(
+ 'SELECT table1.* FROM service."/service/service1" "table1" LEFT OUTER JOIN (SELECT * FROM service."/service/service2") AS "table2" ON "table1"."Integer" = "table2"."Integer"',
- let sqlTransformContext = $sqlString->processQuery();
- let expected = {| FlatInput.all()->project(
+ {| FlatInput.all()->project(
[ x | $x.booleanIn, x | $x.integerIn, x | $x.floatIn, x | $x.decimalIn, x | $x.strictDateIn, x | $x.dateTimeIn, x | $x.stringIn ],
[ 'Boolean', 'Integer', 'Float', 'Decimal', 'StrictDate', 'DateTime', 'String'])
->renameColumns([
@@ -83,16 +86,16 @@ function <> meta::external::query::sql::transformation::queryToPure::
pair('DateTime_table1', 'DateTime'),
pair('String_table1', 'String')
])->restrict(['Boolean', 'Integer', 'Float', 'Decimal', 'StrictDate', 'DateTime', 'String'])
- };
- assertLambdaAndJSONEquals($expected, $sqlTransformContext.lambda());
+ }
+ )
}
function <> meta::external::query::sql::transformation::queryToPure::tests::testSelectStarAndColumnsFromJoinTable():Boolean[1]
{
- let sqlString = 'SELECT table1.*, table2.id, sin(table2.int) FROM service."/service/service1" "table1" LEFT OUTER JOIN (SELECT ID as "id", Integer AS "int" FROM service."/service/service2") AS "table2" ON "table1"."Integer" = "table2"."int"';
+ test(
+ 'SELECT table1.*, table2.id, sin(table2.int) FROM service."/service/service1" "table1" LEFT OUTER JOIN (SELECT ID as "id", Integer AS "int" FROM service."/service/service2") AS "table2" ON "table1"."Integer" = "table2"."int"',
- let sqlTransformContext = $sqlString->processQuery();
- let expected = {| FlatInput.all()->project(
+ {| FlatInput.all()->project(
[ x | $x.booleanIn, x | $x.integerIn, x | $x.floatIn, x | $x.decimalIn, x | $x.strictDateIn, x | $x.dateTimeIn, x | $x.stringIn ],
[ 'Boolean', 'Integer', 'Float', 'Decimal', 'StrictDate', 'DateTime', 'String'])->renameColumns([
pair('Boolean', 'Boolean_table1'),
@@ -124,359 +127,358 @@ function <> meta::external::query::sql::transformation::queryToPure::
col(row:TDSRow[1] | $row.getInteger('id_table2'), 'id'),
col(row:TDSRow[1] | sin($row.getInteger('int_table2')), 'sin(int)')
])
- };
- assertLambdaAndJSONEquals($expected, $sqlTransformContext.lambda());
+ }
+ )
}
function <> meta::external::query::sql::transformation::queryToPure::tests::testSelectColumns():Boolean[1]
{
- let sqlString = 'SELECT Boolean, Integer FROM service."/service/service1"';
- let sqlTransformContext = $sqlString->processQuery();
- let expected = {| FlatInput.all()->project(
+ test(
+ 'SELECT Boolean, Integer FROM service."/service/service1"',
+
+ {| FlatInput.all()->project(
[ x | $x.booleanIn, x | $x.integerIn, x | $x.floatIn, x | $x.decimalIn, x | $x.strictDateIn, x | $x.dateTimeIn, x | $x.stringIn ],
[ 'Boolean', 'Integer', 'Float', 'Decimal', 'StrictDate', 'DateTime', 'String' ])
->restrict(['Boolean', 'Integer'])
- };
- assertLambdaAndJSONEquals($expected, $sqlTransformContext.lambda());
+ })
}
function <> meta::external::query::sql::transformation::queryToPure::tests::testSelectWithAliases():Boolean[1]
{
- let sqlString = 'SELECT Boolean, Integer AS int FROM service."/service/service1"';
- let sqlTransformContext = $sqlString->processQuery();
- let expected = {| FlatInput.all()->project(
+ test(
+ 'SELECT Boolean, Integer AS int FROM service."/service/service1"',
+
+ {| FlatInput.all()->project(
[ x | $x.booleanIn, x | $x.integerIn, x | $x.floatIn, x | $x.decimalIn, x | $x.strictDateIn, x | $x.dateTimeIn, x | $x.stringIn ],
[ 'Boolean', 'Integer', 'Float', 'Decimal', 'StrictDate', 'DateTime', 'String' ])
->restrict(['Boolean', 'Integer'])
->renameColumns(pair('Integer', 'int'))
- };
- assertLambdaAndJSONEquals($expected, $sqlTransformContext.lambda());
+ })
}
function <> meta::external::query::sql::transformation::queryToPure::tests::testSelectColumnMultiTimes():Boolean[1]
{
- let sqlString = 'SELECT String, String as "str" FROM service."/service/service1"';
- let sqlTransformContext = $sqlString->processQuery();
- let expected = {| FlatInput.all()->project(
+ test(
+ 'SELECT String, String as "str" FROM service."/service/service1"',
+
+ {| FlatInput.all()->project(
[ x | $x.booleanIn, x | $x.integerIn, x | $x.floatIn, x | $x.decimalIn, x | $x.strictDateIn, x | $x.dateTimeIn, x | $x.stringIn ],
[ 'Boolean', 'Integer', 'Float', 'Decimal', 'StrictDate', 'DateTime', 'String' ])->project([
col(row:TDSRow[1] | $row.getString('String'), 'String'),
col(row:TDSRow[1] | $row.getString('String'), 'str')
])
- };
- assertLambdaAndJSONEquals($expected, $sqlTransformContext.lambda());
+ })
}
function <> meta::external::query::sql::transformation::queryToPure::tests::testSelectColumnMultiTimesRealiasToExisting():Boolean[1]
{
- let sqlString = 'SELECT String as "str", String as "String" FROM service."/service/service1"';
- let sqlTransformContext = $sqlString->processQuery();
- let expected = {| FlatInput.all()->project(
+ test(
+ 'SELECT String as "str", String as "String" FROM service."/service/service1"',
+
+ {| FlatInput.all()->project(
[ x | $x.booleanIn, x | $x.integerIn, x | $x.floatIn, x | $x.decimalIn, x | $x.strictDateIn, x | $x.dateTimeIn, x | $x.stringIn ],
[ 'Boolean', 'Integer', 'Float', 'Decimal', 'StrictDate', 'DateTime', 'String' ])->project([
col(row:TDSRow[1] | $row.getString('String'), 'str'),
col(row:TDSRow[1] | $row.getString('String'), 'String')
])
- };
- assertLambdaAndJSONEquals($expected, $sqlTransformContext.lambda());
+ })
}
function <> meta::external::query::sql::transformation::queryToPure::tests::testSelectColumnAliasedAsUnusedTableColumnName():Boolean[1]
{
- let sqlString = 'SELECT Integer as "String" FROM service."/service/service1"';
- let sqlTransformContext = $sqlString->processQuery();
- let expected = {| FlatInput.all()->project(
+ test(
+ 'SELECT Integer as "String" FROM service."/service/service1"',
+
+ {| FlatInput.all()->project(
[ x | $x.booleanIn, x | $x.integerIn, x | $x.floatIn, x | $x.decimalIn, x | $x.strictDateIn, x | $x.dateTimeIn, x | $x.stringIn ],
[ 'Boolean', 'Integer', 'Float', 'Decimal', 'StrictDate', 'DateTime', 'String' ])
->restrict('Integer')->renameColumns(pair('Integer', 'String'))
- };
- assertLambdaAndJSONEquals($expected, $sqlTransformContext.lambda());
+ })
}
function <> meta::external::query::sql::transformation::queryToPure::tests::testSelectColumnMultiTimesGroupBy():Boolean[1]
{
- let sqlString = 'SELECT String, String as "str" FROM service."/service/service1" group by 1';
- let sqlTransformContext = $sqlString->processQuery();
- let expected = {| FlatInput.all()->project(
+ test(
+ 'SELECT String, String as "str" FROM service."/service/service1" group by 1',
+
+ {| FlatInput.all()->project(
[ x | $x.booleanIn, x | $x.integerIn, x | $x.floatIn, x | $x.decimalIn, x | $x.strictDateIn, x | $x.dateTimeIn, x | $x.stringIn ],
[ 'Boolean', 'Integer', 'Float', 'Decimal', 'StrictDate', 'DateTime', 'String' ])->project([
col(row:TDSRow[1] | $row.getString('String'), 'String'),
col(row:TDSRow[1] | $row.getString('String'), 'str')
])->restrict(['String', 'str'])->distinct()
- };
- assertLambdaAndJSONEquals($expected, $sqlTransformContext.lambda());
+ })
}
function <> meta::external::query::sql::transformation::queryToPure::tests::testSelectQualified():Boolean[1]
{
- let sqlString = 'SELECT Boolean, service."/service/service1".Integer FROM service."/service/service1"';
- let sqlTransformContext = $sqlString->processQuery();
- let expected = {| FlatInput.all()->project(
+ test(
+ 'SELECT Boolean, service."/service/service1".Integer FROM service."/service/service1"',
+
+ {| FlatInput.all()->project(
[ x | $x.booleanIn, x | $x.integerIn, x | $x.floatIn, x | $x.decimalIn, x | $x.strictDateIn, x | $x.dateTimeIn, x | $x.stringIn ],
[ 'Boolean', 'Integer', 'Float', 'Decimal', 'StrictDate', 'DateTime', 'String' ])
->restrict(['Boolean', 'Integer'])
- };
- assertLambdaAndJSONEquals($expected, $sqlTransformContext.lambda());
+ })
}
function <> meta::external::query::sql::transformation::queryToPure::tests::testSelectQualifiedWithAlias():Boolean[1]
{
- let sqlString = 'SELECT Boolean, table1.Integer FROM service."/service/service1" AS table1';
- let sqlTransformContext = $sqlString->processQuery();
- let expected = {| FlatInput.all()->project(
+ test(
+ 'SELECT Boolean, table1.Integer FROM service."/service/service1" AS table1',
+
+ {| FlatInput.all()->project(
[ x | $x.booleanIn, x | $x.integerIn, x | $x.floatIn, x | $x.decimalIn, x | $x.strictDateIn, x | $x.dateTimeIn, x | $x.stringIn ],
[ 'Boolean', 'Integer', 'Float', 'Decimal', 'StrictDate', 'DateTime', 'String' ])
->restrict(['Boolean', 'Integer'])
- };
- assertLambdaAndJSONEquals($expected, $sqlTransformContext.lambda());
+ })
}
function <> meta::external::query::sql::transformation::queryToPure::tests::testTableFunc():Boolean[1]
{
- let sqlString = 'SELECT Boolean, table1.Integer FROM service(\'/service/service1\') AS table1';
- let sqlTransformContext = $sqlString->processQuery();
- let expected = {| FlatInput.all()->project(
+ test(
+ 'SELECT Boolean, table1.Integer FROM service(\'/service/service1\') AS table1',
+
+ {| FlatInput.all()->project(
[ x | $x.booleanIn, x | $x.integerIn, x | $x.floatIn, x | $x.decimalIn, x | $x.strictDateIn, x | $x.dateTimeIn, x | $x.stringIn ],
[ 'Boolean', 'Integer', 'Float', 'Decimal', 'StrictDate', 'DateTime', 'String' ])
->restrict(['Boolean', 'Integer'])
- };
- assertLambdaAndJSONEquals($expected, $sqlTransformContext.lambda());
+ })
}
function <> meta::external::query::sql::transformation::queryToPure::tests::testSelectQuotedSingleColumn():Boolean[1]
{
- let sqlString = 'SELECT "Boolean", "Integer" FROM service."/service/service1"';
- let sqlTransformContext = $sqlString->processQuery();
- let expected = {| FlatInput.all()->project(
+ test(
+ 'SELECT "Boolean", "Integer" FROM service."/service/service1"',
+
+ {| FlatInput.all()->project(
[ x | $x.booleanIn, x | $x.integerIn, x | $x.floatIn, x | $x.decimalIn, x | $x.strictDateIn, x | $x.dateTimeIn, x | $x.stringIn ],
[ 'Boolean', 'Integer', 'Float', 'Decimal', 'StrictDate', 'DateTime', 'String' ])
->restrict(['Boolean', 'Integer'])
- };
- assertLambdaAndJSONEquals($expected, $sqlTransformContext.lambda());
+ })
}
function <> meta::external::query::sql::transformation::queryToPure::tests::testSelectUnquotedSingleColumn():Boolean[1]
{
- let sqlString = 'SELECT Boolean, Integer FROM service."/service/service1"';
- let sqlTransformContext = $sqlString->processQuery();
- let expected = {| FlatInput.all()->project(
+ test(
+ 'SELECT Boolean, Integer FROM service."/service/service1"',
+
+ {| FlatInput.all()->project(
[ x | $x.booleanIn, x | $x.integerIn, x | $x.floatIn, x | $x.decimalIn, x | $x.strictDateIn, x | $x.dateTimeIn, x | $x.stringIn ],
[ 'Boolean', 'Integer', 'Float', 'Decimal', 'StrictDate', 'DateTime', 'String' ])
->restrict(['Boolean', 'Integer'])
- };
- assertLambdaAndJSONEquals($expected, $sqlTransformContext.lambda());
+ })
}
function <> meta::external::query::sql::transformation::queryToPure::tests::testSimplificationOfNullablesComplex():Boolean[1]
{
- let sqlString = 'SELECT (date_trunc(\'day\', CAST(\'1900-01-01\' AS DATE) + NULL * INTERVAL \'1 DAY\') + 1 * INTERVAL \'1 YEAR\') AS "NULL1", ' +
- 'CAST( FLOOR(EXTRACT(EPOCH FROM CAST((CAST(\'1900-01-01 00:00:00\' AS TIMESTAMP) + NULL * INTERVAL \'1 DAY\') AS TIMESTAMP)) / 86400) - FLOOR(EXTRACT(EPOCH FROM CAST((CAST(\'1900-01-01 00:00:00\' AS TIMESTAMP) + NULL * INTERVAL \'1 DAY\') AS TIMESTAMP)) / 86400) AS BIGINT) AS "NULL2" FROM service."/service/service1"';
- let sqlTransformContext = $sqlString->processQuery();
+ test(
+ 'SELECT (date_trunc(\'day\', CAST(\'1900-01-01\' AS DATE) + NULL * INTERVAL \'1 DAY\') + 1 * INTERVAL \'1 YEAR\') AS "NULL1", ' +
+ 'CAST( FLOOR(EXTRACT(EPOCH FROM CAST((CAST(\'1900-01-01 00:00:00\' AS TIMESTAMP) + NULL * INTERVAL \'1 DAY\') AS TIMESTAMP)) / 86400) - ' +
+ 'FLOOR(EXTRACT(EPOCH FROM CAST((CAST(\'1900-01-01 00:00:00\' AS TIMESTAMP) + NULL * INTERVAL \'1 DAY\') AS TIMESTAMP)) / 86400) AS BIGINT) AS "NULL2" FROM service."/service/service1"',
- let expected = {| FlatInput.all()->project(
+ {| FlatInput.all()->project(
[ x | $x.booleanIn, x | $x.integerIn, x | $x.floatIn, x | $x.decimalIn, x | $x.strictDateIn, x | $x.dateTimeIn, x | $x.stringIn ],
[ 'Boolean', 'Integer', 'Float', 'Decimal', 'StrictDate', 'DateTime', 'String' ])->project([
col(row:TDSRow[1] | []->cast(@Date), 'NULL1'),
col(row:TDSRow[1] | []->cast(@Integer), 'NULL2')
])
- };
-
- assertLambdaAndJSONEquals($expected, $sqlTransformContext.lambda());
+ })
}
//DISTINCT
function <> meta::external::query::sql::transformation::queryToPure::tests::testDistinctAllColumns():Boolean[1]
{
- let sqlString = 'SELECT DISTINCT * FROM service."/service/service1"';
- let sqlTransformContext = $sqlString->processQuery();
- let expected = {| FlatInput.all()->project(
+ test(
+ 'SELECT DISTINCT * FROM service."/service/service1"',
+
+ {| FlatInput.all()->project(
[ x | $x.booleanIn, x | $x.integerIn, x | $x.floatIn, x | $x.decimalIn, x | $x.strictDateIn, x | $x.dateTimeIn, x | $x.stringIn ],
[ 'Boolean', 'Integer', 'Float', 'Decimal', 'StrictDate', 'DateTime', 'String' ])
->distinct()
- };
- assertLambdaAndJSONEquals($expected, $sqlTransformContext.lambda());
+ })
}
function <> meta::external::query::sql::transformation::queryToPure::tests::testDistinctSingleColumn():Boolean[1]
{
- let sqlString = 'SELECT DISTINCT Boolean FROM service."/service/service1"';
- let sqlTransformContext = $sqlString->processQuery();
- let expected = {| FlatInput.all()->project(
+ test(
+ 'SELECT DISTINCT Boolean FROM service."/service/service1"',
+
+ {| FlatInput.all()->project(
[ x | $x.booleanIn, x | $x.integerIn, x | $x.floatIn, x | $x.decimalIn, x | $x.strictDateIn, x | $x.dateTimeIn, x | $x.stringIn ],
[ 'Boolean', 'Integer', 'Float', 'Decimal', 'StrictDate', 'DateTime', 'String' ])
->restrict(['Boolean'])
->distinct()
- };
- assertLambdaAndJSONEquals($expected, $sqlTransformContext.lambda());
+ })
}
//LIMIT-OFFSET
function <> meta::external::query::sql::transformation::queryToPure::tests::testLimit():Boolean[1]
{
- let sqlString = 'SELECT * FROM service."/service/service1" LIMIT 2';
- let sqlTransformContext = $sqlString->processQuery();
- let expected = {| FlatInput.all()->project(
+ test(
+ 'SELECT * FROM service."/service/service1" LIMIT 2',
+
+ {| FlatInput.all()->project(
[ x | $x.booleanIn, x | $x.integerIn, x | $x.floatIn, x | $x.decimalIn, x | $x.strictDateIn, x | $x.dateTimeIn, x | $x.stringIn ],
[ 'Boolean', 'Integer', 'Float', 'Decimal', 'StrictDate', 'DateTime', 'String' ])
->limit(2)
- };
- assertLambdaAndJSONEquals($expected, $sqlTransformContext.lambda());
+ })
}
function <> meta::external::query::sql::transformation::queryToPure::tests::testLimitAll():Boolean[1]
{
- let sqlString = 'SELECT * FROM service."/service/service1" LIMIT ALL';
- let sqlTransformContext = $sqlString->processQuery();
- let expected = {| FlatInput.all()->project(
+ test(
+ 'SELECT * FROM service."/service/service1" LIMIT ALL',
+
+ {| FlatInput.all()->project(
[ x | $x.booleanIn, x | $x.integerIn, x | $x.floatIn, x | $x.decimalIn, x | $x.strictDateIn, x | $x.dateTimeIn, x | $x.stringIn ],
[ 'Boolean', 'Integer', 'Float', 'Decimal', 'StrictDate', 'DateTime', 'String' ])
- };
- assertLambdaAndJSONEquals($expected, $sqlTransformContext.lambda());
+ })
}
function <> meta::external::query::sql::transformation::queryToPure::tests::testOffset():Boolean[1]
{
- let sqlString = 'SELECT * FROM service."/service/service1" OFFSET 1';
- let sqlTransformContext = $sqlString->processQuery();
- let expected = {| FlatInput.all()->project(
+ test(
+ 'SELECT * FROM service."/service/service1" OFFSET 1',
+
+ {| FlatInput.all()->project(
[ x | $x.booleanIn, x | $x.integerIn, x | $x.floatIn, x | $x.decimalIn, x | $x.strictDateIn, x | $x.dateTimeIn, x | $x.stringIn ],
[ 'Boolean', 'Integer', 'Float', 'Decimal', 'StrictDate', 'DateTime', 'String' ])
->drop(1)
- };
- assertLambdaAndJSONEquals($expected, $sqlTransformContext.lambda());
+ })
}
function <> meta::external::query::sql::transformation::queryToPure::tests::testLimitOffset():Boolean[1]
{
- let sqlString = 'SELECT * FROM service."/service/service1" OFFSET 2 LIMIT 1';
- let sqlTransformContext = $sqlString->processQuery();
- let expected = {| FlatInput.all()->project(
+ test(
+ 'SELECT * FROM service."/service/service1" OFFSET 2 LIMIT 1',
+
+ {| FlatInput.all()->project(
[ x | $x.booleanIn, x | $x.integerIn, x | $x.floatIn, x | $x.decimalIn, x | $x.strictDateIn, x | $x.dateTimeIn, x | $x.stringIn ],
[ 'Boolean', 'Integer', 'Float', 'Decimal', 'StrictDate', 'DateTime', 'String' ])
->slice(2, 2 + 1)
- };
- assertLambdaAndJSONEquals($expected, $sqlTransformContext.lambda());
+ })
}
//ORDER BY
function <> meta::external::query::sql::transformation::queryToPure::tests::testOrderBy():Boolean[1]
{
- let sqlString = 'SELECT * FROM service."/service/service1" ORDER BY Integer DESC, Boolean ASC';
- let sqlTransformContext = $sqlString->processQuery();
- let expected = {| FlatInput.all()->project(
+ test(
+ 'SELECT * FROM service."/service/service1" ORDER BY Integer DESC, Boolean ASC',
+
+ {| FlatInput.all()->project(
[ x | $x.booleanIn, x | $x.integerIn, x | $x.floatIn, x | $x.decimalIn, x | $x.strictDateIn, x | $x.dateTimeIn, x | $x.stringIn ],
[ 'Boolean', 'Integer', 'Float', 'Decimal', 'StrictDate', 'DateTime', 'String' ])
->sort([desc('Integer'), asc('Boolean')])
- };
-
- assertLambdaAndJSONEquals($expected, $sqlTransformContext.lambda());
+ })
}
function <> meta::external::query::sql::transformation::queryToPure::tests::testOrderByAlias():Boolean[1]
{
- let sqlString = 'SELECT * FROM service."/service/service1" AS table1 ORDER BY table1.Integer DESC, Boolean';
- let sqlTransformContext = $sqlString->processQuery();
- let expected = {| FlatInput.all()->project(
+ test(
+ 'SELECT * FROM service."/service/service1" AS table1 ORDER BY table1.Integer DESC, Boolean',
+
+ {| FlatInput.all()->project(
[ x | $x.booleanIn, x | $x.integerIn, x | $x.floatIn, x | $x.decimalIn, x | $x.strictDateIn, x | $x.dateTimeIn, x | $x.stringIn ],
[ 'Boolean', 'Integer', 'Float', 'Decimal', 'StrictDate', 'DateTime', 'String' ])
->sort([desc('Integer'), asc('Boolean')])
- };
- assertLambdaAndJSONEquals($expected, $sqlTransformContext.lambda());
+ })
}
function <> meta::external::query::sql::transformation::queryToPure::tests::testOrderByQualified():Boolean[1]
{
- let sqlString = 'SELECT * FROM service."/service/service1" ORDER BY service."/service/service1".Integer DESC, Boolean ASC';
- let sqlTransformContext = $sqlString->processQuery();
- let expected = {| FlatInput.all()->project(
+ test(
+ 'SELECT * FROM service."/service/service1" ORDER BY service."/service/service1".Integer DESC, Boolean ASC',
+
+ {| FlatInput.all()->project(
[ x | $x.booleanIn, x | $x.integerIn, x | $x.floatIn, x | $x.decimalIn, x | $x.strictDateIn, x | $x.dateTimeIn, x | $x.stringIn ],
[ 'Boolean', 'Integer', 'Float', 'Decimal', 'StrictDate', 'DateTime', 'String' ])
->sort([desc('Integer'), asc('Boolean')])
- };
- assertLambdaAndJSONEquals($expected, $sqlTransformContext.lambda());
+ })
}
function <> meta::external::query::sql::transformation::queryToPure::tests::testOrderByIndex():Boolean[1]
{
- let sqlString = 'SELECT Integer, String FROM service."/service/service1" ORDER BY 1 DESC, 2 ASC';
- let sqlTransformContext = $sqlString->processQuery();
- let expected = {| FlatInput.all()->project(
+ test(
+ 'SELECT Integer, String FROM service."/service/service1" ORDER BY 1 DESC, 2 ASC',
+
+ {| FlatInput.all()->project(
[ x | $x.booleanIn, x | $x.integerIn, x | $x.floatIn, x | $x.decimalIn, x | $x.strictDateIn, x | $x.dateTimeIn, x | $x.stringIn ],
[ 'Boolean', 'Integer', 'Float', 'Decimal', 'StrictDate', 'DateTime', 'String' ])
->restrict(['Integer', 'String'])
->sort([desc('Integer'), asc('String')])
- };
- assertLambdaAndJSONEquals($expected, $sqlTransformContext.lambda());
+ })
}
//WHERE
function <> meta::external::query::sql::transformation::queryToPure::tests::testWhere():Boolean[1]
{
- let sqlString = 'SELECT * FROM service."/service/service1" WHERE Integer != 2 AND Integer <> 3';
- let sqlTransformContext = $sqlString->processQuery();
- let expected = {| FlatInput.all()->project(
+ test(
+ 'SELECT * FROM service."/service/service1" WHERE Integer != 2 AND Integer <> 3',
+
+ {| FlatInput.all()->project(
[ x | $x.booleanIn, x | $x.integerIn, x | $x.floatIn, x | $x.decimalIn, x | $x.strictDateIn, x | $x.dateTimeIn, x | $x.stringIn ],
[ 'Boolean', 'Integer', 'Float', 'Decimal', 'StrictDate', 'DateTime', 'String' ])
->filter(row | ($row.getInteger('Integer') != 2) && ($row.getInteger('Integer') != 3))
- };
- assertLambdaEquals($expected, $sqlTransformContext.lambda());
+ }, false)
}
function <> meta::external::query::sql::transformation::queryToPure::tests::testCompositeWhere():Boolean[1]
{
- let sqlString = 'SELECT * FROM service."/service/service1" WHERE (Integer = 2 AND String = \'abc\') OR (String = \'def\' AND Integer = 1)';
- let sqlTransformContext = $sqlString->processQuery();
- let expected = {| FlatInput.all()->project(
+ test(
+ 'SELECT * FROM service."/service/service1" WHERE (Integer = 2 AND String = \'abc\') OR (String = \'def\' AND Integer = 1)',
+
+ {| FlatInput.all()->project(
[ x | $x.booleanIn, x | $x.integerIn, x | $x.floatIn, x | $x.decimalIn, x | $x.strictDateIn, x | $x.dateTimeIn, x | $x.stringIn ],
[ 'Boolean', 'Integer', 'Float', 'Decimal', 'StrictDate', 'DateTime', 'String' ])
->filter(row | ($row.getInteger('Integer') == 2 && $row.getString('String') == 'abc') || ($row.getString('String') == 'def' && $row.getInteger('Integer') == 1))
- };
- assertLambdaEquals($expected, $sqlTransformContext.lambda());
+ }, false)
}
function <> meta::external::query::sql::transformation::queryToPure::tests::testWhereAliases():Boolean[1]
{
- let sqlString = 'SELECT * FROM service."/service/service1" AS table1 WHERE Integer = 2 OR table1.Integer = 3';
- let sqlTransformContext = $sqlString->processQuery();
- let expected = {| FlatInput.all()->project(
+ test(
+ 'SELECT * FROM service."/service/service1" AS table1 WHERE Integer = 2 OR table1.Integer = 3',
+
+ {| FlatInput.all()->project(
[ x | $x.booleanIn, x | $x.integerIn, x | $x.floatIn, x | $x.decimalIn, x | $x.strictDateIn, x | $x.dateTimeIn, x | $x.stringIn ],
[ 'Boolean', 'Integer', 'Float', 'Decimal', 'StrictDate', 'DateTime', 'String' ])
->filter(row | $row.getInteger('Integer') == 2 || $row.getInteger('Integer') == 3)
- };
- assertLambdaEquals($expected, $sqlTransformContext.lambda());
+ }, false)
}
function <> meta::external::query::sql::transformation::queryToPure::tests::testWhereQualified():Boolean[1]
{
- let sqlString = 'SELECT * FROM service."/service/service1" WHERE service."/service/service1".Integer = 2 OR Integer = 3';
- let sqlTransformContext = $sqlString->processQuery();
- let expected = {| FlatInput.all()->project(
+ test(
+ 'SELECT * FROM service."/service/service1" WHERE service."/service/service1".Integer = 2 OR Integer = 3',
+
+ {| FlatInput.all()->project(
[ x | $x.booleanIn, x | $x.integerIn, x | $x.floatIn, x | $x.decimalIn, x | $x.strictDateIn, x | $x.dateTimeIn, x | $x.stringIn ],
[ 'Boolean', 'Integer', 'Float', 'Decimal', 'StrictDate', 'DateTime', 'String' ])
->filter(row | $row.getInteger('Integer') == 2 || $row.getInteger('Integer') == 3)
- };
- assertLambdaEquals($expected, $sqlTransformContext.lambda());
+ }, false)
}
function <> meta::external::query::sql::transformation::queryToPure::tests::testInAndNullOperators():Boolean[1]
{
- let sqlString = 'SELECT * FROM service."/service/service1" WHERE Integer IN (1,2,3) OR Integer IS NULL OR Integer IS NOT NULL';
- let sqlTransformContext = $sqlString->processQuery();
- let expected = {| FlatInput.all()->project(
+ test(
+ 'SELECT * FROM service."/service/service1" WHERE Integer IN (1,2,3) OR Integer IS NULL OR Integer IS NOT NULL',
+
+ {| FlatInput.all()->project(
[ x | $x.booleanIn, x | $x.integerIn, x | $x.floatIn, x | $x.decimalIn, x | $x.strictDateIn, x | $x.dateTimeIn, x | $x.stringIn ],
[ 'Boolean', 'Integer', 'Float', 'Decimal', 'StrictDate', 'DateTime', 'String' ])
->filter(row | $row.getInteger('Integer')->in([1,2,3]) || $row.getInteger('Integer')->isEmpty() || $row.getInteger('Integer')->isNotEmpty())
- };
- assertLambdaEquals($expected, $sqlTransformContext.lambda());
+ }, false)
}
function <> meta::external::query::sql::transformation::queryToPure::tests::testComparisonOperatorsNumber():Boolean[1]
{
- let sqlString = 'SELECT * FROM service."/service/service1" WHERE Integer > 1 OR Integer < 1 OR Integer >= 1 OR Integer <= 1 OR Integer BETWEEN 0 AND 1';
- let sqlTransformContext = $sqlString->processQuery();
- let expected = {| FlatInput.all()->project(
+ test(
+ 'SELECT * FROM service."/service/service1" WHERE Integer > 1 OR Integer < 1 OR Integer >= 1 OR Integer <= 1 OR Integer BETWEEN 0 AND 1',
+
+ {| FlatInput.all()->project(
[ x | $x.booleanIn, x | $x.integerIn, x | $x.floatIn, x | $x.decimalIn, x | $x.strictDateIn, x | $x.dateTimeIn, x | $x.stringIn ],
[ 'Boolean', 'Integer', 'Float', 'Decimal', 'StrictDate', 'DateTime', 'String' ])
->filter(row | ($row.getInteger('Integer') > 1)
@@ -484,52 +486,52 @@ function <> meta::external::query::sql::transformation::queryToPure::
|| ($row.getInteger('Integer') >= 1)
|| ($row.getInteger('Integer') <= 1)
|| (($row.getInteger('Integer') >= 0) && ($row.getInteger('Integer') <= 1)))
- };
- assertLambdaEquals($expected, $sqlTransformContext.lambda());
+ }, false)
}
function <> meta::external::query::sql::transformation::queryToPure::tests::testComparisonOperatorsString():Boolean[1]
{
- let sqlString = 'SELECT * FROM service."/service/service1" WHERE String > \'one\' OR String < \'one\' OR String >= \'one\' OR String <= \'one\'';
- let sqlTransformContext = $sqlString->processQuery();
- let expected = {| FlatInput.all()->project(
+ test(
+ 'SELECT * FROM service."/service/service1" WHERE String > \'one\' OR String < \'one\' OR String >= \'one\' OR String <= \'one\'',
+
+ {| FlatInput.all()->project(
[ x | $x.booleanIn, x | $x.integerIn, x | $x.floatIn, x | $x.decimalIn, x | $x.strictDateIn, x | $x.dateTimeIn, x | $x.stringIn ],
[ 'Boolean', 'Integer', 'Float', 'Decimal', 'StrictDate', 'DateTime', 'String' ])
->filter(row | ($row.getString('String') > 'one') || ($row.getString('String') < 'one') || ($row.getString('String') >= 'one') || ($row.getString('String') <= 'one'))
- };
- assertLambdaEquals($expected, $sqlTransformContext.lambda());
+ }, false)
}
function <> meta::external::query::sql::transformation::queryToPure::tests::testComparisonOperatorsBoolean():Boolean[1]
{
- let sqlString = 'SELECT * FROM service."/service/service1" WHERE Boolean > true OR Boolean < true OR Boolean >= false OR Boolean <= false';
- let sqlTransformContext = $sqlString->processQuery();
- let expected = {| FlatInput.all()->project(
+ test(
+ 'SELECT * FROM service."/service/service1" WHERE Boolean > true OR Boolean < true OR Boolean >= false OR Boolean <= false',
+
+ {| FlatInput.all()->project(
[ x | $x.booleanIn, x | $x.integerIn, x | $x.floatIn, x | $x.decimalIn, x | $x.strictDateIn, x | $x.dateTimeIn, x | $x.stringIn ],
[ 'Boolean', 'Integer', 'Float', 'Decimal', 'StrictDate', 'DateTime', 'String' ])
->filter(row | ($row.getBoolean('Boolean') > true) || ($row.getBoolean('Boolean') < true) || ($row.getBoolean('Boolean') >= false) || ($row.getBoolean('Boolean') <= false))
- };
- assertLambdaEquals($expected, $sqlTransformContext.lambda());
+ }, false)
}
function <> meta::external::query::sql::transformation::queryToPure::tests::testComparisonOperatorsDate():Boolean[1]
{
- let sqlString = 'SELECT * FROM service."/service/service1" WHERE StrictDate > TIMESTAMP \'2023-01-01\' OR StrictDate < CURRENT_DATE OR StrictDate >= TIMESTAMP \'2023-01-02\' OR StrictDate <= CURRENT_DATE OR StrictDate > \'2023-01-03\'';
- let sqlTransformContext = $sqlString->processQuery();
- let expected = {| FlatInput.all()->project(
+ test(
+ 'SELECT * FROM service."/service/service1" WHERE StrictDate > TIMESTAMP \'2023-01-01\' OR StrictDate < CURRENT_DATE OR StrictDate >= TIMESTAMP \'2023-01-02\' OR StrictDate <= CURRENT_DATE OR StrictDate > \'2023-01-03\'',
+
+ {| FlatInput.all()->project(
[ x | $x.booleanIn, x | $x.integerIn, x | $x.floatIn, x | $x.decimalIn, x | $x.strictDateIn, x | $x.dateTimeIn, x | $x.stringIn ],
[ 'Boolean', 'Integer', 'Float', 'Decimal', 'StrictDate', 'DateTime', 'String' ])
->filter(row | ($row.getStrictDate('StrictDate') > parseDate('2023-01-01')) || ($row.getStrictDate('StrictDate') < today())
|| ($row.getStrictDate('StrictDate') >= parseDate('2023-01-02')) || ($row.getStrictDate('StrictDate') <= today()) || ($row.getStrictDate('StrictDate') > parseDate('2023-01-03')))
- };
- assertLambdaEquals($expected, $sqlTransformContext.lambda());
+ }, false)
}
function <> meta::external::query::sql::transformation::queryToPure::tests::testComparisonOperatorsEnum():Boolean[1]
{
- let sqlString = 'SELECT * FROM service."/service/service3" WHERE "The Enum Value" > \'Value2\' or "The Enum Value" < \'Value_3\' or "The Enum Value" >= \'Value2\' or "The Enum Value" <= \'Value_3\' or "The Enum Value" = \'Value1\' or "The Enum Value" != \'Value1\'';
- let sqlTransformContext = $sqlString->processQuery();
- let expected = {|
+ test(
+ 'SELECT * FROM service."/service/service3" WHERE "The Enum Value" > \'Value2\' or "The Enum Value" < \'Value_3\' or "The Enum Value" >= \'Value2\' or "The Enum Value" <= \'Value_3\' or "The Enum Value" = \'Value1\' or "The Enum Value" != \'Value1\'',
+
+ {|
let const = 123;
FlatInput.all()->project(
[
@@ -545,15 +547,15 @@ function <> meta::external::query::sql::transformation::queryToPure::
|| $row.getEnum('The Enum Value') == MyEnum.Value1
|| $row.getEnum('The Enum Value') != MyEnum.Value1
)
- ;};
- assertLambdaEquals($expected, $sqlTransformContext.lambda());
+ ;}, false)
}
function <> meta::external::query::sql::transformation::queryToPure::tests::testDistinctFromOperator():Boolean[1]
{
- let sqlString = 'SELECT * FROM service."/service/service1" WHERE String IS DISTINCT FROM \'ABC\' OR String IS NOT DISTINCT FROM \'DEF\'';
- let sqlTransformContext = $sqlString->processQuery();
- let expected = {| FlatInput.all()->project(
+ test(
+ 'SELECT * FROM service."/service/service1" WHERE String IS DISTINCT FROM \'ABC\' OR String IS NOT DISTINCT FROM \'DEF\'',
+
+ {| FlatInput.all()->project(
[ x | $x.booleanIn, x | $x.integerIn, x | $x.floatIn, x | $x.decimalIn, x | $x.strictDateIn, x | $x.dateTimeIn, x | $x.stringIn ],
[ 'Boolean', 'Integer', 'Float', 'Decimal', 'StrictDate', 'DateTime', 'String' ])
->filter(row |
@@ -561,100 +563,99 @@ function <> meta::external::query::sql::transformation::queryToPure::
||
(($row.getString('String')->isEmpty() && 'DEF'->isEmpty()) || ($row.getString('String') == 'DEF'))
)
- };
- assertLambdaEquals($expected, $sqlTransformContext.lambda());
+ }, false)
}
function <> meta::external::query::sql::transformation::queryToPure::tests::testWhereCombined():Boolean[1]
{
- let sqlString = 'SELECT String, sum(Float) AS "float" FROM service."/service/service1" WHERE Integer = 1 GROUP BY 1';
- let sqlTransformContext = $sqlString->processQuery();
- let expected = {| FlatInput.all()->project(
+ test(
+ 'SELECT String, sum(Float) AS "float" FROM service."/service/service1" WHERE Integer = 1 GROUP BY 1',
+
+ {| FlatInput.all()->project(
[ x | $x.booleanIn, x | $x.integerIn, x | $x.floatIn, x | $x.decimalIn, x | $x.strictDateIn, x | $x.dateTimeIn, x | $x.stringIn ],
[ 'Boolean', 'Integer', 'Float', 'Decimal', 'StrictDate', 'DateTime', 'String' ])
->filter(row | ($row.getInteger('Integer') == 1))
->groupBy('String', agg('float', row | $row.getFloat('Float'), y | $y->sum()))
- };
- assertLambdaEquals($expected, $sqlTransformContext.lambda());
+ }, false)
}
//GROUP BY
function <> meta::external::query::sql::transformation::queryToPure::tests::testGroupBy():Boolean[1]
{
- let sqlString = 'SELECT count(Integer) AS "count" FROM service."/service/service1" GROUP BY String';
- let sqlTransformContext = $sqlString->processQuery();
- let expected = {| FlatInput.all()->project(
+ test(
+ 'SELECT count(Integer) AS "count" FROM service."/service/service1" GROUP BY String',
+
+ {| FlatInput.all()->project(
[ x | $x.booleanIn, x | $x.integerIn, x | $x.floatIn, x | $x.decimalIn, x | $x.strictDateIn, x | $x.dateTimeIn, x | $x.stringIn ],
[ 'Boolean', 'Integer', 'Float', 'Decimal', 'StrictDate', 'DateTime', 'String' ]
)->groupBy('String', agg('count', row | $row.getInteger('Integer'), y | $y->count()))
->restrict('count')
- };
- assertLambdaEquals($expected, $sqlTransformContext.lambda());
+ }, false)
}
function <> meta::external::query::sql::transformation::queryToPure::tests::testGroupByNoAggregates():Boolean[1]
{
- let sqlString = 'SELECT String FROM service."/service/service1" GROUP BY 1';
- let sqlTransformContext = $sqlString->processQuery();
- let expected = {| FlatInput.all()->project(
+ test(
+ 'SELECT String FROM service."/service/service1" GROUP BY 1',
+
+ {| FlatInput.all()->project(
[ x | $x.booleanIn, x | $x.integerIn, x | $x.floatIn, x | $x.decimalIn, x | $x.strictDateIn, x | $x.dateTimeIn, x | $x.stringIn ],
[ 'Boolean', 'Integer', 'Float', 'Decimal', 'StrictDate', 'DateTime', 'String' ]
)->restrict('String')->distinct()
- };
- assertLambdaAndJSONEquals($expected, $sqlTransformContext.lambda());
+ })
}
function <> meta::external::query::sql::transformation::queryToPure::tests::testGroupByIndex():Boolean[1]
{
- let sqlString = 'SELECT String, sum(Integer) AS "sum" FROM service."/service/service1" GROUP BY 1';
- let sqlTransformContext = $sqlString->processQuery();
- let expected = {| FlatInput.all()->project(
+ test(
+ 'SELECT String, sum(Integer) AS "sum" FROM service."/service/service1" GROUP BY 1',
+
+ {| FlatInput.all()->project(
[ x | $x.booleanIn, x | $x.integerIn, x | $x.floatIn, x | $x.decimalIn, x | $x.strictDateIn, x | $x.dateTimeIn, x | $x.stringIn ],
[ 'Boolean', 'Integer', 'Float', 'Decimal', 'StrictDate', 'DateTime', 'String' ]
)->groupBy(['String'], agg('sum', row | $row.getInteger('Integer'), y | $y->sum()))
- };
- assertLambdaEquals($expected, $sqlTransformContext.lambda());
+ }, false)
}
function <> meta::external::query::sql::transformation::queryToPure::tests::testGroupByIndexMultipleWithAlias():Boolean[1]
{
- let sqlString = 'SELECT String, sum(Integer) AS "sum", Boolean AS "bool" FROM service."/service/service1" GROUP BY 1, 3';
- let sqlTransformContext = $sqlString->processQuery();
- let expected = {| FlatInput.all()->project(
+ test(
+ 'SELECT String, sum(Integer) AS "sum", Boolean AS "bool" FROM service."/service/service1" GROUP BY 1, 3',
+
+ {| FlatInput.all()->project(
[ x | $x.booleanIn, x | $x.integerIn, x | $x.floatIn, x | $x.decimalIn, x | $x.strictDateIn, x | $x.dateTimeIn, x | $x.stringIn ],
[ 'Boolean', 'Integer', 'Float', 'Decimal', 'StrictDate', 'DateTime', 'String' ]
)->renameColumns(pair('Boolean', 'bool'))
->groupBy(['String', 'bool'], agg('sum', row | $row.getInteger('Integer'), y | $y->sum()))
->restrict(['String', 'sum', 'bool'])
- };
- assertLambdaEquals($expected, $sqlTransformContext.lambda());
+ }, false)
}
function <> meta::external::query::sql::transformation::queryToPure::tests::testGroupByWithAlias():Boolean[1]
{
- let sqlString = 'SELECT String, sum(Integer) AS "sum", Boolean AS "bool" FROM service."/service/service1" GROUP BY String, "bool"';
- let sqlTransformContext = $sqlString->processQuery();
- let expected = {| FlatInput.all()->project(
+ test(
+ 'SELECT String, sum(Integer) AS "sum", Boolean AS "bool" FROM service."/service/service1" GROUP BY String, "bool"',
+
+ {| FlatInput.all()->project(
[ x | $x.booleanIn, x | $x.integerIn, x | $x.floatIn, x | $x.decimalIn, x | $x.strictDateIn, x | $x.dateTimeIn, x | $x.stringIn ],
[ 'Boolean', 'Integer', 'Float', 'Decimal', 'StrictDate', 'DateTime', 'String' ]
)->renameColumns(pair('Boolean', 'bool'))
->groupBy(['String', 'bool'], agg('sum', row | $row.getInteger('Integer'), y | $y->sum()))
->restrict(['String', 'sum', 'bool'])
- };
- assertLambdaEquals($expected, $sqlTransformContext.lambda());
+ }, false)
}
function <> meta::external::query::sql::transformation::queryToPure::tests::testGroupByFunctions():Boolean[1]
{
- let sqlString = 'SELECT count(Integer) AS "count", count(DISTINCT Integer) AS "distinctCount", SUM(Integer) AS "sum", avg(Integer) AS "avg", ' +
+ test('SELECT count(Integer) AS "count", count(DISTINCT Integer) AS "distinctCount", SUM(Integer) AS "sum", avg(Integer) AS "avg", ' +
'stddev_pop(Integer) AS "stdDevPop", stddev_samp(Integer) AS "stdDevSamp", stddev(Integer) AS "stdDev", ' +
'var_pop(Integer) AS "variancePop", var_samp(Integer) AS "varianceSamp", variance(Integer) AS "variance", ' +
'min(Integer) AS "minInt", min(StrictDate) AS "minDate", min(String) AS "minString", ' +
'max(Integer) AS "maxInt", max(StrictDate) AS "maxDate", max(String) AS "maxString", ' +
- 'string_agg(String) AS "stringAgg", string_agg(cast(Integer AS VARCHAR), \' \') AS "stringAgg2" FROM service."/service/service1" GROUP BY String';
- let sqlTransformContext = $sqlString->processQuery();
- let expected = {| FlatInput.all()->project(
+ 'string_agg(String) AS "stringAgg", string_agg(cast(Integer AS VARCHAR), \' \') AS "stringAgg2" FROM service."/service/service1" GROUP BY String',
+
+ {| FlatInput.all()->project(
[ x | $x.booleanIn, x | $x.integerIn, x | $x.floatIn, x | $x.decimalIn, x | $x.strictDateIn, x | $x.dateTimeIn, x | $x.stringIn ],
[ 'Boolean', 'Integer', 'Float', 'Decimal', 'StrictDate', 'DateTime', 'String' ]
)->groupBy('String', [
@@ -677,15 +678,15 @@ function <> meta::external::query::sql::transformation::queryToPure::
agg('stringAgg', row | $row.getString('String'), y | $y->joinStrings()),
agg('stringAgg2', row | $row.getInteger('Integer')->toString(), y | $y->joinStrings(' '))
])->restrict(['count', 'distinctCount', 'sum', 'avg', 'stdDevPop', 'stdDevSamp', 'stdDev', 'variancePop', 'varianceSamp', 'variance', 'minInt', 'minDate', 'minString', 'maxInt', 'maxDate', 'maxString', 'stringAgg', 'stringAgg2'])
- };
- assertLambdaEquals($expected, $sqlTransformContext.lambda());
+ }, false)
}
function <> meta::external::query::sql::transformation::queryToPure::tests::testGroupByAggregateExpressions():Boolean[1]
{
- let sqlString = 'SELECT Integer, sum(1) AS "sum", count(*) AS "count", sum(Integer + Float) AS "exp", EXTRACT(YEAR FROM MAX("StrictDate")) AS "aggFunctionCall", MAX("StrictDate") + INTERVAL \'1 WEEK\' AS "dateAggMath" FROM service."/service/service1" GROUP BY Integer';
- let sqlTransformContext = $sqlString->processQuery();
- let expected = {| FlatInput.all()->project(
+ test(
+ 'SELECT Integer, sum(1) AS "sum", count(*) AS "count", sum(Integer + Float) AS "exp", EXTRACT(YEAR FROM MAX("StrictDate")) AS "aggFunctionCall", MAX("StrictDate") + INTERVAL \'1 WEEK\' AS "dateAggMath" FROM service."/service/service1" GROUP BY Integer',
+
+ {| FlatInput.all()->project(
[ x | $x.booleanIn, x | $x.integerIn, x | $x.floatIn, x | $x.decimalIn, x | $x.strictDateIn, x | $x.dateTimeIn, x | $x.stringIn ],
[ 'Boolean', 'Integer', 'Float', 'Decimal', 'StrictDate', 'DateTime', 'String' ]
)->groupBy(['Integer'], [
@@ -695,16 +696,15 @@ function <> meta::external::query::sql::transformation::queryToPure::
agg('aggFunctionCall', row | $row.getStrictDate('StrictDate'), y | $y->max()->toOne()->year()),
agg('dateAggMath', row | $row.getStrictDate('StrictDate'), y | $y->max()->toOne()->adjust(1, DurationUnit.WEEKS))
])
- };
-
- assertLambdaEquals($expected, $sqlTransformContext.lambda());
+ }, false)
}
function <> meta::external::query::sql::transformation::queryToPure::tests::testGroupByMixed():Boolean[1]
{
- let sqlString = 'SELECT sum(Integer) AS "SUM", CASE WHEN String = \'abc\' THEN 1 WHEN String = \'def\' THEN 2 ELSE 3 END AS "Number" FROM service."/service/service1" GROUP BY 2';
- let sqlTransformContext = $sqlString->processQuery();
- let expected = {| FlatInput.all()->project(
+ test(
+ 'SELECT sum(Integer) AS "SUM", CASE WHEN String = \'abc\' THEN 1 WHEN String = \'def\' THEN 2 ELSE 3 END AS "Number" FROM service."/service/service1" GROUP BY 2',
+
+ {| FlatInput.all()->project(
[ x | $x.booleanIn, x | $x.integerIn, x | $x.floatIn, x | $x.decimalIn, x | $x.strictDateIn, x | $x.dateTimeIn, x | $x.stringIn ],
[ 'Boolean', 'Integer', 'Float', 'Decimal', 'StrictDate', 'DateTime', 'String' ]
)->extend(
@@ -712,32 +712,31 @@ function <> meta::external::query::sql::transformation::queryToPure::
)->groupBy(['Number'], [
agg('SUM', row | $row.getInteger('Integer'), y | $y->sum())
])->restrict(['SUM', 'Number'])
- };
- assertLambdaEquals($expected, $sqlTransformContext.lambda());
+ }, false)
}
function <> meta::external::query::sql::transformation::queryToPure::tests::testGroupByAggWithinCase():Boolean[1]
{
- let sqlString = 'SELECT CASE WHEN(SUM("Integer") <10) THEN max("Integer") ELSE min("Integer") END AS "MIN/MAX", ' +
- 'CASE WHEN(SUM("Integer") < 10) THEN \'LOW\' ELSE \'HIGH\' END AS "HIGH/LOW" FROM service."/service/service1"';
- let sqlTransformContext = $sqlString->processQuery();
- let expected = {| FlatInput.all()->project(
+ test('SELECT CASE WHEN(SUM("Integer") <10) THEN max("Integer") ELSE min("Integer") END AS "MIN/MAX", ' +
+ 'CASE WHEN(SUM("Integer") < 10) THEN \'LOW\' ELSE \'HIGH\' END AS "HIGH/LOW" FROM service."/service/service1"',
+
+ {| FlatInput.all()->project(
[ x | $x.booleanIn, x | $x.integerIn, x | $x.floatIn, x | $x.decimalIn, x | $x.strictDateIn, x | $x.dateTimeIn, x | $x.stringIn ],
[ 'Boolean', 'Integer', 'Float', 'Decimal', 'StrictDate', 'DateTime', 'String' ]
)->groupBy([], [
agg('MIN/MAX', row | $row.getInteger('Integer'), y | if ($y->sum() < 10, | max($y), | min($y))),
agg('HIGH/LOW', row | $row.getInteger('Integer'), y | if ($y->sum() < 10, | 'LOW', | 'HIGH'))
])
- };
- assertLambdaEquals($expected, $sqlTransformContext.lambda());
+ }, false)
}
//HAVING
function <> meta::external::query::sql::transformation::queryToPure::tests::testHaving():Boolean[1]
{
- let sqlString = 'SELECT count(Integer) AS "count", max(Integer) FROM service."/service/service1" GROUP BY String HAVING count(Integer) > 0 AND count(1) > 0 AND floor(max(Integer)) > 0';
- let sqlTransformContext = $sqlString->processQuery();
- let expected = {| FlatInput.all()->project(
+ test(
+ 'SELECT count(Integer) AS "count", max(Integer) FROM service."/service/service1" GROUP BY String HAVING count(Integer) > 0 AND count(1) > 0 AND floor(max(Integer)) > 0',
+
+ {| FlatInput.all()->project(
[ x | $x.booleanIn, x | $x.integerIn, x | $x.floatIn, x | $x.decimalIn, x | $x.strictDateIn, x | $x.dateTimeIn, x | $x.stringIn ],
[ 'Boolean', 'Integer', 'Float', 'Decimal', 'StrictDate', 'DateTime', 'String' ]
)->groupBy('String', [
@@ -747,15 +746,14 @@ function <> meta::external::query::sql::transformation::queryToPure::
])->filter(row | ($row.getInteger('count') > 0) && ($row.getInteger('count(1)') > 0) && (floor($row.getInteger('max(Integer)')) > 0))
->restrict(['count', 'max(Integer)'])
- };
- assertLambdaEquals($expected, $sqlTransformContext.lambda());
+ }, false)
}
function <> meta::external::query::sql::transformation::queryToPure::tests::testHavingNoGroupby():Boolean[1]
{
- let sqlString = 'SELECT \'abc\', pi() AS "pi" FROM service."/service/service1" HAVING count(1) > 0 AND count(1) < 1000';
- let sqlTransformContext = $sqlString->processQuery();
- let expected = {| FlatInput.all()->project(
+ test('SELECT \'abc\', pi() AS "pi" FROM service."/service/service1" HAVING count(1) > 0 AND count(1) < 1000',
+
+ {| FlatInput.all()->project(
[ x | $x.booleanIn, x | $x.integerIn, x | $x.floatIn, x | $x.decimalIn, x | $x.strictDateIn, x | $x.dateTimeIn, x | $x.stringIn ],
[ 'Boolean', 'Integer', 'Float', 'Decimal', 'StrictDate', 'DateTime', 'String' ]
)->extend([
@@ -767,15 +765,15 @@ function <> meta::external::query::sql::transformation::queryToPure::
])->filter(row | ($row.getInteger('count(1)') > 0) && ($row.getInteger('count(1)') < 1000))
->restrict(['abc', 'pi'])
- };
- assertLambdaEquals($expected, $sqlTransformContext.lambda());
+ }, false)
}
function <> meta::external::query::sql::transformation::queryToPure::tests::testHavingWithJoinAndColumnAlias():Boolean[1]
{
- let sqlString = 'SELECT table1.*, table2.String as "str" FROM service(\'/service/service1\') "table1" LEFT JOIN service(\'/service/service1\') "table2" USING (String) HAVING (COUNT(1) > 0)';
- let sqlTransformContext = $sqlString->processQuery();
- let expected = {| FlatInput.all()->project(
+ test(
+ 'SELECT table1.*, table2.String as "str" FROM service(\'/service/service1\') "table1" LEFT JOIN service(\'/service/service1\') "table2" USING (String) HAVING (COUNT(1) > 0)',
+
+ {| FlatInput.all()->project(
[ x | $x.booleanIn, x | $x.integerIn, x | $x.floatIn, x | $x.decimalIn, x | $x.strictDateIn, x | $x.dateTimeIn, x | $x.stringIn ],
[ 'Boolean', 'Integer', 'Float', 'Decimal', 'StrictDate', 'DateTime', 'String' ])
->renameColumns([
@@ -816,36 +814,35 @@ function <> meta::external::query::sql::transformation::queryToPure::
pair('String_table1', 'String')
])
->restrict(['Boolean', 'Integer', 'Float', 'Decimal', 'StrictDate', 'DateTime', 'String', 'str'])
- };
- assertLambdaEquals($expected, $sqlTransformContext.lambda());
+ }, false)
}
function <> meta::external::query::sql::transformation::queryToPure::tests::testHavingSelectStar():Boolean[1]
{
- let sqlString = 'SELECT * FROM service(\'/service/service1\') HAVING (COUNT(1) > 0)';
- let sqlTransformContext = $sqlString->processQuery();
- let expected = {| FlatInput.all()->project(
+ test(
+ 'SELECT * FROM service(\'/service/service1\') HAVING (COUNT(1) > 0)',
+
+ {| FlatInput.all()->project(
[ x | $x.booleanIn, x | $x.integerIn, x | $x.floatIn, x | $x.decimalIn, x | $x.strictDateIn, x | $x.dateTimeIn, x | $x.stringIn ],
[ 'Boolean', 'Integer', 'Float', 'Decimal', 'StrictDate', 'DateTime', 'String' ])
->groupBy(['Boolean', 'Integer', 'Float', 'Decimal', 'StrictDate', 'DateTime', 'String'], agg('COUNT(1)', row | 1, y | $y->count()))->filter(row | $row.getInteger('COUNT(1)') > 0)
->restrict([ 'Boolean', 'Integer', 'Float', 'Decimal', 'StrictDate', 'DateTime', 'String' ])
- };
- assertLambdaEquals($expected, $sqlTransformContext.lambda());
+ }, false)
}
//CAST
function <> meta::external::query::sql::transformation::queryToPure::tests::testCasts():Boolean[1]
{
- let sqlString = 'SELECT'
- + ' CAST(\'2023-01-01\' AS DATE) AS "constant", CAST(String AS VARCHAR) AS "string", CAST(String AS TEXT) AS "text", CAST(String AS DATE) AS "date",'
- + ' CAST(String AS INTEGER) AS "integer", CAST(String AS BIGINT) AS "bigint", CAST(String AS SMALLINT) AS "smallint", CAST(String AS BOOLEAN) AS "boolean", '
- + ' CAST(String AS DOUBLE PRECISION) AS "double", CAST(String AS NUMERIC) AS "numeric",'
- + ' CAST(String AS TIMESTAMP) AS "timestamp", CAST(Integer AS TEXT) AS "integerText", CAST(Integer AS VARCHAR) AS "integerString", CAST(Integer AS Integer) AS "expression",'
- + ' CAST(String AS VARCHAR(2)) AS "stringChars", CAST(Integer AS VARCHAR(2)) AS "integerStringChars",'
- + ' CAST(Float AS NUMERIC) AS "floatNumeric", CAST(Decimal AS NUMERIC) AS "decimalNumeric", CAST(Decimal AS DOUBLE PRECISION) AS "decimalDoublePrecision",'
- + ' CAST(Float AS DOUBLE PRECISION) AS "floatDoublePrecision", CAST(String AS NUMERIC(4, 2)) AS "numericParams" FROM service."/service/service1"';
- let sqlTransformContext = $sqlString->processQuery();
- let expected = {| FlatInput.all()->project(
+ test('SELECT' +
+ ' CAST(\'2023-01-01\' AS DATE) AS "constant", CAST(String AS VARCHAR) AS "string", CAST(String AS TEXT) AS "text", CAST(String AS DATE) AS "date",' +
+ ' CAST(String AS INTEGER) AS "integer", CAST(String AS BIGINT) AS "bigint", CAST(String AS SMALLINT) AS "smallint", CAST(String AS BOOLEAN) AS "boolean", ' +
+ ' CAST(String AS DOUBLE PRECISION) AS "double", CAST(String AS NUMERIC) AS "numeric",' +
+ ' CAST(String AS TIMESTAMP) AS "timestamp", CAST(Integer AS TEXT) AS "integerText", CAST(Integer AS VARCHAR) AS "integerString", CAST(Integer AS Integer) AS "expression",' +
+ ' CAST(String AS VARCHAR(2)) AS "stringChars", CAST(Integer AS VARCHAR(2)) AS "integerStringChars",' +
+ ' CAST(Float AS NUMERIC) AS "floatNumeric", CAST(Decimal AS NUMERIC) AS "decimalNumeric", CAST(Decimal AS DOUBLE PRECISION) AS "decimalDoublePrecision",' +
+ ' CAST(Float AS DOUBLE PRECISION) AS "floatDoublePrecision", CAST(String AS NUMERIC(4, 2)) AS "numericParams" FROM service."/service/service1"',
+
+ {| FlatInput.all()->project(
[ x | $x.booleanIn, x | $x.integerIn, x | $x.floatIn, x | $x.decimalIn, x | $x.strictDateIn, x | $x.dateTimeIn, x | $x.stringIn ],
[ 'Boolean', 'Integer', 'Float', 'Decimal', 'StrictDate', 'DateTime', 'String' ]
)->project([
@@ -871,17 +868,17 @@ function <> meta::external::query::sql::transformation::queryToPure::
col(row:TDSRow[1] | $row.getFloat('Float'), 'floatDoublePrecision'),
col(row:TDSRow[1] | round(parseDecimal($row.getString('String')), 2), 'numericParams')
])
- };
-
- assertLambdaAndJSONEquals($expected, $sqlTransformContext.lambda());
+ })
}
//CAST
function <> meta::external::query::sql::transformation::queryToPure::tests::testDateCasts():Boolean[1]
{
- let sqlString = 'SELECT CAST(\'2023-01-01\' AS DATE) AS "constantDate", CAST(String AS DATE) AS "date", CAST(\'2023-01-01 10:01:01\' AS TIMESTAMP) AS "constantTimestamp", CAST(\'2023-01-01 10:01:01.12\' AS TIMESTAMP) AS "constantTimestampMillis", CAST(String AS TIMESTAMP) AS "timestamp" FROM service."/service/service1"';
- let sqlTransformContext = $sqlString->processQuery();
- let expected = {| FlatInput.all()->project(
+ test(
+ 'SELECT CAST(\'2023-01-01\' AS DATE) AS "constantDate", CAST(String AS DATE) AS "date", CAST(\'2023-01-01 10:01:01\' AS TIMESTAMP) AS "constantTimestamp", ' +
+ 'CAST(\'2023-01-01 10:01:01.12\' AS TIMESTAMP) AS "constantTimestampMillis", CAST(String AS TIMESTAMP) AS "timestamp" FROM service."/service/service1"',
+
+ {| FlatInput.all()->project(
[ x | $x.booleanIn, x | $x.integerIn, x | $x.floatIn, x | $x.decimalIn, x | $x.strictDateIn, x | $x.dateTimeIn, x | $x.stringIn ],
[ 'Boolean', 'Integer', 'Float', 'Decimal', 'StrictDate', 'DateTime', 'String' ]
)->project([
@@ -891,17 +888,15 @@ function <> meta::external::query::sql::transformation::queryToPure::
col(row:TDSRow[1] | parseDate('2023-01-01T10:01:01.12'), 'constantTimestampMillis'),
col(row:TDSRow[1] | parseDate($row.getString('String')), 'timestamp')
])
- };
-
- assertLambdaAndJSONEquals($expected, $sqlTransformContext.lambda());
+ })
}
function <> meta::external::query::sql::transformation::queryToPure::tests::testNullCasts():Boolean[1]
{
- let sqlString = 'SELECT CAST(NULL AS VARCHAR) AS "string", CAST(NULL AS TEXT) AS "text", CAST(NULL AS DATE) AS "date",'
- + ' CAST(NULL AS INTEGER) AS "integer", CAST(NULL AS BOOLEAN) AS "boolean", CAST(NULL AS DOUBLE PRECISION) AS "double", CAST(NULL AS NUMERIC) AS "numeric", CAST(NULL AS TIMESTAMP) AS "timestamp" FROM service."/service/service1"';
- let sqlTransformContext = $sqlString->processQuery();
- let expected = {| FlatInput.all()->project(
+ test('SELECT CAST(NULL AS VARCHAR) AS "string", CAST(NULL AS TEXT) AS "text", CAST(NULL AS DATE) AS "date", ' +
+ 'CAST(NULL AS INTEGER) AS "integer", CAST(NULL AS BOOLEAN) AS "boolean", CAST(NULL AS DOUBLE PRECISION) AS "double", CAST(NULL AS NUMERIC) AS "numeric", CAST(NULL AS TIMESTAMP) AS "timestamp" FROM service."/service/service1"',
+
+ {| FlatInput.all()->project(
[ x | $x.booleanIn, x | $x.integerIn, x | $x.floatIn, x | $x.decimalIn, x | $x.strictDateIn, x | $x.dateTimeIn, x | $x.stringIn ],
[ 'Boolean', 'Integer', 'Float', 'Decimal', 'StrictDate', 'DateTime', 'String' ]
)->project([
@@ -914,17 +909,17 @@ function <> meta::external::query::sql::transformation::queryToPure::
col(row:TDSRow[1] | cast([], @Decimal), 'numeric'),
col(row:TDSRow[1] | cast([], @DateTime), 'timestamp')
])
- };
- assertLambdaAndJSONEquals($expected, $sqlTransformContext.lambda());
+ })
}
//CASE
function <> meta::external::query::sql::transformation::queryToPure::tests::testMultiSearchedCaseWhen():Boolean[1]
{
- let sqlString = 'SELECT CASE WHEN String = \'abc\' THEN 1 WHEN String = \'def\' THEN NULL ELSE 3 END AS "Number" FROM service."/service/service1"';
- let sqlTransformContext = $sqlString->processQuery();
- let expected = {| FlatInput.all()->project(
+ test(
+ 'SELECT CASE WHEN String = \'abc\' THEN 1 WHEN String = \'def\' THEN NULL ELSE 3 END AS "Number" FROM service."/service/service1"',
+
+ {| FlatInput.all()->project(
[ x | $x.booleanIn, x | $x.integerIn, x | $x.floatIn, x | $x.decimalIn, x | $x.strictDateIn, x | $x.dateTimeIn, x | $x.stringIn ],
[ 'Boolean', 'Integer', 'Float', 'Decimal', 'StrictDate', 'DateTime', 'String' ])
->project(
@@ -932,15 +927,15 @@ function <> meta::external::query::sql::transformation::queryToPure::
col(row:TDSRow[1] | if ($row.getString('String') == 'abc', | 1, | if ($row.getString('String') == 'def', | [], | 3)), 'Number')
]
)
- };
- assertLambdaAndJSONEquals($expected, $sqlTransformContext.lambda());
+ })
}
function <> meta::external::query::sql::transformation::queryToPure::tests::testCaseWhen():Boolean[1]
{
- let sqlString = 'SELECT CASE String WHEN \'abc\' THEN 1 WHEN \'def\' THEN 2 ELSE 3 END AS "Number" FROM service."/service/service1"';
- let sqlTransformContext = $sqlString->processQuery();
- let expected = {| FlatInput.all()->project(
+ test(
+ 'SELECT CASE String WHEN \'abc\' THEN 1 WHEN \'def\' THEN 2 ELSE 3 END AS "Number" FROM service."/service/service1"',
+
+ {| FlatInput.all()->project(
[ x | $x.booleanIn, x | $x.integerIn, x | $x.floatIn, x | $x.decimalIn, x | $x.strictDateIn, x | $x.dateTimeIn, x | $x.stringIn ],
[ 'Boolean', 'Integer', 'Float', 'Decimal', 'StrictDate', 'DateTime', 'String' ])
->project(
@@ -948,18 +943,17 @@ function <> meta::external::query::sql::transformation::queryToPure::
col(row:TDSRow[1] | if ($row.getString('String') == 'abc', | 1, | if ($row.getString('String') == 'def', | 2, | 3)), 'Number')
]
)
- };
- assertLambdaAndJSONEquals($expected, $sqlTransformContext.lambda());
+ })
}
///ARITHMETIC
function <> meta::external::query::sql::transformation::queryToPure::tests::testArithmetic():Boolean[1]
{
- let sqlString = 'SELECT 1 + 2 AS "plus", 1 - 2 AS "minus", 1 * 2 AS "multiply", 1 / 2 AS "divide", 1 % 2 AS "mod", 1 ^ 2 AS "pow", Integer + Float AS "column plus" FROM service."/service/service1"';
+ test(
+ 'SELECT 1 + 2 AS "plus", 1 - 2 AS "minus", 1 * 2 AS "multiply", 1 / 2 AS "divide", 1 % 2 AS "mod", 1 ^ 2 AS "pow", Integer + Float AS "column plus" FROM service."/service/service1"',
- let sqlTransformContext = $sqlString->processQuery();
- let expected = {| FlatInput.all()->project(
+ {| FlatInput.all()->project(
[ x | $x.booleanIn, x | $x.integerIn, x | $x.floatIn, x | $x.decimalIn, x | $x.strictDateIn, x | $x.dateTimeIn, x | $x.stringIn ],
[ 'Boolean', 'Integer', 'Float', 'Decimal', 'StrictDate', 'DateTime', 'String' ])
->project(
@@ -973,16 +967,15 @@ function <> meta::external::query::sql::transformation::queryToPure::
col(row:TDSRow[1] | $row.getInteger('Integer') + $row.getFloat('Float'), 'column plus')
]
)
- };
- assertLambdaAndJSONEquals($expected, $sqlTransformContext.lambda());
+ })
}
function <> meta::external::query::sql::transformation::queryToPure::tests::testArithmeticNullable():Boolean[1]
{
- let sqlString = 'SELECT 1 + NULL AS "plus", 1 - NULL AS "minus", 1 * NULL AS "multiply", 1 / NULL AS "divide", 1 % NULL AS "mod", 1 ^ NULL AS "pow" FROM service."/service/service1"';
+ test(
+ 'SELECT 1 + NULL AS "plus", 1 - NULL AS "minus", 1 * NULL AS "multiply", 1 / NULL AS "divide", 1 % NULL AS "mod", 1 ^ NULL AS "pow" FROM service."/service/service1"',
- let sqlTransformContext = $sqlString->processQuery();
- let expected = {| FlatInput.all()->project(
+ {| FlatInput.all()->project(
[ x | $x.booleanIn, x | $x.integerIn, x | $x.floatIn, x | $x.decimalIn, x | $x.strictDateIn, x | $x.dateTimeIn, x | $x.stringIn ],
[ 'Boolean', 'Integer', 'Float', 'Decimal', 'StrictDate', 'DateTime', 'String' ])
->project(
@@ -995,17 +988,16 @@ function <> meta::external::query::sql::transformation::queryToPure::
col(row:TDSRow[1] | []->cast(@Number), 'pow')
]
)
- };
- assertLambdaAndJSONEquals($expected, $sqlTransformContext.lambda());
+ })
}
//JOIN
function <> meta::external::query::sql::transformation::queryToPure::tests::testLeftJoinSubqueryOn():Boolean[1]
{
- let sqlString = 'SELECT table1.Integer FROM service."/service/service1" "table1" LEFT OUTER JOIN (SELECT Integer FROM service."/service/service2") AS "table2" ON "table1"."Integer" = "table2"."Integer"';
+ test(
+ 'SELECT table1.Integer FROM service."/service/service1" "table1" LEFT OUTER JOIN (SELECT Integer FROM service."/service/service2") AS "table2" ON "table1"."Integer" = "table2"."Integer"',
- let sqlTransformContext = $sqlString->processQuery();
- let expected = {| FlatInput.all()->project(
+ {| FlatInput.all()->project(
[ x | $x.booleanIn, x | $x.integerIn, x | $x.floatIn, x | $x.decimalIn, x | $x.strictDateIn, x | $x.dateTimeIn, x | $x.stringIn ],
[ 'Boolean', 'Integer', 'Float', 'Decimal', 'StrictDate', 'DateTime', 'String' ])->renameColumns([
pair('Boolean', 'Boolean_table1'),
@@ -1024,17 +1016,15 @@ function <> meta::external::query::sql::transformation::queryToPure::
pair('Integer', 'Integer_table2')
]), meta::relational::metamodel::join::JoinType.LEFT_OUTER, {row1:TDSRow[1], row2:TDSRow[1] | $row1.getInteger('Integer_table1') == $row2.getInteger('Integer_table2')}
)->restrict('Integer_table1')->renameColumns(pair('Integer_table1', 'Integer'))
- };
-
- assertLambdaAndJSONEquals($expected, $sqlTransformContext.lambda());
+ })
}
function <> meta::external::query::sql::transformation::queryToPure::tests::testLeftJoinSubqueryUsing():Boolean[1]
{
- let sqlString = 'SELECT table1.Integer AS "Int", table2.String AS "Str" FROM service."/service/service1" AS table1 LEFT OUTER JOIN (SELECT Integer, String FROM service."/service/service1") AS table2 USING (Integer)';
+ test(
+ 'SELECT table1.Integer AS "Int", table2.String AS "Str" FROM service."/service/service1" AS table1 LEFT OUTER JOIN (SELECT Integer, String FROM service."/service/service1") AS table2 USING (Integer)',
- let sqlTransformContext = $sqlString->processQuery();
- let expected = {| FlatInput.all()->project(
+ {| FlatInput.all()->project(
[ x | $x.booleanIn, x | $x.integerIn, x | $x.floatIn, x | $x.decimalIn, x | $x.strictDateIn, x | $x.dateTimeIn, x | $x.stringIn ],
[ 'Boolean', 'Integer', 'Float', 'Decimal', 'StrictDate', 'DateTime', 'String' ])->renameColumns([
pair('Boolean', 'Boolean_table1'),
@@ -1059,16 +1049,15 @@ function <> meta::external::query::sql::transformation::queryToPure::
pair('Integer_table1', 'Int'),
pair('String_table2', 'Str')
])
- };
- assertLambdaAndJSONEquals($expected, $sqlTransformContext.lambda());
+ });
}
function <> meta::external::query::sql::transformation::queryToPure::tests::testCrossJoin():Boolean[1]
{
- let sqlString = 'SELECT table1.Integer AS "Int", table2.String AS "Str" FROM service."/service/service1" table1 CROSS JOIN service."/service/service2" table2';
+ test(
+ 'SELECT table1.Integer AS "Int", table2.String AS "Str" FROM service."/service/service1" table1 CROSS JOIN service."/service/service2" table2',
- let sqlTransformContext = $sqlString->processQuery();
- let expected = {| FlatInput.all()->project(
+ {| FlatInput.all()->project(
[ x | $x.booleanIn, x | $x.integerIn, x | $x.floatIn, x | $x.decimalIn, x | $x.strictDateIn, x | $x.dateTimeIn, x | $x.stringIn ],
[ 'Boolean', 'Integer', 'Float', 'Decimal', 'StrictDate', 'DateTime', 'String' ])->renameColumns([
pair('Boolean', 'Boolean_table1'),
@@ -1090,17 +1079,15 @@ function <> meta::external::query::sql::transformation::queryToPure::
pair('Integer_table1', 'Int'),
pair('String_table2', 'Str')
])
- };
-
- assertLambdaAndJSONEquals($expected, $sqlTransformContext.lambda());
+ })
}
function <> meta::external::query::sql::transformation::queryToPure::tests::testImplicitJoin():Boolean[1]
{
- let sqlString = 'SELECT table1.Integer AS "Int", table2.String AS "Str" FROM service."/service/service1" table1, service."/service/service2" table2 where table1.Integer = table2.Integer';
+ test(
+ 'SELECT table1.Integer AS "Int", table2.String AS "Str" FROM service."/service/service1" table1, service."/service/service2" table2 where table1.Integer = table2.Integer',
- let sqlTransformContext = $sqlString->processQuery();
- let expected = {| FlatInput.all()->project(
+ {| FlatInput.all()->project(
[ x | $x.booleanIn, x | $x.integerIn, x | $x.floatIn, x | $x.decimalIn, x | $x.strictDateIn, x | $x.dateTimeIn, x | $x.stringIn ],
[ 'Boolean', 'Integer', 'Float', 'Decimal', 'StrictDate', 'DateTime', 'String' ])->renameColumns([
pair('Boolean', 'Boolean_table1'),
@@ -1123,17 +1110,15 @@ function <> meta::external::query::sql::transformation::queryToPure::
pair('Integer_table1', 'Int'),
pair('String_table2', 'Str')
])
- };
-
- assertLambdaEquals($expected, $sqlTransformContext.lambda());
+ }, false)
}
function <> meta::external::query::sql::transformation::queryToPure::tests::testLeftJoinRelationOn():Boolean[1]
{
- let sqlString = 'SELECT table1.Integer AS Integer, table2.String AS String FROM service."/service/service1" AS table1 LEFT OUTER JOIN service."/service/service2" AS table2 ON (table1.Integer = table2.Integer)';
+ test(
+ 'SELECT table1.Integer AS Integer, table2.String AS String FROM service."/service/service1" AS table1 LEFT OUTER JOIN service."/service/service2" AS table2 ON (table1.Integer = table2.Integer)',
- let sqlTransformContext = $sqlString->processQuery();
- let expected = {| FlatInput.all()->project(
+ {| FlatInput.all()->project(
[ x | $x.booleanIn, x | $x.integerIn, x | $x.floatIn, x | $x.decimalIn, x | $x.strictDateIn, x | $x.dateTimeIn, x | $x.stringIn ],
[ 'Boolean', 'Integer', 'Float', 'Decimal', 'StrictDate', 'DateTime', 'String' ])->renameColumns([
pair('Boolean', 'Boolean_table1'),
@@ -1156,67 +1141,61 @@ function <> meta::external::query::sql::transformation::queryToPure::
pair('Integer_table1', 'Integer'),
pair('String_table2', 'String')
])
- };
-
- assertLambdaAndJSONEquals($expected, $sqlTransformContext.lambda());
+ })
}
function <> meta::external::query::sql::transformation::queryToPure::tests::testMultiJoin():Boolean[1]
{
- let sqlString = 'SELECT * FROM (SELECT * FROM service(\'/service/service1\')) "table1" LEFT JOIN (SELECT * FROM service(\'/service/service2\')) "table2" ON ("table1"."String" = "table2"."ID") LEFT JOIN (SELECT * FROM service(\'/service/service2\')) "table3" ON ("table1"."String" = "table3"."String") WHERE "table2"."String" = \'ABC\'';
+ test(
+ 'SELECT * FROM (SELECT * FROM service(\'/service/service1\')) "table1" LEFT JOIN (SELECT * FROM service(\'/service/service2\')) "table2" ON ("table1"."String" = "table2"."ID") ' +
+ 'LEFT JOIN (SELECT * FROM service(\'/service/service2\')) "table3" ON ("table1"."String" = "table3"."String") WHERE "table2"."String" = \'ABC\'',
- let sqlTransformContext = $sqlString->processQuery();
-
- let expected = {|FlatInput.all()
- ->project([{x|$x.booleanIn}, {x|$x.integerIn}, {x|$x.floatIn}, {x|$x.decimalIn}, {x|$x.strictDateIn}, {x|$x.dateTimeIn}, {x|$x.stringIn}], ['Boolean', 'Integer', 'Float', 'Decimal', 'StrictDate', 'DateTime', 'String'])
- ->renameColumns([
- pair('Boolean', 'Boolean_table1'),
- pair('Integer', 'Integer_table1'),
- pair('Float', 'Float_table1'),
- pair('Decimal', 'Decimal_table1'),
- pair('StrictDate', 'StrictDate_table1'),
- pair('DateTime', 'DateTime_table1'),
- pair('String', 'String_table1')
- ])
- ->join(FlatInput.all()
- ->project([{x|$x.idIn}, {x|$x.integerIn}, {x|$x.stringIn}], ['ID', 'Integer', 'String'])
- ->renameColumns([
- pair('ID', 'ID_table2'),
- pair('Integer', 'Integer_table2'),
- pair('String', 'String_table2')
- ]),
- meta::relational::metamodel::join::JoinType.LEFT_OUTER,
- {row1, row2|$row1.getString('String_table1') == $row2.getInteger('ID_table2')})
- ->join(meta::external::query::sql::transformation::queryToPure::tests::FlatInput.all()
- ->project([{x|$x.idIn}, {x|$x.integerIn}, {x|$x.stringIn}], ['ID', 'Integer', 'String'])
- ->renameColumns([
- pair('ID', 'ID_table3'),
- pair('Integer', 'Integer_table3'),
- pair('String', 'String_table3')
- ]),
- meta::relational::metamodel::join::JoinType.LEFT_OUTER,
- {row1, row2|$row1.getString('String_table1') == $row2.getString('String_table3')})
- ->filter({row|$row.getString('String_table2') == 'ABC'})
- ->renameColumns([
- pair('Boolean_table1', 'Boolean'),
- pair('Float_table1', 'Float'),
- pair('Decimal_table1', 'Decimal'),
- pair('StrictDate_table1', 'StrictDate'),
- pair('DateTime_table1', 'DateTime')
- ])
- };
-
- assertLambdaEquals($expected, $sqlTransformContext.lambda());
+ {|FlatInput.all()
+ ->project([{x|$x.booleanIn}, {x|$x.integerIn}, {x|$x.floatIn}, {x|$x.decimalIn}, {x|$x.strictDateIn}, {x|$x.dateTimeIn}, {x|$x.stringIn}], ['Boolean', 'Integer', 'Float', 'Decimal', 'StrictDate', 'DateTime', 'String'])
+ ->renameColumns([
+ pair('Boolean', 'Boolean_table1'),
+ pair('Integer', 'Integer_table1'),
+ pair('Float', 'Float_table1'),
+ pair('Decimal', 'Decimal_table1'),
+ pair('StrictDate', 'StrictDate_table1'),
+ pair('DateTime', 'DateTime_table1'),
+ pair('String', 'String_table1')
+ ])
+ ->join(FlatInput.all()
+ ->project([{x|$x.idIn}, {x|$x.integerIn}, {x|$x.stringIn}], ['ID', 'Integer', 'String'])
+ ->renameColumns([
+ pair('ID', 'ID_table2'),
+ pair('Integer', 'Integer_table2'),
+ pair('String', 'String_table2')
+ ]),
+ meta::relational::metamodel::join::JoinType.LEFT_OUTER,
+ {row1, row2|$row1.getString('String_table1') == $row2.getInteger('ID_table2')})
+ ->join(meta::external::query::sql::transformation::queryToPure::tests::FlatInput.all()
+ ->project([{x|$x.idIn}, {x|$x.integerIn}, {x|$x.stringIn}], ['ID', 'Integer', 'String'])
+ ->renameColumns([
+ pair('ID', 'ID_table3'),
+ pair('Integer', 'Integer_table3'),
+ pair('String', 'String_table3')
+ ]),
+ meta::relational::metamodel::join::JoinType.LEFT_OUTER,
+ {row1, row2|$row1.getString('String_table1') == $row2.getString('String_table3')})
+ ->filter({row|$row.getString('String_table2') == 'ABC'})
+ ->renameColumns([
+ pair('Boolean_table1', 'Boolean'),
+ pair('Float_table1', 'Float'),
+ pair('Decimal_table1', 'Decimal'),
+ pair('StrictDate_table1', 'StrictDate'),
+ pair('DateTime_table1', 'DateTime')
+ ])}, false)
}
//UNION
function <> meta::external::query::sql::transformation::queryToPure::tests::testUnion():Boolean[1]
{
- let sqlString = 'SELECT Integer FROM service."/service/service1" UNION SELECT Integer FROM service."/service/service2"';
+ test('SELECT Integer FROM service."/service/service1" UNION SELECT Integer FROM service."/service/service2"',
- let sqlTransformContext = $sqlString->processQuery();
- let expected = {|
+ {|
FlatInput.all()
->project(
[ x | $x.booleanIn, x | $x.integerIn, x | $x.floatIn, x | $x.decimalIn, x | $x.strictDateIn, x | $x.dateTimeIn, x | $x.stringIn ],
@@ -1229,17 +1208,16 @@ function <> meta::external::query::sql::transformation::queryToPure::
[ 'ID', 'Integer', 'String' ])
->restrict('Integer')
)
- };
- assertLambdaAndJSONEquals($expected, $sqlTransformContext.lambda());
+ })
}
//CURRENT TIME
function <> meta::external::query::sql::transformation::queryToPure::tests::testCurrentTime():Boolean[1]
{
- let sqlString = 'SELECT CURRENT_TIME, CURRENT_TIMESTAMP, CURRENT_DATE, CURRENT_TIME AS time, CURRENT_TIMESTAMP AS timestamp, CURRENT_DATE AS date FROM service."/service/service1"';
+ test(
+ 'SELECT CURRENT_TIME, CURRENT_TIMESTAMP, CURRENT_DATE, CURRENT_TIME AS time, CURRENT_TIMESTAMP AS timestamp, CURRENT_DATE AS date FROM service."/service/service1"',
- let sqlTransformContext = $sqlString->processQuery();
- let expected = {|
+ {|
FlatInput.all()
->project(
[ x | $x.booleanIn, x | $x.integerIn, x | $x.floatIn, x | $x.decimalIn, x | $x.strictDateIn, x | $x.dateTimeIn, x | $x.stringIn ],
@@ -1252,18 +1230,17 @@ function <> meta::external::query::sql::transformation::queryToPure::
col(row:TDSRow[1] | now(), 'timestamp'),
col(row:TDSRow[1] | today(), 'date')
])
- };
- assertLambdaAndJSONEquals($expected, $sqlTransformContext.lambda());
+ })
}
//DATE_TRUNC
function <> meta::external::query::sql::transformation::queryToPure::tests::testDateTrunc():Boolean[1]
{
- let sqlString = 'SELECT date_trunc(\'year\', StrictDate) AS "YEAR", date_trunc(\'quarter\', CAST(\'2023-01-01\' AS DATE)) AS "QUARTER", date_trunc(\'month\', StrictDate) AS "MONTH", date_trunc(\'week\', StrictDate) AS "WEEK", ' +
- 'date_trunc(\'day\', StrictDate) AS "DAY", date_trunc(\'hour\', StrictDate) AS "HOUR", date_trunc(\'minute\', StrictDate) AS "MINUTE", date_trunc(\'second\', StrictDate) AS "SECOND" FROM service."/service/service1"';
+ test(
+ 'SELECT date_trunc(\'year\', StrictDate) AS "YEAR", date_trunc(\'quarter\', CAST(\'2023-01-01\' AS DATE)) AS "QUARTER", date_trunc(\'month\', StrictDate) AS "MONTH", date_trunc(\'week\', StrictDate) AS "WEEK", ' +
+ 'date_trunc(\'day\', StrictDate) AS "DAY", date_trunc(\'hour\', StrictDate) AS "HOUR", date_trunc(\'minute\', StrictDate) AS "MINUTE", date_trunc(\'second\', StrictDate) AS "SECOND" FROM service."/service/service1"',
- let sqlTransformContext = $sqlString->processQuery();
- let expected = {|
+ {|
FlatInput.all()
->project(
[ x | $x.booleanIn, x | $x.integerIn, x | $x.floatIn, x | $x.decimalIn, x | $x.strictDateIn, x | $x.dateTimeIn, x | $x.stringIn ],
@@ -1278,19 +1255,17 @@ function <> meta::external::query::sql::transformation::queryToPure::
col(row:TDSRow[1] | firstSecondOfMinute($row.getStrictDate('StrictDate')), 'MINUTE'),
col(row:TDSRow[1] | firstMillisecondOfSecond($row.getStrictDate('StrictDate')), 'SECOND')
])
- };
- assertLambdaAndJSONEquals($expected, $sqlTransformContext.lambda());
+ })
}
//DATE_PART
function <> meta::external::query::sql::transformation::queryToPure::tests::testDatePart():Boolean[1]
{
- let sqlString = 'SELECT date_part(\'year\', StrictDate) AS "YEAR", date_part(\'quarter\', CAST(\'2023-01-01\' AS DATE)) AS "QUARTER", date_part(\'month\', StrictDate) AS "MONTH", date_part(\'week\', StrictDate) AS "WEEK", ' +
+ test('SELECT date_part(\'year\', StrictDate) AS "YEAR", date_part(\'quarter\', CAST(\'2023-01-01\' AS DATE)) AS "QUARTER", date_part(\'month\', StrictDate) AS "MONTH", date_part(\'week\', StrictDate) AS "WEEK", ' +
'date_part(\'dow\', StrictDate) AS "DOW", date_part(\'day\', StrictDate) AS "DAY", date_part(\'doy\', StrictDate) AS "DOY", date_part(\'hour\', StrictDate) AS "HOUR", date_part(\'minute\', StrictDate) AS "MINUTE", ' +
- 'date_part(\'second\', StrictDate) AS "SECOND", date_part(\'epoch\', StrictDate) AS "EPOCH" FROM service."/service/service1"';
+ 'date_part(\'second\', StrictDate) AS "SECOND", date_part(\'epoch\', StrictDate) AS "EPOCH" FROM service."/service/service1"',
- let sqlTransformContext = $sqlString->processQuery();
- let expected = {|
+ {|
FlatInput.all()
->project(
[ x | $x.booleanIn, x | $x.integerIn, x | $x.floatIn, x | $x.decimalIn, x | $x.strictDateIn, x | $x.dateTimeIn, x | $x.stringIn ],
@@ -1308,19 +1283,18 @@ function <> meta::external::query::sql::transformation::queryToPure::
col(row:TDSRow[1] | second($row.getStrictDate('StrictDate')), 'SECOND'),
col(row:TDSRow[1] | toEpochValue($row.getStrictDate('StrictDate')), 'EPOCH')
])
- };
- assertLambdaAndJSONEquals($expected, $sqlTransformContext.lambda());
+ })
}
//EXTRACT
function <> meta::external::query::sql::transformation::queryToPure::tests::testExtract():Boolean[1]
{
- let sqlString = 'SELECT EXTRACT(\'year\' FROM StrictDate) AS "YEAR", EXTRACT(\'quarter\' FROM CAST(\'2023-01-01\' AS DATE)) AS "QUARTER", EXTRACT(\'month\' FROM StrictDate) AS "MONTH", EXTRACT(\'week\' FROM StrictDate) AS "WEEK", ' +
- 'EXTRACT(\'dow\' FROM StrictDate) AS "DOW", EXTRACT(\'day\' FROM StrictDate) AS "DAY", EXTRACT(\'doy\' FROM StrictDate) AS "DOY", EXTRACT(\'hour\' FROM StrictDate) AS "HOUR", EXTRACT(\'minute\' FROM StrictDate) AS "MINUTE", ' +
- 'EXTRACT(\'second\' FROM StrictDate) AS "SECOND", EXTRACT(\'epoch\' FROM StrictDate) AS "EPOCH" FROM service."/service/service1"';
+ test(
+ 'SELECT EXTRACT(\'year\' FROM StrictDate) AS "YEAR", EXTRACT(\'quarter\' FROM CAST(\'2023-01-01\' AS DATE)) AS "QUARTER", EXTRACT(\'month\' FROM StrictDate) AS "MONTH", EXTRACT(\'week\' FROM StrictDate) AS "WEEK", ' +
+ 'EXTRACT(\'dow\' FROM StrictDate) AS "DOW", EXTRACT(\'day\' FROM StrictDate) AS "DAY", EXTRACT(\'doy\' FROM StrictDate) AS "DOY", EXTRACT(\'hour\' FROM StrictDate) AS "HOUR", EXTRACT(\'minute\' FROM StrictDate) AS "MINUTE", ' +
+ 'EXTRACT(\'second\' FROM StrictDate) AS "SECOND", EXTRACT(\'epoch\' FROM StrictDate) AS "EPOCH" FROM service."/service/service1"',
- let sqlTransformContext = $sqlString->processQuery();
- let expected = {|
+ {|
FlatInput.all()
->project(
[ x | $x.booleanIn, x | $x.integerIn, x | $x.floatIn, x | $x.decimalIn, x | $x.strictDateIn, x | $x.dateTimeIn, x | $x.stringIn ],
@@ -1338,27 +1312,26 @@ function <> meta::external::query::sql::transformation::queryToPure::
col(row:TDSRow[1] | second($row.getStrictDate('StrictDate')), 'SECOND'),
col(row:TDSRow[1] | toEpochValue($row.getStrictDate('StrictDate')), 'EPOCH')
])
- };
- assertLambdaAndJSONEquals($expected, $sqlTransformContext.lambda());
+ })
}
//INTERVAL
function <> meta::external::query::sql::transformation::queryToPure::tests::testIntervalArithmetic():Boolean[1]
{
- let sqlString = 'SELECT ' +
- 'StrictDate + INTERVAL \'1 YEAR 3 WEEKS 2 DAYS\' AS "INTERVAL_ADD", ' +
- 'StrictDate + 1 + INTERVAL \'1 YEAR 3 WEEKS 2 DAYS\' AS "INTERVAL_MULTI_ADD", ' +
- 'StrictDate + 1 AS "NUMERIC_ADD", ' +
- 'StrictDate + 6 * INTERVAL \'1 YEAR 3 WEEKS 2 DAYS\' AS "INTERVAL_TIMES", ' +
- 'StrictDate + NULL * INTERVAL \'1 YEAR 3 WEEKS 2 DAYS\' AS "INTERVAL_TIMES_NULL", ' +
- 'StrictDate + NULL + INTERVAL \'1 YEAR 3 WEEKS 2 DAYS\' AS "INTERVAL_ADD_NULL", ' +
- '(CAST(\'2023-01-01\' AS DATE) + 2 * INTERVAL \'1 DAY\') + 3 * INTERVAL \'2 DAY\' AS "INTERVAL_MIX", ' +
- 'StrictDate + EXTRACT(\'year\' FROM StrictDate) * INTERVAL \'2 YEAR 3 DAYS\' AS "INTERVAL_MIX2", ' +
- 'CAST((DATE_TRUNC( \'DAY\', CAST("StrictDate" AS DATE) ) + (EXTRACT(DOW FROM "StrictDate") * INTERVAL \'1 DAY\')) AS DATE) AS "INTERVAL_MIX3" ' +
- 'FROM service."/service/service1"';
-
- let sqlTransformContext = $sqlString->processQuery();
- let expected = {|
+ test(
+ 'SELECT ' +
+ 'StrictDate + INTERVAL \'1 YEAR 3 WEEKS 2 DAYS\' AS "INTERVAL_ADD", ' +
+ 'StrictDate + 1 + INTERVAL \'1 YEAR 3 WEEKS 2 DAYS\' AS "INTERVAL_MULTI_ADD", ' +
+ 'StrictDate + 1 AS "NUMERIC_ADD", ' +
+ 'StrictDate + 6 * INTERVAL \'1 YEAR 3 WEEKS 2 DAYS\' AS "INTERVAL_TIMES", ' +
+ 'StrictDate + NULL * INTERVAL \'1 YEAR 3 WEEKS 2 DAYS\' AS "INTERVAL_TIMES_NULL", ' +
+ 'StrictDate + NULL + INTERVAL \'1 YEAR 3 WEEKS 2 DAYS\' AS "INTERVAL_ADD_NULL", ' +
+ '(CAST(\'2023-01-01\' AS DATE) + 2 * INTERVAL \'1 DAY\') + 3 * INTERVAL \'2 DAY\' AS "INTERVAL_MIX", ' +
+ 'StrictDate + EXTRACT(\'year\' FROM StrictDate) * INTERVAL \'2 YEAR 3 DAYS\' AS "INTERVAL_MIX2", ' +
+ 'CAST((DATE_TRUNC( \'DAY\', CAST("StrictDate" AS DATE) ) + (EXTRACT(DOW FROM "StrictDate") * INTERVAL \'1 DAY\')) AS DATE) AS "INTERVAL_MIX3" ' +
+ 'FROM service."/service/service1"',
+
+ {|
FlatInput.all()
->project(
[ x | $x.booleanIn, x | $x.integerIn, x | $x.floatIn, x | $x.decimalIn, x | $x.strictDateIn, x | $x.dateTimeIn, x | $x.stringIn ],
@@ -1374,19 +1347,20 @@ function <> meta::external::query::sql::transformation::queryToPure::
col(row:TDSRow[1] | $row.getStrictDate('StrictDate')->adjust(year($row.getStrictDate('StrictDate')) * 2, DurationUnit.YEARS)->adjust(year($row.getStrictDate('StrictDate')) * 3, DurationUnit.DAYS), 'INTERVAL_MIX2'),
col(row:TDSRow[1] | $row.getStrictDate('StrictDate')->firstHourOfDay()->adjust(($row.getStrictDate('StrictDate')->dayOfWeekNumber() * 1), DurationUnit.DAYS), 'INTERVAL_MIX3')
])
- };
- assertLambdaAndJSONEquals($expected, $sqlTransformContext.lambda());
+ })
}
//STRING FUNCTIONS
function <> meta::external::query::sql::transformation::queryToPure::tests::testStringFunctions():Boolean[1]
{
- let sqlString = 'SELECT ascii(String) AS "ASCII", chr(Integer) AS "CHR", concat(String, \'abc\') AS "CONCAT", String || \'abc\' AS "CONCAT2", regexp_like(String, \'test\') AS "MATCH", char_length(String) AS "CHAR_LENGTH", length(String) AS "LENGTH", ltrim(String) AS "LTRIM", ltrim(String, \' \') AS "LTRIM2", md5(String) AS "MD5", upper(String) AS "UPPER", ' +
- 'lower(String) AS "LOWER", repeat(String, 2) AS "REPEAT", replace(String, \'A\', \'a\') AS "REPLACE", starts_with(String, \'a\') AS "STARTSWITH", strpos(String, \'abc\') AS "STRPOS", reverse(String) AS "REVERSE", rtrim(String) AS "RTRIM", rtrim(String, \' \') AS "RTRIM2", ' +
- 'sha256(String) AS "SHA256", split_part(String, \',\', 1) AS "SPLITPART", split_part(String, \',\', Integer) AS "SPLITPART2", substring(String, 1) AS "SUBSTRING", substr(String, 1, 2) AS "SUBSTR", btrim(String) AS "TRIM", btrim(String, \' \') AS "TRIM2" FROM service."/service/service1"';
+ test(
+ 'SELECT ascii(String) AS "ASCII", chr(Integer) AS "CHR", concat(String, \'abc\') AS "CONCAT", String || \'abc\' AS "CONCAT2", regexp_like(String, \'test\') AS "MATCH", ' +
+ 'char_length(String) AS "CHAR_LENGTH", length(String) AS "LENGTH", ltrim(String) AS "LTRIM", ltrim(String, \' \') AS "LTRIM2", md5(String) AS "MD5", upper(String) AS "UPPER", ' +
+ 'lower(String) AS "LOWER", repeat(String, 2) AS "REPEAT", replace(String, \'A\', \'a\') AS "REPLACE", starts_with(String, \'a\') AS "STARTSWITH", strpos(String, \'abc\') AS "STRPOS",' +
+ 'reverse(String) AS "REVERSE", rtrim(String) AS "RTRIM", rtrim(String, \' \') AS "RTRIM2", sha256(String) AS "SHA256", split_part(String, \',\', 1) AS "SPLITPART", ' +
+ 'split_part(String, \',\', Integer) AS "SPLITPART2", substring(String, 1) AS "SUBSTRING", substr(String, 1, 2) AS "SUBSTR", btrim(String) AS "TRIM", btrim(String, \' \') AS "TRIM2" FROM service."/service/service1"',
- let sqlTransformContext = $sqlString->processQuery();
- let expected = {|
+ {|
FlatInput.all()
->project(
[ x | $x.booleanIn, x | $x.integerIn, x | $x.floatIn, x | $x.decimalIn, x | $x.strictDateIn, x | $x.dateTimeIn, x | $x.stringIn ],
@@ -1419,18 +1393,18 @@ function <> meta::external::query::sql::transformation::queryToPure::
col(row:TDSRow[1] | trim($row.getString('String')), 'TRIM'),
col(row:TDSRow[1] | trim($row.getString('String')), 'TRIM2')
])
- };
- assertLambdaAndJSONEquals($expected, $sqlTransformContext.lambda());
+ })
}
function <> meta::external::query::sql::transformation::queryToPure::tests::testStringFunctionsNullable():Boolean[1]
{
- let sqlString = 'SELECT ascii(NULL) AS "ASCII", chr(NULL) AS "CHR", regexp_like(NULL, \'test\') AS "MATCH", char_length(NULL) AS "CHAR_LENGTH", length(NULL) AS "LENGTH", ltrim(NULL) AS "LTRIM", ltrim(NULL, \' \') AS "LTRIM2", md5(NULL) AS "MD5", upper(NULL) AS "UPPER", ' +
- 'lower(NULL) AS "LOWER", replace(NULL, \'A\', \'a\') AS "REPLACE", starts_with(NULL, \'a\') AS "STARTSWITH", strpos(NULL, \'abc\') AS "STRPOS", reverse(NULL) AS "REVERSE", rtrim(NULL) AS "RTRIM", rtrim(NULL, \' \') AS "RTRIM2", ' +
- 'sha256(NULL) AS "SHA256", substring(NULL, 1) AS "SUBSTRING", substr(NULL, 1, 2) AS "SUBSTR", btrim(NULL) AS "TRIM", btrim(NULL, \' \') AS "TRIM2" FROM service."/service/service1"';
+ test(
+ 'SELECT ascii(NULL) AS "ASCII", chr(NULL) AS "CHR", regexp_like(NULL, \'test\') AS "MATCH", char_length(NULL) AS "CHAR_LENGTH", length(NULL) AS "LENGTH", ltrim(NULL) AS "LTRIM", ' +
+ 'ltrim(NULL, \' \') AS "LTRIM2", md5(NULL) AS "MD5", upper(NULL) AS "UPPER", lower(NULL) AS "LOWER", replace(NULL, \'A\', \'a\') AS "REPLACE", starts_with(NULL, \'a\') AS "STARTSWITH", ' +
+ 'strpos(NULL, \'abc\') AS "STRPOS", reverse(NULL) AS "REVERSE", rtrim(NULL) AS "RTRIM", rtrim(NULL, \' \') AS "RTRIM2", sha256(NULL) AS "SHA256", substring(NULL, 1) AS "SUBSTRING", ' +
+ 'substr(NULL, 1, 2) AS "SUBSTR", btrim(NULL) AS "TRIM", btrim(NULL, \' \') AS "TRIM2" FROM service."/service/service1"',
- let sqlTransformContext = $sqlString->processQuery();
- let expected = {|
+ {|
FlatInput.all()
->project(
[ x | $x.booleanIn, x | $x.integerIn, x | $x.floatIn, x | $x.decimalIn, x | $x.strictDateIn, x | $x.dateTimeIn, x | $x.stringIn ],
@@ -1458,21 +1432,21 @@ function <> meta::external::query::sql::transformation::queryToPure::
col(row:TDSRow[1] | []->cast(@String), 'TRIM'),
col(row:TDSRow[1] | []->cast(@String), 'TRIM2')
])
- };
- assertLambdaAndJSONEquals($expected, $sqlTransformContext.lambda());
+ })
}
//MATH FUNCTIONS
function <> meta::external::query::sql::transformation::queryToPure::tests::testMathFunctions():Boolean[1]
{
- let sqlString = 'SELECT abs(Integer) AS "ABS", acos(Integer) AS "ACOS", asin(Integer) AS "ASIN", atan(Integer) AS "ATAN", atan2(Integer, 1) AS "ATAN2", ' +
- 'ceil(Integer) AS "CEIL", ceiling(Integer) AS "CEILING", cos(Integer) AS "COS", cot(Integer) AS "COT", degrees(Integer) AS "DEGREES", div(Integer, 1) AS "DIV", exp(Integer) AS "EXP", floor(Float) AS "FLOOR", ' +
- 'log(Integer) AS "LOG", ln(Integer) AS "LN", mod(Integer, 1) AS "MOD", pi() AS "PI", power(Integer, 2) AS "POWER", radians(Integer) AS "RADIANS", round(Integer) AS "ROUND", round(Decimal, 1) AS "ROUND_DEC", sign(Integer) AS "SIGN", ' +
- 'sin(Integer) AS "SIN", sqrt(Integer) AS "SQRT", tan(Integer) AS "TAN", trunc(Integer) AS "TRUNC" FROM service."/service/service1"';
+ test(
+ 'SELECT abs(Integer) AS "ABS", acos(Integer) AS "ACOS", asin(Integer) AS "ASIN", atan(Integer) AS "ATAN", atan2(Integer, 1) AS "ATAN2", ' +
+ 'ceil(Integer) AS "CEIL", ceiling(Integer) AS "CEILING", cos(Integer) AS "COS", cot(Integer) AS "COT", degrees(Integer) AS "DEGREES", div(Integer, 1) AS "DIV", ' +
+ 'exp(Integer) AS "EXP", floor(Float) AS "FLOOR", log(Integer) AS "LOG", ln(Integer) AS "LN", mod(Integer, 1) AS "MOD", pi() AS "PI", power(Integer, 2) AS "POWER", ' +
+ 'radians(Integer) AS "RADIANS", round(Integer) AS "ROUND", round(Decimal, 1) AS "ROUND_DEC", sign(Integer) AS "SIGN", ' +
+ 'sin(Integer) AS "SIN", sqrt(Integer) AS "SQRT", tan(Integer) AS "TAN", trunc(Integer) AS "TRUNC" FROM service."/service/service1"',
- let sqlTransformContext = $sqlString->processQuery();
- let expected = {|
+ {|
FlatInput.all()
->project(
[ x | $x.booleanIn, x | $x.integerIn, x | $x.floatIn, x | $x.decimalIn, x | $x.strictDateIn, x | $x.dateTimeIn, x | $x.stringIn ],
@@ -1505,19 +1479,18 @@ function <> meta::external::query::sql::transformation::queryToPure::
col(row:TDSRow[1] | tan($row.getInteger('Integer')), 'TAN'),
col(row:TDSRow[1] | if ($row.getInteger('Integer') > 0, | floor($row.getInteger('Integer')), | ceiling($row.getInteger('Integer'))), 'TRUNC')
])
- };
- assertLambdaAndJSONEquals($expected, $sqlTransformContext.lambda());
+ })
}
function <> meta::external::query::sql::transformation::queryToPure::tests::testMathFunctionsNullable():Boolean[1]
{
- let sqlString = 'SELECT abs(NULL) AS "ABS", acos(NULL) AS "ACOS", asin(NULL) AS "ASIN", atan(NULL) AS "ATAN", atan2(NULL, 1) AS "ATAN2", ' +
- 'ceil(NULL) AS "CEIL", ceiling(NULL) AS "CEILING", cos(NULL) AS "COS", cot(NULL) AS "COT", degrees(NULL) AS "DEGREES", div(NULL, 1) AS "DIV", exp(NULL) AS "EXP", floor(NULL) AS "FLOOR", ' +
- 'log(NULL) AS "LOG", ln(NULL) AS "LN", mod(NULL, 1) AS "MOD", power(NULL, 2) AS "POWER", radians(NULL) AS "RADIANS", round(NULL) AS "ROUND", round(NULL, 1) AS "ROUND_DEC", sign(NULL) AS "SIGN", ' +
- 'sin(NULL) AS "SIN", sqrt(NULL) AS "SQRT", tan(NULL) AS "TAN", trunc(NULL) AS "TRUNC" FROM service."/service/service1"';
+ test(
+ 'SELECT abs(NULL) AS "ABS", acos(NULL) AS "ACOS", asin(NULL) AS "ASIN", atan(NULL) AS "ATAN", atan2(NULL, 1) AS "ATAN2", ' +
+ 'ceil(NULL) AS "CEIL", ceiling(NULL) AS "CEILING", cos(NULL) AS "COS", cot(NULL) AS "COT", degrees(NULL) AS "DEGREES", div(NULL, 1) AS "DIV", exp(NULL) AS "EXP", floor(NULL) AS "FLOOR", ' +
+ 'log(NULL) AS "LOG", ln(NULL) AS "LN", mod(NULL, 1) AS "MOD", power(NULL, 2) AS "POWER", radians(NULL) AS "RADIANS", round(NULL) AS "ROUND", round(NULL, 1) AS "ROUND_DEC", sign(NULL) AS "SIGN", ' +
+ 'sin(NULL) AS "SIN", sqrt(NULL) AS "SQRT", tan(NULL) AS "TAN", trunc(NULL) AS "TRUNC" FROM service."/service/service1"',
- let sqlTransformContext = $sqlString->processQuery();
- let expected = {|
+ {|
FlatInput.all()
->project(
[ x | $x.booleanIn, x | $x.integerIn, x | $x.floatIn, x | $x.decimalIn, x | $x.strictDateIn, x | $x.dateTimeIn, x | $x.stringIn ],
@@ -1549,17 +1522,16 @@ function <> meta::external::query::sql::transformation::queryToPure::
col(row:TDSRow[1] | []->cast(@Float), 'TAN'),
col(row:TDSRow[1] | []->cast(@Integer), 'TRUNC')
])
- };
- assertLambdaAndJSONEquals($expected, $sqlTransformContext.lambda());
+ })
}
//COLLECTION FUNCTIONS
function <> meta::external::query::sql::transformation::queryToPure::tests::testCollectionFunctions():Boolean[1]
{
- let sqlString = 'SELECT coalesce(NULL, Integer, 1) AS "COALESCE" FROM service."/service/service1"';
+ test(
+ 'SELECT coalesce(NULL, Integer, 1) AS "COALESCE" FROM service."/service/service1"',
- let sqlTransformContext = $sqlString->processQuery();
- let expected = {|
+ {|
FlatInput.all()
->project(
[ x | $x.booleanIn, x | $x.integerIn, x | $x.floatIn, x | $x.decimalIn, x | $x.strictDateIn, x | $x.dateTimeIn, x | $x.stringIn ],
@@ -1567,28 +1539,21 @@ function <> meta::external::query::sql::transformation::queryToPure::
->project([
col(row:TDSRow[1] | meta::pure::tds::extensions::firstNotNull([$row.getInteger('Integer'), 1]), 'COALESCE')
])
- };
-
- assertLambdaAndJSONEquals($expected, $sqlTransformContext.lambda());
-
- let plan = $sqlTransformContext->getPlan($sqlTransformContext.sources, $sqlTransformContext.extensions);
- let sql = $plan.rootExecutionNode->cast(@meta::relational::mapping::RelationalTdsInstantiationExecutionNode).executionNodes->cast(@meta::relational::mapping::SQLExecutionNode).sqlQuery;
-
- assertEquals('select coalesce("root".integer, 1) as "COALESCE" from flat as "root"', $sql);
+ })
}
//GROUP FUNCTIONS
function <> meta::external::query::sql::transformation::queryToPure::tests::testGroupFunctions():Boolean[1]
{
- let sqlString = 'SELECT String, ' +
- 'percentile_cont(0.1) WITHIN GROUP (ORDER BY Integer ASC) AS "PERCENTILE_CONT_ASC", ' +
- 'percentile_cont(0.2) WITHIN GROUP (ORDER BY Integer DESC) AS "PERCENTILE_CONT_DESC", ' +
- 'percentile_disc(0.3) WITHIN GROUP (ORDER BY Integer ASC) AS "PERCENTILE_DISC_ASC", ' +
- 'percentile_disc(0.4) WITHIN GROUP (ORDER BY Integer DESC) AS "PERCENTILE_DISC_DESC" ' +
- 'FROM service."/service/service1" GROUP BY String';
+ test(
+ 'SELECT String, ' +
+ 'percentile_cont(0.1) WITHIN GROUP (ORDER BY Integer ASC) AS "PERCENTILE_CONT_ASC", ' +
+ 'percentile_cont(0.2) WITHIN GROUP (ORDER BY Integer DESC) AS "PERCENTILE_CONT_DESC", ' +
+ 'percentile_disc(0.3) WITHIN GROUP (ORDER BY Integer ASC) AS "PERCENTILE_DISC_ASC", ' +
+ 'percentile_disc(0.4) WITHIN GROUP (ORDER BY Integer DESC) AS "PERCENTILE_DISC_DESC" ' +
+ 'FROM service."/service/service1" GROUP BY String',
- let sqlTransformContext = $sqlString->processQuery();
- let expected = {|
+ {|
FlatInput.all()
->project(
[ x | $x.booleanIn, x | $x.integerIn, x | $x.floatIn, x | $x.decimalIn, x | $x.strictDateIn, x | $x.dateTimeIn, x | $x.stringIn ],
@@ -1599,22 +1564,20 @@ function <> meta::external::query::sql::transformation::queryToPure::
agg('PERCENTILE_DISC_ASC', row | $row.getInteger('Integer'), y | $y->percentile(0.3, true, false)),
agg('PERCENTILE_DISC_DESC', row | $row.getInteger('Integer'), y | $y->percentile(0.4, false, false))
])
- };
-
- assertLambdaEquals($expected, $sqlTransformContext.lambda());
+ }, false)
}
//WINDOW FUNCTIONS
function <> meta::external::query::sql::transformation::queryToPure::tests::testWindowFunctions():Boolean[1]
{
- let sqlString = 'SELECT String AS "string", Integer, ' +
- 'row_number() OVER (PARTITION BY String ORDER BY Integer ASC) AS "ROW", ' +
- 'dense_rank() OVER (PARTITION BY String ORDER BY Integer DESC) AS "DENSE RANK", ' +
- 'rank() OVER (PARTITION BY String ORDER BY Integer ASC) AS "RANK" ' +
- 'FROM service."/service/service1"';
+ test(
+ 'SELECT String AS "string", Integer, ' +
+ 'row_number() OVER (PARTITION BY String ORDER BY Integer ASC) AS "ROW", ' +
+ 'dense_rank() OVER (PARTITION BY String ORDER BY Integer DESC) AS "DENSE RANK", ' +
+ 'rank() OVER (PARTITION BY String ORDER BY Integer ASC) AS "RANK" ' +
+ 'FROM service."/service/service1"',
- let sqlTransformContext = $sqlString->processQuery();
- let expected = {|
+ {|
FlatInput.all()
->project(
[ x | $x.booleanIn, x | $x.integerIn, x | $x.floatIn, x | $x.decimalIn, x | $x.strictDateIn, x | $x.dateTimeIn, x | $x.stringIn ],
@@ -1624,21 +1587,19 @@ function <> meta::external::query::sql::transformation::queryToPure::
->olapGroupBy(['String'], desc('Integer'), y | $y->meta::pure::functions::math::olap::denseRank(), 'DENSE RANK')
->olapGroupBy(['String'], asc('Integer'), y | $y->meta::pure::functions::math::olap::rank(), 'RANK')
->restrict(['string', 'Integer', 'ROW', 'DENSE RANK', 'RANK'])
- };
-
- assertLambdaEquals($expected, $sqlTransformContext.lambda());
+ }, false)
}
function <> meta::external::query::sql::transformation::queryToPure::tests::testProjectWithWindowFunctions():Boolean[1]
{
- let sqlString = 'SELECT String, abs(Integer) AS "ABS", ' +
- 'row_number() OVER (PARTITION BY upper(String) ORDER BY EXTRACT(YEAR FROM StrictDate) + 10 ASC) AS "ROW", ' +
- 'dense_rank() OVER (PARTITION BY String ORDER BY Integer DESC) AS "DENSE RANK", ' +
- 'rank() OVER (PARTITION BY String ORDER BY Integer ASC) AS "RANK" ' +
- 'FROM service."/service/service1"';
+ test(
+ 'SELECT String, abs(Integer) AS "ABS", ' +
+ 'row_number() OVER (PARTITION BY upper(String) ORDER BY EXTRACT(YEAR FROM StrictDate) + 10 ASC) AS "ROW", ' +
+ 'dense_rank() OVER (PARTITION BY String ORDER BY Integer DESC) AS "DENSE RANK", ' +
+ 'rank() OVER (PARTITION BY String ORDER BY Integer ASC) AS "RANK" ' +
+ 'FROM service."/service/service1"',
- let sqlTransformContext = $sqlString->processQuery();
- let expected = {|
+ {|
FlatInput.all()
->project(
[ x | $x.booleanIn, x | $x.integerIn, x | $x.floatIn, x | $x.decimalIn, x | $x.strictDateIn, x | $x.dateTimeIn, x | $x.stringIn],
@@ -1652,21 +1613,19 @@ function <> meta::external::query::sql::transformation::queryToPure::
->olapGroupBy(['String'], desc('Integer'), y | $y->meta::pure::functions::math::olap::denseRank(), 'DENSE RANK')
->olapGroupBy(['String'], asc('Integer'), y | $y->meta::pure::functions::math::olap::rank(), 'RANK')
->restrict(['String', 'ABS', 'ROW', 'DENSE RANK', 'RANK'])
- };
-
- assertLambdaEquals($expected, $sqlTransformContext.lambda());
+ }, false)
}
function <> meta::external::query::sql::transformation::queryToPure::tests::testGroupByWithWindowFunctions():Boolean[1]
{
- let sqlString = 'SELECT String, Integer, sum(Integer) AS "SUM", ' +
- 'row_number() OVER (PARTITION BY String ORDER BY Integer ASC) AS "ROW", ' +
- 'dense_rank() OVER (PARTITION BY String ORDER BY Integer DESC) AS "DENSE RANK", ' +
- 'rank() OVER (PARTITION BY String ORDER BY Integer ASC) AS "RANK" ' +
- 'FROM service."/service/service1" GROUP BY String, Integer';
+ test(
+ 'SELECT String, Integer, sum(Integer) AS "SUM", ' +
+ 'row_number() OVER (PARTITION BY String ORDER BY Integer ASC) AS "ROW", ' +
+ 'dense_rank() OVER (PARTITION BY String ORDER BY Integer DESC) AS "DENSE RANK", ' +
+ 'rank() OVER (PARTITION BY String ORDER BY Integer ASC) AS "RANK" ' +
+ 'FROM service."/service/service1" GROUP BY String, Integer',
- let sqlTransformContext = $sqlString->processQuery();
- let expected = {|
+ {|
FlatInput.all()
->project(
[ x | $x.booleanIn, x | $x.integerIn, x | $x.floatIn, x | $x.decimalIn, x | $x.strictDateIn, x | $x.dateTimeIn, x | $x.stringIn ],
@@ -1675,23 +1634,21 @@ function <> meta::external::query::sql::transformation::queryToPure:
->olapGroupBy(['String'], desc('Integer'), y | $y->meta::pure::functions::math::olap::denseRank(), 'DENSE RANK')
->olapGroupBy(['String'], asc('Integer'), y | $y->meta::pure::functions::math::olap::rank(), 'RANK')
->groupBy(['String', 'Integer'], agg('SUM', row | $row.getInteger('Integer'), y | $y->sum()))
- };
-
- assertLambdaAndJSONEquals($expected, $sqlTransformContext.lambda());
+ })
}
//LIKE
function <> meta::external::query::sql::transformation::queryToPure::tests::testLike():Boolean[1]
{
- let sqlString = 'SELECT ' +
- 'String like \'b\' AS "EQUAL", ' +
- 'String like \'b%\' AS "STARTS_WITH", ' +
- 'String like \'%b\' AS "ENDS_WITH", ' +
- 'String like \'%b%\' AS "CONTAINS"' +
- 'FROM service."/service/service1"';
+ test(
+ 'SELECT ' +
+ 'String like \'b\' AS "EQUAL", ' +
+ 'String like \'b%\' AS "STARTS_WITH", ' +
+ 'String like \'%b\' AS "ENDS_WITH", ' +
+ 'String like \'%b%\' AS "CONTAINS"' +
+ 'FROM service."/service/service1"',
- let sqlTransformContext = $sqlString->processQuery();
- let expected = {|
+ {|
FlatInput.all()
->project(
[ x | $x.booleanIn, x | $x.integerIn, x | $x.floatIn, x | $x.decimalIn, x | $x.strictDateIn, x | $x.dateTimeIn, x | $x.stringIn ],
@@ -1700,53 +1657,53 @@ function <> meta::external::query::sql::transformation::queryToPure::
col(row:TDSRow[1] | equal($row.getString('String'), 'b'), 'EQUAL'),
col(row:TDSRow[1] | startsWith($row.getString('String'), 'b'), 'STARTS_WITH'),
col(row:TDSRow[1] | endsWith($row.getString('String'), 'b'), 'ENDS_WITH'),
- col(row:TDSRow[1] | contains($row.getString('String'), 'b'), 'CONTAINS')
+ col(row:TDSRow[1] | contains($row.getString('String'), 'b'), 'CONTAINS')
])
- };
- assertLambdaAndJSONEquals($expected, $sqlTransformContext.lambda());
+ })
}
function <> meta::external::query::sql::transformation::queryToPure::tests::testFromScopingSimple():Boolean[1]
{
- let sqlString = 'SELECT * FROM service."/service/service1"';
- let sqlTransformContext = $sqlString->processQuery(true);
- let expected = {| FlatInput.all()->project(
+ test(
+ 'SELECT * FROM service."/service/service1"',
+
+ {| FlatInput.all()->project(
[ x | $x.booleanIn, x | $x.integerIn, x | $x.floatIn, x | $x.decimalIn, x | $x.strictDateIn, x | $x.dateTimeIn, x | $x.stringIn ],
[ 'Boolean', 'Integer', 'Float', 'Decimal', 'StrictDate', 'DateTime', 'String' ])->from(dummyMapping, dummyRuntime())
- }->meta::pure::router::preeval::preval(sqlExtensions());
-
- assertLambdaJSONEquals($expected, $sqlTransformContext.lambda());
+ }->meta::pure::router::preeval::preval(sqlExtensions()), testSources(), true, false, true)
}
function <> meta::external::query::sql::transformation::queryToPure::tests::testFromScopingNoMapping():Boolean[1]
{
- let sqlString = 'SELECT * FROM service."/service/service1"';
let mapping = meta::external::query::sql::transformation::queryToPure::emptyMapping();
+ let sources = serviceToSource(createService('/service/service1', | FlatInput.all()->project(x | $x.stringIn, 'String'), [], dummyRuntime()));
- let sqlTransformContext = $sqlString->processQuery(serviceToSource(createService('/service/service1', | FlatInput.all()->project(x | $x.stringIn, 'String'), [], dummyRuntime())), true);
- let expected = {| FlatInput.all()->project(x | $x.stringIn, 'String')->from($mapping, dummyRuntime())}->meta::pure::router::preeval::preval(sqlExtensions());
+ test(
+ 'SELECT * FROM service."/service/service1"',
- assertLambdaJSONEquals($expected, $sqlTransformContext.lambda());
+ {|
+ FlatInput.all()->project(x | $x.stringIn, 'String')->from($mapping, dummyRuntime())
+ }->meta::pure::router::preeval::preval(sqlExtensions()), $sources, true, false, true);
}
function <> meta::external::query::sql::transformation::queryToPure::tests::testFromScopingSimpleNested():Boolean[1]
{
- let sqlString = 'SELECT * FROM (SELECT Integer FROM service."/service/service1")';
- let sqlTransformContext = $sqlString->processQuery(true);
- let expected = {| FlatInput.all()->project(
+ test(
+ 'SELECT * FROM (SELECT Integer FROM service."/service/service1")',
+
+ {|
+ FlatInput.all()->project(
[ x | $x.booleanIn, x | $x.integerIn, x | $x.floatIn, x | $x.decimalIn, x | $x.strictDateIn, x | $x.dateTimeIn, x | $x.stringIn ],
[ 'Boolean', 'Integer', 'Float', 'Decimal', 'StrictDate', 'DateTime', 'String' ])->restrict('Integer')->from(dummyMapping, dummyRuntime())
- }->meta::pure::router::preeval::preval(sqlExtensions());
-
- assertLambdaJSONEquals($expected, $sqlTransformContext.lambda());
+ }->meta::pure::router::preeval::preval(sqlExtensions()), testSources(), true, false, true)
}
function <> meta::external::query::sql::transformation::queryToPure::tests::testFromScopingJoin():Boolean[1]
{
- let sqlString = 'SELECT table1.Integer FROM service."/service/service1" "table1" LEFT OUTER JOIN (SELECT Integer AS "int" FROM service."/service/service2") AS "table2" ON "table1"."Integer" = "table2"."int"';
+ test(
+ 'SELECT table1.Integer FROM service."/service/service1" "table1" LEFT OUTER JOIN (SELECT Integer AS "int" FROM service."/service/service2") AS "table2" ON "table1"."Integer" = "table2"."int"',
- let sqlTransformContext = $sqlString->processQuery(true);
- let expected = {| FlatInput.all()->project(
+ {| FlatInput.all()->project(
[ x | $x.booleanIn, x | $x.integerIn, x | $x.floatIn, x | $x.decimalIn, x | $x.strictDateIn, x | $x.dateTimeIn, x | $x.stringIn ],
[ 'Boolean', 'Integer', 'Float', 'Decimal', 'StrictDate', 'DateTime', 'String' ])->restrict('Integer')->from(dummyMapping, dummyRuntime())
->join(FlatInput.all()->project(
@@ -1754,17 +1711,15 @@ function <> meta::external::query::sql::transformation::queryToPure:
['ID', 'Integer', 'String']
)->renameColumns(pair('Integer', 'int'))->restrict(['int'])->from(dummyMapping, dummyRuntime()), meta::relational::metamodel::join::JoinType.LEFT_OUTER, {row1:TDSRow[1], row2:TDSRow[1] | $row1.getInteger('Integer') == $row2.getInteger('int')}
)->restrict('Integer')
- }->meta::pure::router::preeval::preval(sqlExtensions());
-
- assertLambdaJSONEquals($expected, $sqlTransformContext.lambda());
+ }->meta::pure::router::preeval::preval(sqlExtensions()))
}
function <> meta::external::query::sql::transformation::queryToPure::tests::testFromScopingUnion():Boolean[1]
{
- let sqlString = 'SELECT Integer FROM service."/service/service1" UNION SELECT Integer FROM service."/service/service2"';
+ test(
+ 'SELECT Integer FROM service."/service/service1" UNION SELECT Integer FROM service."/service/service2"',
- let sqlTransformContext = $sqlString->processQuery(true);
- let expected = {|
+ {|
FlatInput.all()
->project(
[ x | $x.booleanIn, x | $x.integerIn, x | $x.floatIn, x | $x.decimalIn, x | $x.strictDateIn, x | $x.dateTimeIn, x | $x.stringIn ],
@@ -1777,16 +1732,15 @@ function <> meta::external::query::sql::transformation::queryToPure::
[ 'ID', 'Integer', 'String' ])
->restrict('Integer')->from(dummyMapping, dummyRuntime())
)
- }->meta::pure::router::preeval::preval(sqlExtensions());
-
- assertLambdaJSONEquals($expected, $sqlTransformContext.lambda());
+ }->meta::pure::router::preeval::preval(sqlExtensions()), testSources(), true, false, true)
}
function <> meta::external::query::sql::transformation::queryToPure::tests::testParameterizedAllSupplied():Boolean[1]
{
- let sqlString = 'SELECT * FROM service(\'/service/service4/{id}\', id => \'abc\', ints => [1,2,3], date => \'2023-01-01\') LIMIT 1';
- let sqlTransformContext = $sqlString->processQuery();
- let expected = {id:String[1], ints:Integer[*], date:StrictDate[0..1]|
+ test(
+ 'SELECT * FROM service(\'/service/service4/{id}\', id => \'abc\', ints => [1,2,3], date => \'2023-01-01\') LIMIT 1',
+
+ {id:String[1], ints:Integer[*], date:StrictDate[0..1]|
FlatInput.all()->filter(f | $f.idIn == $id && $f.integerIn->in($ints) && ($f.strictDateIn > $date))->project(
[
x | $x.idIn, x | $x.integerIn, x | $x.enumVal
@@ -1794,16 +1748,15 @@ function <> meta::external::query::sql::transformation::queryToPure::
[
'ID', 'Integer', 'Enum'
]
- )->limit(1);};
-
- assertLambdaEquals($expected, $sqlTransformContext.lambda());
+ )->limit(1)}, false)
}
function <> meta::external::query::sql::transformation::queryToPure::tests::testParameterizedNotSupplied():Boolean[1]
{
- let sqlString = 'SELECT * FROM service(\'/service/service4/{id}\', id => \'abc\') LIMIT 1';
- let sqlTransformContext = $sqlString->processQuery();
- let expected = {id:String[1], ints:Integer[*], date:StrictDate[0..1]|
+ test(
+ 'SELECT * FROM service(\'/service/service4/{id}\', id => \'abc\') LIMIT 1',
+
+ {id:String[1], ints:Integer[*], date:StrictDate[0..1]|
FlatInput.all()->filter(f | $f.idIn == $id && $f.integerIn->in($ints) && ($f.strictDateIn > $date))->project(
[
@@ -1812,15 +1765,15 @@ function <> meta::external::query::sql::transformation::queryToPure::
[
'ID', 'Integer', 'Enum'
]
- )->limit(1);};
- assertLambdaAndJSONEquals($expected, $sqlTransformContext.lambda());
+ )->limit(1)})
}
function <> meta::external::query::sql::transformation::queryToPure::tests::testMultiLineQuery():Boolean[1]
{
- let sqlString = 'SELECT * FROM service."/service/service3"';
- let sqlTransformContext = $sqlString->processQuery();
- let expected = {|
+ test(
+ 'SELECT * FROM service."/service/service3"',
+
+ {|
let const = 123;
FlatInput.all()->project(
[
@@ -1829,15 +1782,15 @@ function <> meta::external::query::sql::transformation::queryToPure::
[
'ID', 'Integer', 'The Enum Value', 'The Type', 'Const'
]
- );};
- assertLambdaAndJSONEquals($expected, $sqlTransformContext.lambda());
+ );})
}
function <> meta::external::query::sql::transformation::queryToPure::tests::testParameterizedMultiLineJoin():Boolean[1]
{
- let sqlString = 'SELECT * FROM service(\'/service/service4/{id}\', id => \'abc\') union select ID, Integer, "The Enum Value" from service(\'/service/service3\')';
- let sqlTransformContext = $sqlString->processQuery();
- let expected = {id_1:String[1], ints_1:Integer[*], date_1:StrictDate[0..1]|
+ test(
+ 'SELECT * FROM service(\'/service/service4/{id}\', id => \'abc\') union select ID, Integer, "The Enum Value" from service(\'/service/service3\')',
+
+ {id_1:String[1], ints_1:Integer[*], date_1:StrictDate[0..1]|
let const_3 = 123;
@@ -1855,9 +1808,7 @@ function <> meta::external::query::sql::transformation::queryToPure::
[
'ID', 'Integer', 'The Enum Value', 'The Type', 'Const'
]
- )->restrict(['ID', 'Integer', 'The Enum Value']));};
-
- assertLambdaAndJSONEquals($expected, $sqlTransformContext.lambda());
+ )->restrict(['ID', 'Integer', 'The Enum Value']));})
}
@@ -1909,13 +1860,13 @@ function <> meta::external::query::sql::transformation::queryToPure::
let actualSchema = $sqlString->processQuery(true).columns()->meta::external::query::sql::tdsColsToSchema();
- let expectedCol1 = ^PrimitiveValueSchemaColumn(name='Boolean', type=meta::external::query::sql::PrimitiveType.Boolean);
- let expectedCol2 = ^PrimitiveValueSchemaColumn(name='Integer', type=meta::external::query::sql::PrimitiveType.Integer);
- let expectedCol3 = ^PrimitiveValueSchemaColumn(name='Float', type=meta::external::query::sql::PrimitiveType.Float);
- let expectedCol4 = ^PrimitiveValueSchemaColumn(name='Decimal', type=meta::external::query::sql::PrimitiveType.Decimal);
- let expectedCol5 = ^PrimitiveValueSchemaColumn(name='StrictDate', type=meta::external::query::sql::PrimitiveType.StrictDate);
- let expectedCol6 = ^PrimitiveValueSchemaColumn(name='DateTime', type=meta::external::query::sql::PrimitiveType.DateTime);
- let expectedCol7 = ^PrimitiveValueSchemaColumn(name='String', type=meta::external::query::sql::PrimitiveType.String);
+ let expectedCol1 = ^PrimitiveSchemaColumn(name='Boolean', type=meta::external::query::sql::schema::metamodel::PrimitiveType.Boolean);
+ let expectedCol2 = ^PrimitiveSchemaColumn(name='Integer', type=meta::external::query::sql::schema::metamodel::PrimitiveType.Integer);
+ let expectedCol3 = ^PrimitiveSchemaColumn(name='Float', type=meta::external::query::sql::schema::metamodel::PrimitiveType.Float);
+ let expectedCol4 = ^PrimitiveSchemaColumn(name='Decimal', type=meta::external::query::sql::schema::metamodel::PrimitiveType.Decimal);
+ let expectedCol5 = ^PrimitiveSchemaColumn(name='StrictDate', type=meta::external::query::sql::schema::metamodel::PrimitiveType.StrictDate);
+ let expectedCol6 = ^PrimitiveSchemaColumn(name='DateTime', type=meta::external::query::sql::schema::metamodel::PrimitiveType.DateTime);
+ let expectedCol7 = ^PrimitiveSchemaColumn(name='String', type=meta::external::query::sql::schema::metamodel::PrimitiveType.String);
let expectedSchema = ^Schema(columns=[$expectedCol1, $expectedCol2, $expectedCol3, $expectedCol4, $expectedCol5, $expectedCol6, $expectedCol7]);
assertEquals($expectedSchema, $actualSchema);
@@ -1927,9 +1878,9 @@ function <> meta::external::query::sql::transformation::queryToPure::
let actualSchema = $sqlString->processQuery(true).columns()->meta::external::query::sql::tdsColsToSchema();
- let expectedCol1 = ^PrimitiveValueSchemaColumn(name='ID', type=meta::external::query::sql::PrimitiveType.Integer);
- let expectedCol2 = ^PrimitiveValueSchemaColumn(name='Integer', type=meta::external::query::sql::PrimitiveType.Integer);
- let expectedCol3 = ^PrimitiveValueSchemaColumn(name='String', type=meta::external::query::sql::PrimitiveType.String);
+ let expectedCol1 = ^PrimitiveSchemaColumn(name='ID', type=meta::external::query::sql::schema::metamodel::PrimitiveType.Integer);
+ let expectedCol2 = ^PrimitiveSchemaColumn(name='Integer', type=meta::external::query::sql::schema::metamodel::PrimitiveType.Integer);
+ let expectedCol3 = ^PrimitiveSchemaColumn(name='String', type=meta::external::query::sql::schema::metamodel::PrimitiveType.String);
let expectedSchema = ^Schema(columns=[$expectedCol1, $expectedCol2, $expectedCol3]);
assertEquals($expectedSchema, $actualSchema);
@@ -1941,13 +1892,13 @@ function <> meta::external::query::sql::transformation::queryToPure::
let actualSchema = $sqlString->processQuery(true).columns()->meta::external::query::sql::tdsColsToSchema();
- let expectedCol1 = ^PrimitiveValueSchemaColumn(name='ID', type=meta::external::query::sql::PrimitiveType.Integer);
- let expectedCol2 = ^PrimitiveValueSchemaColumn(name='Integer', type=meta::external::query::sql::PrimitiveType.Integer);
- let expectedCol3 = ^EnumValueSchemaColumn(name='The Enum Value', type=MyEnum->elementToPath());
- let expectedCol4 = ^EnumValueSchemaColumn(name='The Type', type=FieldType->elementToPath());
- let expectedCol5 = ^PrimitiveValueSchemaColumn(name='Const', type=meta::external::query::sql::PrimitiveType.Integer);
- let expectedEnum1 = ^meta::external::query::sql::Enum(type=MyEnum->elementToPath(), values=MyEnum->enumValues()->map(v:meta::pure::metamodel::type::Enum[1] | $v->id()));
- let expectedEnum2 = ^meta::external::query::sql::Enum(type=FieldType->elementToPath(), values=FieldType->enumValues()->map(v:meta::pure::metamodel::type::Enum[1] | $v->id()));
+ let expectedCol1 = ^PrimitiveSchemaColumn(name='ID', type=meta::external::query::sql::schema::metamodel::PrimitiveType.Integer);
+ let expectedCol2 = ^PrimitiveSchemaColumn(name='Integer', type=meta::external::query::sql::schema::metamodel::PrimitiveType.Integer);
+ let expectedCol3 = ^EnumSchemaColumn(name='The Enum Value', type=MyEnum->elementToPath());
+ let expectedCol4 = ^EnumSchemaColumn(name='The Type', type=FieldType->elementToPath());
+ let expectedCol5 = ^PrimitiveSchemaColumn(name='Const', type=meta::external::query::sql::schema::metamodel::PrimitiveType.Integer);
+ let expectedEnum1 = ^meta::external::query::sql::schema::metamodel::Enum(type=MyEnum->elementToPath(), values=MyEnum->enumValues()->map(v:meta::pure::metamodel::type::Enum[1] | $v->id()));
+ let expectedEnum2 = ^meta::external::query::sql::schema::metamodel::Enum(type=FieldType->elementToPath(), values=FieldType->enumValues()->map(v:meta::pure::metamodel::type::Enum[1] | $v->id()));
let expectedSchema = ^Schema(columns=[$expectedCol1, $expectedCol2, $expectedCol3, $expectedCol4,$expectedCol5], enums=[$expectedEnum1, $expectedEnum2]);
assertEquals($expectedSchema, $actualSchema);
@@ -1996,16 +1947,16 @@ function <> meta::external::query::sql::transformation::queryToPure::
doNameTest(^ArrayLiteral(values = [^IntegerLiteral(value = 1), ^IntegerLiteral(value = 2)]), '1,2');
doNameTest(^NullLiteral(), 'NULL');
- doNameTest(^LikePredicate(value = ^StringLiteral(value = 'a', quoted = false),
+ doNameTest(^LikePredicate(value = ^StringLiteral(value = 'a', quoted = false),
pattern = ^StringLiteral(value = 'b', quoted = false),
ignoreCase = false), 'a LIKE b');
- doNameTest(^LikePredicate(value = ^StringLiteral(value = 'a', quoted = false),
+ doNameTest(^LikePredicate(value = ^StringLiteral(value = 'a', quoted = false),
+ pattern = ^StringLiteral(value = 'b', quoted = false),
+ ignoreCase = true), 'a ILIKE b');
+ doNameTest(^LikePredicate(value = ^StringLiteral(value = 'a', quoted = false),
pattern = ^StringLiteral(value = 'b', quoted = false),
- ignoreCase = true), 'a ILIKE b');
- doNameTest(^LikePredicate(value = ^StringLiteral(value = 'a', quoted = false),
- pattern = ^StringLiteral(value = 'b', quoted = false),
escape = ^StringLiteral(value = '!', quoted = false),
- ignoreCase = false), 'a LIKE b ESCAPE !');
+ ignoreCase = false), 'a LIKE b ESCAPE !');
doNameTest(^LogicalBinaryExpression(left = ^BooleanLiteral(value = true), right = ^BooleanLiteral(value = false),type = LogicalBinaryType.AND), 'true AND false');
doNameTest(^LogicalBinaryExpression(left = ^BooleanLiteral(value = true), right = ^BooleanLiteral(value = false),type = LogicalBinaryType.OR), 'true OR false');
@@ -2021,6 +1972,36 @@ function <> meta::external::query::sql::transformation::queryToPure::
defaultValue = ^IntegerLiteral(value = 1)), 'CASE WHEN true = false THEN 2 ELSE 1 END');
}
+
+function meta::external::query::sql::transformation::queryToPure::tests::testSources():SQLSource[*]
+{
+ [
+ serviceToSource(Service1()),
+ serviceToSource(Service2()),
+ serviceToSource(Service3()),
+ serviceToSource(Service4())
+ ]
+}
+
+function meta::external::query::sql::transformation::queryToPure::tests::test(sql:String[1], expected:FunctionDefinition[1]):Boolean[1]
+{
+ test($sql, $expected, true);
+}
+
+function meta::external::query::sql::transformation::queryToPure::tests::test(sql:String[1], expected:FunctionDefinition[1], assertJSON:Boolean[1]):Boolean[1]
+{
+ test($sql, $expected, testSources(), false, true, $assertJSON);
+}
+
+function meta::external::query::sql::transformation::queryToPure::tests::test(sql:String[1], expected:FunctionDefinition[1], sources:SQLSource[*], scopeWithFrom:Boolean[1], assertLambda:Boolean[1], assertJSON:Boolean[1]):Boolean[1]
+{
+ let sqlTransformContext = $sql->processQuery($sources, $scopeWithFrom);
+ let actual = $sqlTransformContext.lambda();
+
+ if ($assertLambda, | assertLambdaEquals($expected, $actual), | true);
+ if ($assertJSON, | assertLambdaJSONEquals($expected, $actual), | true);
+}
+
function meta::external::query::sql::transformation::queryToPure::tests::processQuery(sql: String[1]): SqlTransformContext[1]
{
processQuery($sql, false);
@@ -2044,9 +2025,4 @@ function meta::external::query::sql::transformation::queryToPure::tests::process
let context = rootContext($sources, $extensions);
$query->processRootQuery(^$context(scopeWithFrom = $scopeWithFrom));
-}
-
-function meta::external::query::sql::transformation::queryToPure::tests::forceGetStringType(col: TDSColumn[1]): String[1]
-{
- $col.type->toOne()->elementToPath();
-}
+}
\ No newline at end of file
diff --git a/legend-engine-xts-sql/legend-engine-xt-sql-pure/src/main/resources/core_external_query_sql/binding/model.pure b/legend-engine-xts-sql/legend-engine-xt-sql-pure/src/main/resources/core_external_query_sql/binding/model.pure
deleted file mode 100644
index 899ee07cf30..00000000000
--- a/legend-engine-xts-sql/legend-engine-xt-sql-pure/src/main/resources/core_external_query_sql/binding/model.pure
+++ /dev/null
@@ -1,100 +0,0 @@
-// Copyright 2023 Goldman Sachs
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-
-Class meta::external::query::sql::SchemaColumn
-{
- <> name: String[1];
-}
-
-Class meta::external::query::sql::PrimitiveValueSchemaColumn extends meta::external::query::sql::SchemaColumn
-{
- <> type: meta::external::query::sql::PrimitiveType[1];
-}
-
-Class meta::external::query::sql::EnumValueSchemaColumn extends meta::external::query::sql::SchemaColumn
-{
- <> type: String[1];
-}
-
-
-Class meta::external::query::sql::Schema
-{
- <> columns: meta::external::query::sql::SchemaColumn[*];
- <> enums: meta::external::query::sql::Enum[*];
-}
-
-Enum meta::external::query::sql::PrimitiveType
-{
- Boolean,
- StrictDate,
- Number,
- String,
- LatestDate,
- Float,
- DateTime,
- Date,
- Integer,
- Decimal
-}
-
-Class meta::external::query::sql::Enum
-{
- <> type: String[1];
- <> values: String[*];
-}
-
-function meta::external::query::sql::stringToPrimitiveType(dt : String[1]) : meta::external::query::sql::PrimitiveType[1]
-{
- let type = newMap(
- [
- pair('Boolean', meta::external::query::sql::PrimitiveType.Boolean),
- pair('StrictDate', meta::external::query::sql::PrimitiveType.StrictDate),
- pair('Number', meta::external::query::sql::PrimitiveType.Number),
- pair('String', meta::external::query::sql::PrimitiveType.String),
- pair('LatestDate', meta::external::query::sql::PrimitiveType.LatestDate),
- pair('Float', meta::external::query::sql::PrimitiveType.Float),
- pair('DateTime', meta::external::query::sql::PrimitiveType.DateTime),
- pair('Date', meta::external::query::sql::PrimitiveType.Date),
- pair('Integer', meta::external::query::sql::PrimitiveType.Integer),
- pair('Decimal', meta::external::query::sql::PrimitiveType.Decimal)
- ]
- )->get($dt);
- if($type->isEmpty(), |fail('Unknown primitive type: ' + $dt), |[]);
- $type->toOne();
-}
-
-function meta::external::query::sql::tdsColToSchemaCol(col: TDSColumn[1]): meta::external::query::sql::SchemaColumn[1]
-{
- let columnName = $col.name;
- if($col.type->isEmpty(), |fail('Column type is empty for col: ' + $columnName), |[]);
- let tdsType = $col.type->toOne();
- let columnPrimitiveType = $col.type->match([
- s:PrimitiveType[1] | ^meta::external::query::sql::PrimitiveValueSchemaColumn(type=$tdsType->meta::pure::functions::meta::elementToPath()->meta::external::query::sql::stringToPrimitiveType(),name=$columnName),
- e:Enumeration[1] | ^meta::external::query::sql::EnumValueSchemaColumn(type=$tdsType->meta::pure::functions::meta::elementToPath(),name=$columnName),
- a:Any[*] | fail('Unsupported type on column: ' + $columnName + ' (' + $tdsType->meta::pure::functions::meta::elementToPath() + '), only primitive types and enums are supported');
- ])->cast(@meta::external::query::sql::SchemaColumn);
-}
-
-function meta::external::query::sql::tdsColsToSchema(cols: TDSColumn[*]): meta::external::query::sql::Schema[1]
-{
- let schemaCols = $cols->map(v:TDSColumn[1] | $v->meta::external::query::sql::tdsColToSchemaCol());
- let enums = $cols
- ->map(c:TDSColumn[1] | $c.type->match([
- e:Enumeration[1] | ^meta::external::query::sql::Enum(type=$e->meta::pure::functions::meta::elementToPath(), values=$e->enumValues()->map( v:Enum[1] | $v->id())),
- a:Any[*] | []
- ]))
- ->distinct();
- ^meta::external::query::sql::Schema(columns=$schemaCols, enums=$enums);
-}
diff --git a/legend-engine-xts-sql/legend-engine-xt-sql-pure/src/main/resources/core_external_query_sql/binding/schema.pure b/legend-engine-xts-sql/legend-engine-xt-sql-pure/src/main/resources/core_external_query_sql/binding/schema.pure
new file mode 100644
index 00000000000..f75ada02117
--- /dev/null
+++ b/legend-engine-xts-sql/legend-engine-xt-sql-pure/src/main/resources/core_external_query_sql/binding/schema.pure
@@ -0,0 +1,58 @@
+// Copyright 2023 Goldman Sachs
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+
+function meta::external::query::sql::schema::stringToPrimitiveType(dt : String[1]) : meta::external::query::sql::schema::metamodel::PrimitiveType[1]
+{
+ let type = newMap(
+ [
+ pair('Boolean', meta::external::query::sql::schema::metamodel::PrimitiveType.Boolean),
+ pair('StrictDate', meta::external::query::sql::schema::metamodel::PrimitiveType.StrictDate),
+ pair('Number', meta::external::query::sql::schema::metamodel::PrimitiveType.Number),
+ pair('String', meta::external::query::sql::schema::metamodel::PrimitiveType.String),
+ pair('LatestDate', meta::external::query::sql::schema::metamodel::PrimitiveType.LatestDate),
+ pair('Float', meta::external::query::sql::schema::metamodel::PrimitiveType.Float),
+ pair('DateTime', meta::external::query::sql::schema::metamodel::PrimitiveType.DateTime),
+ pair('Date', meta::external::query::sql::schema::metamodel::PrimitiveType.Date),
+ pair('Integer', meta::external::query::sql::schema::metamodel::PrimitiveType.Integer),
+ pair('Decimal', meta::external::query::sql::schema::metamodel::PrimitiveType.Decimal)
+ ]
+ )->get($dt);
+ if($type->isEmpty(), |fail('Unknown primitive type: ' + $dt), |[]);
+ $type->toOne();
+}
+
+function meta::external::query::sql::schema::tdsColToSchemaCol(col: TDSColumn[1]): meta::external::query::sql::schema::metamodel::SchemaColumn[1]
+{
+ let columnName = $col.name;
+ if($col.type->isEmpty(), |fail('Column type is empty for col: ' + $columnName), |[]);
+ let tdsType = $col.type->toOne();
+ let columnPrimitiveType = $col.type->match([
+ s:PrimitiveType[1] | ^meta::external::query::sql::schema::metamodel::PrimitiveSchemaColumn(type=$tdsType->meta::pure::functions::meta::elementToPath()->meta::external::query::sql::schema::stringToPrimitiveType(),name=$columnName),
+ e:Enumeration[1] | ^meta::external::query::sql::schema::metamodel::EnumSchemaColumn(type=$tdsType->meta::pure::functions::meta::elementToPath(),name=$columnName),
+ a:Any[*] | fail('Unsupported type on column: ' + $columnName + ' (' + $tdsType->meta::pure::functions::meta::elementToPath() + '), only primitive types and enums are supported');
+ ])->cast(@meta::external::query::sql::schema::metamodel::SchemaColumn);
+}
+
+function meta::external::query::sql::tdsColsToSchema(cols: TDSColumn[*]): meta::external::query::sql::schema::metamodel::Schema[1]
+{
+ let schemaCols = $cols->map(v:TDSColumn[1] | $v->meta::external::query::sql::schema::tdsColToSchemaCol());
+ let enums = $cols
+ ->map(c:TDSColumn[1] | $c.type->match([
+ e:Enumeration[1] | ^meta::external::query::sql::schema::metamodel::Enum(type=$e->meta::pure::functions::meta::elementToPath(), values=$e->enumValues()->map( v:Enum[1] | $v->id())),
+ a:Any[*] | []
+ ]))
+ ->distinct();
+ ^meta::external::query::sql::schema::metamodel::Schema(columns=$schemaCols, enums=$enums);
+}
diff --git a/legend-engine-xts-sql/legend-engine-xt-sql-query/pom.xml b/legend-engine-xts-sql/legend-engine-xt-sql-query/pom.xml
index 8a69596ec87..18db6143fc2 100644
--- a/legend-engine-xts-sql/legend-engine-xt-sql-query/pom.xml
+++ b/legend-engine-xts-sql/legend-engine-xt-sql-query/pom.xml
@@ -33,10 +33,6 @@
org.finos.legend.pure
legend-pure-m3-core
-
- org.finos.legend.pure
- legend-pure-runtime-java-engine-compiled
-
diff --git a/legend-engine-xts-sql/legend-engine-xt-sql-query/src/main/java/org/finos/legend/engine/query/sql/api/SQLExecutor.java b/legend-engine-xts-sql/legend-engine-xt-sql-query/src/main/java/org/finos/legend/engine/query/sql/api/SQLExecutor.java
new file mode 100644
index 00000000000..798afbdf56b
--- /dev/null
+++ b/legend-engine-xts-sql/legend-engine-xt-sql-query/src/main/java/org/finos/legend/engine/query/sql/api/SQLExecutor.java
@@ -0,0 +1,293 @@
+// Copyright 2023 Goldman Sachs
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+package org.finos.legend.engine.query.sql.api;
+
+import org.eclipse.collections.api.RichIterable;
+import org.eclipse.collections.api.block.function.Function;
+import org.eclipse.collections.api.block.function.Function3;
+import org.eclipse.collections.api.collection.MutableCollection;
+import org.eclipse.collections.api.factory.Lists;
+import org.eclipse.collections.api.factory.Maps;
+import org.eclipse.collections.api.list.MutableList;
+import org.eclipse.collections.api.map.MutableMap;
+import org.eclipse.collections.api.multimap.MutableMultimap;
+import org.eclipse.collections.api.tuple.Pair;
+import org.eclipse.collections.impl.map.mutable.UnifiedMap;
+import org.eclipse.collections.impl.tuple.Tuples;
+import org.eclipse.collections.impl.utility.Iterate;
+import org.eclipse.collections.impl.utility.ListIterate;
+import org.eclipse.collections.impl.utility.internal.IterableIterate;
+import org.finos.legend.engine.language.pure.compiler.toPureGraph.PureModel;
+import org.finos.legend.engine.language.pure.modelManager.ModelManager;
+import org.finos.legend.engine.plan.execution.PlanExecutor;
+import org.finos.legend.engine.plan.execution.result.ConstantResult;
+import org.finos.legend.engine.plan.execution.result.Result;
+import org.finos.legend.engine.plan.generation.transformers.PlanTransformer;
+import org.finos.legend.engine.plan.platform.PlanPlatform;
+import org.finos.legend.engine.protocol.pure.PureClientVersions;
+import org.finos.legend.engine.protocol.pure.v1.model.context.PureModelContext;
+import org.finos.legend.engine.protocol.pure.v1.model.context.PureModelContextData;
+import org.finos.legend.engine.protocol.pure.v1.model.context.PureModelContextPointer;
+import org.finos.legend.engine.protocol.pure.v1.model.executionPlan.SingleExecutionPlan;
+import org.finos.legend.engine.protocol.pure.v1.model.valueSpecification.raw.Lambda;
+import org.finos.legend.engine.protocol.sql.metamodel.ProtocolToMetamodelTranslator;
+import org.finos.legend.engine.protocol.sql.metamodel.Query;
+import org.finos.legend.engine.protocol.sql.schema.metamodel.MetamodelToProtocolTranslator;
+import org.finos.legend.engine.protocol.sql.schema.metamodel.Schema;
+import org.finos.legend.engine.query.sql.api.sources.SQLContext;
+import org.finos.legend.engine.query.sql.api.sources.SQLSource;
+import org.finos.legend.engine.query.sql.api.sources.SQLSourceProvider;
+import org.finos.legend.engine.query.sql.api.sources.SQLSourceResolvedContext;
+import org.finos.legend.engine.query.sql.api.sources.SQLSourceTranslator;
+import org.finos.legend.engine.query.sql.api.sources.TableSource;
+import org.finos.legend.engine.query.sql.api.sources.TableSourceExtractor;
+import org.finos.legend.engine.shared.core.ObjectMapperFactory;
+import org.finos.legend.engine.shared.core.operational.errorManagement.EngineException;
+import org.finos.legend.engine.shared.core.operational.logs.LogInfo;
+import org.finos.legend.engine.shared.core.operational.logs.LoggingEventType;
+import org.finos.legend.engine.shared.core.operational.prometheus.MetricsHandler;
+import org.finos.legend.pure.generated.Root_meta_external_query_sql_metamodel_Query;
+import org.finos.legend.pure.generated.Root_meta_external_query_sql_schema_metamodel_Schema;
+import org.finos.legend.pure.generated.Root_meta_external_query_sql_transformation_queryToPure_PlanGenerationResult;
+import org.finos.legend.pure.generated.Root_meta_external_query_sql_transformation_queryToPure_SQLSource;
+import org.finos.legend.pure.generated.Root_meta_external_query_sql_transformation_queryToPure_SqlTransformContext;
+import org.finos.legend.pure.generated.Root_meta_pure_executionPlan_ExecutionPlan;
+import org.finos.legend.pure.generated.Root_meta_pure_extension_Extension;
+import org.finos.legend.pure.generated.core_external_format_json_toJSON;
+import org.finos.legend.pure.generated.core_external_query_sql_binding_fromPure_fromPure;
+import org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.function.FunctionDefinition;
+import org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.function.LambdaFunction;
+import org.finos.legend.pure.m3.execution.ExecutionSupport;
+import org.pac4j.core.profile.CommonProfile;
+import org.slf4j.Logger;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import static org.finos.legend.engine.plan.generation.PlanGenerator.transformExecutionPlan;
+
+public class SQLExecutor
+{
+ private static final Logger LOGGER = org.slf4j.LoggerFactory.getLogger(SQLExecutor.class);
+ private final ModelManager modelManager;
+ private final PlanExecutor planExecutor;
+ private final Function> routerExtensions;
+ private final Iterable extends PlanTransformer> transformers;
+ private final MutableMap