From 817648f3ee95983caca3c1ab8040aa1ca16d3e0a Mon Sep 17 00:00:00 2001 From: Mohammed Ibrahim Date: Tue, 30 Jul 2024 22:58:15 -0400 Subject: [PATCH] Resolve class properties from supertype on mapping compilation (#2988) --- .../toPureGraph/HelperModelBuilder.java | 19 +++++- .../TestRelationalCompilationFromGrammar.java | 59 +++++++++++++++++++ .../pom.xml | 25 ++++++++ 3 files changed, 102 insertions(+), 1 deletion(-) diff --git a/legend-engine-core/legend-engine-core-base/legend-engine-core-language-pure/legend-engine-language-pure-compiler/src/main/java/org/finos/legend/engine/language/pure/compiler/toPureGraph/HelperModelBuilder.java b/legend-engine-core/legend-engine-core-base/legend-engine-core-language-pure/legend-engine-language-pure-compiler/src/main/java/org/finos/legend/engine/language/pure/compiler/toPureGraph/HelperModelBuilder.java index 46e098b307e..e707a23dbf8 100644 --- a/legend-engine-core/legend-engine-core-base/legend-engine-core-language-pure/legend-engine-language-pure-compiler/src/main/java/org/finos/legend/engine/language/pure/compiler/toPureGraph/HelperModelBuilder.java +++ b/legend-engine-core/legend-engine-core-base/legend-engine-core-language-pure/legend-engine-language-pure-compiler/src/main/java/org/finos/legend/engine/language/pure/compiler/toPureGraph/HelperModelBuilder.java @@ -16,6 +16,7 @@ import org.eclipse.collections.api.RichIterable; import org.eclipse.collections.api.factory.Lists; +import org.eclipse.collections.api.list.ListIterable; import org.eclipse.collections.impl.utility.LazyIterate; import org.eclipse.collections.impl.utility.ListIterate; import org.finos.legend.engine.protocol.pure.v1.model.context.EngineErrorType; @@ -56,6 +57,7 @@ import org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.valuespecification.ValueSpecificationContext; import org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.valuespecification.VariableExpression; import org.finos.legend.pure.m3.navigation.M3Paths; +import org.finos.legend.pure.m3.navigation.linearization.C3Linearization; import org.finos.legend.pure.m4.coreinstance.CoreInstance; import org.finos.legend.pure.runtime.java.compiled.execution.CompiledExecutionSupport; import org.slf4j.Logger; @@ -473,7 +475,8 @@ public static AbstractProperty getAppliedProperty(CompileContext context, org for (CoreInstance c_type : org.finos.legend.pure.m3.navigation.type.Type.getGeneralizationResolutionOrder(_class, context.pureModel.getExecutionSupport().getProcessorSupport())) { org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.type.Class type = (org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.type.Class) c_type; - AbstractProperty property = type._properties().detect(p -> name.equals(p.getName())); + ListIterable orderedGeneralizations = C3Linearization.getTypeGeneralizationLinearization(type, context.pureModel.getExecutionSupport().getProcessorSupport()); + AbstractProperty property = getCompatibleProperty(orderedGeneralizations, name); if (property != null) { return property; @@ -497,6 +500,20 @@ public static AbstractProperty getAppliedProperty(CompileContext context, org throw new EngineException("Can't find property '" + name + "' in [" + org.finos.legend.pure.m3.navigation.type.Type.getGeneralizationResolutionOrder(_class, context.pureModel.getExecutionSupport().getProcessorSupport()).makeString(", ") + "]", sourceInformation, EngineErrorType.COMPILATION); } + public static AbstractProperty getCompatibleProperty(ListIterable orderedGeneralizations, String name) + { + for (CoreInstance instance : orderedGeneralizations) + { + org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.type.Class type = (org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.type.Class) instance; + AbstractProperty property = type._properties().detect(p -> name.equals(p.getName())); + if (property != null) + { + return property; + } + } + return null; + } + public static QualifiedProperty getCompatibleDerivedProperty(RichIterable> qualifiedProperties, String name, Optional> parameters) { RichIterable> propertiesWithSameName = qualifiedProperties.select(p -> name.equals(p._name())); 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 97348093e59..c313f8f454c 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 @@ -2702,4 +2702,63 @@ public void testCompilationMissingEnumMapping() throws Exception Assert.assertEquals(1, warnings.size()); Assert.assertEquals("{\"sourceInformation\":{\"sourceId\":\"\",\"startLine\":24,\"startColumn\":9,\"endLine\":24,\"endColumn\":33},\"message\":\"Missing an EnumerationMapping for the enum property 'type'. Enum properties require an EnumerationMapping in order to transform the store values into the Enum.\"}", new ObjectMapper().writeValueAsString(warnings.get(0))); } + + @Test + public void testMappingToPropertyWithDerivedPropertyConflict() + { + test("###Relational\n" + + + "Database demo::stores::Db\n" + + "(\n" + + " Schema First\n" + + " (\n" + + " Table Source\n" + + " (\n" + + " accountNumber INTEGER PRIMARY KEY,\n" + + " name VARCHAR(200)\n" + + " )\n" + + " )\n" + + ")\n" + + "\n" + + "\n" + + "###Pure\n" + + "Class demo::model::ChildClass extends demo::model::BaseClass, demo::model::BaseClass2 \n" + + "{\n" + + " Name: String[1];\n" + + " accountNumber(num: Integer[1],name: String[1]) {$num + $name->size()}: Integer[1];\n" + + "}\n" + + "\n" + + "Class demo::model::BaseClass2 extends demo::model::BaseClass2Parent\n" + + "{\n" + + "}\n" + + "\n" + + "Class demo::model::BaseClass extends demo::model::BaseClassParent\n" + + "{\n" + + "}\n" + + "\n" + + "Class demo::model::BaseClassParent\n" + + "{\n" + + "}\n" + + "\n" + + "Class demo::model::BaseClass2Parent\n" + + "{\n" + + " accountNumber: Integer[1];\n" + + "}\n" + + "\n" + + "\n" + + "###Mapping\n" + + "Mapping demo::mapping::Map1\n" + + "(\n" + + " *demo::model::ChildClass: Relational\n" + + " {\n" + + " ~primaryKey\n" + + " (\n" + + " [demo::stores::Db]First.Source.accountNumber\n" + + " )\n" + + " ~mainTable [demo::stores::Db]First.Source\n" + + " Name: [demo::stores::Db]First.Source.name,\n" + + " accountNumber: [demo::stores::Db]First.Source.accountNumber\n" + + " }\n" + + ")\n"); + } } diff --git a/legend-engine-xts-serviceStore/legend-engine-xt-serviceStore-executionPlan/pom.xml b/legend-engine-xts-serviceStore/legend-engine-xt-serviceStore-executionPlan/pom.xml index 5fe938615c3..82581b8dba6 100644 --- a/legend-engine-xts-serviceStore/legend-engine-xt-serviceStore-executionPlan/pom.xml +++ b/legend-engine-xts-serviceStore/legend-engine-xt-serviceStore-executionPlan/pom.xml @@ -52,6 +52,25 @@ + + + org.apache.maven.plugins + maven-dependency-plugin + + + dependency-analyze + test-compile + + analyze-only + + + + com.fasterxml.jackson.core:jackson-databind + + + + + @@ -150,6 +169,12 @@ + + + com.fasterxml.jackson.core + jackson-databind + + commons-codec commons-codec