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