0

I need to pass a string representation of a <string,string> map into my U-SQL program, and deserialize it into a C# Dictionary<string,string> so I can then turn it to a U-SQL SqlMap. I need to do it in a constant-foldable way. My most recent attempt:

DECLARE @MapStr string = "{\"key\": \"val\"}";
DECLARE CONST @map = new SqlMap<string,string>(JsonConvert.DeserializeObject<Dictionary<string, string>>(@MapStr));

Fails with "E_CSC_USER_EXPRESSIONNOTCONSTANTFOLDABLE: Expression cannot be constant folded."

I have found numerous ways to deserialize a string into a map, but none so far were constant foldable. I can't find a list of constant-foldable c# expressions, which would also be helpful here.

Alex
  • 139
  • 1
  • 7

2 Answers2

0

From the docs:

... can be computed at compile time (so called constant-foldable expressions)

In C# constants are defined as:

immutable values which are known at compile time and do not change for the life of the program. Constants are declared with the const modifier. Only the C# built-in types (excluding System.Object) may be declared as const. User-defined types, including classes, structs, and arrays, cannot be const.

So it seems you can use only what can be defined as constant in C#, so you are limited to expressions of built-in types (excluding System.Object).

Guru Stron
  • 102,774
  • 10
  • 95
  • 132
  • Thanks for the links! This is interesting, as the doc specifically says arrays cannot be const, yet we have achieved this using the String.Split() function-- I guess this works because string expressions are const foldable, so even if the result is an array, it's fine? Sadly I don't see any String functions that could make a map. Do you think the best move is to just use 2 ordered arrays (key array and value array)? – Alex Jun 29 '20 at 21:56
  • @Alex, interesting. If it works with arrays, maybe try `... @map =new SqlMap { {"key", "val"}};` ? – Guru Stron Jun 29 '20 at 22:01
  • Sadly, I can't do that because the key-value pairs must be passed into the program as a string, so I'm missing the link between the string and the expression you suggested (which does seem to be const-foldable!). Any thoughts on how to get it into that form? – Alex Jun 29 '20 at 22:11
  • @Alex I'm out of my depth here. Is this string passed into the program in runtime or compile time? – Guru Stron Jun 29 '20 at 22:16
  • 1
    It's at compile time--the way it works is it adds DECLARE statements (like the first line in my code snippet) to the top of the main script, which we then parse into other types if needed. It's being called by ADF, and we are only able to pass strings from ADF to ADLA. No worries if it seems impossible! If that's the case I'll just use ordered arrays, which is annoying but works. – Alex Jun 29 '20 at 22:22
0

In case anyone else was curious, I believe this is not possible:

  • Only String and built-in type expressions are constant-foldable, excluding Objects (such as arrays and maps). (see other answer for links on this)
  • There are no built-in expressions or String expressions that evaluate to a SqlMap
  • Therefore there are no constant-foldable expressions that evaluate to a SqlMap

For my specific purposes, I was able to use a configuration file that created CONST SqlMaps and use this, but that would not be a possibility if we had more than a finite set of possible inputs.

Alex
  • 139
  • 1
  • 7