1
votes

In M language, there is Type.ForRecord function which can be used to create a record type dynamically.

// These two expressios are exchangeable

type [A = Int64.Type, optional B = text]

Type.ForRecord(
    [
         A = [Type = type number, Optional = false],
         B = [Type = type text, Optional = true]
    ],
    false
)

Using this, we are able to create a new record type based on an existing type with an additional field like below.

// These two expressions are exchangeable

type [A = Int64.Type, optional B = text, optional C = date]

let
    existingType = [A = Int64.Type, optional B = text],
    newFieldName = "C",
    newFieldType = type date
in
    Type.ForRecord(
        Record.AddField(
            Type.RecordFields(existingType),
            newFieldName,
            [Type = newFieldType, Optional = true]
        ),
        false
    )

Now, I am looking for a way to do a similar thing with table types. I want to be able to modify an existing table type adding a new column. The name and the type of the new column is dynamically determined in the runtime.

// I want this result

type table [A = Int64.Type, B = text, C = date]

// How can I create a new table type adding column `C = date`?

let
    existingType = type table [A = Int64.Type, B = text],
    newColumnName = "C",
    newColumnType = type date
in
    ...

I was expecting there is a function like Type.ForTable, but I could not find such. Is there any idea?

1

1 Answers

3
votes

The trivial way to do this is as follows:

newType = type table [A = Int64.Type, B = text, newFieldName = newFieldType]

But that isn't going to work if your existingType is dynamic.


If you keep your existingType definition as a generic record (rather than a table), you can get the new table type by casting it to a table type after adding the new record field.

let
    existingType = type /*no table here*/ [A = Int64.Type, B = text],
    newFieldName = "C",
    newFieldType = type date,
    newType =
    Type.ForRecord(
        Record.AddField(
            Type.RecordFields(existingType),
            newFieldName,
            [Type = newFieldType, Optional = false]
        ),
        false
    ),
    newTableType = type table newType
in
    newTableType