diff --git a/.github/workflows/sdt-duckdb.yml b/.github/workflows/sdt-duckdb.yml
new file mode 100644
index 00000000000..4b815c46032
--- /dev/null
+++ b/.github/workflows/sdt-duckdb.yml
@@ -0,0 +1,77 @@
+# Copyright 2024 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.
+
+name: (SDT) DuckDB SQL Dialect Tests
+
+env:
+ CI_DEPLOY_USERNAME: ${{ secrets.CI_DEPLOY_USERNAME }}
+ CI_DEPLOY_PASSWORD: ${{ secrets.CI_DEPLOY_PASSWORD }}
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
+ PROJECT_DIR: legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-dbExtension/legend-engine-xt-relationalStore-duckdb/legend-engine-xt-relationalStore-duckdb-sqlDialectTranslation-pure
+
+on: [push, pull_request]
+
+jobs:
+ build:
+ runs-on: ubuntu-latest
+ steps:
+ - name: Set up JDK
+ uses: actions/setup-java@v4
+ with:
+ java-version: 11
+ distribution: zulu
+ server-id: ossrh
+ server-username: CI_DEPLOY_USERNAME
+ server-password: CI_DEPLOY_PASSWORD
+
+ - name: Check Java version
+ run: java -version
+
+ - name: Checkout repo
+ uses: actions/checkout@v4
+
+ - name: Build core_external_store_relational_sql_dialect_translation_duckdb
+ run: |
+ mvn -B -e -pl ${{ env.PROJECT_DIR }} clean install -am -DskipTests=true
+
+ - name: Run SDT Test
+ run: |
+ mvn -B -e -pl ${{ env.PROJECT_DIR }} test -Dtest=Test_DuckDB_SDT
+
+ - name: Upload Test Results
+ if: always()
+ uses: actions/upload-artifact@v4
+ with:
+ name: test-results
+ path: ${{ env.PROJECT_DIR }}/target/surefire-reports/*.xml
+
+ - name: Publish Test Results
+ uses: mikepenz/action-junit-report@v4
+ if: always()
+ with:
+ report_paths: '${{ env.PROJECT_DIR }}/target/surefire-reports/*.xml'
+ fail_on_failure: true
+ summary: true
+ detailed_summary: true
+ include_passed: true
+ check_name: DuckDB SDT Report
+ job_name: DuckDB SDT Report
+
+ - name: Upload CI Event
+ if: always()
+ uses: actions/upload-artifact@v4
+ with:
+ name: event-file
+ path: ${{ github.event_path }}
diff --git a/.github/workflows/sdt-postgres.yml b/.github/workflows/sdt-postgres.yml
new file mode 100644
index 00000000000..762c487edb7
--- /dev/null
+++ b/.github/workflows/sdt-postgres.yml
@@ -0,0 +1,77 @@
+# Copyright 2024 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.
+
+name: (SDT) Postgres SQL Dialect Tests
+
+env:
+ CI_DEPLOY_USERNAME: ${{ secrets.CI_DEPLOY_USERNAME }}
+ CI_DEPLOY_PASSWORD: ${{ secrets.CI_DEPLOY_PASSWORD }}
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
+ PROJECT_DIR: legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-generation/legend-engine-xt-relationalStore-pure/legend-engine-xt-relationalStore-SDT-pure
+
+on: [push, pull_request]
+
+jobs:
+ build:
+ runs-on: ubuntu-latest
+ steps:
+ - name: Set up JDK
+ uses: actions/setup-java@v4
+ with:
+ java-version: 11
+ distribution: zulu
+ server-id: ossrh
+ server-username: CI_DEPLOY_USERNAME
+ server-password: CI_DEPLOY_PASSWORD
+
+ - name: Check Java version
+ run: java -version
+
+ - name: Checkout repo
+ uses: actions/checkout@v4
+
+ - name: Build core_external_store_relational_sdt
+ run: |
+ mvn -B -e -pl ${{ env.PROJECT_DIR }} clean install -am -DskipTests=true
+
+ - name: Run SDT Test
+ run: |
+ mvn -B -e -pl ${{ env.PROJECT_DIR }} test -Dtest=Test_Postgres_SDT
+
+ - name: Upload Test Results
+ if: always()
+ uses: actions/upload-artifact@v4
+ with:
+ name: test-results
+ path: ${{ env.PROJECT_DIR }}/target/surefire-reports/*.xml
+
+ - name: Publish Test Results
+ uses: mikepenz/action-junit-report@v4
+ if: always()
+ with:
+ report_paths: '${{ env.PROJECT_DIR }}/target/surefire-reports/*.xml'
+ fail_on_failure: true
+ summary: true
+ detailed_summary: true
+ include_passed: true
+ check_name: Postgres SDT Report
+ job_name: Postgres SDT Report
+
+ - name: Upload CI Event
+ if: always()
+ uses: actions/upload-artifact@v4
+ with:
+ name: event-file
+ path: ${{ github.event_path }}
diff --git a/legend-engine-config/legend-engine-extensions-collection-generation/pom.xml b/legend-engine-config/legend-engine-extensions-collection-generation/pom.xml
index de3b2b1a7e0..386d5935190 100644
--- a/legend-engine-config/legend-engine-extensions-collection-generation/pom.xml
+++ b/legend-engine-config/legend-engine-extensions-collection-generation/pom.xml
@@ -356,6 +356,11 @@
legend-engine-xt-relationalStore-sqlDialectTranslation-pure
runtime
+
+ org.finos.legend.engine
+ legend-engine-xt-relationalStore-duckdb-sqlDialectTranslation-pure
+ runtime
+
diff --git a/legend-engine-config/legend-engine-extensions-collection-generation/src/test/java/org/finos/legend/engine/extensions/collection/generation/TestExtensions.java b/legend-engine-config/legend-engine-extensions-collection-generation/src/test/java/org/finos/legend/engine/extensions/collection/generation/TestExtensions.java
index 2522ab7a88f..f7d70e917e9 100644
--- a/legend-engine-config/legend-engine-extensions-collection-generation/src/test/java/org/finos/legend/engine/extensions/collection/generation/TestExtensions.java
+++ b/legend-engine-config/legend-engine-extensions-collection-generation/src/test/java/org/finos/legend/engine/extensions/collection/generation/TestExtensions.java
@@ -586,6 +586,7 @@ protected Iterable getExpectedCodeRepositories()
.with("core_nonrelational_mongodb_java_platform_binding")
.with("core_external_store_relational_sql_planning")
.with("core_external_store_relational_sql_dialect_translation")
+ .with("core_external_store_relational_sql_dialect_translation_duckdb")
;
}
}
diff --git a/legend-engine-pure/legend-engine-pure-ide/legend-engine-pure-ide-light-http-server/pom.xml b/legend-engine-pure/legend-engine-pure-ide/legend-engine-pure-ide-light-http-server/pom.xml
index 6389d630a6c..1b763bc9fad 100644
--- a/legend-engine-pure/legend-engine-pure-ide/legend-engine-pure-ide-light-http-server/pom.xml
+++ b/legend-engine-pure/legend-engine-pure-ide/legend-engine-pure-ide-light-http-server/pom.xml
@@ -278,6 +278,11 @@
runtime
${project.version}
+
+ org.finos.legend.engine
+ legend-engine-xt-relationalStore-SDT-pure
+ runtime
+
diff --git a/legend-engine-pure/legend-engine-pure-ide/legend-engine-pure-ide-light-http-server/src/main/java/org/finos/legend/engine/ide/PureIDELight.java b/legend-engine-pure/legend-engine-pure-ide/legend-engine-pure-ide-light-http-server/src/main/java/org/finos/legend/engine/ide/PureIDELight.java
index 805e1a346eb..d1c989912e2 100644
--- a/legend-engine-pure/legend-engine-pure-ide/legend-engine-pure-ide-light-http-server/src/main/java/org/finos/legend/engine/ide/PureIDELight.java
+++ b/legend-engine-pure/legend-engine-pure-ide/legend-engine-pure-ide-light-http-server/src/main/java/org/finos/legend/engine/ide/PureIDELight.java
@@ -122,6 +122,8 @@ protected MutableList buildRepositories(SourceLocationCon
.with(this.buildCore("legend-engine-xts-dataquality/legend-engine-xt-dataquality-pure", "dataquality"))
.with(this.buildCore("legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-generation/legend-engine-xt-relationalStore-pure/legend-engine-xt-relationalStore-sqlPlanning-pure", "external-store-relational-sql-planning"))
.with(this.buildCore("legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-generation/legend-engine-xt-relationalStore-pure/legend-engine-xt-relationalStore-sqlDialectTranslation-pure", "external-store-relational-sql-dialect-translation"))
+ .with(this.buildCore("legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-generation/legend-engine-xt-relationalStore-pure/legend-engine-xt-relationalStore-SDT-pure", "external-store-relational-sdt"))
+ .with(this.buildCore("legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-dbExtension/legend-engine-xt-relationalStore-duckdb/legend-engine-xt-relationalStore-duckdb-sqlDialectTranslation-pure", "external-store-relational-sql-dialect-translation-duckdb"))
;
}
diff --git a/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-dbExtension/legend-engine-xt-relationalStore-duckdb/legend-engine-xt-relationalStore-duckdb-sqlDialectTranslation-pure/pom.xml b/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-dbExtension/legend-engine-xt-relationalStore-duckdb/legend-engine-xt-relationalStore-duckdb-sqlDialectTranslation-pure/pom.xml
new file mode 100644
index 00000000000..a6e2f35f9ed
--- /dev/null
+++ b/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-dbExtension/legend-engine-xt-relationalStore-duckdb/legend-engine-xt-relationalStore-duckdb-sqlDialectTranslation-pure/pom.xml
@@ -0,0 +1,181 @@
+
+
+
+
+
+ org.finos.legend.engine
+ legend-engine-xt-relationalStore-duckdb
+ 4.63.2-SNAPSHOT
+
+ 4.0.0
+
+ legend-engine-xt-relationalStore-duckdb-sqlDialectTranslation-pure
+ jar
+ Legend Engine - XT - Relational Store - DuckDB - SQL Dialect Translation - Pure
+
+
+
+
+ org.finos.legend.pure
+ legend-pure-maven-generation-par
+
+ ${project.basedir}/src/main/resources
+ ${legend.pure.version}
+
+ core_external_store_relational_sql_dialect_translation_duckdb
+
+
+ ${project.basedir}/src/main/resources/core_external_store_relational_sql_dialect_translation_duckdb.definition.json
+
+
+
+
+ generate-sources
+
+ build-pure-jar
+
+
+
+
+
+ org.finos.legend.engine
+ legend-engine-xt-relationalStore-sqlDialectTranslation-pure
+ ${project.version}
+
+
+ org.finos.legend.pure
+ legend-pure-m2-dsl-diagram-grammar
+ ${legend.pure.version}
+
+
+
+
+ org.finos.legend.pure
+ legend-pure-maven-generation-java
+
+
+ compile
+
+ build-pure-compiled-jar
+
+
+ true
+ true
+ modular
+ true
+
+ core_external_store_relational_sql_dialect_translation_duckdb
+
+
+
+
+
+
+ org.finos.legend.engine
+ legend-engine-xt-relationalStore-sqlDialectTranslation-pure
+ ${project.version}
+
+
+ org.finos.legend.pure
+ legend-pure-m2-dsl-diagram-grammar
+ ${legend.pure.version}
+
+
+
+
+
+ maven-surefire-plugin
+
+ false
+
+ **/Test_DuckDB_SDT*.java
+ **/SdtTestSuiteBuilder*.java
+
+
+
+
+
+
+
+
+
+ org.finos.legend.pure
+ legend-pure-m4
+
+
+ org.finos.legend.pure
+ legend-pure-m3-core
+
+
+ org.finos.legend.pure
+ legend-pure-runtime-java-engine-compiled
+
+
+
+
+
+ org.finos.legend.engine
+ legend-engine-pure-platform-java
+
+
+ org.finos.legend.engine
+ legend-engine-pure-code-compiled-core
+
+
+ org.finos.legend.engine
+ legend-engine-xt-relationalStore-postgresSqlModel-pure
+
+
+ org.finos.legend.engine
+ legend-engine-xt-relationalStore-sqlDialectTranslation-pure
+
+
+
+
+ org.eclipse.collections
+ eclipse-collections
+
+
+ org.eclipse.collections
+ eclipse-collections-api
+
+
+
+
+ junit
+ junit
+
+
+ org.finos.legend.engine
+ legend-engine-xt-relationalStore-SDT-pure
+ test
+
+
+ org.finos.legend.engine
+ legend-engine-xt-relationalStore-duckdb-PCT
+ test
+
+
+ org.finos.legend.engine
+ legend-engine-xt-relationalStore-SDT-pure
+ test-jar
+ ${project.version}
+ test
+
+
+
+
diff --git a/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-dbExtension/legend-engine-xt-relationalStore-duckdb/legend-engine-xt-relationalStore-duckdb-sqlDialectTranslation-pure/src/main/java/org/finos/legend/pure/code/core/CoreExternalStoreRelationalSqlDialectTranslationDuckDBCodeRepositoryProvider.java b/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-dbExtension/legend-engine-xt-relationalStore-duckdb/legend-engine-xt-relationalStore-duckdb-sqlDialectTranslation-pure/src/main/java/org/finos/legend/pure/code/core/CoreExternalStoreRelationalSqlDialectTranslationDuckDBCodeRepositoryProvider.java
new file mode 100644
index 00000000000..1897b4045cf
--- /dev/null
+++ b/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-dbExtension/legend-engine-xt-relationalStore-duckdb/legend-engine-xt-relationalStore-duckdb-sqlDialectTranslation-pure/src/main/java/org/finos/legend/pure/code/core/CoreExternalStoreRelationalSqlDialectTranslationDuckDBCodeRepositoryProvider.java
@@ -0,0 +1,29 @@
+// Copyright 2024 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.pure.code.core;
+
+import org.finos.legend.pure.m3.serialization.filesystem.repository.CodeRepository;
+import org.finos.legend.pure.m3.serialization.filesystem.repository.CodeRepositoryProvider;
+import org.finos.legend.pure.m3.serialization.filesystem.repository.GenericCodeRepository;
+
+public class CoreExternalStoreRelationalSqlDialectTranslationDuckDBCodeRepositoryProvider implements CodeRepositoryProvider
+{
+ @Override
+ public CodeRepository repository()
+ {
+ return GenericCodeRepository.build("core_external_store_relational_sql_dialect_translation_duckdb.definition.json");
+ }
+}
+
diff --git a/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-dbExtension/legend-engine-xt-relationalStore-duckdb/legend-engine-xt-relationalStore-duckdb-sqlDialectTranslation-pure/src/main/resources/META-INF/services/org.finos.legend.pure.m3.serialization.filesystem.repository.CodeRepositoryProvider b/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-dbExtension/legend-engine-xt-relationalStore-duckdb/legend-engine-xt-relationalStore-duckdb-sqlDialectTranslation-pure/src/main/resources/META-INF/services/org.finos.legend.pure.m3.serialization.filesystem.repository.CodeRepositoryProvider
new file mode 100644
index 00000000000..03f3448f973
--- /dev/null
+++ b/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-dbExtension/legend-engine-xt-relationalStore-duckdb/legend-engine-xt-relationalStore-duckdb-sqlDialectTranslation-pure/src/main/resources/META-INF/services/org.finos.legend.pure.m3.serialization.filesystem.repository.CodeRepositoryProvider
@@ -0,0 +1 @@
+org.finos.legend.pure.code.core.CoreExternalStoreRelationalSqlDialectTranslationDuckDBCodeRepositoryProvider
\ No newline at end of file
diff --git a/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-dbExtension/legend-engine-xt-relationalStore-duckdb/legend-engine-xt-relationalStore-duckdb-sqlDialectTranslation-pure/src/main/resources/core_external_store_relational_sql_dialect_translation_duckdb.definition.json b/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-dbExtension/legend-engine-xt-relationalStore-duckdb/legend-engine-xt-relationalStore-duckdb-sqlDialectTranslation-pure/src/main/resources/core_external_store_relational_sql_dialect_translation_duckdb.definition.json
new file mode 100644
index 00000000000..3fc3c5aee00
--- /dev/null
+++ b/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-dbExtension/legend-engine-xt-relationalStore-duckdb/legend-engine-xt-relationalStore-duckdb-sqlDialectTranslation-pure/src/main/resources/core_external_store_relational_sql_dialect_translation_duckdb.definition.json
@@ -0,0 +1,19 @@
+{
+ "name": "core_external_store_relational_sql_dialect_translation_duckdb",
+ "pattern": "(meta::external::store::relational::sqlDialectTranslation::duckDB)(::.*)?",
+ "dependencies": [
+ "platform",
+ "platform_dsl_store",
+ "platform_dsl_mapping",
+ "platform_dsl_path",
+ "platform_dsl_graph",
+ "platform_dsl_diagram",
+ "platform_store_relational",
+ "core_functions_standard",
+ "core_functions_unclassified",
+ "core_functions_json",
+ "core",
+ "core_external_store_relational_postgres_sql_model",
+ "core_external_store_relational_sql_dialect_translation"
+ ]
+}
\ No newline at end of file
diff --git a/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-dbExtension/legend-engine-xt-relationalStore-duckdb/legend-engine-xt-relationalStore-duckdb-sqlDialectTranslation-pure/src/main/resources/core_external_store_relational_sql_dialect_translation_duckdb/duckDBSqlDialect.pure b/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-dbExtension/legend-engine-xt-relationalStore-duckdb/legend-engine-xt-relationalStore-duckdb-sqlDialectTranslation-pure/src/main/resources/core_external_store_relational_sql_dialect_translation_duckdb/duckDBSqlDialect.pure
new file mode 100644
index 00000000000..1603ac173b1
--- /dev/null
+++ b/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-dbExtension/legend-engine-xt-relationalStore-duckdb/legend-engine-xt-relationalStore-duckdb-sqlDialectTranslation-pure/src/main/resources/core_external_store_relational_sql_dialect_translation_duckdb/duckDBSqlDialect.pure
@@ -0,0 +1,162 @@
+// Copyright 2024 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.
+
+import meta::external::query::sql::metamodel::*;
+import meta::external::store::relational::sqlDialectTranslation::*;
+import meta::external::store::relational::sqlDialectTranslation::defaults::*;
+import meta::external::store::relational::sqlDialectTranslation::duckDB::*;
+import meta::external::store::relational::sqlDialectTranslation::utils::*;
+import meta::pure::extension::*;
+
+function meta::external::store::relational::sqlDialectTranslation::duckDB::duckDBSqlDialect(): SqlDialect[1]
+{
+ ^SqlDialect
+ (
+ dbType = 'DuckDB',
+ quoteConfig = duckDBQuoteConfiguration(),
+ nodeProcessors = duckDBDialectNodeProcessors(),
+ identifierProcessor = duckDBIdentifierProcessor(),
+ expressionPrecedenceComparator = duckDBExpressionPrecedenceComparator(),
+ keywords = duckDBKeywords()
+ )
+}
+
+
+function meta::external::store::relational::sqlDialectTranslation::duckDB::duckDBSqlDialectExtension(): Extension[1]
+{
+ ^Extension
+ (
+ type = 'DuckDBSqlDialectExtension',
+ moduleExtensions = [
+ ^SqlDialectTranslationModuleExtension
+ (
+ module = sqlDialectTranslationModuleExtensionName(),
+ extraSqlDialects = duckDBSqlDialect()
+ )
+ ]
+ )
+}
+
+function <> meta::external::store::relational::sqlDialectTranslation::duckDB::duckDBQuoteConfiguration(): QuoteConfiguration[1]
+{
+ ^QuoteConfiguration
+ (
+ start = '"',
+ end = '"',
+ escape = '""'
+ )
+}
+
+function <> meta::external::store::relational::sqlDialectTranslation::duckDB::duckDBDialectNodeProcessors(): Map, NodeProcessor>[1]
+{
+ newMap(
+ duckDBDialectStatementProcessors()
+ ->concatenate(
+ duckDBDialectRelationProcessors()
+ )
+ ->concatenate(
+ duckDBDialectExpressionProcessors()
+ )
+ ->concatenate(
+ duckDBDialectLiteralProcessors()
+ )
+ ->concatenate(
+ duckDBDialectSelectItemProcessors()
+ )
+ ->concatenate(
+ duckDBDialectOtherNodeProcessors()
+ )
+ ->map(n | pair($n.nodeType, $n))
+ )
+}
+
+function <> meta::external::store::relational::sqlDialectTranslation::duckDB::duckDBDialectStatementProcessors(): NodeProcessor[*]
+{
+ [
+ queryProcessor_default(),
+ windowProcessor_default()
+ ]
+}
+
+function <> meta::external::store::relational::sqlDialectTranslation::duckDB::duckDBDialectRelationProcessors(): NodeProcessor[*]
+{
+ [
+ tableProcessor_default(),
+ aliasedRelationProcessor_default(),
+ joinProcessor_default(),
+ querySpecificationProcessor_default(),
+ unionProcessor_default()
+ ]
+}
+
+function <> meta::external::store::relational::sqlDialectTranslation::duckDB::duckDBDialectExpressionProcessors(): NodeProcessor[*]
+{
+ [
+ comparisonExpressionNodeProcessor_default(),
+ logicalBinaryExpressionNodeProcessor_default(),
+ notExpressionNodeProcessor_default(),
+ arithmeticExpressionNodeProcessor_default(),
+ columnTypeProcessor_default(),
+ castProcessor_default()
+ ]
+}
+
+function <> meta::external::store::relational::sqlDialectTranslation::duckDB::duckDBDialectLiteralProcessors(): NodeProcessor[*]
+{
+ [
+ integerLiteralNodeProcessor_default(),
+ stringLiteralNodeProcessor_default(),
+ booleanLiteralNodeProcessor_default(),
+ longLiteralNodeProcessor_default(),
+ doubleLiteralNodeProcessor_default(),
+ nullLiteralNodeProcessor_default()
+ ]
+}
+
+function <> meta::external::store::relational::sqlDialectTranslation::duckDB::duckDBDialectSelectItemProcessors(): NodeProcessor[*]
+{
+ [
+ allColumnsNodeProcessor_default(),
+ singleColumnNodeProcessor_default()
+ ]
+}
+
+function <> meta::external::store::relational::sqlDialectTranslation::duckDB::duckDBDialectOtherNodeProcessors(): NodeProcessor[*]
+{
+ [
+ sortItemProcessor_default(),
+ selectProcessor_default()
+ ]
+}
+
+function <> meta::external::store::relational::sqlDialectTranslation::duckDB::duckDBIdentifierProcessor(): IdentifierProcessor[1]
+{
+ identifierProcessor_default()
+}
+
+function <> meta::external::store::relational::sqlDialectTranslation::duckDB::duckDBExpressionPrecedenceComparator(): ExpressionPrecedenceComparator[1]
+{
+ ^ExpressionPrecedenceComparator(
+ findOperatorType = findOperatorType_default_Expression_1__String_1_,
+ operatorPrecedence = operatorPrecedence_default()
+ )
+}
+
+function <> meta::external::store::relational::sqlDialectTranslation::duckDB::duckDBKeywords(): String[*]
+{
+ [
+ // TODO: Update
+ 'date'
+ ]
+}
diff --git a/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-dbExtension/legend-engine-xt-relationalStore-duckdb/legend-engine-xt-relationalStore-duckdb-sqlDialectTranslation-pure/src/test/java/org/finos/legend/engine/relational/sdt/duckdb/Test_DuckDB_SDT.java b/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-dbExtension/legend-engine-xt-relationalStore-duckdb/legend-engine-xt-relationalStore-duckdb-sqlDialectTranslation-pure/src/test/java/org/finos/legend/engine/relational/sdt/duckdb/Test_DuckDB_SDT.java
new file mode 100644
index 00000000000..d6e840bbcb5
--- /dev/null
+++ b/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-dbExtension/legend-engine-xt-relationalStore-duckdb/legend-engine-xt-relationalStore-duckdb-sqlDialectTranslation-pure/src/test/java/org/finos/legend/engine/relational/sdt/duckdb/Test_DuckDB_SDT.java
@@ -0,0 +1,35 @@
+// Copyright 2024 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.relational.sdt.duckdb;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+import org.eclipse.collections.api.factory.Lists;
+import org.eclipse.collections.api.factory.Maps;
+import org.finos.legend.engine.relational.test.sdt.SdtTestSuiteBuilder;
+
+import static org.finos.legend.pure.generated.core_external_store_relational_sql_dialect_translation_duckdb_duckDBSqlDialect.Root_meta_external_store_relational_sqlDialectTranslation_duckDB_duckDBSqlDialectExtension__Extension_1_;
+
+public class Test_DuckDB_SDT extends TestSuite
+{
+ public static Test suite()
+ {
+ return SdtTestSuiteBuilder.buildSdtTestSuite(
+ "DuckDB",
+ es -> Lists.immutable.of(Root_meta_external_store_relational_sqlDialectTranslation_duckDB_duckDBSqlDialectExtension__Extension_1_(es)),
+ Maps.mutable.empty()
+ );
+ }
+}
diff --git a/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-dbExtension/legend-engine-xt-relationalStore-duckdb/legend-engine-xt-relationalStore-duckdb-sqlDialectTranslation-pure/src/test/java/org/finos/legend/pure/code/core/Test_Pure_ExternalStoreRelationalSqlDialectTranslationDuckDB.java b/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-dbExtension/legend-engine-xt-relationalStore-duckdb/legend-engine-xt-relationalStore-duckdb-sqlDialectTranslation-pure/src/test/java/org/finos/legend/pure/code/core/Test_Pure_ExternalStoreRelationalSqlDialectTranslationDuckDB.java
new file mode 100644
index 00000000000..63b90f9b6dd
--- /dev/null
+++ b/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-dbExtension/legend-engine-xt-relationalStore-duckdb/legend-engine-xt-relationalStore-duckdb-sqlDialectTranslation-pure/src/test/java/org/finos/legend/pure/code/core/Test_Pure_ExternalStoreRelationalSqlDialectTranslationDuckDB.java
@@ -0,0 +1,32 @@
+// Copyright 2024 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.pure.code.core;
+
+import junit.framework.TestSuite;
+import org.finos.legend.pure.m3.execution.test.PureTestBuilder;
+import org.finos.legend.pure.m3.execution.test.TestCollection;
+import org.finos.legend.pure.runtime.java.compiled.execution.CompiledExecutionSupport;
+import org.finos.legend.pure.runtime.java.compiled.testHelper.PureTestBuilderCompiled;
+
+public class Test_Pure_ExternalStoreRelationalSqlDialectTranslationDuckDB
+{
+ public static TestSuite suite()
+ {
+ CompiledExecutionSupport executionSupport = PureTestBuilderCompiled.getClassLoaderExecutionSupport();
+ TestSuite suite = new TestSuite();
+ suite.addTest(PureTestBuilderCompiled.buildSuite(TestCollection.collectTests("meta::external::store::relational::sqlDialectTranslation::duckDB", executionSupport.getProcessorSupport(), fn -> PureTestBuilderCompiled.generatePureTestCollection(fn, executionSupport), ci -> PureTestBuilder.satisfiesConditions(ci, executionSupport.getProcessorSupport())), executionSupport));
+ return suite;
+ }
+}
diff --git a/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-dbExtension/legend-engine-xt-relationalStore-duckdb/pom.xml b/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-dbExtension/legend-engine-xt-relationalStore-duckdb/pom.xml
index 1fafd936735..f27d3ae5b10 100644
--- a/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-dbExtension/legend-engine-xt-relationalStore-duckdb/pom.xml
+++ b/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-dbExtension/legend-engine-xt-relationalStore-duckdb/pom.xml
@@ -18,6 +18,7 @@
legend-engine-xt-relationalStore-duckdb-grammar
legend-engine-xt-relationalStore-duckdb-protocol
legend-engine-xt-relationalStore-duckdb-pure
+ legend-engine-xt-relationalStore-duckdb-sqlDialectTranslation-pure
diff --git a/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-execution/legend-engine-xt-relationalStore-executionPlan/pom.xml b/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-execution/legend-engine-xt-relationalStore-executionPlan/pom.xml
index df6d7ac3a9c..cc48a627922 100644
--- a/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-execution/legend-engine-xt-relationalStore-executionPlan/pom.xml
+++ b/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-execution/legend-engine-xt-relationalStore-executionPlan/pom.xml
@@ -294,11 +294,6 @@
legend-pure-m2-dsl-mapping-grammar
test
-
- org.finos.legend.engine
- legend-engine-configuration-contract-extension-pure
- test
-
org.finos.legend.engine
legend-engine-xt-javaPlatformBinding-pure
diff --git a/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-generation/legend-engine-xt-relationalStore-pure/legend-engine-xt-relationalStore-SDT-pure/pom.xml b/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-generation/legend-engine-xt-relationalStore-pure/legend-engine-xt-relationalStore-SDT-pure/pom.xml
new file mode 100644
index 00000000000..f04e7dc6bfd
--- /dev/null
+++ b/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-generation/legend-engine-xt-relationalStore-pure/legend-engine-xt-relationalStore-SDT-pure/pom.xml
@@ -0,0 +1,245 @@
+
+
+
+
+
+ org.finos.legend.engine
+ legend-engine-xt-relationalStore-pure
+ 4.63.2-SNAPSHOT
+
+ 4.0.0
+
+ legend-engine-xt-relationalStore-SDT-pure
+ jar
+ Legend Engine - XT - Relational Store - SDT - PAR/JAVA
+
+
+
+
+ org.finos.legend.pure
+ legend-pure-maven-generation-par
+
+ src/main/resources
+ ${legend.pure.version}
+
+ core_external_store_relational_sdt
+
+
+ ${project.basedir}/src/main/resources/core_external_store_relational_sdt.definition.json
+
+
+
+
+ generate-sources
+
+ build-pure-jar
+
+
+
+
+
+ org.finos.legend.pure
+ legend-pure-m2-dsl-diagram-grammar
+ ${legend.pure.version}
+
+
+ org.finos.legend.engine
+ legend-engine-pure-code-compiled-core
+ ${project.version}
+
+
+ org.finos.legend.engine
+ legend-engine-xt-relationalStore-postgresSqlModel-pure
+ ${project.version}
+
+
+ org.finos.legend.engine
+ legend-engine-xt-relationalStore-sqlDialectTranslation-pure
+ ${project.version}
+
+
+
+
+ org.finos.legend.pure
+ legend-pure-maven-generation-java
+
+
+ compile
+
+ build-pure-compiled-jar
+
+
+ true
+ true
+ modular
+ true
+
+ core_external_store_relational_sdt
+
+
+
+
+
+
+ org.finos.legend.pure
+ legend-pure-m2-dsl-diagram-grammar
+ ${legend.pure.version}
+
+
+ org.finos.legend.engine
+ legend-engine-pure-code-compiled-core
+ ${project.version}
+
+
+ org.finos.legend.engine
+ legend-engine-xt-relationalStore-postgresSqlModel-pure
+ ${project.version}
+
+
+ org.finos.legend.engine
+ legend-engine-xt-relationalStore-sqlDialectTranslation-pure
+ ${project.version}
+
+
+
+
+ maven-surefire-plugin
+
+ false
+
+ **/Test_Postgres_SDT*.java
+ **/SdtTestSuiteBuilder*.java
+
+
+
+
+ org.apache.maven.plugins
+ maven-jar-plugin
+
+
+
+ test-jar
+
+
+
+
+
+
+
+
+
+
+ org.finos.legend.pure
+ legend-pure-m4
+
+
+ org.finos.legend.pure
+ legend-pure-m3-core
+
+
+ org.finos.legend.pure
+ legend-pure-runtime-java-engine-compiled
+
+
+ org.finos.legend.pure
+ legend-pure-runtime-java-engine-interpreted
+
+
+ org.finos.legend.pure
+ legend-pure-m2-store-relational-pure
+
+
+ org.finos.legend.pure
+ legend-pure-runtime-java-extension-interpreted-store-relational
+
+
+ org.finos.legend.pure
+ legend-pure-runtime-java-extension-compiled-store-relational
+
+
+
+
+
+ org.finos.legend.engine
+ legend-engine-pure-platform-java
+
+
+ org.finos.legend.engine
+ legend-engine-pure-platform-store-relational-java
+
+
+ org.finos.legend.engine
+ legend-engine-pure-runtime-java-extension-compiled-functions-unclassified
+
+
+ org.finos.legend.engine
+ legend-engine-pure-code-compiled-core
+
+
+ org.finos.legend.engine
+ legend-engine-xt-relationalStore-postgresSqlModel-pure
+
+
+ org.finos.legend.engine
+ legend-engine-xt-relationalStore-sqlDialectTranslation-pure
+
+
+ org.finos.legend.engine
+ legend-engine-xt-relationalStore-protocol
+
+
+ org.finos.legend.engine
+ legend-engine-xt-relationalStore-executionPlan
+
+
+ org.finos.legend.engine
+ legend-engine-xt-relationalStore-executionPlan-connection
+
+
+ org.finos.legend.engine
+ legend-engine-xt-relationalStore-executionPlan-connection-authentication-default
+
+
+
+
+ org.eclipse.collections
+ eclipse-collections
+
+
+ org.eclipse.collections
+ eclipse-collections-api
+
+
+
+
+ junit
+ junit
+
+
+ org.finos.legend.engine
+ legend-engine-test-framework
+ test
+
+
+ org.finos.legend.engine
+ legend-engine-xt-relationalStore-postgres-PCT
+ test
+
+
+
+
+
\ No newline at end of file
diff --git a/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-generation/legend-engine-xt-relationalStore-pure/legend-engine-xt-relationalStore-SDT-pure/src/main/java/org/finos/legend/engine/pure/runtime/relational/sdt/RunSqlDialectTestQueryHelper.java b/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-generation/legend-engine-xt-relationalStore-pure/legend-engine-xt-relationalStore-SDT-pure/src/main/java/org/finos/legend/engine/pure/runtime/relational/sdt/RunSqlDialectTestQueryHelper.java
new file mode 100644
index 00000000000..baf051e5c95
--- /dev/null
+++ b/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-generation/legend-engine-xt-relationalStore-pure/legend-engine-xt-relationalStore-SDT-pure/src/main/java/org/finos/legend/engine/pure/runtime/relational/sdt/RunSqlDialectTestQueryHelper.java
@@ -0,0 +1,96 @@
+// Copyright 2024 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.pure.runtime.relational.sdt;
+
+import org.eclipse.collections.api.RichIterable;
+import org.eclipse.collections.api.block.function.Function;
+import org.finos.legend.engine.authentication.LegendDefaultDatabaseAuthenticationFlowProvider;
+import org.finos.legend.engine.authentication.LegendDefaultDatabaseAuthenticationFlowProviderConfiguration;
+import org.finos.legend.engine.plan.execution.stores.relational.config.TemporaryTestDbConfiguration;
+import org.finos.legend.engine.plan.execution.stores.relational.connection.manager.ConnectionManagerSelector;
+import org.finos.legend.engine.plan.execution.stores.relational.connection.tests.api.TestConnectionIntegration;
+import org.finos.legend.engine.plan.execution.stores.relational.connection.tests.api.TestConnectionIntegrationLoader;
+import org.finos.legend.engine.protocol.pure.v1.model.packageableElement.store.relational.connection.DatabaseType;
+import org.finos.legend.engine.protocol.pure.v1.model.packageableElement.store.relational.connection.RelationalDatabaseConnection;
+import org.finos.legend.pure.m3.exception.PureExecutionException;
+
+import javax.security.auth.Subject;
+import java.sql.Connection;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.Collections;
+import java.util.Optional;
+
+public class RunSqlDialectTestQueryHelper
+{
+ private RunSqlDialectTestQueryHelper()
+ {
+
+ }
+
+ public static T runTestQueryAndTransformResultSet(String dbType, String testQuery, RichIterable extends String> setupSqls, RichIterable extends String> teardownSqls, Function resultSetTransformFunction) throws SQLException
+ {
+ TestConnectionIntegration found = TestConnectionIntegrationLoader.extensions().select(c -> c.getDatabaseType() == DatabaseType.valueOf(dbType)).getFirst();
+ if (found == null)
+ {
+ throw new PureExecutionException("Can't find a TestConnectionIntegration for dbType " + dbType + ". Available ones are " + TestConnectionIntegrationLoader.extensions().collect(c -> c.getDatabaseType().name()));
+ }
+ RelationalDatabaseConnection relationalDatabaseConnection = found.getConnection();
+
+ Connection connection = null;
+ Statement statement = null;
+ try
+ {
+ LegendDefaultDatabaseAuthenticationFlowProvider flowProvider = new LegendDefaultDatabaseAuthenticationFlowProvider();
+ flowProvider.configure(new LegendDefaultDatabaseAuthenticationFlowProviderConfiguration());
+ ConnectionManagerSelector connectionManagerSelector = new ConnectionManagerSelector(new TemporaryTestDbConfiguration(-1), Collections.emptyList(), Optional.of(flowProvider));
+ connection = connectionManagerSelector.getDatabaseConnection((Subject) null, relationalDatabaseConnection);
+ statement = connection.createStatement();
+
+ for (String s : setupSqls)
+ {
+ statement.execute(s);
+ }
+
+ try (ResultSet resultSet = statement.executeQuery(testQuery))
+ {
+ return resultSetTransformFunction.apply(resultSet);
+ }
+ }
+ finally
+ {
+ if (statement != null)
+ {
+ for (String s : teardownSqls)
+ {
+ try
+ {
+ statement.execute(s);
+ }
+ catch (Exception e)
+ {
+ // Run remaining teardown stmts without failing
+ System.out.println(e.getMessage());
+ }
+ }
+
+ statement.close();
+ connection.close();
+ }
+ }
+ }
+}
diff --git a/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-generation/legend-engine-xt-relationalStore-pure/legend-engine-xt-relationalStore-SDT-pure/src/main/java/org/finos/legend/engine/pure/runtime/relational/sdt/compiled/RunSqlDialectTestQueryCompiledExtension.java b/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-generation/legend-engine-xt-relationalStore-pure/legend-engine-xt-relationalStore-SDT-pure/src/main/java/org/finos/legend/engine/pure/runtime/relational/sdt/compiled/RunSqlDialectTestQueryCompiledExtension.java
new file mode 100644
index 00000000000..7e525996f55
--- /dev/null
+++ b/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-generation/legend-engine-xt-relationalStore-pure/legend-engine-xt-relationalStore-SDT-pure/src/main/java/org/finos/legend/engine/pure/runtime/relational/sdt/compiled/RunSqlDialectTestQueryCompiledExtension.java
@@ -0,0 +1,120 @@
+// Copyright 2024 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.pure.runtime.relational.sdt.compiled;
+
+import org.eclipse.collections.api.RichIterable;
+import org.eclipse.collections.api.block.function.Function;
+import org.eclipse.collections.api.factory.Lists;
+import org.eclipse.collections.api.list.ListIterable;
+import org.eclipse.collections.api.list.MutableList;
+import org.eclipse.collections.impl.list.mutable.FastList;
+import org.finos.legend.engine.pure.runtime.relational.sdt.RunSqlDialectTestQueryHelper;
+import org.finos.legend.pure.generated.Root_meta_relational_metamodel_SQLNull_Impl;
+import org.finos.legend.pure.generated.Root_meta_relational_metamodel_execute_ResultSet;
+import org.finos.legend.pure.generated.Root_meta_relational_metamodel_execute_ResultSet_Impl;
+import org.finos.legend.pure.generated.Root_meta_relational_metamodel_execute_Row;
+import org.finos.legend.pure.generated.Root_meta_relational_metamodel_execute_Row_Impl;
+import org.finos.legend.pure.m3.coreinstance.meta.relational.metamodel.SQLNull;
+import org.finos.legend.pure.m3.exception.PureExecutionException;
+import org.finos.legend.pure.m4.coreinstance.CoreInstance;
+import org.finos.legend.pure.runtime.java.compiled.execution.CompiledExecutionSupport;
+import org.finos.legend.pure.runtime.java.compiled.extension.BaseCompiledExtension;
+import org.finos.legend.pure.runtime.java.compiled.generation.ProcessorContext;
+import org.finos.legend.pure.runtime.java.compiled.generation.processors.natives.AbstractNative;
+import org.finos.legend.pure.runtime.java.extension.store.relational.compiled.RelationalNativeImplementation;
+import org.finos.legend.pure.runtime.java.extension.store.relational.compiled.natives.ResultSetValueHandlers;
+
+import java.sql.ResultSet;
+import java.sql.ResultSetMetaData;
+import java.sql.SQLException;
+import java.util.GregorianCalendar;
+import java.util.TimeZone;
+
+public class RunSqlDialectTestQueryCompiledExtension extends BaseCompiledExtension
+{
+ public RunSqlDialectTestQueryCompiledExtension()
+ {
+ super(
+ "core_external_store_relational_sdt",
+ () -> Lists.fixedSize.with(new RunSqlDialectTestQuery()),
+ Lists.fixedSize.with(),
+ Lists.fixedSize.empty(),
+ Lists.fixedSize.empty());
+ }
+
+ public static class RunSqlDialectTestQuery extends AbstractNative
+ {
+ public RunSqlDialectTestQuery()
+ {
+ super("runSqlDialectTestQuery_String_1__String_1__String_MANY__String_MANY__ResultSet_1_");
+ }
+
+ @Override
+ public String build(CoreInstance topLevelElement, CoreInstance functionExpression, ListIterable transformedParams, ProcessorContext processorContext)
+ {
+ return "org.finos.legend.engine.pure.runtime.relational.sdt.compiled.RunSqlDialectTestQueryCompiledExtension.RunSqlDialectTestQuery.compileExec(" +
+ transformedParams.get(0) + ", " + // DB Type
+ transformedParams.get(1) + ", " + // Test Query
+ transformedParams.get(2) + ", " + // Setup Sqls
+ transformedParams.get(3) + ", " + // Teardown Sqls
+ "(CompiledExecutionSupport) es)";
+ }
+
+ public static Root_meta_relational_metamodel_execute_ResultSet compileExec(String dbType, String testQuery, RichIterable extends String> setupSqls, RichIterable extends String> teardownSqls, CompiledExecutionSupport es)
+ {
+ Function transformer = (resultSet) ->
+ {
+ try
+ {
+ ResultSetMetaData resultSetMetaData = resultSet.getMetaData();
+ Root_meta_relational_metamodel_execute_ResultSet pureResult = new Root_meta_relational_metamodel_execute_ResultSet_Impl("");
+ SQLNull sqlNull = new Root_meta_relational_metamodel_SQLNull_Impl("SQLNull");
+
+ int count = resultSetMetaData.getColumnCount();
+ MutableList columns = FastList.newList(count);
+ for (int i = 1; i <= count; i++)
+ {
+ String column = resultSetMetaData.getColumnLabel(i);
+ columns.add(column);
+ }
+ pureResult._columnNames(columns);
+
+ ListIterable handlers = ResultSetValueHandlers.getHandlers(resultSetMetaData);
+ MutableList rows = FastList.newList();
+ while (resultSet.next())
+ {
+ MutableList
+
+
+
org.finos.legend.engine
legend-engine-pure-platform-java
-
-
-
+
+ org.finos.legend.engine
+ legend-engine-pure-runtime-java-extension-compiled-functions-unclassified
+
org.finos.legend.engine
legend-engine-pure-code-compiled-core
diff --git a/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-generation/legend-engine-xt-relationalStore-pure/legend-engine-xt-relationalStore-sqlDialectTranslation-pure/src/main/resources/core_external_store_relational_sql_dialect_translation.definition.json b/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-generation/legend-engine-xt-relationalStore-pure/legend-engine-xt-relationalStore-sqlDialectTranslation-pure/src/main/resources/core_external_store_relational_sql_dialect_translation.definition.json
index a79c88db8b3..649ebfe67ab 100644
--- a/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-generation/legend-engine-xt-relationalStore-pure/legend-engine-xt-relationalStore-sqlDialectTranslation-pure/src/main/resources/core_external_store_relational_sql_dialect_translation.definition.json
+++ b/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-generation/legend-engine-xt-relationalStore-pure/legend-engine-xt-relationalStore-sqlDialectTranslation-pure/src/main/resources/core_external_store_relational_sql_dialect_translation.definition.json
@@ -3,6 +3,15 @@
"pattern": "(meta::external::store::relational::sqlDialectTranslation)(::.*)?",
"dependencies": [
"platform",
+ "platform_dsl_store",
+ "platform_dsl_mapping",
+ "platform_dsl_path",
+ "platform_dsl_graph",
+ "platform_dsl_diagram",
+ "platform_store_relational",
+ "core_functions_standard",
+ "core_functions_unclassified",
+ "core_functions_json",
"core",
"core_external_store_relational_postgres_sql_model"
]
diff --git a/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-generation/legend-engine-xt-relationalStore-pure/legend-engine-xt-relationalStore-sqlDialectTranslation-pure/src/main/resources/core_external_store_relational_sql_dialect_translation/defaults/sqlDialectDefaults.pure b/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-generation/legend-engine-xt-relationalStore-pure/legend-engine-xt-relationalStore-sqlDialectTranslation-pure/src/main/resources/core_external_store_relational_sql_dialect_translation/defaults/sqlDialectDefaults.pure
new file mode 100644
index 00000000000..36d4f06b74b
--- /dev/null
+++ b/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-generation/legend-engine-xt-relationalStore-pure/legend-engine-xt-relationalStore-sqlDialectTranslation-pure/src/main/resources/core_external_store_relational_sql_dialect_translation/defaults/sqlDialectDefaults.pure
@@ -0,0 +1,729 @@
+// Copyright 2024 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.
+
+import meta::external::query::sql::metamodel::*;
+import meta::external::store::relational::sqlDialectTranslation::*;
+import meta::external::store::relational::sqlDialectTranslation::defaults::*;
+import meta::external::store::relational::sqlDialectTranslation::utils::*;
+
+Enum meta::external::store::relational::sqlDialectTranslation::defaults::SqlOperatorTypes_default
+{
+ DOT, // .
+ TYPECAST, // ::
+ ARRAY_ELEMENT_SELECTION, // []
+ UNARY_PLUS_MINUS, // + , -
+ COLLATE,
+ AT,
+ EXPONENTIATION, // ^
+ MULTIPLICATION_DIVISION_MODULO, // * , /, %
+ ADDITION_SUBTRACTION, // + , -
+ OTHER_NATIVE_USER_DEFINED_OPERATOR,
+ BETWEEN,
+ IN,
+ STRING_MATCH, // Like, Similar, Regex
+ BASIC_COMPARISON, // < > = <= >= <>
+ IS_CHECK, // IS NULL, IS NOT NULL, IS DISTINCT FROM etc.
+ NOT,
+ AND,
+ OR
+}
+
+function meta::external::store::relational::sqlDialectTranslation::defaults::findOperatorType_default(e: meta::external::query::sql::metamodel::Expression[1]): String[1]
+{
+ $e->match([
+ {c: ComparisonExpression[1] |
+ if(
+ [
+ pair(|$c.operator == ComparisonOperator.EQUAL, | SqlOperatorTypes_default.BASIC_COMPARISON),
+ pair(|$c.operator == ComparisonOperator.NOT_EQUAL, | SqlOperatorTypes_default.BASIC_COMPARISON),
+ pair(|$c.operator == ComparisonOperator.LESS_THAN, | SqlOperatorTypes_default.BASIC_COMPARISON),
+ pair(|$c.operator == ComparisonOperator.LESS_THAN_OR_EQUAL, | SqlOperatorTypes_default.BASIC_COMPARISON),
+ pair(|$c.operator == ComparisonOperator.GREATER_THAN, | SqlOperatorTypes_default.BASIC_COMPARISON),
+ pair(|$c.operator == ComparisonOperator.GREATER_THAN_OR_EQUAL, | SqlOperatorTypes_default.BASIC_COMPARISON),
+ pair(|$c.operator == ComparisonOperator.IS_DISTINCT_FROM, | SqlOperatorTypes_default.IS_CHECK),
+ pair(|$c.operator == ComparisonOperator.IS_NOT_DISTINCT_FROM, | SqlOperatorTypes_default.IS_CHECK),
+ pair(|$c.operator == ComparisonOperator.REGEX_MATCH, | SqlOperatorTypes_default.STRING_MATCH),
+ pair(|$c.operator == ComparisonOperator.REGEX_MATCH_CI, | SqlOperatorTypes_default.STRING_MATCH),
+ pair(|$c.operator == ComparisonOperator.REGEX_NO_MATCH, | SqlOperatorTypes_default.STRING_MATCH),
+ pair(|$c.operator == ComparisonOperator.REGEX_NO_MATCH_CI, | SqlOperatorTypes_default.STRING_MATCH),
+ pair(|$c.operator == ComparisonOperator.LIKE, | SqlOperatorTypes_default.STRING_MATCH),
+ pair(|$c.operator == ComparisonOperator.ILIKE, | SqlOperatorTypes_default.STRING_MATCH),
+ pair(|$c.operator == ComparisonOperator.NOT_LIKE, | SqlOperatorTypes_default.STRING_MATCH),
+ pair(|$c.operator == ComparisonOperator.NOT_ILIKE, | SqlOperatorTypes_default.STRING_MATCH)
+ ],
+ | fail('Unhandled comparator type: ' + $c.operator->toString()); SqlOperatorTypes_default.OTHER_NATIVE_USER_DEFINED_OPERATOR;
+ );
+ },
+ {l: LogicalBinaryExpression[1] |
+ if(
+ [
+ pair(|$l.type == LogicalBinaryType.AND, | SqlOperatorTypes_default.AND),
+ pair(|$l.type == LogicalBinaryType.OR, | SqlOperatorTypes_default.OR)
+ ],
+ | fail('Unhandled logical binary expression type: ' + $l.type->toString()); SqlOperatorTypes_default.OTHER_NATIVE_USER_DEFINED_OPERATOR;
+ );
+ },
+ {l: NotExpression[1] | SqlOperatorTypes_default.NOT},
+ {a: ArithmeticExpression[1] |
+ if(
+ [
+ pair(|$a.type == ArithmeticType.ADD, | SqlOperatorTypes_default.ADDITION_SUBTRACTION),
+ pair(|$a.type == ArithmeticType.SUBTRACT, | SqlOperatorTypes_default.ADDITION_SUBTRACTION),
+ pair(|$a.type == ArithmeticType.MULTIPLY, | SqlOperatorTypes_default.MULTIPLICATION_DIVISION_MODULO),
+ pair(|$a.type == ArithmeticType.DIVIDE, | SqlOperatorTypes_default.MULTIPLICATION_DIVISION_MODULO),
+ pair(|$a.type == ArithmeticType.MODULUS, | SqlOperatorTypes_default.MULTIPLICATION_DIVISION_MODULO),
+ pair(|$a.type == ArithmeticType.POWER, | SqlOperatorTypes_default.EXPONENTIATION)
+ ],
+ | fail('Unhandled arithemtic expression type: ' + $a.type->toString()); SqlOperatorTypes_default.OTHER_NATIVE_USER_DEFINED_OPERATOR;
+ );
+ },
+ {q: QualifiedNameReference[1] | SqlOperatorTypes_default.DOT},
+ {i: IsNullPredicate[1] | SqlOperatorTypes_default.IS_CHECK},
+ {i: IsNotNullPredicate[1] | SqlOperatorTypes_default.IS_CHECK},
+ {i: NegativeExpression[1] | SqlOperatorTypes_default.UNARY_PLUS_MINUS},
+ {i: InPredicate[1] | SqlOperatorTypes_default.IN},
+ {b: BetweenPredicate[1] | SqlOperatorTypes_default.BETWEEN},
+ a: meta::external::query::sql::metamodel::Expression[1] | fail('Unknown expression type - ' + $e->class()->elementToPath()); SqlOperatorTypes_default.OTHER_NATIVE_USER_DEFINED_OPERATOR;
+ ])->toString()
+}
+
+function meta::external::store::relational::sqlDialectTranslation::defaults::operatorPrecedence_default(): Map[1]
+{
+ // https://www.postgresql.org/docs/current/sql-syntax-lexical.html#SQL-PRECEDENCE
+
+ let operatorPrecedenceOrder = [
+ SqlOperatorTypes_default.DOT->toString(),
+ SqlOperatorTypes_default.TYPECAST->toString(),
+ SqlOperatorTypes_default.ARRAY_ELEMENT_SELECTION->toString(),
+ SqlOperatorTypes_default.UNARY_PLUS_MINUS->toString(),
+ SqlOperatorTypes_default.COLLATE->toString(),
+ SqlOperatorTypes_default.AT->toString(),
+ SqlOperatorTypes_default.EXPONENTIATION->toString(),
+ SqlOperatorTypes_default.MULTIPLICATION_DIVISION_MODULO->toString(),
+ SqlOperatorTypes_default.ADDITION_SUBTRACTION->toString(),
+ SqlOperatorTypes_default.OTHER_NATIVE_USER_DEFINED_OPERATOR->toString(),
+ SqlOperatorTypes_default.BETWEEN->toString(),
+ SqlOperatorTypes_default.IN->toString(),
+ SqlOperatorTypes_default.STRING_MATCH->toString(),
+ SqlOperatorTypes_default.BASIC_COMPARISON->toString(),
+ SqlOperatorTypes_default.IS_CHECK->toString(),
+ SqlOperatorTypes_default.NOT->toString(),
+ SqlOperatorTypes_default.AND->toString(),
+ SqlOperatorTypes_default.OR->toString()
+ ];
+
+ $operatorPrecedenceOrder->zip($operatorPrecedenceOrder->size()->range())->newMap();
+}
+
+function meta::external::store::relational::sqlDialectTranslation::defaults::identifierProcessor_default(): IdentifierProcessor[1]
+{
+ identifierProcessor
+ (
+ {sqlDialect, identifier, shouldQuote, state, config |
+ if ($shouldQuote || $identifier->in($sqlDialect.keywords),
+ | if ($sqlDialect.quoteConfig->isEmpty(),
+ | // Quoting configuration unknown. Hence returning the identifier as is
+ $identifier,
+ | let quoteCfg = $sqlDialect.quoteConfig->toOne();
+ $quoteCfg.start + $identifier->replace($quoteCfg.end, $quoteCfg.escape) + $quoteCfg.end;
+ ),
+ | $identifier
+ )
+ }
+ )
+}
+
+function meta::external::store::relational::sqlDialectTranslation::defaults::integerLiteralNodeProcessor_default(): NodeProcessor[1]
+{
+ nodeProcessor(
+ IntegerLiteral,
+ {sqlDialect, i, state, config |
+ $i.value->toString()
+ },
+ {n | true}
+ )
+}
+
+function meta::external::store::relational::sqlDialectTranslation::defaults::stringLiteralNodeProcessor_default(): NodeProcessor[1]
+{
+ nodeProcessor(
+ StringLiteral,
+ {sqlDialect, s, state, config |
+ '\'' + $s.value->replace('\'', '\'\'') + '\''
+ },
+ {n | true}
+ )
+}
+
+function meta::external::store::relational::sqlDialectTranslation::defaults::booleanLiteralNodeProcessor_default(): NodeProcessor[1]
+{
+ nodeProcessor(
+ BooleanLiteral,
+ {sqlDialect, s, state, config |
+ $sqlDialect->keyword(if($s.value , | 'true', | 'false'), $state, $config)
+ },
+ {n | true}
+ )
+}
+
+function meta::external::store::relational::sqlDialectTranslation::defaults::longLiteralNodeProcessor_default(): NodeProcessor[1]
+{
+ nodeProcessor(
+ LongLiteral,
+ {sqlDialect, l, state, config |
+ $l.value->toString()
+ },
+ {n | true}
+ )
+}
+
+function meta::external::store::relational::sqlDialectTranslation::defaults::doubleLiteralNodeProcessor_default(): NodeProcessor[1]
+{
+ nodeProcessor(
+ DoubleLiteral,
+ {sqlDialect, d, state, config |
+ $d.value->toString()
+ },
+ {n | true}
+ )
+}
+
+function meta::external::store::relational::sqlDialectTranslation::defaults::nullLiteralNodeProcessor_default(): NodeProcessor[1]
+{
+ nodeProcessor(
+ NullLiteral,
+ {sqlDialect, d, state, config |
+ $sqlDialect->keyword('null', $state, $config)
+ },
+ {n | true}
+ )
+}
+
+function meta::external::store::relational::sqlDialectTranslation::defaults::allColumnsNodeProcessor_default(): NodeProcessor[1]
+{
+ nodeProcessor(
+ AllColumns,
+ {sqlDialect, a, state, config |
+ let prefix = if ($a.prefix->isNotEmpty(), | $sqlDialect->executeIdentifierProcessor($a.prefix->toOne(), false, $state, $config) + '.', | '');
+ $prefix + '*';
+ }
+ )
+}
+
+function meta::external::store::relational::sqlDialectTranslation::defaults::singleColumnNodeProcessor_default(): NodeProcessor[1]
+{
+ nodeProcessor(
+ SingleColumn,
+ {sqlDialect, s, state, config |
+ let suffix = if ($s.alias->isNotEmpty(),
+ | ' ' + $sqlDialect->keyword('as', $state, $config) + ' ' + $sqlDialect->executeIdentifierProcessor($s.alias->toOne(), false, $state, $config),
+ | ''
+ );
+ $sqlDialect->executeNodeProcessor($s.expression, $state, $config) + $suffix;
+ }
+ )
+}
+
+function meta::external::store::relational::sqlDialectTranslation::defaults::comparisonExpressionNodeProcessor_default(): NodeProcessor[1]
+{
+ nodeProcessor(
+ ComparisonExpression,
+ {sqlDialect, c, state, config |
+ let leftExpr = $sqlDialect->executeNodeProcessor($c.left, $c, $state, $config);
+ let rightExpr = $sqlDialect->executeNodeProcessor($c.right, $c, $state, $config);
+ let comparator = if(
+ [
+ pair(|$c.operator == ComparisonOperator.EQUAL, | '='),
+ pair(|$c.operator == ComparisonOperator.NOT_EQUAL, | '<>'),
+ pair(|$c.operator == ComparisonOperator.LESS_THAN, | '<'),
+ pair(|$c.operator == ComparisonOperator.LESS_THAN_OR_EQUAL, | '<='),
+ pair(|$c.operator == ComparisonOperator.GREATER_THAN, | '>'),
+ pair(|$c.operator == ComparisonOperator.GREATER_THAN_OR_EQUAL, | '>='),
+ pair(|$c.operator == ComparisonOperator.IS_DISTINCT_FROM, | $sqlDialect->keyword('is distinct from', $state, $config)),
+ pair(|$c.operator == ComparisonOperator.IS_NOT_DISTINCT_FROM, | $sqlDialect->keyword('is not distinct from', $state, $config)),
+ pair(|$c.operator == ComparisonOperator.REGEX_MATCH, | '~'),
+ pair(|$c.operator == ComparisonOperator.REGEX_MATCH_CI, | '~*'),
+ pair(|$c.operator == ComparisonOperator.REGEX_NO_MATCH, | '!~'),
+ pair(|$c.operator == ComparisonOperator.REGEX_NO_MATCH_CI, | '!~*'),
+ pair(|$c.operator == ComparisonOperator.LIKE, | '~~'),
+ pair(|$c.operator == ComparisonOperator.ILIKE, | '~~*'),
+ pair(|$c.operator == ComparisonOperator.NOT_LIKE, | '!~~'),
+ pair(|$c.operator == ComparisonOperator.NOT_ILIKE, | '!~~*')
+ ],
+ | failWithMessage('Unhandled comparator type: ' + $c.operator->toString())
+ );
+
+ $leftExpr + ' ' + $comparator + ' ' + $rightExpr;
+ }
+ )
+}
+
+function meta::external::store::relational::sqlDialectTranslation::defaults::logicalBinaryExpressionNodeProcessor_default(): NodeProcessor[1]
+{
+ nodeProcessor(
+ LogicalBinaryExpression,
+ {sqlDialect, l, state, config |
+ let leftExpr = $sqlDialect->executeNodeProcessor($l.left, $l, $state, $config);
+ let rightExpr = $sqlDialect->executeNodeProcessor($l.right, $l, $state, $config);
+ if(
+ [
+ pair(|$l.type == LogicalBinaryType.AND, | $leftExpr + ' ' + $sqlDialect->keyword('and', $state, $config) + ' ' + $rightExpr;),
+ pair(|$l.type == LogicalBinaryType.OR, | $leftExpr + ' ' + $sqlDialect->keyword('or', $state, $config) + ' ' + $rightExpr;)
+ ],
+ | failWithMessage('Unhandled binary expression type: ' + $l.type->toString())
+ );
+ }
+ )
+}
+
+function meta::external::store::relational::sqlDialectTranslation::defaults::notExpressionNodeProcessor_default(): NodeProcessor[1]
+{
+ nodeProcessor(
+ NotExpression,
+ {sqlDialect, e, state, config |
+ $sqlDialect->keyword('not', $state, $config) + ' ' + $sqlDialect->executeNodeProcessor($e.value, $e, $state, $config)
+ }
+ )
+}
+
+function meta::external::store::relational::sqlDialectTranslation::defaults::arithmeticExpressionNodeProcessor_default(): NodeProcessor[1]
+{
+ nodeProcessor(
+ ArithmeticExpression,
+ {sqlDialect, a, state, config |
+ let isDivide = $a->isDivideExpr();
+ let castAsDecimalIfDivide = {e: meta::external::query::sql::metamodel::Expression[1] |
+ if ($isDivide, | ^Cast(type = ^ColumnType(name = 'decimal'), expression = $e), | $e)
+ };
+ let leftExpr = $sqlDialect->executeNodeProcessor($castAsDecimalIfDivide->eval($a.left), $a, $state, $config);
+ let rightExpr = $sqlDialect->executeNodeProcessor($castAsDecimalIfDivide->eval($a.right), $a, $state, $config);
+ let operator = if(
+ [
+ pair(|$a.type == ArithmeticType.ADD, | '+'),
+ pair(|$a.type == ArithmeticType.SUBTRACT, | '-'),
+ pair(|$a.type == ArithmeticType.MULTIPLY, | '*'),
+ pair(|$a.type == ArithmeticType.DIVIDE, | '/'),
+ pair(|$a.type == ArithmeticType.MODULUS, | '%'),
+ pair(|$a.type == ArithmeticType.POWER, | '^')
+ ],
+ | failWithMessage('Unhandled arithmetic operator type: ' + $a.type->toString())
+ );
+
+ $leftExpr + ' ' + $operator + ' ' + $rightExpr;
+ }
+ )
+}
+
+function meta::external::store::relational::sqlDialectTranslation::defaults::qualifiedNameReferenceNodeProcessor_default(): NodeProcessor[1]
+{
+ nodeProcessor(
+ QualifiedNameReference,
+ {sqlDialect, q, state, config |
+ $sqlDialect->qualifiedName($q.name, $state, $config)
+ }
+ )
+}
+
+function meta::external::store::relational::sqlDialectTranslation::defaults::isNullPredicateNodeProcessor_default(): NodeProcessor[1]
+{
+ nodeProcessor(
+ IsNullPredicate,
+ {sqlDialect, e, state, config |
+ $sqlDialect->executeNodeProcessor($e.value, $e, $state, $config) + ' ' + $sqlDialect->keyword('is null', $state, $config)
+ }
+ )
+}
+
+function meta::external::store::relational::sqlDialectTranslation::defaults::isNotNullPredicateNodeProcessor_default(): NodeProcessor[1]
+{
+ nodeProcessor(
+ IsNotNullPredicate,
+ {sqlDialect, e, state, config |
+ $sqlDialect->executeNodeProcessor($e.value, $e, $state, $config) + ' ' + $sqlDialect->keyword('is not null', $state, $config)
+ }
+ )
+}
+
+function meta::external::store::relational::sqlDialectTranslation::defaults::negativeNodeProcessor_default(): NodeProcessor[1]
+{
+ nodeProcessor(
+ NegativeExpression,
+ {sqlDialect, e, state, config |
+ '-' + $sqlDialect->executeNodeProcessor($e.value, $e, $state, $config)
+ }
+ )
+}
+
+function meta::external::store::relational::sqlDialectTranslation::defaults::currentTimeNodeProcessor_default(): NodeProcessor[1]
+{
+ nodeProcessor(
+ CurrentTime,
+ {sqlDialect, c, state, config |
+ let type = if(
+ [
+ pair(|$c.type == CurrentTimeType.TIME, | $sqlDialect->keyword('current_time', $state, $config)),
+ pair(|$c.type == CurrentTimeType.TIMESTAMP, | $sqlDialect->keyword('current_timestamp', $state, $config)),
+ pair(|$c.type == CurrentTimeType.DATE, | $sqlDialect->keyword('current_date', $state, $config))
+ ],
+ | failWithMessage('Unhandled current time type: ' + $c.type->toString())
+ );
+ let precision = if ($c.precision->isNotEmpty(), | '(' + $c.precision->toOne()->toString() + ')', | '');
+ $type + $precision;
+ },
+ {n | true}
+ )
+}
+
+function meta::external::store::relational::sqlDialectTranslation::defaults::whenClauseNodeProcessor_default(): NodeProcessor[1]
+{
+ nodeProcessor(
+ WhenClause,
+ {sqlDialect, w, state, config |
+ let sep0 = $state.separator(0, $config);
+ let sep1 = $state.separator(1, $config);
+ $sqlDialect->keyword('when', $state, $config) + $sep1 + $sqlDialect->executeNodeProcessor($w.operand, [], $state->increaseLevel(), $config) +
+ $sep0 + $sqlDialect->keyword('then', $state, $config) + $sep1 + $sqlDialect->executeNodeProcessor($w.result, [], $state->increaseLevel(), $config);
+ },
+ {n | true}
+ )
+}
+
+function meta::external::store::relational::sqlDialectTranslation::defaults::searchedCaseExpressionNodeProcessor_default(): NodeProcessor[1]
+{
+ nodeProcessor(
+ SearchedCaseExpression,
+ {sqlDialect, c, state, config |
+ let sep0 = $state.separator(0, $config);
+ let sep1 = $state.separator(1, $config);
+ let sep2 = $state.separator(2, $config);
+ let default = if ($c.defaultValue->isNotEmpty(),
+ | $sep1 + $sqlDialect->keyword('else', $state, $config) +
+ $sep2 + $sqlDialect->executeNodeProcessor($c.defaultValue->toOne(), [], $state->increaseLevel()->increaseLevel(), $config),
+ | ''
+ );
+ let whenClauses = $c.whenClauses->map(w | $sqlDialect->executeNodeProcessor($w, [], $state->increaseLevel(), $config))->joinStrings($sep1);
+ $sqlDialect->keyword('case', $state, $config) + $sep1 + $whenClauses + $default + $sep0 + $sqlDialect->keyword('end', $state, $config);
+ },
+ {n | true}
+ )
+}
+
+function meta::external::store::relational::sqlDialectTranslation::defaults::columnTypeProcessor_default(): NodeProcessor[1]
+{
+ nodeProcessor(
+ ColumnType,
+ {sqlDialect, c, state, config |
+ $sqlDialect->keyword($c.name, $state, $config) +
+ if ($c.parameters->isNotEmpty(), | $c.parameters->map(p | $p->toString())->joinStrings('(', ', ', ')'), | '');
+ },
+ {n | true}
+ )
+}
+
+function meta::external::store::relational::sqlDialectTranslation::defaults::castProcessor_default(): NodeProcessor[1]
+{
+ nodeProcessor(
+ Cast,
+ {sqlDialect, c, state, config |
+ $sqlDialect->keyword('cast', $state, $config) + '(' + $sqlDialect->executeNodeProcessor($c.expression, [], $state, $config) + ' ' +
+ $sqlDialect->keyword('as', $state, $config) + ' ' + $sqlDialect->executeNodeProcessor($c.type, [], $state, $config) + ')'
+ },
+ {n | true}
+ )
+}
+
+function meta::external::store::relational::sqlDialectTranslation::defaults::inListExpressionProcessor_default(): NodeProcessor[1]
+{
+ nodeProcessor(
+ InListExpression,
+ {sqlDialect, l, state, config |
+ let sep0 = $state.separator(0, $config);
+ let sep1 = $state.separator(1, $config);
+ let whenClauses = $l.values->map(v | $sqlDialect->executeNodeProcessor($v, [], $state->increaseLevel(), $config))->joinStrings(',' + $sep1);
+ '(' + $sep1 + $whenClauses + $sep0 + ')';
+ },
+ {n | true}
+ )
+}
+
+function meta::external::store::relational::sqlDialectTranslation::defaults::inPredicateProcessor_default(): NodeProcessor[1]
+{
+ nodeProcessor(
+ InPredicate,
+ {sqlDialect, i, state, config |
+ $sqlDialect->executeNodeProcessor($i.value, $i, $state, $config) + ' ' + $sqlDialect->keyword('in', $state, $config) + ' ' +
+ $sqlDialect->executeNodeProcessor($i.valueList, $i, $state, $config)
+ }
+ )
+}
+
+function meta::external::store::relational::sqlDialectTranslation::defaults::extractProcessor_default(): NodeProcessor[1]
+{
+ nodeProcessor(
+ Extract,
+ {sqlDialect, e, state, config |
+ $sqlDialect->keyword('extract', $state, $config) + '(' + $sqlDialect->keyword($e.field.name->toLower(), $state, $config) + ' ' +
+ $sqlDialect->keyword('from', $state, $config) + ' ' + $sqlDialect->executeNodeProcessor($e.expression, [], $state, $config) + ')';
+ },
+ {n | true}
+ )
+}
+
+function meta::external::store::relational::sqlDialectTranslation::defaults::betweenPredicateProcessor_default(): NodeProcessor[1]
+{
+ nodeProcessor(
+ BetweenPredicate,
+ {sqlDialect, b, state, config |
+ $sqlDialect->executeNodeProcessor($b.value, $b, $state, $config) + ' ' + $sqlDialect->keyword('between', $state, $config) + ' ' +
+ $sqlDialect->executeNodeProcessor($b.min, $b, $state, $config) + ' ' + $sqlDialect->keyword('and', $state, $config) + ' ' + $sqlDialect->executeNodeProcessor($b.max, $b, $state, $config);
+ }
+ )
+}
+
+function meta::external::store::relational::sqlDialectTranslation::defaults::sortItemProcessor_default(): NodeProcessor[1]
+{
+ nodeProcessor(
+ SortItem,
+ {sqlDialect, s, state, config |
+ $sqlDialect->executeNodeProcessor($s.sortKey, [], $state, $config) + ' ' +
+ if(
+ [
+ pair(|$s.ordering == SortItemOrdering.ASCENDING, | $sqlDialect->keyword('asc', $state, $config)),
+ pair(|$s.ordering == SortItemOrdering.DESCENDING, | $sqlDialect->keyword('desc', $state, $config))
+ ],
+ | failWithMessage('Unhandled sort item ordering type: ' + $s.ordering->toString())
+ ) +
+ if(
+ [
+ pair(|$s.nullOrdering == SortItemNullOrdering.FIRST, | ' ' + $sqlDialect->keyword('nulls first', $state, $config)),
+ pair(|$s.nullOrdering == SortItemNullOrdering.LAST, | ' ' + $sqlDialect->keyword('nulls last', $state, $config)),
+ pair(|$s.nullOrdering == SortItemNullOrdering.UNDEFINED, | '')
+ ],
+ | failWithMessage('Unhandled sort item null ordering type: ' + $s.nullOrdering->toString())
+ );
+ }
+ )
+}
+
+function meta::external::store::relational::sqlDialectTranslation::defaults::windowProcessor_default(): NodeProcessor[1]
+{
+ nodeProcessor(
+ meta::external::query::sql::metamodel::Window,
+ {sqlDialect, w, state, config |
+ let sep0 = $state.separator(0, $config);
+ let sep1 = $state.separator(1, $config);
+ if ($w.windowRef->isNotEmpty(),
+ | $w.windowRef->toOne(),
+ | let partitions = if ($w.partitions->isNotEmpty(),
+ | $sqlDialect->keyword('partition by', $state, $config) + $sep1 + $w.partitions->map(p | $sqlDialect->executeNodeProcessor($p, [], $state->increaseLevel(), $config))->joinStrings(',' + $sep1),
+ | ''
+ );
+ let orderBy = if ($w.orderBy->isNotEmpty(),
+ | let sep = if ($w.partitions->isNotEmpty(), | $sep0, | '');
+ $sep + $sqlDialect->keyword('order by', $state, $config) + $sep1 + $w.orderBy->map(o | $sqlDialect->executeNodeProcessor($o, [], $state->increaseLevel(), $config))->joinStrings(',' + $sep1);,
+ | ''
+ );
+ assert($w.windowFrame->isEmpty(), | 'Window frame processing not implemented yet');
+ $partitions + $orderBy;
+ );
+ }
+ )
+}
+
+function meta::external::store::relational::sqlDialectTranslation::defaults::functionCallProcessor_default(): NodeProcessor[1]
+{
+ nodeProcessor(
+ FunctionCall,
+ {sqlDialect, f, state, config |
+ assert($f.distinct == false, | 'Distinct function call processing not implemented yet');
+ assert($f.filter->isEmpty(), | 'Filtered function call processing not implemented yet');
+ assert($f.group->isEmpty(), | 'Grouped function call processing not implemented yet');
+ assert($f.orderBy->isEmpty(), | 'Sorted function call processing not implemented yet');
+
+ let sep0 = $state.separator(0, $config);
+ let sep1 = $state.separator(1, $config);
+
+ $sqlDialect->qualifiedName($f.name, $state, $config) + '(' + if($f.arguments->isEmpty(), | '', | $sep1) +
+ $f.arguments->map(a | $sqlDialect->executeNodeProcessor($a, [], $state->increaseLevel(), $config))->joinStrings(',' + $sep1) +
+ + if($f.arguments->isEmpty(), | '', | $sep0) + ')' +
+ if ($f.window->isNotEmpty(),
+ | ' ' + $sqlDialect->keyword('over', $state, $config) + ' (' + $sep1 + $sqlDialect->executeNodeProcessor($f.window->toOne(), [], $state->increaseLevel(), $config) + $sep0 + ')',
+ | ''
+ );
+ },
+ {n | true}
+ )
+}
+
+function meta::external::store::relational::sqlDialectTranslation::defaults::tableProcessor_default(): NodeProcessor[1]
+{
+ nodeProcessor(
+ Table,
+ {sqlDialect, t, state, config |
+ $sqlDialect->qualifiedName($t.name, $state, $config)
+ }
+ )
+}
+
+function meta::external::store::relational::sqlDialectTranslation::defaults::aliasedRelationProcessor_default(): NodeProcessor[1]
+{
+ nodeProcessor(
+ AliasedRelation,
+ {sqlDialect, a, state, config |
+ $sqlDialect->executeNodeProcessor($a.relation, $state, $config) + ' ' + $sqlDialect->keyword('as', $state, $config) + ' '
+ + $sqlDialect->executeIdentifierProcessor($a.alias, false, $state, $config)
+ }
+ )
+}
+
+function meta::external::store::relational::sqlDialectTranslation::defaults::joinProcessor_default(): NodeProcessor[1]
+{
+ nodeProcessor(
+ Join,
+ {sqlDialect, j, state, config |
+ let sep0 = $state.separator(0, $config);
+ let sep1 = $state.separator(1, $config);
+ let left = $sqlDialect->executeNodeProcessor($j.left, $state, $config);
+ let right = $sqlDialect->executeNodeProcessor($j.right, $state->increaseLevel(), $config);
+ let type = if(
+ [
+ pair(|$j.type == JoinType.CROSS, | $sqlDialect->keyword('cross join', $state, $config)),
+ pair(|$j.type == JoinType.LEFT, | $sqlDialect->keyword('left outer join', $state, $config)),
+ pair(|$j.type == JoinType.RIGHT, | $sqlDialect->keyword('right outer join', $state, $config)),
+ pair(|$j.type == JoinType.INNER, | $sqlDialect->keyword('inner join', $state, $config))
+ ],
+ | failWithMessage('Unhandled join type: ' + $j.type->toString())
+ );
+ let isNaturalJoin = $j.criteria->isNotEmpty() && $j.criteria->toOne()->instanceOf(NaturalJoin);
+
+ $left + $sep0 + if($isNaturalJoin, | $sqlDialect->keyword('natural', $state, $config) + ' ', | '') + $type +
+ $sep1 + $right +
+ if ($j.criteria->isNotEmpty() && (!$isNaturalJoin),
+ | $sep1 + $sqlDialect->keyword('on', $state, $config) + ' ' +
+ $j.criteria->toOne()->match([
+ o: JoinOn[1] | '(' + $sqlDialect->executeNodeProcessor($o.expression, $state, $config) + ')',
+ a: Any[*] | failWithMessage('Unhandled join criteria: ' + $a->class()->elementToPath())
+ ]),
+ | ''
+ );
+ }
+ )
+}
+
+function meta::external::store::relational::sqlDialectTranslation::defaults::selectProcessor_default(): NodeProcessor