From 6db15bfc3603bc60c3050282527ab7011c87eced Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20Fallas=20Avenda=C3=B1o?= Date: Thu, 30 Nov 2023 15:58:14 -0600 Subject: [PATCH] Sf/basicdocumentation (#106) * In-progress documentation and fixes/coverage * Add minor updates * Add missing elements * Add latest changes * Split initial documents * Code review comments --- cli/cli.js | 4 +- docs/snowpark/snowpark-backend-types.md | 41 ++ .../snowpark-backend-using-and-customize.md | 232 ++++++++ .../snowpark-backend-value-mapping.md | 398 +++++++++++++ docs/snowpark/snowpark-backend.md | 525 ++++++++++++++++++ docs/snowpark/sp_caching_decoration.png | Bin 0 -> 89220 bytes docs/snowpark/sp_inline_decoration.png | Bin 0 -> 72945 bytes redistributable/Snowpark/decorations/elm.json | 24 + .../Snowpark/decorations/morphir.json | 4 + .../SnowparkGenCustomization/Decorations.elm | 5 + .../FunctionMappingsForPlainScala.elm | 65 ++- src/Morphir/Snowpark/LetMapping.elm | 2 +- src/Morphir/Snowpark/MapFunctionsMapping.elm | 120 +++- src/Morphir/Snowpark/PatternMatchMapping.elm | 4 +- src/Morphir/Snowpark/ReferenceUtils.elm | 12 +- src/Morphir/Snowpark/TypeRefMapping.elm | 4 +- src/Morphir/Snowpark/Utils.elm | 2 +- 17 files changed, 1403 insertions(+), 39 deletions(-) create mode 100644 docs/snowpark/snowpark-backend-types.md create mode 100644 docs/snowpark/snowpark-backend-using-and-customize.md create mode 100644 docs/snowpark/snowpark-backend-value-mapping.md create mode 100644 docs/snowpark/snowpark-backend.md create mode 100644 docs/snowpark/sp_caching_decoration.png create mode 100644 docs/snowpark/sp_inline_decoration.png create mode 100644 redistributable/Snowpark/decorations/elm.json create mode 100644 redistributable/Snowpark/decorations/morphir.json create mode 100644 redistributable/Snowpark/decorations/src/SnowparkGenCustomization/Decorations.elm diff --git a/cli/cli.js b/cli/cli.js index 703b91233..7ba6ab044 100644 --- a/cli/cli.js +++ b/cli/cli.js @@ -140,7 +140,9 @@ function copyRedistributables(options, outputPath) { copyScalaFeature('core') } else if (options.target == 'TypeScript') { copyFiles('TypeScript/', outputPath) - } + } else if (options.target == 'Snowpark') { + copyFiles('Snowpark/', outputPath) + } } function copyRecursiveSync(src, dest) { diff --git a/docs/snowpark/snowpark-backend-types.md b/docs/snowpark/snowpark-backend-types.md new file mode 100644 index 000000000..039db2b7c --- /dev/null +++ b/docs/snowpark/snowpark-backend-types.md @@ -0,0 +1,41 @@ +--- +id: snowpark-backend-types +--- + +# Type mappings + +**TODO** + + When generating code using DataFrame operations types are mapped using the following criteria: + +| Elm/Morphir-IR type | Generated Scala type | Expected Snowflake type | +|-----------------------------------|--------------------------------|--------------------------------------------------------------------------------------------------------------------| +| `Int` | `Column`\* | [INT](https://docs.snowflake.com/en/sql-reference/data-types-numeric#int-integer-bigint-smallint-tinyint-byteint) | +| `Float` | `Column`\* | [DOUBLE](https://docs.snowflake.com/en/sql-reference/data-types-numeric#double-double-precision-real) | +| `Bool` | `Column`\* | [BOOLEAN](https://docs.snowflake.com/en/sql-reference/data-types-logical#boolean) | +| `String` | `Column`\* | [VARCHAR](https://docs.snowflake.com/en/sql-reference/data-types-text) | +| Custom types without parameters | `Column`\* | [VARCHAR](https://docs.snowflake.com/en/sql-reference/data-types-text) | +| Custom types with parameters | `Column`\* | [OBJECT](https://docs.snowflake.com/en/sql-reference/data-types-semistructured#object) | +| Type alias | *As aliased* | *As aliased* | +| Record | Columns wrapper or **Column** | N/A | +| List of Record representing table | `DataFrame`\*\* | N/A | + +\* Snowpark [Column](https://docs.snowflake.com/developer-guide/snowpark/reference/scala/com/snowflake/snowpark/Column.html). + +\*\* Snowpark [DataFrame](https://docs.snowflake.com/developer-guide/snowpark/reference/scala/com/snowflake/snowpark/DataFrame.html). + + +When generating the code using Scala expressions the type conversion generates: + +| Elm/Morphir-IR type | Generated Scala type | +|-----------------------------------|--------------------------------| +| `Int` | `Int` | +| `Float` | `Double` | +| `Bool` | `Boolean` | +| `String` | `String` | +| Custom types without parameters | `String` | +| Custom types with parameters | **NOT IMPLEMENTED** | +| Type alias | *As aliased* | +| Record | Columns wrapper or **Column** | +| List of Record representing table | `DataFrame` | +| Complex Record | Scala case class | diff --git a/docs/snowpark/snowpark-backend-using-and-customize.md b/docs/snowpark/snowpark-backend-using-and-customize.md new file mode 100644 index 000000000..17feaaca3 --- /dev/null +++ b/docs/snowpark/snowpark-backend-using-and-customize.md @@ -0,0 +1,232 @@ +--- +id: snowpark-backend-using-and-customize +--- + + +## Using the Snowpark backend and customizing the output + +### Using the backend + +The backend is selected by specifying `Snowpark` as the target. For example: + +```bash +$ morphir-elm gen -t Snowpark -o outputDir +``` + +### Identifying not supported cases + +The output directory where the Scala code was generated contains a file called `GenerationReport.md`. This is a markdown file which contains the following information: + +- Generation issues by function: Elements not converted listed by function +- Listing of functions generated using the DataFrame operations strategy +- Listing of functions generated using the Scala expressions strategy +- Listing of types identified as `DataFrames` + +An example of this report: + +```markdown +# Generation report + + +## Generation issues + + +### MyModel:Basic:getTasksEstimationInSeconds22 + +- Call to function not generated: Morphir.SDK:List:range + +## Functions generated using DataFrame operations strategy + +- `MyModel:Basic:addThreeNumbers` +- `MyModel:Basic:checkLastName` +- `MyModel:Basic:classifyDepartment` +- `MyModel:Basic:getEmployeeWithLastName` +- `MyModel:Basic:getEmployeesInList` +- `MyModel:Basic:getEmployeesWithLastName` +- `MyModel:Basic:toSpString` + +## Functions generated using Scala strategy + +- MyModel:Basic:avgSalaries + +## Types identified as DataFrames + +- MyModel:Basic:department +- MyModel:Basic:employee +``` + +### Customizing the output using decorations + +The Snowpark backend supports a way to apply two customizations using [Morphir decorations](https://morphir.finos.org/docs/decorations-users-guide) . + +Two customizations could be applied : "Inline function call" or "Cache result" . + +#### Inlining functions + +The **Inline element** decoration allows the user to inline a function definition. For example given the following code: + +```elm +toSpString : CardinalDirection -> String +toSpString direction = + case direction of + North -> + "Norte" + South -> + "Sur" + East -> + "Este" + West -> + "Oeste" + +spanishDirections : List Directions -> List { translation : String } +spanishDirections directions = + directions + |> List.map (\dir -> { translation = toSpString dir.direction }) +``` + +The generated code for these definitions is: + +```scala +def toSpString( + direction: com.snowflake.snowpark.Column +)( + implicit sfSession: com.snowflake.snowpark.Session +): com.snowflake.snowpark.Column = + com.snowflake.snowpark.functions.when( + (direction) === (myModel.Basic.CardinalDirection.West), + com.snowflake.snowpark.functions.lit("Oeste") + ).when( + (direction) === (myModel.Basic.CardinalDirection.East), + com.snowflake.snowpark.functions.lit("Este") + ).when( + (direction) === (myModel.Basic.CardinalDirection.South), + com.snowflake.snowpark.functions.lit("Sur") + ).when( + (direction) === (myModel.Basic.CardinalDirection.North), + com.snowflake.snowpark.functions.lit("Norte") + ) + +def spanishDirections( + directions: com.snowflake.snowpark.DataFrame +)( + implicit sfSession: com.snowflake.snowpark.Session +): com.snowflake.snowpark.DataFrame = { + val directionsColumns: myModel.Basic.Directions = new myModel.Basic.DirectionsWrapper(directions) + + directions.select(myModel.Basic.toSpString(directionsColumns.direction).as("translation")) +} +``` + +By adding the `Inline element` decoration we can inline the `toSpString` function call inside `spanishDirections`. + +![inline decoration](sp_inline_decoration.png) + +Regenerating the code with these decorations shows that the definition was inlined in the place where the function was invoked. + +```scala + def spanishDirections( + directions: com.snowflake.snowpark.DataFrame + )( + implicit sfSession: com.snowflake.snowpark.Session + ): com.snowflake.snowpark.DataFrame = { + val directionsColumns: myModel.Basic.Directions = new myModel.Basic.DirectionsWrapper(directions) + + directions.select(com.snowflake.snowpark.functions.when( + (directionsColumns.direction) === (myModel.Basic.CardinalDirection.West), + com.snowflake.snowpark.functions.lit("Oeste") + ).when( + (directionsColumns.direction) === (myModel.Basic.CardinalDirection.East), + com.snowflake.snowpark.functions.lit("Este") + ).when( + (directionsColumns.direction) === (myModel.Basic.CardinalDirection.South), + com.snowflake.snowpark.functions.lit("Sur") + ).when( + (directionsColumns.direction) === (myModel.Basic.CardinalDirection.North), + com.snowflake.snowpark.functions.lit("Norte") + ).as("translation")) + } +``` + +#### Cache result + +Another customization allows the user to specify that caching code need to be generated for a specific function. + +For example given this function: + +```elm +getEmployeesWithLastName : String -> List Employee -> List Employee +getEmployeesWithLastName lastName employees = + employees + |> List.filter (\employee -> employee.lastName == lastName) +``` + +The code generated for this function looks like this: + +```scala + def getEmployeeWithLastName( + lastName: com.snowflake.snowpark.Column + )( + employees: com.snowflake.snowpark.DataFrame + )( + implicit sfSession: com.snowflake.snowpark.Session + ): com.snowflake.snowpark.DataFrame = { + val employeesColumns: myModel.Basic.Employee = new myModel.Basic.EmployeeWrapper(employees) + + employees.filter(myModel.Basic.checkLastName(lastName)(employeesColumns)) + } +``` + +We can add caching to this function with a decoration like this: + +![inline decoration](sp_caching_decoration.png) + +Regenerating the code show a different output. + +```scala +def getEmployeesWithLastName( + lastName: com.snowflake.snowpark.Column +)( + employees: com.snowflake.snowpark.DataFrame +)( + implicit sfSession: com.snowflake.snowpark.Session +): com.snowflake.snowpark.DataFrame = + getEmployeesWithLastNameCache.getOrElseUpdate( + (lastName, employees, sfSession), + { + val employeesColumns: myModel.Basic.Employee = new myModel.Basic.EmployeeWrapper(employees) + + employees.filter((employeesColumns.lastName) === (lastName)) + }.cacheResult + ) +``` + +Notice that this code use the [cacheResult](https://docs.snowflake.com/en/developer-guide/snowpark/scala/working-with-dataframes#caching-a-dataframe) mechanism. + +### Configuring the project for using Snowpark decorations + +Some modifications to the `morphir.json` are required to add these decorations. Here is an example of the configuration that needs to be added to this file: + +```json +{ + "name": "MyModel", + "sourceDirectory": "src", + "decorations": { + "snowparkgendecorations": { + "displayName" : "Snowpark generation customization", + "entryPoint": "SnowparkGenCustomization:Decorations:GenerationCustomization", + "ir": "out/decorations/morphir-ir.json", + "storageLocation": "spdecorations.json" + } + } +} +``` + +Every time code is generated with this Snowpark backend a `decorations` directory is created in the output directory. This directory contains the `morphir-ir.json` file to use the customizations. + +### Using decoration when generating code + +The `-dec` command line parameter is used to specify the decorations generated with the Morphir UI . For example given that the `spdecorations.json` name is used in the `storageLocation` section we can write: + +```bash +$ morphir-elm gen -t Snowpark -o output -dec spdecorations.json +``` diff --git a/docs/snowpark/snowpark-backend-value-mapping.md b/docs/snowpark/snowpark-backend-value-mapping.md new file mode 100644 index 000000000..30b142129 --- /dev/null +++ b/docs/snowpark/snowpark-backend-value-mapping.md @@ -0,0 +1,398 @@ +--- +id: snowpark-backend-value-mappings +--- + + +# Value mappings for DataFrame operations + +## Literals + +*Source* + +```elm +10 +"Hello" +True +``` + +*Target* + +```Scala +com.snowflake.snowpark.functions.lit(10) +com.snowflake.snowpark.functions.lit("Hello") +com.snowflake.snowpark.functions.lit(true) +``` + +## Field access values + +Field access expressions like `a.b` are converted depending on the value that is being accessed. For example the following function contains an access to the `lastName` field of the `Employee` record: + +*Source* + +```elm +checkLastName : String -> Employee -> Bool +checkLastName name employee = + if employee.lastName == name then + True + else + False +``` + +*Target* + +```scala + def checkLastName( + name: com.snowflake.snowpark.Column + )( + employee: myModel.Basic.Employee + )( + implicit sfSession: com.snowflake.snowpark.Session + ): com.snowflake.snowpark.Column = + com.snowflake.snowpark.functions.when( + (employee.lastName) === (name), + com.snowflake.snowpark.functions.lit(true) + ).otherwise(com.snowflake.snowpark.functions.lit(false)) +``` + +As presented above the `employee.lastName` expression in Elm was generated as `employee.lastName`. + +## Variable values + +Variable access like `myValue` are almost always converted to variable accesses in Scala. There are few exceptions like access to global elements where identifiers are generated fully qualified. + +## Constructor call values + +Constructor invocations are generated depending of the current strategy being used by the backend. Some cases include: + +### Custom type without parameters + +*Source* + +```elm +type CardinalDirection + = North + | South + | East + | West + +myFunc : CardinalDirection +myFunc = + let + direction = North + in + direction +``` + +*Target* + +```scala +object CardinalDirection{ + + def East: com.snowflake.snowpark.Column = + com.snowflake.snowpark.functions.lit("East") + + def North: com.snowflake.snowpark.Column = + com.snowflake.snowpark.functions.lit("North") + + def South: com.snowflake.snowpark.Column = + com.snowflake.snowpark.functions.lit("South") + + def West: com.snowflake.snowpark.Column = + com.snowflake.snowpark.functions.lit("West") + +} + +def myFunc: com.snowflake.snowpark.Column = { + val direction = myModel.Basic.CardinalDirection.North + + direction +} +``` + +Notice that the call to construct `North` was replaced by an access to the helper object `CardinalDirection` . + + +### Custom type with parameters + +In this case the convention is use a JSON object to represent values. For example: + +*Source* + +```elm +type TimeRange = + Zero + | Seconds Int + | MinutesAndSeconds Int Int + +createMinutesAndSecs : Int -> Int -> TimeRange +createMinutesAndSecs min sec = + MinutesAndSeconds min sec +``` + +*Target* + +```scala + def createMinutesAndSecs( + min: com.snowflake.snowpark.Column + )( + sec: com.snowflake.snowpark.Column + )( + implicit sfSession: com.snowflake.snowpark.Session + ): com.snowflake.snowpark.Column = + com.snowflake.snowpark.functions.object_construct( + com.snowflake.snowpark.functions.lit("__tag"), + com.snowflake.snowpark.functions.lit("MinutesAndSeconds"), + com.snowflake.snowpark.functions.lit("field0"), + min, + com.snowflake.snowpark.functions.lit("field1"), + sec + ) +``` + +### Returning records from functions + +In the case that a function returns a record, an [array](https://docs.snowflake.com/en/sql-reference/data-types-semistructured#array) is created to store the data. + +*Source* + +```elm +type alias EmpRes = + { code : Int + , name : String + } + +applyProcToEmployee : Employee -> Maybe EmpRes +applyProcToEmployee employee = + if employee.lastName == "Solo" then + Just <| EmpRes 1010 employee.firstName + else + Nothing +``` + +*Target* + +```scala + def applyProcToEmployee( + employee: myModel.Basic.Employee + )( + implicit sfSession: com.snowflake.snowpark.Session + ): com.snowflake.snowpark.Column = + com.snowflake.snowpark.functions.when( + (employee.lastName) === (com.snowflake.snowpark.functions.lit("Solo")), + com.snowflake.snowpark.functions.array_construct( + com.snowflake.snowpark.functions.lit(1010), + employee.firstName + ) + ).otherwise(com.snowflake.snowpark.functions.lit(null)) +``` + +## List literal values + +Literal lists are converted a Scala [Seq](https://www.scala-lang.org/api/2.12.x/scala/collection/Seq.html) . + +*Source* + +```elm +someNames : List String +someNames = [ "Solo", "Jones" ] +``` + +*Target* + +```scala + def someNames: Seq[com.snowflake.snowpark.Column] = + Seq( + com.snowflake.snowpark.functions.lit("Solo"), + com.snowflake.snowpark.functions.lit("Jones") + ) +``` + +Sometimes that mapping function for an specific builtin function like `List.member` maybe change the conversion of literal lists. + +## Case/of values + +[Case/of](https://guide.elm-lang.org/types/pattern_matching) expressions are converted to a series of [when/otherwise](https://docs.snowflake.com/developer-guide/snowpark/reference/scala/com/snowflake/snowpark/CaseExpr.html#when(condition:com.snowflake.snowpark.Column,value:com.snowflake.snowpark.Column):com.snowflake.snowpark.CaseExpr) expressions. + +*Source* + +```elm +type CardinalDirection + = North + | South + | East + | West + +toSpString : CardinalDirection -> String +toSpString direction = + case direction of + North -> + "Norte" + South -> + "Sur" + East -> + "Este" + West -> + "Oeste" +``` + +*Target* + +```scala + def toSpString( + direction: com.snowflake.snowpark.Column + )( + implicit sfSession: com.snowflake.snowpark.Session + ): com.snowflake.snowpark.Column = + com.snowflake.snowpark.functions.when( + (direction) === (myModel.Basic.CardinalDirection.West), + com.snowflake.snowpark.functions.lit("Oeste") + ).when( + (direction) === (myModel.Basic.CardinalDirection.East), + com.snowflake.snowpark.functions.lit("Este") + ).when( + (direction) === (myModel.Basic.CardinalDirection.South), + com.snowflake.snowpark.functions.lit("Sur") + ).when( + (direction) === (myModel.Basic.CardinalDirection.North), + com.snowflake.snowpark.functions.lit("Norte") + ) +``` + +## If/then/else values + +`If/then/else` expressions are converted to a series of [when/otherwise](https://docs.snowflake.com/developer-guide/snowpark/reference/scala/com/snowflake/snowpark/CaseExpr.html#when(condition:com.snowflake.snowpark.Column,value:com.snowflake.snowpark.Column):com.snowflake.snowpark.CaseExpr) expressions. + +*Source* + +```elm +if employee.lastName == name then + True +else + False +``` + +*Target* + +```scala + def checkLastName( + name: com.snowflake.snowpark.Column + )( + employee: myModel.Basic.Employee + )( + implicit sfSession: com.snowflake.snowpark.Session + ): com.snowflake.snowpark.Column = + com.snowflake.snowpark.functions.when( + (employee.lastName) === (name), + com.snowflake.snowpark.functions.lit(true) + ).otherwise(com.snowflake.snowpark.functions.lit(false)) +``` + +## Let definition values + +`Let` expressions are converted to a sequence of Scala `val` declarations: + +*Source* + +```elm +myFunc2: Int -> Int +myFunc2 x = + let + y = x + 1 + z = y + 1 + in + x + y + z +``` + +*Target* + +```scala + def myFunc2( + x: com.snowflake.snowpark.Column + )( + implicit sfSession: com.snowflake.snowpark.Session + ): com.snowflake.snowpark.Column = { + val y = (x) + (com.snowflake.snowpark.functions.lit(1)) + + val z = (y) + (com.snowflake.snowpark.functions.lit(1)) + + ((x) + (y)) + (z) + } +``` + +## Tuple values + +Tuples are treated as Snowflake [arrays](https://docs.snowflake.com/en/sql-reference/data-types-semistructured#array) . For example: + +*Source* + +```elm +let + y = x + 1 + z = y + 1 +in +(x, y, z) +``` + +*Target* + +```scala +{ + val y = (x) + (com.snowflake.snowpark.functions.lit(1)) + + val z = (y) + (com.snowflake.snowpark.functions.lit(1)) + + com.snowflake.snowpark.functions.array_construct( + x, + y, + z + ) +} +``` + +## Record values + +**TODO** + +## User defined function invocation values + +User defined functions are generated as Scala methods . This backend define the functions using [multiple parameter lists](https://docs.scala-lang.org/tour/multiple-parameter-lists.html) . + +```elm +aValue = addThreeNumbers 10 20 30 + +addThreeNumbers : Int -> Int -> Int -> Int +addThreeNumbers x y z = + x + y + z + +addTwo : Int -> Int -> Int +addTwo = addThreeNumbers 2 +``` + +*Target* + +```scala + def aValue: TypeNotConverted = + myModel.Basic.addThreeNumbers(com.snowflake.snowpark.functions.lit(10))(com.snowflake.snowpark.functions.lit(20))(com.snowflake.snowpark.functions.lit(30)) + + def addThreeNumbers( + x: com.snowflake.snowpark.Column + )( + y: com.snowflake.snowpark.Column + )( + z: com.snowflake.snowpark.Column + )( + implicit sfSession: com.snowflake.snowpark.Session + ): com.snowflake.snowpark.Column = + ((x) + (y)) + (z) + + def addTwo: com.snowflake.snowpark.Column => com.snowflake.snowpark.Column => com.snowflake.snowpark.Column = + myModel.Basic.addThreeNumbers(com.snowflake.snowpark.functions.lit(2)) +``` + +## Builtin function invocation values + +Builtin functions are converted using different strategies depending on each case. The following document contains a description of this case. + +# Value mappings for plain Scala operations + +**TODO** diff --git a/docs/snowpark/snowpark-backend.md b/docs/snowpark/snowpark-backend.md new file mode 100644 index 000000000..5a9e4f3bb --- /dev/null +++ b/docs/snowpark/snowpark-backend.md @@ -0,0 +1,525 @@ +--- +id: snowpark-backend +--- + +# Snowpark Backend + +**TODO** + +**Snowpark** backend uses Scala as its JVM language. + +## Generation conventions and strategies + +The **Snowpark** backend supports two basic code generation strategies: + +- Generating code that manipulates DataFrame expressions +- Generating "plain" Scala code + +The backend uses a series of conventions for deciding which strategy is used to convert the code of a function. The conventions apply to types and function definitions. + +### Type definition conventions + +Type definitions in the input **Morphir IR** are classified according to the following conventions: + +#### Records that represent tables + +Records are classified as "representing a table definition" according to the types of its members. A DataFrame compatible type is one of the following: + +- A basic datatype + - Int + - Float + - Bool + - String +- A [custom type](https://guide.elm-lang.org/types/custom_types.html) +- A [Maybe](https://package.elm-lang.org/packages/elm/core/latest/Maybe) type used with a DataFrame compatible type +- An [alias](https://guide.elm-lang.org/types/type_aliases) of a DataFrame compatible type + +An example of these kinds of records is the following: + +```elm +type alias Employee = + { firstName : String + , lastName : String + } +``` + + +The **Snowpark** backend generates the following code for each type definiton: + +```scala + trait Employee { + + def firstName: com.snowflake.snowpark.Column + + def lastName: com.snowflake.snowpark.Column + + } + + object Employee extends Employee{ + + def firstName: com.snowflake.snowpark.Column = + com.snowflake.snowpark.functions.col("firstName") + + def lastName: com.snowflake.snowpark.Column = + com.snowflake.snowpark.functions.col("lastName") + + val schema = com.snowflake.snowpark.types.StructType( + com.snowflake.snowpark.types.StructField( + "FirstName", + com.snowflake.snowpark.types.StringType, + false + ), + com.snowflake.snowpark.types.StructField( + "LastName", + com.snowflake.snowpark.types.StringType, + false + ) + ) + + def createEmptyDataFrame( + session: com.snowflake.snowpark.Session + ): com.snowflake.snowpark.DataFrame = + emptyDataFrameCache.getOrElseUpdate( + true, + session.createDataFrame( + Seq( + + ), + schema + ) + ) + + val emptyDataFrameCache: scala.collection.mutable.HashMap[Boolean, com.snowflake.snowpark.DataFrame] = new scala.collection.mutable.HashMap( + + ) + + } + + class EmployeeWrapper( + df: com.snowflake.snowpark.DataFrame + ) extends Employee{ + + def firstName: com.snowflake.snowpark.Column = + df("firstName") + + def lastName: com.snowflake.snowpark.Column = + df("lastName") + + } +``` + +This code includes: + +- A [trait](https://docs.scala-lang.org/tour/traits.html) with the definitions of the columns +- A [singleton object](https://docs.scala-lang.org/tour/singleton-objects.html) implementing the trait with the column definitions and an utility method to create an empty DataFrame for the current record +- A column wrapper class implementing the previous trait and giving access to the specific columns of a DataFrame + +#### Records representing Scala classes + +Records that contain fields that are not compatible with table column definitions are classified as "complex" and are generated as [Scala case classes](https://docs.scala-lang.org/tour/case-classes.html). + +Examples of these types are: + +- Lists +- Other record definitions +- Functions + +For example: + +```elm +type alias DataFromCompany + = + { employees : List Employee + , departments: List Department + } +``` + +The backend generates the following class for this record definition: + +```scala + case class DataFromCompany( + employees: com.snowflake.snowpark.DataFrame, + departments: com.snowflake.snowpark.DataFrame + ){} +``` + +#### Types representing DataFrames + +This backend considers lists of "records representing tables" as a [**Snowpark** DataFrame](https://docs.snowflake.com/en/developer-guide/snowpark/scala/working-with-dataframes) . For example: + + +```elm +getEmployeesWithLastName : String -> List Employee -> List Employee +getEmployeesWithLastName lastName employees = + employees + |> List.filter (\employee -> employee.lastName == lastName) +``` + +In this case references to `List Employee` are converted to DataFrames: + +```scala + def getEmployeesWithLastName( + lastName: com.snowflake.snowpark.Column + )( + employees: com.snowflake.snowpark.DataFrame + )( + implicit sfSession: com.snowflake.snowpark.Session + ): com.snowflake.snowpark.DataFrame = { + val employeesColumns: myModel.Basic.Employee = new myModel.Basic.EmployeeWrapper(employees) + + employees.filter((employeesColumns.lastName) === (lastName)) + } +``` + +### Custom types + +The **Snowpark** backend uses two conventions to deal with [custom types](https://guide.elm-lang.org/types/custom_types.html) used as a field of a *DataFrame record*. These conventions depend of the presence of parameters for type constructors. + +#### 1. Convention for custom types without data + +Custom types that define constructors without parameters are treated as a `String` (or `CHAR`, `VARCHAR`) column. + +For example: + +```elm +type CardinalDirection + = North + | South + | East + | West + +type alias Directions = + { + id : Int, + direction : CardinalDirection + } + +northDirections : List Directions -> List Directions +northDirections dirs = + dirs + |> List.filter (\e -> e.direction == North) +``` + +In this case the backend assumes that the code stored in a `Directions` table has a column of type `VARCHAR` or `CHAR` with text with the name of field. For example: + +| ID | DIRECTION | +|-----|------------| +| 10 | 'North' | +| 23 | 'East' | +| 43 | 'South' | + +As a convenience the backend generates a Scala object with the definition of the possible values: + +```Scala +object CardinalDirection{ + +def East: com.snowflake.snowpark.Column = + com.snowflake.snowpark.functions.lit("East") + +def North: com.snowflake.snowpark.Column = + com.snowflake.snowpark.functions.lit("North") + +def Sourth: com.snowflake.snowpark.Column = + com.snowflake.snowpark.functions.lit("South") + +def West: com.snowflake.snowpark.Column = + com.snowflake.snowpark.functions.lit("West") + +} +``` +Notice the use of [lit](https://docs.snowflake.com/developer-guide/snowpark/reference/scala/com/snowflake/snowpark/functions$.html#lit(literal:Any):com.snowflake.snowpark.Column) to indicate that we expect a literal string value for each constructor. + +This class is used where the value of the possible constructors is used. For example for the definition of `northDirections` above the comparison with `North` is generated as follows: + +```Scala + def northDirections( + dirs: com.snowflake.snowpark.DataFrame + )( + implicit sfSession: com.snowflake.snowpark.Session + ): com.snowflake.snowpark.DataFrame = { + val dirsColumns: myModel.Basic.Directions = new myModel.Basic.DirectionsWrapper(dirs) + + dirs.filter((dirsColumns.direction) === (myModel.Basic.CardinalDirection.North)) + } +``` + +#### 2. Convention for custom types with data + +In the case that a custom type has constructors with parameters this backend assumes that values of this type are stored in a [OBJECT column](https://docs.snowflake.com/en/sql-reference/data-types-semistructured#object) . + +The encoding of column is defined as follows: + +- Values are encoded as a `JSON` object +- A special property of this object called `__tag` is used to determine which variant is used in the current value +- All the parameters in order are stored in properties called `field0`, `field1`, `field2` ... `fieldN` + +Given the following custom type definition: + +```elm +type TimeRange = + Zero + | Seconds Int + | MinutesAndSeconds Int Int + +type alias TasksEstimations = + { + taskId : Int, + estimation : TimeRange + } +``` + +The data for `TaskEstimations estimation` is expected to be stored in a table using an `OBJECT` column: + +| TASKID | ESTIMATION | +|--------|-------------------------------------------------------------------| +| 10 | `{ "__tag": "Zero" }` | +| 20 | `{ "__tag": "MinutesAndSeconds", "field0": 10, "field1": 20 }` | +| 30 | `{ "__tag": "Seconds", "field0": 2 }` | + +Pattern matching operations that manipulate values of this type are generated as operations that process JSON expressions following this convention. + +For example: + +```elm +getTasksEstimationInSeconds : List TasksEstimations -> List { seconds : Int } +getTasksEstimationInSeconds tasks = + tasks + |> List.map (\t -> + let + seconds = + case t.estimation of + Zero -> + 0 + Seconds s -> + s + MinutesAndSeconds mins secs -> + mins*60 + secs + in + { seconds = seconds }) + +``` + +This code is generated as: + +```scala + def getTasksEstimationInSeconds( + tasks: com.snowflake.snowpark.DataFrame + )( + implicit sfSession: com.snowflake.snowpark.Session + ): com.snowflake.snowpark.DataFrame = { + val tasksColumns: myModel.Basic.TasksEstimations = new myModel.Basic.TasksEstimationsWrapper(tasks) + + tasks.select(com.snowflake.snowpark.functions.when( + (tasksColumns.estimation("__tag")) === (com.snowflake.snowpark.functions.lit("Zero")), + com.snowflake.snowpark.functions.lit(0) + ).when( + (tasksColumns.estimation("__tag")) === (com.snowflake.snowpark.functions.lit("Seconds")), + tasksColumns.estimation("field0") + ).when( + (tasksColumns.estimation("__tag")) === (com.snowflake.snowpark.functions.lit("MinutesAndSeconds")), + ((tasksColumns.estimation("field0")) * (com.snowflake.snowpark.functions.lit(60))) + (tasksColumns.estimation("field1")) + ).as("seconds")) + } + +``` + +### Function definition conventions + +These conventions are based on the input and return types of a function. There are strategies: using DataFrame expressions or using Scala expressions. The following sections have more details. + +#### Code generation using DataFrame expressions manipulation + +For functions that receive or return DataFrames, simple types, or records the generation strategy is to generate DataFrame expressions for example: + +Given the following functions: + +```elm +checkLastName : String -> Employee -> Bool +checkLastName name employee = + if employee.lastName == name then + True + else + False + +getEmployeeWithLastName : String -> List Employee -> List Employee +getEmployeeWithLastName lastName employees = + employees + |> List.filter (\e -> checkLastName lastName e) +``` + +In this case the backend generates the following code: + +```scala + def checkLastName( + name: com.snowflake.snowpark.Column + )( + employee: myModel.Basic.Employee + )( + implicit sfSession: com.snowflake.snowpark.Session + ): com.snowflake.snowpark.Column = + com.snowflake.snowpark.functions.when( + (employee.lastName) === (name), + com.snowflake.snowpark.functions.lit(true) + ).otherwise(com.snowflake.snowpark.functions.lit(false)) + + def getEmployeeWithLastName( + lastName: com.snowflake.snowpark.Column + )( + employees: com.snowflake.snowpark.DataFrame + )( + implicit sfSession: com.snowflake.snowpark.Session + ): com.snowflake.snowpark.DataFrame = { + val employeesColumns: myModel.Basic.Employee = new myModel.Basic.EmployeeWrapper(employees) + + employees.filter(myModel.Basic.checkLastName(lastName)(employeesColumns)) + } +``` + +Notice that language constructs are converted to DataFrame expression. For example in the way the `if` expression was converted to a combination of [`when`](https://docs.snowflake.com/ko/developer-guide/snowpark/reference/scala/com/snowflake/snowpark/functions$.html#when(condition:com.snowflake.snowpark.Column,value:com.snowflake.snowpark.Column):com.snowflake.snowpark.CaseExpr) and [`otherwise`](https://docs.snowflake.com/ko/developer-guide/snowpark/reference/scala/com/snowflake/snowpark/CaseExpr.html#otherwise(value:com.snowflake.snowpark.Column):com.snowflake.snowpark.Column) calls. + +#### Conventions for functions from values to lists of records + +If the function doesn't receive a DataFrame but produces lists of records, the strategy for code generation changes . In this case the convention assumes that an array of semi-structured objects is being created instead of a DataFrame. + +For example: + +```elm +type alias Department = { + name : String + } + +type Buildings + = B1 + | B2 + | B3 + +type alias DeptBuildingClassification = + { + deptName : String, + building : Buildings + } + +classifyDepartment : Department -> List DeptBuildingClassification +classifyDepartment dept = + if List.member dept.name ["HR", "IT"] then + [ { deptName = dept.name + , building = B1 } ] + else if String.startsWith "DEVEL" dept.name then + [ { deptName = dept.name + , building = B2 } + , { deptName = dept.name + , building = B3 } ] + else + [ ] + +getBuildings : List Department -> List DeptBuildingClassification +getBuildings depts = + depts + |> List.concatMap (\e -> classifyDepartment e) +``` + +Notice the function `classifyDepartment` which generates a list of records but does not receive a list of records. In this case the code is generated as: + +```scala + def classifyDepartment( + dept: myModel.Basic.Department + )( + implicit sfSession: com.snowflake.snowpark.Session + ): com.snowflake.snowpark.Column = + com.snowflake.snowpark.functions.when( + dept.name.in(Seq( + com.snowflake.snowpark.functions.lit("HR"), + com.snowflake.snowpark.functions.lit("IT") + )), + com.snowflake.snowpark.functions.array_construct(com.snowflake.snowpark.functions.array_construct( + dept.name, + myModel.Basic.Buildings.B1 + )) + ).otherwise(com.snowflake.snowpark.functions.when( + com.snowflake.snowpark.functions.startswith( + dept.name, + com.snowflake.snowpark.functions.lit("DEVEL") + ), + com.snowflake.snowpark.functions.array_construct( + com.snowflake.snowpark.functions.array_construct( + dept.name, + myModel.Basic.Buildings.B2 + ), + com.snowflake.snowpark.functions.array_construct( + dept.name, + myModel.Basic.Buildings.B3 + ) + ) + ).otherwise(com.snowflake.snowpark.functions.array_construct( + + ))) + + def getBuildings( + depts: com.snowflake.snowpark.DataFrame + )( + implicit sfSession: com.snowflake.snowpark.Session + ): com.snowflake.snowpark.DataFrame = { + val deptsColumns: myModel.Basic.Department = new myModel.Basic.DepartmentWrapper(depts) + + depts.select(myModel.Basic.classifyDepartment(myModel.Basic.Department).as("result")).flatten(com.snowflake.snowpark.functions.col("result")).select( + com.snowflake.snowpark.functions.as_char(com.snowflake.snowpark.functions.col("value")(0)).as("deptName"), + com.snowflake.snowpark.functions.col("value")(1).as("building") + ) + } +``` + +#### Code generation using Scala expressions + +When a function receives *"complex"* types as parameters the strategy is changed to use a Scala expression approach. + +For example: + +```elm +type alias EmployeeSal = + { firstName : String + , lastName : String + , salary : Float + } + + +type alias DataForCompany + = + { employees : List EmployeeSal + , departments: List Department + } + +avgSalaries : DataForCompany -> Float +avgSalaries companyData = + let + sum = companyData.employees + |> List.map (\e -> e.salary) + |> List.sum + count = companyData.employees + |> List.length + in + sum / (toFloat count) +``` + +In this case code for `avgSalaries` is going to perform a Scala division operation with the result of two DataFrame operations: + +```Scala + def avgSalaries( + companyData: myModel.Basic.DataForCompany + )( + implicit sfSession: com.snowflake.snowpark.Session + ): Double = { + val sum = companyData.employees.select(myModel.Basic.EmployeeSal.salary.as("result")).select(com.snowflake.snowpark.functions.coalesce( + com.snowflake.snowpark.functions.sum(com.snowflake.snowpark.functions.col("result")), + com.snowflake.snowpark.functions.lit(0) + )).first.get.getDouble(0) + + val count = companyData.employees.count + + (sum) / (count.toDouble) + } +``` + +Code generation for this strategy is meant to be used for code that manipulates the result of performing DataFrame operations . At this moment its coverage is very limited. + + + diff --git a/docs/snowpark/sp_caching_decoration.png b/docs/snowpark/sp_caching_decoration.png new file mode 100644 index 0000000000000000000000000000000000000000..d197a069ec918a4582d0bb2932228345d0de59b3 GIT binary patch literal 89220 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 Jhk-7}tH8zcOr);EQsU0`?|lE9R!g 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 literal 0 HcmV?d00001 diff --git a/redistributable/Snowpark/decorations/elm.json b/redistributable/Snowpark/decorations/elm.json new file mode 100644 index 000000000..ce2a08dc7 --- /dev/null +++ b/redistributable/Snowpark/decorations/elm.json @@ -0,0 +1,24 @@ +{ + "type": "application", + "source-directories": [ + "src" + ], + "elm-version": "0.19.1", + "dependencies": { + "direct": { + "elm/browser": "1.0.2", + "elm/core": "1.0.5", + "elm/html": "1.0.0" + }, + "indirect": { + "elm/json": "1.1.3", + "elm/time": "1.0.0", + "elm/url": "1.0.0", + "elm/virtual-dom": "1.0.3" + } + }, + "test-dependencies": { + "direct": {}, + "indirect": {} + } +} diff --git a/redistributable/Snowpark/decorations/morphir.json b/redistributable/Snowpark/decorations/morphir.json new file mode 100644 index 000000000..437165aec --- /dev/null +++ b/redistributable/Snowpark/decorations/morphir.json @@ -0,0 +1,4 @@ +{ + "name": "SnowparkGenCustomization", + "sourceDirectory": "src" +} diff --git a/redistributable/Snowpark/decorations/src/SnowparkGenCustomization/Decorations.elm b/redistributable/Snowpark/decorations/src/SnowparkGenCustomization/Decorations.elm new file mode 100644 index 000000000..fc1345efe --- /dev/null +++ b/redistributable/Snowpark/decorations/src/SnowparkGenCustomization/Decorations.elm @@ -0,0 +1,5 @@ +module SnowparkGenCustomization.Decorations exposing (..) + +type GenerationCustomization = + InlineElement + | CacheResult diff --git a/src/Morphir/Snowpark/FunctionMappingsForPlainScala.elm b/src/Morphir/Snowpark/FunctionMappingsForPlainScala.elm index 994c9d136..0e11d6f48 100644 --- a/src/Morphir/Snowpark/FunctionMappingsForPlainScala.elm +++ b/src/Morphir/Snowpark/FunctionMappingsForPlainScala.elm @@ -18,10 +18,12 @@ import Morphir.Snowpark.MapFunctionsMapping exposing (FunctionMappingTable , mapUncurriedFunctionCall , dataFrameMappings , dataFrameMappings) -import Morphir.Snowpark.MappingContext exposing (ValueMappingContext, isUnionTypeWithoutParams) +import Morphir.Snowpark.MappingContext exposing (ValueMappingContext, isUnionTypeWithoutParams, isCandidateForDataFrame) import Morphir.Snowpark.Operatorsmaps exposing (mapOperator) import Morphir.Snowpark.PatternMatchMapping exposing (PatternMatchValues) -import Morphir.Snowpark.ReferenceUtils exposing (errorValueAndIssue, mapLiteralToPlainLiteral) +import Morphir.Snowpark.ReferenceUtils exposing (errorValueAndIssue, curryCall, mapLiteralToPlainLiteral) +import Morphir.IR.Value as Value +import Morphir.IR.Value as Value mapValueForPlainScala : TypedValue -> ValueMappingContext -> ValueGenerationResult mapValueForPlainScala value ctx = @@ -95,6 +97,7 @@ specificMappings = , ( basicsFunctionName [ "negate" ], mapNegateFunction ) , ( basicsFunctionName [ "max" ], mapMaxMinFunction "max" ) , ( basicsFunctionName [ "min" ], mapMaxMinFunction "min" ) + , ( basicsFunctionName [ "to", "float"], mapToFloatFunctionCall ) ] |> Dict.fromList @@ -118,27 +121,46 @@ mapListRangeFunction ( _, args ) mapValue ctx = _ -> errorValueAndIssue "List range scenario not supported" + mapListMapFunction : (TypedValue, List (TypedValue)) -> Constants.MapValueType -> ValueMappingContext -> ValueGenerationResult -mapListMapFunction ( _, args ) mapValue ctx = +mapListMapFunction (( _, args ) as call) mapValue ctx = case args of [ action, collection ] -> - let - (mappedStart, startIssues) = mapMapPredicate action mapValue ctx - (mappedEnd, endIssues) = mapValue collection ctx - in - (Scala.Apply (Scala.Select mappedEnd "map") [ Scala.ArgValue Nothing mappedStart], startIssues ++ endIssues) + if isCandidateForDataFrame (Value.valueAttribute collection) ctx.typesContextInfo then + MapDfOperations.mapValue (curryCall call) ctx + else + let + (mappedStart, startIssues) = mapMapPredicate action mapValue ctx + (mappedEnd, endIssues) = mapValue collection ctx + in + (Scala.Apply (Scala.Select mappedEnd "map") [ Scala.ArgValue Nothing mappedStart], startIssues ++ endIssues) _ -> errorValueAndIssue "List map scenario not supported" mapListSumFunction : (TypedValue, List (TypedValue)) -> Constants.MapValueType -> ValueMappingContext -> ValueGenerationResult -mapListSumFunction ( _, args ) mapValue ctx = +mapListSumFunction (( _, args ) as call) mapValue ctx = + let + collectionComesFromDataFrameProjection : TypedValue -> Bool + collectionComesFromDataFrameProjection collection = + case collection of + ValueIR.Apply + _ + (ValueIR.Apply _ (Value.Reference _ ( [ [ "morphir" ], [ "s", "d", "k" ] ], [ [ "list" ] ], [ "map" ] )) _) + innerCollection -> + isCandidateForDataFrame (ValueIR.valueAttribute innerCollection) ctx.typesContextInfo + _ -> + False + in case args of [ collection ] -> - let - (mappedCollection, collectionIssues) = mapValue collection ctx - in - ( Scala.Apply (Scala.Select mappedCollection "reduce") [ Scala.ArgValue Nothing (Scala.BinOp (Scala.Wildcard) "+" (Scala.Wildcard)) ] - , collectionIssues) + if collectionComesFromDataFrameProjection collection then + MapDfOperations.mapValue (curryCall call) ctx + else + let + (mappedCollection, collectionIssues) = mapValue collection ctx + in + ( Scala.Apply (Scala.Select mappedCollection "reduce") [ Scala.ArgValue Nothing (Scala.BinOp (Scala.Wildcard) "+" (Scala.Wildcard)) ] + , collectionIssues) _ -> errorValueAndIssue "List sum scenario not supported" @@ -207,8 +229,6 @@ mapMapPredicate action mapValue ctx = _ -> mapValue action ctx - - mapForOperatorCall : Name.Name -> TypedValue -> TypedValue -> Constants.MapValueType -> ValueMappingContext -> ValueGenerationResult mapForOperatorCall optname left right mapValue ctx = let @@ -220,4 +240,15 @@ mapForOperatorCall optname left right mapValue ctx = in (Scala.BinOp leftValue operatorname rightValue , leftValueIssues ++ rightValueIssues ) - \ No newline at end of file + + +mapToFloatFunctionCall : (TypedValue, List TypedValue) -> Constants.MapValueType -> ValueMappingContext -> ValueGenerationResult +mapToFloatFunctionCall ( _, args ) mapValue ctx = + case args of + [ value ] -> + let + (mappedValue, valueIssues) = mapValue value ctx + in + (Scala.Select mappedValue "toDouble", valueIssues) + _ -> + errorValueAndIssue "`toFloat` scenario not supported" diff --git a/src/Morphir/Snowpark/LetMapping.elm b/src/Morphir/Snowpark/LetMapping.elm index 74160c504..d3c7b8af4 100644 --- a/src/Morphir/Snowpark/LetMapping.elm +++ b/src/Morphir/Snowpark/LetMapping.elm @@ -1,4 +1,4 @@ -module Morphir.Snowpark.LetMapping exposing (mapLetDefinition) +module Morphir.Snowpark.LetMapping exposing (mapLetDefinition, collectNestedLetDeclarations) import List import Morphir.IR.Name as Name diff --git a/src/Morphir/Snowpark/MapFunctionsMapping.elm b/src/Morphir/Snowpark/MapFunctionsMapping.elm index 780782ca0..3f9265e7e 100644 --- a/src/Morphir/Snowpark/MapFunctionsMapping.elm +++ b/src/Morphir/Snowpark/MapFunctionsMapping.elm @@ -35,6 +35,10 @@ import Morphir.Snowpark.ReferenceUtils exposing (errorValueAndIssue import Morphir.Snowpark.UserDefinedFunctionMapping exposing (tryToConvertUserFunctionCall) import Morphir.Snowpark.Utils exposing (collectMaybeList) import Morphir.Snowpark.Operatorsmaps exposing (mapOperator) +import Morphir.Snowpark.LetMapping exposing (collectNestedLetDeclarations) +import Morphir.Snowpark.MappingContext exposing (addLocalDefinitions) +import Morphir.IR.Type as Type +import Morphir.IR.Name as Name type alias MappingFunctionType = (TypedValue, List TypedValue) -> Constants.MapValueType -> ValueMappingContext -> ValueGenerationResult @@ -65,6 +69,7 @@ dataFrameMappings = , ( listFunctionName [ "concat", "map"], mapListConcatMapFunction ) , ( listFunctionName [ "concat" ], mapListConcatFunction ) , ( listFunctionName [ "sum" ], mapListSumFunction ) + , ( listFunctionName [ "length" ], mapListLengthFunction ) , ( maybeFunctionName [ "just" ], mapJustFunction ) , ( maybeFunctionName [ "map" ], mapMaybeMapFunction ) , ( maybeFunctionName [ "with", "default" ], mapMaybeWithDefaultFunction ) @@ -91,11 +96,14 @@ dataFrameMappings = , ( basicsFunctionName ["floor"] , mapFloorFunctionCall ) , ( basicsFunctionName ["min"] , mapMinMaxFunctionCall ("min", "<")) , ( basicsFunctionName ["max"] , mapMinMaxFunctionCall ("max", ">")) + , ( basicsFunctionName ["to", "float"] , mapToFloatFunctionCall ) , ( stringsFunctionName ["concat"] , mapStringConcatFunctionCall ) , ( stringsFunctionName ["to", "upper"] , mapStringCaseCall ("String.toUpper", "upper") ) , ( stringsFunctionName ["to", "lower"] , mapStringCaseCall ("String.toLower", "lower") ) , ( stringsFunctionName ["reverse"] , mapStringReverse ) , ( stringsFunctionName ["replace"] , mapStringReplace ) + , ( stringsFunctionName ["starts", "with"] , mapStartsEndsWith ("String.statsWith", "startswith") ) + , ( stringsFunctionName ["ends", "with"] , mapStartsEndsWith ("String.endsWith", "endswith") ) , ( ([["morphir"], ["s","d","k"]], [["aggregate"]], ["aggregate"]), mapAggregateFunction ) ] |> Dict.fromList @@ -177,7 +185,7 @@ mapListMemberFunction ( _, args ) mapValue ctx = in ( Scala.Apply (Scala.Select variable "in") [ Scala.ArgValue Nothing applySequence ], issues) _ -> - errorValueAndIssue "List.member scenario not converted" + errorValueAndIssue "`List.member` scenario not converted" mapListConcatMapFunction : (TypedValue, List TypedValue) -> Constants.MapValueType -> ValueMappingContext -> ValueGenerationResult mapListConcatMapFunction ( _, args ) mapValue ctx = @@ -333,6 +341,21 @@ mapListSumFunction ( _, args ) mapValue ctx = _ -> errorValueAndIssue "List sum scenario not supported" +mapListLengthFunction : (TypedValue, List TypedValue) -> Constants.MapValueType -> ValueMappingContext -> ValueGenerationResult +mapListLengthFunction ( _, args ) mapValue ctx = + case args of + [ elements ] -> + if isCandidateForDataFrame (ValueIR.valueAttribute elements) ctx.typesContextInfo then + let + (mappedCollection, collectionIssues) = + mapValue elements ctx + in + (Scala.Select mappedCollection "count", collectionIssues) + else + errorValueAndIssue "`List.length` scenario not supported" + _ -> + errorValueAndIssue "`List.length` scenario not supported" + generateForListSum : TypedValue -> ValueMappingContext -> Constants.MapValueType -> ValueGenerationResult generateForListSum collection ctx mapValue = case collection of @@ -393,7 +416,16 @@ generateForListFilter predicate sourceRelation ctx mapValue = (Scala.Apply (Scala.Ref (scalaPathToModule functionName) (functionName |> FQName.getLocalName |> Name.toCamelCase)) [Scala.ArgValue Nothing typeRefExpr], [])) _ -> - errorValueAndIssue "Unsupported filter function scenario2" + errorValueAndIssue "Unsupported filter function with referenced function" + (ValueIR.Apply ((Type.Function _ fromTpe toType) as tpe) _ _) as call -> + let + newLambda = + (ValueIR.Lambda + tpe + (ValueIR.AsPattern fromTpe (ValueIR.WildcardPattern fromTpe) [ "_t" ]) + (ValueIR.Apply toType call (ValueIR.Variable fromTpe [ "_t" ]))) + in + generateForListFilter newLambda sourceRelation ctx mapValue _ -> errorValueAndIssue "Unsupported filter function scenario" else @@ -529,17 +561,7 @@ processLambdaWithRecordBody functionExpr ctx mapValue = ValueIR.Lambda (TypeIR.Function _ _ returnType) (ValueIR.AsPattern _ _ _) (ValueIR.Record _ fields) -> if isAnonymousRecordWithSimpleTypes returnType ctx.typesContextInfo || isTypeRefToRecordWithSimpleTypes returnType ctx.typesContextInfo then - Just (fields - |> getFieldsInCorrectOrder returnType ctx - |> List.map (\(fieldName, value) -> - (Name.toCamelCase fieldName, (mapValue value ctx))) - |> List.map (\(fieldName, (value, issues)) -> - ((Scala.Apply - (Scala.Select value "as") - [ Scala.ArgValue Nothing (Scala.Literal (Scala.StringLit fieldName))]) - , issues)) - |> List.map (\(value, issues) -> (Scala.ArgValue Nothing value, issues)) - |> List.unzip) + processMapRecordFields fields returnType ctx mapValue else Nothing @@ -550,6 +572,9 @@ processLambdaWithRecordBody functionExpr ctx mapValue = mapValue expr ctx in Just ([Scala.ArgValue Nothing mappedBody], [ mappedBodyIssues ]) + else if isAnonymousRecordWithSimpleTypes returnType ctx.typesContextInfo + || isTypeRefToRecordWithSimpleTypes returnType ctx.typesContextInfo then + processLambdaBodyOfNonRecordLambda expr ctx mapValue else Nothing ValueIR.FieldFunction _ _ -> @@ -561,6 +586,52 @@ processLambdaWithRecordBody functionExpr ctx mapValue = _ -> Nothing + +processMapRecordFields : Dict (Name.Name) TypedValue -> Type () -> ValueMappingContext -> (Constants.MapValueType) -> Maybe ( List Scala.ArgValue, List (List GenerationIssue) ) +processMapRecordFields fields returnType ctx mapValue = + Just (fields + |> getFieldsInCorrectOrder returnType ctx + |> List.map (\(fieldName, value) -> + (Name.toCamelCase fieldName, (mapValue value ctx))) + |> List.map (\(fieldName, (value, issues)) -> + ((Scala.Apply + (Scala.Select value "as") + [ Scala.ArgValue Nothing (Scala.Literal (Scala.StringLit fieldName))]) + , issues)) + |> List.map (\(value, issues) -> (Scala.ArgValue Nothing value, issues)) + |> List.unzip) + +processLambdaBodyOfNonRecordLambda : TypedValue -> ValueMappingContext -> Constants.MapValueType -> Maybe ((List Scala.ArgValue, List (List GenerationIssue))) +processLambdaBodyOfNonRecordLambda body ctx mapValue = + case body of + (ValueIR.LetDefinition _ _ _ _) as topDefinition -> + let + (letDecls, letBodyExpr) = + collectNestedLetDeclarations topDefinition [] + (newCtx, resultIssues) = + letDecls + |> List.foldr + (\(name, def) (currentCtx, currentIssues) -> + let + (mappedDecl, issues) = + mapValue def.body currentCtx + newIssues = + currentIssues ++ issues + in + ( addReplacementForIdentifier name mappedDecl currentCtx + , newIssues)) + (ctx ,[]) + in + case letBodyExpr of + ValueIR.Record recordType fields -> + processMapRecordFields fields recordType newCtx mapValue + |> Maybe.map (\(args, issuesLst) -> (args, issuesLst ++ [resultIssues])) + _ -> + Nothing + + _ -> + Nothing + getFieldsInCorrectOrder : Type () -> ValueMappingContext -> Dict Name.Name TypedValue -> List (Name.Name, TypedValue) getFieldsInCorrectOrder originalType ctx fields = case originalType of @@ -736,6 +807,17 @@ mapMinMaxFunctionCall (morphirName, operator) ( _, args ) mapValue ctx = _ -> errorValueAndIssue ("`" ++ morphirName ++ " scenario not supported") +mapToFloatFunctionCall : (TypedValue, List TypedValue) -> Constants.MapValueType -> ValueMappingContext -> ValueGenerationResult +mapToFloatFunctionCall ( _, args ) mapValue ctx = + case args of + [ value ] -> + let + (mappedValue, valueIssues) = mapValue value ctx + in + (Constants.applySnowparkFunc "as_double" [ mappedValue ], valueIssues) + _ -> + errorValueAndIssue "`toFloat` scenario not supported" + mapFloorFunctionCall : (TypedValue, List TypedValue) -> Constants.MapValueType -> ValueMappingContext -> ValueGenerationResult mapFloorFunctionCall ( _, args ) mapValue ctx = case args of @@ -759,6 +841,18 @@ mapStringCaseCall (morphirName, spName) ( _, args ) mapValue ctx = _ -> errorValueAndIssue ("`" ++ morphirName ++ "` scenario not supported") +mapStartsEndsWith : (String, String) -> (TypedValue, List TypedValue) -> Constants.MapValueType -> ValueMappingContext -> ValueGenerationResult +mapStartsEndsWith (morphirName, spName) ( _, args ) mapValue ctx = + case args of + [ prefixOrSuffix, str ] -> + let + (mappedStr, strIssues) = mapValue str ctx + (mappedPrefixOrSuffix, prefixOrIssues) = mapValue prefixOrSuffix ctx + issues = strIssues ++ prefixOrIssues + in + (Constants.applySnowparkFunc spName [ mappedStr, mappedPrefixOrSuffix ], issues) + _ -> + errorValueAndIssue ("`" ++ morphirName ++ "` scenario not supported") mapStringReverse : (TypedValue, List TypedValue) -> Constants.MapValueType -> ValueMappingContext -> ValueGenerationResult mapStringReverse ( _, args ) mapValue ctx = diff --git a/src/Morphir/Snowpark/PatternMatchMapping.elm b/src/Morphir/Snowpark/PatternMatchMapping.elm index e18ebfee5..6ed1793a8 100644 --- a/src/Morphir/Snowpark/PatternMatchMapping.elm +++ b/src/Morphir/Snowpark/PatternMatchMapping.elm @@ -294,9 +294,9 @@ checkUnionWithParams expr cases ctx = ((WildcardPattern _, wildCardResult)::restReversed) -> (collectMaybeList checkConstructorForUnionOfWithParams restReversed) |> Maybe.map (\parts -> (UnionTypesWithParams parts (Just wildCardResult))) - ((ConstructorPattern _ _ [], _)::_) as constructorCases -> + ((ConstructorPattern _ _ _, _)::_) as constructorCases -> (collectMaybeList checkConstructorForUnionOfWithParams constructorCases) - |> Maybe.map (\parts -> (UnionTypesWithParams parts Nothing)) + |> Maybe.map (\parts -> (UnionTypesWithParams (List.reverse parts) Nothing)) _ -> Nothing else diff --git a/src/Morphir/Snowpark/ReferenceUtils.elm b/src/Morphir/Snowpark/ReferenceUtils.elm index e8e000305..790787221 100644 --- a/src/Morphir/Snowpark/ReferenceUtils.elm +++ b/src/Morphir/Snowpark/ReferenceUtils.elm @@ -8,13 +8,14 @@ module Morphir.Snowpark.ReferenceUtils exposing ( , getListTypeParameter , getFunctionInputTypes , mapLiteralToPlainLiteral - , errorValueAndIssue) + , errorValueAndIssue + , curryCall) import Morphir.IR.Name as Name import Morphir.IR.FQName as FQName import Morphir.IR.Literal exposing (Literal(..)) import Morphir.IR.Type as IrType -import Morphir.IR.Value as Value exposing (Value(..)) +import Morphir.IR.Value as Value exposing (Value(..), TypedValue) import Morphir.Scala.AST as Scala import Morphir.Snowpark.Constants as Constants import Morphir.Snowpark.MappingContext exposing (MappingContextInfo, isRecordWithSimpleTypes) @@ -101,4 +102,9 @@ getFunctionInputTypes tpe = errorValueAndIssue : GenerationIssue -> (Scala.Value, List GenerationIssue) errorValueAndIssue issue = - (Scala.Literal (Scala.StringLit issue), [ issue ]) \ No newline at end of file + (Scala.Literal (Scala.StringLit issue), [ issue ]) + +curryCall : (TypedValue, List (TypedValue)) -> TypedValue +curryCall (func, args) = + args + |> List.foldl (\arg current -> Value.Apply (Value.valueAttribute arg) current arg) func \ No newline at end of file diff --git a/src/Morphir/Snowpark/TypeRefMapping.elm b/src/Morphir/Snowpark/TypeRefMapping.elm index fbd5b5aeb..c706b53da 100644 --- a/src/Morphir/Snowpark/TypeRefMapping.elm +++ b/src/Morphir/Snowpark/TypeRefMapping.elm @@ -89,7 +89,7 @@ checkForBasicTypeToScala tpe ctx = Reference _ ([ [ "morphir" ], [ "s", "d", "k" ] ],[ [ "basics" ] ], [ "double" ]) _ -> Just <| Scala.TypeVar "Double" Reference _ ([ [ "morphir" ], [ "s", "d", "k" ] ],[ [ "basics" ] ], [ "bool" ]) _ -> - Just <| Scala.TypeVar "Bool" + Just <| Scala.TypeVar "Boolean" Reference _ ([ [ "morphir" ], [ "s", "d", "k" ] ], [ [ "string" ] ], [ "string" ]) _ -> Just <| Scala.TypeVar "String" Reference _ fullName [] -> @@ -204,6 +204,8 @@ mapTypeReferenceToBuiltinTypes tpe ctx = Scala.TypeVar "Double" Type.Reference _ ( [ [ "morphir" ], [ "s", "d", "k" ] ], [ [ "basics" ] ], [ "int" ] ) [] -> Scala.TypeVar "Int" + Type.Reference _ ( [ [ "morphir" ], [ "s", "d", "k" ] ], [ [ "string" ] ], [ "string" ] ) [] -> + Scala.TypeVar "String" Type.Reference _ fullTypeName [] -> if isTypeAlias fullTypeName ctx then resolveTypeAlias fullTypeName ctx diff --git a/src/Morphir/Snowpark/Utils.elm b/src/Morphir/Snowpark/Utils.elm index 98481d719..997fd57b0 100644 --- a/src/Morphir/Snowpark/Utils.elm +++ b/src/Morphir/Snowpark/Utils.elm @@ -26,4 +26,4 @@ collectMaybeListAux action aList current = |> Maybe.map (\newFirst -> collectMaybeListAux action rest (newFirst::current)) |> Maybe.withDefault Nothing [] -> - Just (List.reverse current) \ No newline at end of file + Just (List.reverse current)