So I'm trying to create a function that dynamically projects a column from the source table based on a string columnName field, and I found the column_ifexits function which seems to (mostly) meet my needs. So if I do something like this:
MyTable (FooA:string, FooB:string, FooC:string)
.create-or-alter function GetFoo(columnName:string = 'FooA')
{
MyTable
| project Foo = column_ifexists(columnName, FooA)
}
This mostly works. If I pass a valid field name to GetFoo(), I get a projection of just that column from the source table. If I pass an invalid field name, or omit the field name paramter, I get a projection of the FooA column from the source table. Great. The only problem is, if I pass an empty string to the GetFoo() function, I get an exception:
column_ifexists(): argument #1 must be a non-empty string literal
So I figure, "okay, that should be relatively simple to fix," and I make the following adjustment:
.create-or-alter function GetFoo(columnName:string = 'FooA')
{
let columnNameFixed = iff(isempty(columnName), 'FooA', columnName);
MyTable
| project Foo = column_ifexists(columnNameFixed, FooA)
}
But now, no matter what I pass in to the function, I get this exception:
column_ifexists(): argument #0 must be string literal
I tried wrapping the iff() call in a call to toscalar() which the docs specifically say should return a constant, but that's apparently not good enough. So how can I possibly fix this function to properly handle an empty string input? And if anyone know why column_ifexists doesn't just automatically treat the empty string input as a non-existent column name and return the specified default column, I'd love to hear about it.