{**
Checks whether escape syntax is used.
@return a True if escape syntax is used.
}
function TZPostgreSQLQuoteState.CheckEscapeSyntax(Stream: TStream): Boolean;
var
ReadChar: Char;
begin
Result := not FStandardConformingStrings;
if FStandardConformingStrings then
begin
Stream.Seek(-SizeOf(Char), soFromCurrent);
if Stream.Position >= SizeOf(Char) then
begin
Stream.Seek(-SizeOf(Char), soFromCurrent);
Stream.Read(ReadChar, SizeOf(Char));
Result := UpperCase(ReadChar) = 'E';
Stream.Seek(SizeOf(Char), soFromCurrent);
end;
end;
end;
{**
Return a quoted string token from a reader. This method
will collect characters until it sees a match to the
character that the tokenizer used to switch to this state.
@return a quoted string token from a reader
}
function TZPostgreSQLQuoteState.NextToken(Stream: TStream;
FirstChar: Char; Tokenizer: TZTokenizer): TZToken;
const BackSlash = Char('\');
var
ReadChar: Char;
LastChar: Char;
QuoteCount: Integer;
EscapeSyntax: Boolean;
begin
Result.Value := FirstChar;
QuoteCount := 1;
EscapeSyntax := False;
if FirstChar = '"' then
begin
Result.TokenType := ttWord;
end
else
begin
Result.TokenType := ttQuoted;
EscapeSyntax := CheckEscapeSyntax(Stream);
end;
LastChar := #0;
while Stream.Read(ReadChar, SizeOf(Char)) > 0 do
begin
if ReadChar = FirstChar then
Inc(QuoteCount);
if (LastChar = FirstChar) and (ReadChar <> FirstChar) then
begin
if QuoteCount mod 2 = 0 then
begin
Stream.Seek(-SizeOf(Char), soFromCurrent);
Break;
end;
end;
Result.Value := Result.Value + ReadChar;
if (LastChar = BackSlash) and EscapeSyntax then
LastChar := #0
else if (LastChar = FirstChar) and (ReadChar = FirstChar) then
LastChar := #0
else LastChar := ReadChar;
end;
end;
It does what we just need. All we have to do is set FStandardComformingStrings to a valid value.
did commit a fix for your test according Ansi-IDE's and UTF8 Strings.
Also did i manipulate the EscapeString function again. I created an overload for D12_UP and added my ZPlainString function to the Ansi IDE's to avoid bad encoded escape behavior.
Look at my modified tokenizer.
This i understand. Other possibility is you create a ttWord childstate. "E" is a word state. If you check the next char for "\" or"'" then go on reading and change the result state(dependend on StandartConfirmingStrings)...
This detection brings up a new question: Which state will this detected sequence have?
Other possibility is you create a ttWord childstate. "E" is a word state. If you check the next char for "\" or"'" then go on reading and change the result state(dependend on StandartConfirmingStrings).
Yes, it's also a good algorythm. But it's only "'" you have to check. "\" can't follow E.
this is slightly annoying. Hmpf if i do understand all this correctly do you slightly rebuild the whole tokenizer of PostgreSQL. Which is needed for user generated external sended statments.
I don't know and didn't expect such a syntax...
Our issues are now only the external sended Statements after Fixing the Escape behavior for Parameter values, right?
Next thing i don't like: example of stUnicodeStream.
First we do UTF8ToString(in Blob.GetUnicodeString)- then on EscapeString(UTF8Encode(Value), PlainEscaping(AnsiValue), UTF8ToString(AnsiValue))-> then send Statment: UTF8Encode(on sending the query).
What about speed decrease here? Only to be 100% unicode safe? Isn't that a stupid sh...it?
I planned to avoid such stupid things, an overloaded Statement execution for D12_UP. You can find some abstract definitions in ZDbcStatement.pas. But i had not the time to complete this. IF that would be ready then we encode the strings only once and no issues to see. (The reason for my overload of today)
Which doesn't solves the issues from external sended statments, except the user uses this new overload..
Zeos7_branches_ testing_r1637 compiles and runs on D2006, DXE2 32/64, LazarusWin1.1.0/fpc 2.7.1 32/64. (With a small exception on Oracle AQ$_QUEUES in DXE2-32).
Zeos7_branches_ testing_r1640 compiles and runs on D2006, DXE2 32/64, LazarusWin1.1.0/fpc 2.7.1 32/64. (With a small exception on Oracle AQ$_QUEUES in DXE2-32).
2012-08-18 13:52:01 CEST [127.0.0.1(49731)]/prosalon prosalon_apo STATEMENT: select *,null as typ_upustu_tmp, null as czas_trwania_tmp,null as thumb from (SELECT * from data.klienci
)q WHERE (imie ~ 'ed') AND (usr_status >= 0)
difference is imie ~* 'ed' versus imie ~ 'ed'.
whit PrepareSQL=false query send to postgres is correct and i got expected results.