Si, certamente. In effetti così non si capisce.. è una roba un po' perversina che avviene solo con specifiche query sql e infatti m'è uscita fuori dopo anni di funzionamento senza traumi di un demone che cataloga messaggi mail.
Cerco di raccontarla con un esempio, è un po' un rimpallo di chiamate però.
Allora... immaginiamo di avere un'applicazione che si connette ad un db postgres tramite sqldb e che debba eseguire un comando sql un po' strano simile a questo:
INSERT INTO test(testo, dataora, dataora2) values (''DUMMY\'',(timestamp ''2023-09-08 11:14:16''),(timestamp ''2023-09-08 11:14:16''))
(ovviamente c'è una tabella test con un campo varchar-qualcosa e 2 campi timestamp without timezone).
Quando viene fatta la prepare della query, sqldb esegue questo codice:
procedure TCustomSQLStatement.DoPrepare;
[...]
Database.PrepareStatement(FCursor,Transaction,FServerSQL,FParams);
[...]
che esegue la procedura
procedure TPQConnection.PrepareStatement
[...]
AParams.ParseSQL(buf,false,sqEscapeSlash in ConnOptions, sqEscapeRepeat in ConnOptions,psPostgreSQL)
[...]
che a sua volta richiama nella unit DB questo codice:
function TParams.DoParseSQL(SQL: String; Options : TSQLParseOptions; ParameterStyle: TParamStyle; out
ParamBinding: TParambinding; MacroChar : Char; out ReplaceString: string): String;
[...]
while SkipComments(p,spoEscapeSlash in Options ,spoEscapeRepeat in options) do ;
[...]
quest'ultima viene quindi invocata con il parametro dell'escape slash a true perchè travasato dalle ConnOptions della connessione:
function SkipComments(var p: PChar; EscapeSlash, EscapeRepeat : Boolean) : Boolean;
[...]
SkipQuotesString(p, p^, EscapeSlash, EscapeRepeat);
[...]
che richiama:
procedure SkipQuotesString(var p : pchar; QuoteChar : char; EscapeSlash, EscapeRepeat : Boolean);
[...]
if EscapeSlash and (p^='\') and (p[1] <> #0) then Inc(p,2) // make sure we handle \' and \\ correct
[...]
che interpreta malamente la stringa SQL e fa fallire la prepare.
Gli viene passata una stringa sql un po' stramba che non andrebbe analizzata ma come faccio ad evitare che bypassi la ricerca dei parametri senza escape degli slash? Dovrei levare sqEscapeSlash dalla ConnOptions della connessione al db ma mi pare non si possa. Sto perdendo di vista la luna concentrato sul dito?
Per tamponare 2 workaround possono essere o quello di derivare una classe da TPQConnection per poi andare a eliminare il parametro da FConnOptions che è protected oppure quello di sterilizzare lo slash della query con ma mi chiedevo se stavo perdendo di vista una via più semplice e pulita.
Grazie!!