diff --git a/legend-engine-xts-hostedService/legend-engine-xt-hostedService-compiler/src/main/java/org/finos/legend/engine/language/hostedService/compiler/toPureGraph/HostedServiceCompilerExtension.java b/legend-engine-xts-hostedService/legend-engine-xt-hostedService-compiler/src/main/java/org/finos/legend/engine/language/hostedService/compiler/toPureGraph/HostedServiceCompilerExtension.java index d169902ec5b..d1720fb9909 100644 --- a/legend-engine-xts-hostedService/legend-engine-xt-hostedService-compiler/src/main/java/org/finos/legend/engine/language/hostedService/compiler/toPureGraph/HostedServiceCompilerExtension.java +++ b/legend-engine-xts-hostedService/legend-engine-xt-hostedService-compiler/src/main/java/org/finos/legend/engine/language/hostedService/compiler/toPureGraph/HostedServiceCompilerExtension.java @@ -25,6 +25,7 @@ import org.finos.legend.engine.protocol.hostedService.metamodel.HostedServiceDeploymentConfiguration; import org.finos.legend.engine.protocol.functionActivator.metamodel.Ownership; import org.finos.legend.engine.protocol.hostedService.metamodel.control.UserList; +import org.finos.legend.engine.protocol.pure.v1.model.packageableElement.domain.Function; import org.finos.legend.engine.protocol.pure.v1.model.packageableElement.service.ExecutionEnvironmentInstance; import org.finos.legend.pure.generated.Root_meta_external_function_activator_DeploymentOwnership_Impl; import org.finos.legend.pure.generated.Root_meta_external_function_activator_hostedService_HostedService; @@ -64,7 +65,7 @@ public Iterable> getExtraProcessors() ), Processor.newProcessor( HostedService.class, - org.eclipse.collections.impl.factory.Lists.fixedSize.with(HostedServiceDeploymentConfiguration.class, ExecutionEnvironmentInstance.class), + org.eclipse.collections.impl.factory.Lists.fixedSize.with(HostedServiceDeploymentConfiguration.class, ExecutionEnvironmentInstance.class, Function.class), this::buildHostedService )//, // Processor.newProcessor( diff --git a/legend-engine-xts-hostedService/legend-engine-xt-hostedService-compiler/src/test/java/org/finos/legend/engine/language/hostedService/compiler/toPureGraph/test/TestHostedServiceCompilationFromGrammar.java b/legend-engine-xts-hostedService/legend-engine-xt-hostedService-compiler/src/test/java/org/finos/legend/engine/language/hostedService/compiler/toPureGraph/test/TestHostedServiceCompilationFromGrammar.java index 467470a980e..cd7ce4ba583 100644 --- a/legend-engine-xts-hostedService/legend-engine-xt-hostedService-compiler/src/test/java/org/finos/legend/engine/language/hostedService/compiler/toPureGraph/test/TestHostedServiceCompilationFromGrammar.java +++ b/legend-engine-xts-hostedService/legend-engine-xt-hostedService-compiler/src/test/java/org/finos/legend/engine/language/hostedService/compiler/toPureGraph/test/TestHostedServiceCompilationFromGrammar.java @@ -16,6 +16,7 @@ package org.finos.legend.engine.language.hostedService.compiler.toPureGraph.test; import org.finos.legend.engine.language.pure.compiler.test.TestCompilationFromGrammar; +import org.junit.Test; public class TestHostedServiceCompilationFromGrammar extends TestCompilationFromGrammar.TestCompilationFromGrammarTestSuite { @@ -41,4 +42,23 @@ public String getDuplicatedElementTestExpectedErrorMessage() { return "COMPILATION error at [5:1-7:108]: Duplicated element 'anything::Name'"; } + + @Test + public void testHostedServiceGrammar() + { + test("###HostedService\n" + + "HostedService model::NewActivator\n" + + "{\n" + + " pattern : '/pattern';\n" + + " ownership : Deployment { identifier: '' };\n" + + " function : model::Firm_QueryFunction():Integer[1];\n" + + " documentation : '';\n" + + " autoActivateUpdates : true;\n" + + "}\n" + + "###Pure\n" + + "function model::Firm_QueryFunction(): Integer[1]\n" + + "{\n" + + " 1 + 1;\n" + + "}"); + } } diff --git a/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-generation/legend-engine-xt-relationalStore-grammar/src/main/java/org/finos/legend/engine/language/pure/compiler/toPureGraph/HelperRelationalBuilder.java b/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-generation/legend-engine-xt-relationalStore-grammar/src/main/java/org/finos/legend/engine/language/pure/compiler/toPureGraph/HelperRelationalBuilder.java index d4bf0f74421..20dc452ac27 100644 --- a/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-generation/legend-engine-xt-relationalStore-grammar/src/main/java/org/finos/legend/engine/language/pure/compiler/toPureGraph/HelperRelationalBuilder.java +++ b/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-generation/legend-engine-xt-relationalStore-grammar/src/main/java/org/finos/legend/engine/language/pure/compiler/toPureGraph/HelperRelationalBuilder.java @@ -1502,14 +1502,26 @@ public static void processRootRelationalClassMapping(RootRelationalInstanceSetIm { if (rsi._mainTableAlias() == null && rsi._superSetImplementationId() != null) { - PropertyMappingsImplementation superMapping = Root_meta_pure_mapping_superMapping_PropertyMappingsImplementation_1__PropertyMappingsImplementation_$0_1$_(rsi, context.pureModel.getExecutionSupport()); - if (superMapping == null) + PropertyMappingsImplementation currentPmi = rsi; + boolean mainTableAliasFound = false; + while (!mainTableAliasFound) { - throw new EngineException("Can't find the main table for class '" + classMapping.id + "'"); - } - if (superMapping instanceof RootRelationalInstanceSetImplementation) - { - rsi._mainTableAlias(((RootRelationalInstanceSetImplementation) superMapping)._mainTableAlias()); + PropertyMappingsImplementation superMapping = Root_meta_pure_mapping_superMapping_PropertyMappingsImplementation_1__PropertyMappingsImplementation_$0_1$_(currentPmi, context.pureModel.getExecutionSupport()); + if (superMapping == null) + { + throw new EngineException("Can't find the main table for class '" + classMapping.id + "'"); + } + if (superMapping instanceof RootRelationalInstanceSetImplementation) + { + RootRelationalInstanceSetImplementation superRsi = (RootRelationalInstanceSetImplementation) superMapping; + TableAlias mainTableAlias = superRsi._mainTableAlias(); + if (mainTableAlias != null) + { + rsi._mainTableAlias(mainTableAlias); + mainTableAliasFound = true; + } + } + currentPmi = superMapping; } } diff --git a/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-generation/legend-engine-xt-relationalStore-grammar/src/test/java/org/finos/legend/engine/language/pure/compiler/test/TestRelationalCompilationFromGrammar.java b/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-generation/legend-engine-xt-relationalStore-grammar/src/test/java/org/finos/legend/engine/language/pure/compiler/test/TestRelationalCompilationFromGrammar.java index 4f88fcad35c..698237e8c03 100644 --- a/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-generation/legend-engine-xt-relationalStore-grammar/src/test/java/org/finos/legend/engine/language/pure/compiler/test/TestRelationalCompilationFromGrammar.java +++ b/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-generation/legend-engine-xt-relationalStore-grammar/src/test/java/org/finos/legend/engine/language/pure/compiler/test/TestRelationalCompilationFromGrammar.java @@ -381,6 +381,289 @@ public void testSelfJoin() ")"); } + @Test + public void testSuperMappingMainTableAlias() + { + test("###Relational\n" + + "Database store::test::testDatabase\n" + + "(\n" + + " Table ABC\n" + + " (\n" + + " id INTEGER PRIMARY KEY,\n" + + " aName VARCHAR(20),\n" + + " bName VARCHAR(20),\n" + + " cName VARCHAR(20),\n" + + " m1Id INTEGER,\n" + + " m2Id INTEGER,\n" + + " m3Id INTEGER,\n" + + " m4Id INTEGER,\n" + + " n1Id INTEGER,\n" + + " n2Id INTEGER,\n" + + " n3Id INTEGER,\n" + + " o1Id INTEGER,\n" + + " o2Id INTEGER\n" + + " )\n" + + " Table DEF\n" + + " (\n" + + " id INTEGER PRIMARY KEY,\n" + + " dName VARCHAR(20),\n" + + " eName VARCHAR(20),\n" + + " fName VARCHAR(20)\n" + + " )\n" + + " Table GHI\n" + + " (\n" + + " id INTEGER PRIMARY KEY,\n" + + " gName VARCHAR(20),\n" + + " hName VARCHAR(20),\n" + + " iName VARCHAR(20)\n" + + " )\n" + + " Table JKL\n" + + " (\n" + + " id INTEGER PRIMARY KEY,\n" + + " jName VARCHAR(20),\n" + + " kName VARCHAR(20),\n" + + " lName VARCHAR(20)\n" + + " )\n" + + " Table ABC2\n" + + " (\n" + + " id INTEGER PRIMARY KEY,\n" + + " aName VARCHAR(20),\n" + + " bName VARCHAR(20),\n" + + " cName VARCHAR(20),\n" + + " m1Id INTEGER,\n" + + " m2Id INTEGER,\n" + + " m3Id INTEGER,\n" + + " m4Id INTEGER,\n" + + " n1Id INTEGER,\n" + + " n2Id INTEGER,\n" + + " n3Id INTEGER,\n" + + " o1Id INTEGER,\n" + + " o2Id INTEGER\n" + + " )\n" + + " Table DEF2\n" + + " (\n" + + " id INTEGER PRIMARY KEY,\n" + + " dName VARCHAR(20),\n" + + " eName VARCHAR(20),\n" + + " fName VARCHAR(20)\n" + + " )\n" + + " Table GHI2\n" + + " (\n" + + " id INTEGER PRIMARY KEY,\n" + + " gName VARCHAR(20),\n" + + " hName VARCHAR(20),\n" + + " iName VARCHAR(20)\n" + + " )\n" + + " Table JKL2\n" + + " (\n" + + " id INTEGER PRIMARY KEY,\n" + + " jName VARCHAR(20),\n" + + " kName VARCHAR(20),\n" + + " lName VARCHAR(20)\n" + + " )\n" + + "\n" + + " Join AE(ABC.id = DEF.id)\n" + + " Join BH(ABC.id = GHI.id)\n" + + " Join CK(ABC.id = JKL.id)\n" + + " Join A2E2(ABC2.id = DEF2.id)\n" + + " Join B2H2(ABC2.id = GHI2.id)\n" + + " Join C2K2(ABC2.id = JKL2.id)\n" + + "\n" + + " Filter AFilter(ABC.aName = 'aName1')\n" + + " Filter CFilter(ABC.cName = 'cName1')\n" + + ")\n" + + "\n" + + "Database my::db\n" + + "(\n" + + " Table PersonTable\n" + + " (\n" + + " NAME CHAR(200) PRIMARY KEY\n" + + " )\n" + + " Table EmployeeTable\n" + + " (\n" + + " FIRMNAME CHAR(200) PRIMARY KEY\n" + + " )\n" + + ")\n" + + "\n" + + "\n" + + "###Pure\n" + + "Class model::test::A\n" + + "{\n" + + " id: Integer[1];\n" + + " aName: String[1];\n" + + " m1: model::test::M[1];\n" + + " m2: model::test::M[1];\n" + + "}\n" + + "\n" + + "Class model::test::B extends model::test::A\n" + + "{\n" + + " bName: String[1];\n" + + " n1: model::test::N[1];\n" + + " n2: model::test::N[1];\n" + + "}\n" + + "\n" + + "Class model::test::C extends model::test::B\n" + + "{\n" + + " cName: String[1];\n" + + " o1: model::test::O[1];\n" + + " o2: model::test::O[1];\n" + + "}\n" + + "\n" + + "Class model::test::D\n" + + "{\n" + + " id: Integer[1];\n" + + " dName: String[1];\n" + + "}\n" + + "\n" + + "Class model::test::E extends model::test::D\n" + + "{\n" + + " eName: String[1];\n" + + "}\n" + + "\n" + + "Class model::test::F extends model::test::E\n" + + "{\n" + + " fName: String[1];\n" + + "}\n" + + "\n" + + "Class model::test::G\n" + + "{\n" + + " id: Integer[1];\n" + + " gName: String[1];\n" + + "}\n" + + "\n" + + "Class model::test::H extends model::test::G\n" + + "{\n" + + " hName: String[1];\n" + + "}\n" + + "\n" + + "Class model::test::I extends model::test::H\n" + + "{\n" + + " iName: String[1];\n" + + "}\n" + + "\n" + + "Class model::test::J\n" + + "{\n" + + " id: Integer[1];\n" + + " jName: String[1];\n" + + "}\n" + + "\n" + + "Class model::test::K extends model::test::J\n" + + "{\n" + + " kName: String[1];\n" + + "}\n" + + "\n" + + "Class model::test::L extends model::test::K\n" + + "{\n" + + " lName: String[1];\n" + + "}\n" + + "\n" + + "Class model::test::M\n" + + "{\n" + + " id: Integer[1];\n" + + " mName: String[1];\n" + + "}\n" + + "\n" + + "Class model::test::N\n" + + "{\n" + + " id: Integer[1];\n" + + " nName: String[1];\n" + + "}\n" + + "\n" + + "Class model::test::O\n" + + "{\n" + + " id: Integer[1];\n" + + " oName: String[1];\n" + + "}\n" + + "\n" + + "Class model::Person\n" + + "{\n" + + " name: String[1];\n" + + "}\n" + + "\n" + + "Class model::Employee extends model::Person\n" + + "{\n" + + " firmName: String[1];\n" + + "}\n" + + "\n" + + "\n" + + "###Mapping\n" + + "Mapping mapping::testAMapping\n" + + "(\n" + + " model::test::A[a]: Relational\n" + + " {\n" + + " ~primaryKey\n" + + " (\n" + + " [store::test::testDatabase]ABC.id\n" + + " )\n" + + " ~mainTable [store::test::testDatabase]ABC\n" + + " id: [store::test::testDatabase]ABC.id,\n" + + " aName: [store::test::testDatabase]ABC.aName\n" + + " }\n" + + ")\n" + + "\n" + + "Mapping mapping::testB1Mapping\n" + + "(\n" + + " include mapping mapping::testAMapping\n" + + "\n" + + " model::test::B[b1] extends [a]: Relational\n" + + " {\n" + + " }\n" + + ")\n" + + "\n" + + "Mapping mapping::testB2Mapping\n" + + "(\n" + + " include mapping mapping::testAMapping\n" + + "\n" + + " model::test::B[b2] extends [a]: Relational\n" + + " {\n" + + " aName: concat('bName_', [store::test::testDatabase]ABC.aName),\n" + + " bName: [store::test::testDatabase]ABC.bName\n" + + " }\n" + + ")\n" + + "\n" + + "Mapping mapping::testC1Mapping\n" + + "(\n" + + " include mapping mapping::testB1Mapping\n" + + "\n" + + " model::test::C[c1] extends [b1]: Relational\n" + + " {\n" + + " }\n" + + ")\n" + + "\n" + + "Mapping mapping::testC2Mapping\n" + + "(\n" + + " include mapping mapping::testB2Mapping\n" + + "\n" + + " model::test::C[c2] extends [b2]: Relational\n" + + " {\n" + + " aName: concat('cName_', [store::test::testDatabase]ABC.aName),\n" + + " bName: concat('cName_', [store::test::testDatabase]ABC.bName),\n" + + " cName: [store::test::testDatabase]ABC.cName\n" + + " }\n" + + ")\n" + + "\n" + + "Mapping model::map\n" + + "(\n" + + " *model::Person[id]: Relational\n" + + " {\n" + + " ~primaryKey\n" + + " (\n" + + " [my::db]PersonTable.NAME\n" + + " )\n" + + " ~mainTable [my::db]PersonTable\n" + + " }\n" + + " *model::Employee extends [id]: Relational\n" + + " {\n" + + " ~primaryKey\n" + + " (\n" + + " [my::db]EmployeeTable.FIRMNAME\n" + + " )\n" + + " ~mainTable [my::db]EmployeeTable\n" + + " firmName: [my::db]EmployeeTable.FIRMNAME\n" + + " }\n" + + ")"); + } + @Test public void testMissingColumnOnMilestoning() {