From 339b304d79ee391b4c15a771983d015793c5cf1c Mon Sep 17 00:00:00 2001 From: Mohammed Ibrahim Date: Mon, 27 Jan 2025 14:29:31 -0500 Subject: [PATCH 1/3] Add Tabular function showcase --- .../Tabular Function/code.pure | 304 ++++++++++++++++++ .../Tabular Function/info.md | 7 + showcases/pom.xml | 2 +- 3 files changed, 312 insertions(+), 1 deletion(-) create mode 100644 showcases/data/Store/Relational Store/Database Specification/Tabular Function/code.pure create mode 100644 showcases/data/Store/Relational Store/Database Specification/Tabular Function/info.md diff --git a/showcases/data/Store/Relational Store/Database Specification/Tabular Function/code.pure b/showcases/data/Store/Relational Store/Database Specification/Tabular Function/code.pure new file mode 100644 index 000000000..e3c2a4a6c --- /dev/null +++ b/showcases/data/Store/Relational Store/Database Specification/Tabular Function/code.pure @@ -0,0 +1,304 @@ +###Relational +Database demo::udtf::DemoDb +( + Schema Org + ( + Table Firm + ( + firmId INTEGER, + legalname VARCHAR(200) + ) + TabularFunction Person + ( + firstname VARCHAR(200), + lastname VARCHAR(200), + age INTEGER, + associatedFirmId INTEGER + ) + TabularFunction Person2 + ( + firstname VARCHAR(200), + lastname VARCHAR(200), + age INTEGER, + associatedFirmId INTEGER + ) + TabularFunction ParentAndChildren + ( + firstname VARCHAR(200), + lastname VARCHAR(200), + id INTEGER, + age INTEGER, + parentId INTEGER + ) + ) + + Join firm_person(Org.Firm.firmId = Org.Person.associatedFirmId) + Join firm_person2(Org.Firm.firmId = Org.Person2.associatedFirmId) + Join relationship(Org.ParentAndChildren.parentId = {target}.id) + +) + + +###Pure +Class demo::udtf::Org::Firm +{ + firmId: Integer[1]; + legalname: String[1]; +} + +Class demo::udtf::Org::Person +{ + firstname: String[1]; + lastname: String[1]; + age: Integer[1]; + associatedFirmId: Integer[1]; + id: Integer[1]; +} + +Association demo::udtf::Person_person +{ + parent: demo::udtf::Org::Person[1]; + children: demo::udtf::Org::Person[1..*]; +} + +Association demo::udtf::firm_person +{ + assoacitedFirm: demo::udtf::Org::Firm[1]; + associatedPerson: demo::udtf::Org::Person[1..*]; +} + +function demo::udtf::Org::FirmToPerson(): meta::pure::tds::TabularDataSet[1] +{ + demo::udtf::Org::Firm.all() + ->project( + [ + x|$x.firmId, + x|$x.associatedPerson.age + ], + [ + 'Firm Id', + 'Associated Person/Age' + ] + )->from( + demo::udtf::DemoMapping, + demo::runtimes::DemoRuntime + ) +} + +function demo::udtf::Org::FirmToPersonWithFilterOnPerson(): meta::pure::tds::TabularDataSet[1] +{ + demo::udtf::Org::Firm.all()->filter( + x|$x.associatedPerson->exists( + x_1|$x_1.firstname == 'David' + ) + )->project( + [ + x|$x.firmId, + x|$x.associatedPerson.age + ], + [ + 'Firm Id', + 'Associated Person/Age' + ] + )->from( + demo::udtf::DemoMapping, + demo::runtimes::DemoRuntime + ) +} + +function demo::udtf::Org::FirmToPersonWithFilterOnPersonUsingUnion(): meta::pure::tds::TabularDataSet[1] +{ + demo::udtf::Org::Firm.all()->filter( + x|$x.associatedPerson->exists( + x_1|$x_1.firstname == 'David' + ) + )->project( + [ + x|$x.firmId, + x|$x.associatedPerson.age + ], + [ + 'Firm Id', + 'Associated Person/Age' + ] + )->from( + demo::udtf::DemoMappingUnion, + demo::runtimes::DemoRuntime + ) +} + + +function demo::udtf::Org::FetchChildrenViaSelfJoin(): meta::pure::tds::TabularDataSet[1] +{ + demo::udtf::Org::Person.all()->project( + [ + x|$x.firstname, + x|$x.id, + x|$x.children.age, + x|$x.children.id, + x|$x.children.firstname + ], + [ + 'Firstname', + 'Id', + 'Children/Age', + 'Children/Id', + 'Children/Firstname' + ] + )->from( + demo::udtf::DemoMappingSelfJoin, + demo::runtimes::DemoRuntime + ) +} + + +###Mapping +Mapping demo::udtf::DemoMapping +( + *demo::udtf::Org::Firm[f]: Relational + { + ~primaryKey + ( + [demo::udtf::DemoDb]Org.Firm.firmId, + [demo::udtf::DemoDb]Org.Firm.legalname + ) + ~mainTable [demo::udtf::DemoDb]Org.Firm + firmId: [demo::udtf::DemoDb]Org.Firm.firmId, + legalname: [demo::udtf::DemoDb]Org.Firm.legalname + } + *demo::udtf::Org::Person[p]: Relational + { + + ~mainTable [demo::udtf::DemoDb]Org.Person + firstname: [demo::udtf::DemoDb]Org.Person.firstname, + lastname: [demo::udtf::DemoDb]Org.Person.lastname, + age: [demo::udtf::DemoDb]Org.Person.age + } + + demo::udtf::firm_person: Relational + { + AssociationMapping + ( + assoacitedFirm[p,f]: [demo::udtf::DemoDb]@firm_person, + associatedPerson[f,p]: [demo::udtf::DemoDb]@firm_person + ) + } +) + +###Mapping +Mapping demo::udtf::DemoMappingUnion +( + *demo::udtf::Org::Person: Operation + { + meta::pure::router::operations::union_OperationSetImplementation_1__SetImplementation_MANY_(p1,p2) + } + *demo::udtf::Org::Firm[f]: Relational + { + ~primaryKey + ( + [demo::udtf::DemoDb]Org.Firm.firmId, + [demo::udtf::DemoDb]Org.Firm.legalname + ) + ~mainTable [demo::udtf::DemoDb]Org.Firm + firmId: [demo::udtf::DemoDb]Org.Firm.firmId, + legalname: [demo::udtf::DemoDb]Org.Firm.legalname + } + demo::udtf::Org::Person[p1]: Relational + { + ~mainTable [demo::udtf::DemoDb]Org.Person + firstname: [demo::udtf::DemoDb]Org.Person.firstname, + lastname: [demo::udtf::DemoDb]Org.Person.lastname, + age: [demo::udtf::DemoDb]Org.Person.age + } + demo::udtf::Org::Person[p2]: Relational + { + ~mainTable [demo::udtf::DemoDb]Org.Person2 + firstname: [demo::udtf::DemoDb]Org.Person2.firstname, + lastname: [demo::udtf::DemoDb]Org.Person2.lastname, + age: [demo::udtf::DemoDb]Org.Person2.age + } + + demo::udtf::firm_person: Relational + { + AssociationMapping + ( + assoacitedFirm[p1,f]: [demo::udtf::DemoDb]@firm_person, + assoacitedFirm[p2,f]: [demo::udtf::DemoDb]@firm_person2, + associatedPerson[f,p1]: [demo::udtf::DemoDb]@firm_person, + associatedPerson[f,p2]: [demo::udtf::DemoDb]@firm_person2 + ) + } +) + +###Mapping +Mapping demo::udtf::DemoMappingSelfJoin +( + *demo::udtf::Org::Person[p1]: Relational + { + ~primaryKey + ( + [demo::udtf::DemoDb]Org.ParentAndChildren.firstname + ) + ~mainTable [demo::udtf::DemoDb]Org.ParentAndChildren + firstname: [demo::udtf::DemoDb]Org.ParentAndChildren.firstname, + lastname: [demo::udtf::DemoDb]Org.ParentAndChildren.lastname, + id: [demo::udtf::DemoDb]Org.ParentAndChildren.id, + age: [demo::udtf::DemoDb]Org.ParentAndChildren.age + } + + demo::udtf::Person_person: Relational + { + AssociationMapping + ( + children[p1,p1]: [demo::udtf::DemoDb]@relationship, + parent[p1,p1]: [demo::udtf::DemoDb]@relationship + ) + } +) + +###Connection +RelationalDatabaseConnection demo::udtf::DemoSnowflakeConnection +{ + store: demo::udtf::DemoDb; + type: Snowflake; + specification: Snowflake + { + name: 'SUMMIT_MDM_DATA'; + account: 'sfcedeawseast1d01'; + warehouse: 'DEMO_WH'; + region: 'us-east-1'; + }; + auth: SnowflakePublic + { + publicUserName: 'isThis'; + privateKeyVaultReference: 'Hi'; + passPhraseVaultReference: 'What'; + }; +} + + +###Runtime +Runtime demo::runtimes::DemoRuntime +{ + mappings: + [ + demo::udtf::DemoMapping + ]; + connections: + [ + demo::udtf::DemoDb: + [ + connection_2: demo::udtf::DemoSnowflakeConnection + ] + ]; +} + +###Snowflake +SnowflakeApp demo::udtf::snowflakeApp::App1 +{ + applicationName : 'App1_revised'; + function : demo::udtf::Org::FirmToPersonWithFilterOnPersonUsingUnion():TabularDataSet[1]; + ownership : Deployment { identifier: '441143'}; + description : 'test App'; + activationConfiguration : demo::udtf::DemoSnowflakeConnection; +} \ No newline at end of file diff --git a/showcases/data/Store/Relational Store/Database Specification/Tabular Function/info.md b/showcases/data/Store/Relational Store/Database Specification/Tabular Function/info.md new file mode 100644 index 000000000..c6bc28d79 --- /dev/null +++ b/showcases/data/Store/Relational Store/Database Specification/Tabular Function/info.md @@ -0,0 +1,7 @@ +--- +title: Relational Database Specification with Tabular Functions +description: Example of database specification with tabular Function. +--- + +Tabular functions are database objects that effectively function as parameterized views. +This showcase gives examples of tabular functions that do not accept any parameters. \ No newline at end of file diff --git a/showcases/pom.xml b/showcases/pom.xml index 5ec8da9bd..df67f5eaa 100644 --- a/showcases/pom.xml +++ b/showcases/pom.xml @@ -16,7 +16,7 @@ 1.8 3 data - 4.54.1 + 4.68.0 From 4d497551023435cc825a966eea9a44abf6bbd9b4 Mon Sep 17 00:00:00 2001 From: Mohammed Ibrahim Date: Mon, 27 Jan 2025 15:21:42 -0500 Subject: [PATCH 2/3] update import --- showcases/src/test/java/org/example/ShowcaseCompilerTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/showcases/src/test/java/org/example/ShowcaseCompilerTest.java b/showcases/src/test/java/org/example/ShowcaseCompilerTest.java index af2e7125e..2ff10a70b 100644 --- a/showcases/src/test/java/org/example/ShowcaseCompilerTest.java +++ b/showcases/src/test/java/org/example/ShowcaseCompilerTest.java @@ -8,7 +8,7 @@ import org.finos.legend.engine.language.pure.grammar.to.PureGrammarComposerContext; import org.finos.legend.engine.protocol.pure.v1.ProtocolToClassifierPathLoader; import org.finos.legend.engine.protocol.pure.v1.model.context.PureModelContextData; -import org.finos.legend.engine.protocol.pure.v1.model.packageableElement.PackageableElement; +import org.finos.legend.engine.protocol.pure.v1.model.PackageableElement; import org.finos.legend.engine.protocol.pure.v1.model.test.assertion.status.AssertFail; import org.finos.legend.engine.protocol.pure.v1.model.test.assertion.status.AssertionStatus; import org.finos.legend.engine.protocol.pure.v1.model.test.assertion.status.EqualToJsonAssertFail; From ca2252cb7523a11f9fc9fff829a0f11015f0c6a2 Mon Sep 17 00:00:00 2001 From: Mohammed Ibrahim Date: Mon, 27 Jan 2025 16:00:40 -0500 Subject: [PATCH 3/3] fix tests --- .../Essential/Functions/Date/Basic/code.pure | 6 ++---- .../data/Model/Build a data model/code.pure | 4 ++-- .../Tabular Function/code.pure | 17 +++++++++-------- .../data/Store/Relational Store/Query/code.pure | 12 ++++++------ 4 files changed, 19 insertions(+), 20 deletions(-) diff --git a/showcases/data/Essential/Functions/Date/Basic/code.pure b/showcases/data/Essential/Functions/Date/Basic/code.pure index 5a40f450d..bfcf19e49 100644 --- a/showcases/data/Essential/Functions/Date/Basic/code.pure +++ b/showcases/data/Essential/Functions/Date/Basic/code.pure @@ -18,9 +18,7 @@ Mapping examples::stringToDate::StringToDateMapping targetValue: if( $src.sourceValue->isEmpty(), |[], - |$src.sourceValue->toOne()->parseDate()->cast( - @StrictDate - ) + |$src.sourceValue->toOne()->parseDate()->cast(@StrictDate) ) } @@ -48,4 +46,4 @@ Mapping examples::stringToDate::StringToDateMapping assert: '{"targetValue":"2022-02-17"}'; ) ] -) \ No newline at end of file +) diff --git a/showcases/data/Model/Build a data model/code.pure b/showcases/data/Model/Build a data model/code.pure index e5ed72d85..acae9f364 100644 --- a/showcases/data/Model/Build a data model/code.pure +++ b/showcases/data/Model/Build a data model/code.pure @@ -352,7 +352,7 @@ Mapping _03_modelToModelMapping::simpleModelToModelMapping *_01_basic::Product: Pure { ~src _03_modelToModelMapping::S_Product - ~filter !($src.classification.type == 'type2') + ~filter $src.classification.type != 'type2' name: $src.name, synonyms[_01_basic_Synonym]: $src.synonym, classification[_01_basic_ProductClassification]: $src.classification @@ -461,7 +461,7 @@ Mapping _03_modelToModelMapping::unionMapping _01_basic::Product[p1]: Pure { ~src _03_modelToModelMapping::S_Product - ~filter !($src.classification.type == 'type2') + ~filter $src.classification.type != 'type2' name: $src.name, classification[_01_basic_ProductClassification]: $src.classification, synonyms[_01_basic_Synonym]: $src.synonym diff --git a/showcases/data/Store/Relational Store/Database Specification/Tabular Function/code.pure b/showcases/data/Store/Relational Store/Database Specification/Tabular Function/code.pure index e3c2a4a6c..6d6043397 100644 --- a/showcases/data/Store/Relational Store/Database Specification/Tabular Function/code.pure +++ b/showcases/data/Store/Relational Store/Database Specification/Tabular Function/code.pure @@ -8,6 +8,7 @@ Database demo::udtf::DemoDb firmId INTEGER, legalname VARCHAR(200) ) + TabularFunction Person ( firstname VARCHAR(200), @@ -34,8 +35,7 @@ Database demo::udtf::DemoDb Join firm_person(Org.Firm.firmId = Org.Person.associatedFirmId) Join firm_person2(Org.Firm.firmId = Org.Person2.associatedFirmId) - Join relationship(Org.ParentAndChildren.parentId = {target}.id) - + Join relationship(Org.ParentAndChildren.parentId = {target}.id) ) @@ -69,8 +69,7 @@ Association demo::udtf::firm_person function demo::udtf::Org::FirmToPerson(): meta::pure::tds::TabularDataSet[1] { - demo::udtf::Org::Firm.all() - ->project( + demo::udtf::Org::Firm.all()->project( [ x|$x.firmId, x|$x.associatedPerson.age @@ -127,7 +126,6 @@ function demo::udtf::Org::FirmToPersonWithFilterOnPersonUsingUnion(): meta::pure ) } - function demo::udtf::Org::FetchChildrenViaSelfJoin(): meta::pure::tds::TabularDataSet[1] { demo::udtf::Org::Person.all()->project( @@ -168,7 +166,6 @@ Mapping demo::udtf::DemoMapping } *demo::udtf::Org::Person[p]: Relational { - ~mainTable [demo::udtf::DemoDb]Org.Person firstname: [demo::udtf::DemoDb]Org.Person.firstname, lastname: [demo::udtf::DemoDb]Org.Person.lastname, @@ -185,6 +182,7 @@ Mapping demo::udtf::DemoMapping } ) + ###Mapping Mapping demo::udtf::DemoMappingUnion ( @@ -230,12 +228,13 @@ Mapping demo::udtf::DemoMappingUnion } ) + ###Mapping Mapping demo::udtf::DemoMappingSelfJoin ( *demo::udtf::Org::Person[p1]: Relational { - ~primaryKey + ~primaryKey ( [demo::udtf::DemoDb]Org.ParentAndChildren.firstname ) @@ -256,6 +255,7 @@ Mapping demo::udtf::DemoMappingSelfJoin } ) + ###Connection RelationalDatabaseConnection demo::udtf::DemoSnowflakeConnection { @@ -293,6 +293,7 @@ Runtime demo::runtimes::DemoRuntime ]; } + ###Snowflake SnowflakeApp demo::udtf::snowflakeApp::App1 { @@ -301,4 +302,4 @@ SnowflakeApp demo::udtf::snowflakeApp::App1 ownership : Deployment { identifier: '441143'}; description : 'test App'; activationConfiguration : demo::udtf::DemoSnowflakeConnection; -} \ No newline at end of file +} diff --git a/showcases/data/Store/Relational Store/Query/code.pure b/showcases/data/Store/Relational Store/Query/code.pure index 044872be9..e17d36a79 100644 --- a/showcases/data/Store/Relational Store/Query/code.pure +++ b/showcases/data/Store/Relational Store/Query/code.pure @@ -607,7 +607,7 @@ function showcase::northwind::store::functions::NorthwindExtendd(): Any[*] function showcase::simple::functions::simpleFunctionSort(): Any[*] { #>{showcase::simple::store::TestDatabase.TEST0}#->filter( - c|!($c.FIRSTNAME == 'Doe') + c|$c.FIRSTNAME != 'Doe' )->from( showcase::simple::connection::TestRuntime )->sort( @@ -620,8 +620,8 @@ function showcase::simple::functions::simpleFunctionSort(): Any[*] function showcase::simple::functions::simpleTableFunctionFilter(): Any[*] { #>{showcase::simple::store::TestDatabase.TEST0}#->filter( - c|!($c.FIRSTNAME == 'Doe') && - !($c.LASTNAME == 'Doe') + c|($c.FIRSTNAME != 'Doe') && + ($c.LASTNAME != 'Doe') )->from( showcase::simple::connection::TestRuntime )->sort( @@ -634,7 +634,7 @@ function showcase::simple::functions::simpleTableFunctionFilter(): Any[*] function showcase::simple::functions::simpleTableFunctionGroup(): Any[*] { #>{showcase::simple::store::TestDatabase.TEST0}#->filter( - c|!($c.FIRSTNAME == 'Doe') + c|$c.FIRSTNAME != 'Doe' )->from( showcase::simple::connection::TestRuntime )->groupBy( @@ -650,8 +650,8 @@ function showcase::simple::functions::simpleTableFunctionGroup(): Any[*] function showcase::simple::functions::simpleTableFunctionSlice(): Any[*] { #>{showcase::simple::store::TestDatabase.TEST0}#->filter( - c|!($c.FIRSTNAME == 'Doe') && - !($c.LASTNAME == 'Doe') + c|($c.FIRSTNAME != 'Doe') && + ($c.LASTNAME != 'Doe') )->from( showcase::simple::connection::TestRuntime )