Thanks, I'm going to have to do that I guess.
It should also be noted that nowhere in the documentation for JSON_OBJECT does it mention this behavior.
In fact, it says: "JSON_OBJECT returns object values as either a string (enclosed in double quotes), or a number. Numbers are returned in canonical format. A numeric string is returned as a literal, enclosed in double quotes. All other data types (for example, Date or $List) are returned as a string"
Which also isn't true for another reason as it returns booleans as true/false
Yes, I need the plain old value as a string in the JSON output as you say.
I also don't have control over the saving (for this process at least).
I was thinking of maybe appending $CHAR(0) to the end of every non-null string in the select query itself and the just running a $replace on the string, but there are fields that have been set to empty string from SQL (UPDATE Whatever SET Field = '' WHERE ID = 8) which is then returned by CachéSQL as $CHAR(0).
Maybe append something in the $CHAR(128) to $CHAR(159) range since we're running 8 bit Caché and the modified version of 8859-1 that Caché uses doesn't seem to use those characters?
I can build these structures manually but JSON_OBJECT promised such simplicity and it's annoying to find out it interprets the values instead of just passing them through. (And breaking on "{I'm not JSON despite the curly braces}" type strings)
If anyone is curious, I did manage to get around this with an ugly workaround:
And then replacing the CHAR(128) later:
Set item = $REPLACE(item, $CHAR(128), "")
Note: We are running 8-bit Caché, not Unicode, so $CHAR(128) is unused and available for us as a placeholder