Interpolated strings and SQL
Walter Bright
newshound2 at digitalmars.com
Tue Jan 9 23:21:34 UTC 2024
P.S. Thank you for your well constructed arguments.
On 1/9/2024 1:35 PM, Nickolay Bukreyev wrote:
> A valid point, thanks. Could you test if that fixes the issue?
Yes, that works.
> We are probably talking about different things. Adam’s implementation constructs
> a format string at compile time thanks to `enum` storage class [in line
> 36](https://github.com/adamdruppe/interpolation-examples/blob/a8a5d4d4ee37ee9ae3942c4f4e8489011c3c4673/lib/sql.d#L36).
Yes, you're right.
> Constructing it at compile time is essential so that we can validate the generated SQL and abort compilation, as Paolo [demonstrated](https://forum.dlang.org/post/qbtbyxcglwijjbeygtvi@forum.dlang.org).
That only checks one aspect of correctness - nested string interpolations.
>> execi could be extended to reject arguments that contain %s sequences.
> I disagree. Storing a string that contains `%s` in a database should be allowed
> (storing any string should obviously be allowed, regardless of its contents).
True, which is why a % that is not intended as a format specifier is entered as %%.
> But `execi` is unable to differentiate between a string that happens to contain
> `%s` and a nested format string:
>
> ```
> // DIP1027
> example(i"prefix1 $(i"prefix2 $(x) suffix2") suffix1");
> // Gets rewritten as:
> example("prefix1 %s suffix1", "prefix2 %s suffix2", x);
> ```
>
> I might be wrong, but it appears to me that DIP1027 is not able to deal with
> nested format strings, in a general case.
The expansion for `example` has a mismatch in the number of formats (1) and
number of arguments (2). This can be detected at runtime by `example`, as I've
explained.
A compile time way is DIP1027 can be modified to reject any arguments that
consist of tuples with other than one element. This would eliminate nested
istring tuples at compile time.
> DIP1036 has no such limitation
> (demonstrated in point 2
> [here](https://forum.dlang.org/post/lizjwxdgsnmgykaoczyf@forum.dlang.org)).
DIP1036 cannot detect other problems with the string literals. It seems like a
lot of complexity to deal with only one issue with malformed strings at compile
time rather than runtime.
> I explained
> [here](https://forum.dlang.org/post/qkvxnbqjefnvjyytfana@forum.dlang.org) why
> these two arguments are valuable. Aren’t free of cost—correct unless you enable
> inlining. `execi` may require some changes (like `filterOutEmpty` I showed
> above) to make them free of cost, but it is doable.
You'd have to also make every formatted writer a template, and add the filter to
them.
> You are right, it doesn’t. Timon’s point (expressed as “This does not work”) is
> that DIP1036 is able to do validation at compile time while DIP1027 is only able
> to do it at runtime, when this function actually gets invoked.
The only validation it does is check for nested string interpolations.
More information about the Digitalmars-d
mailing list