1 {*********************************************************}
3 { Zeos Database Objects }
4 { PostgreSQL Database Connectivity Classes }
6 { Originally written by Sergey Seroukhov }
7 { and Sergey Merkuriev }
9 {*********************************************************}
11 {@********************************************************}
12 { Copyright (c) 1999-2012 Zeos Development Group }
14 { License Agreement: }
16 { This library is distributed in the hope that it will be }
17 { useful, but WITHOUT ANY WARRANTY; without even the }
18 { implied warranty of MERCHANTABILITY or FITNESS FOR }
19 { A PARTICULAR PURPOSE. See the GNU Lesser General }
20 { Public License for more details. }
22 { The source code of the ZEOS Libraries and packages are }
23 { distributed under the Library GNU General Public }
24 { License (see the file COPYING / COPYING.ZEOS) }
25 { with the following modification: }
26 { As a special exception, the copyright holders of this }
27 { library give you permission to link this library with }
28 { independent modules to produce an executable, }
29 { regardless of the license terms of these independent }
30 { modules, and to copy and distribute the resulting }
31 { executable under terms of your choice, provided that }
32 { you also meet, for each linked independent module, }
33 { the terms and conditions of the license of that module. }
34 { An independent module is a module which is not derived }
35 { from or based on this library. If you modify this }
36 { library, you may extend this exception to your version }
37 { of the library, but you are not obligated to do so. }
38 { If you do not wish to do so, delete this exception }
39 { statement from your version. }
42 { The project web site is located on: }
43 { http://zeos.firmos.at (FORUM) }
44 { http://sourceforge.net/p/zeoslib/tickets/ (BUGTRACKER)}
45 { svn://svn.code.sf.net/p/zeoslib/code-0/trunk (SVN) }
47 { http://www.sourceforge.net/projects/zeoslib. }
50 { Zeos Development Group. }
51 {********************************************************@}
53 unit ZDbcPostgreSqlUtils;
60 Classes, {$IFDEF MSEgui}mclasses,{$ENDIF} SysUtils,
61 ZDbcIntfs, ZPlainPostgreSqlDriver, ZDbcPostgreSql, ZDbcLogging,
62 ZCompatibility, ZVariant;
65 Indicate what field type is a number (integer, float and etc.)
66 @param the SQLType field type value
67 @result true if field type number
69 function IsNumber(Value: TZSQLType): Boolean;
72 Return ZSQLType from PostgreSQL type name
73 @param Connection a connection to PostgreSQL
74 @param The TypeName is PostgreSQL type name
75 @return The ZSQLType type
77 function PostgreSQLToSQLType(Connection: IZPostgreSQLConnection;
78 TypeName: string): TZSQLType; overload;
81 Another version of PostgreSQLToSQLType()
82 - comparing integer should be faster than AnsiString?
83 Return ZSQLType from PostgreSQL type name
84 @param Connection a connection to PostgreSQL
85 @param TypeOid is PostgreSQL type OID
86 @return The ZSQLType type
88 function PostgreSQLToSQLType(const ConSettings: PZConSettings;
89 const OIDAsBlob: Boolean; const TypeOid: Integer): TZSQLType; overload;
92 Return PostgreSQL type name from ZSQLType
93 @param The ZSQLType type
94 @return The Postgre TypeName
96 function SQLTypeToPostgreSQL(SQLType: TZSQLType; IsOidAsBlob: Boolean): string;
99 add by Perger -> based on SourceForge:
100 [ 1520587 ] Fix for 1484704: bytea corrupted on post when not using utf8,
103 Converts a binary string into escape PostgreSQL format.
104 @param Value a binary stream.
105 @return a string in PostgreSQL binary string escape format.
107 function EncodeBinaryString(const Value: AnsiString): AnsiString;
110 Encode string which probably consists of multi-byte characters.
111 Characters ' (apostraphy), low value (value zero), and \ (back slash) are encoded. Since we have noticed that back slash is the second byte of some BIG5 characters (each of them is two bytes in length), we need a characterset aware encoding function.
112 @param CharactersetCode the characterset in terms of enumerate code.
113 @param Value the regular string.
114 @return the encoded string.
116 function PGEscapeString(Handle: Pointer; const Value: RawByteString;
117 ConSettings: PZConSettings; WasEncoded: Boolean = False): RawByteString;
120 Converts an string from escape PostgreSQL format.
121 @param Value a string in PostgreSQL escape format.
122 @return a regular string.
124 function DecodeString(const Value: AnsiString): AnsiString;
127 Checks for possible sql errors.
128 @param Connection a reference to database connection to execute Rollback.
129 @param PlainDriver a PostgreSQL plain driver.
130 @param Handle a PostgreSQL connection reference.
131 @param LogCategory a logging category.
132 @param LogMessage a logging message.
133 @param ResultHandle the Handle to the Result
136 function CheckPostgreSQLError(Connection: IZConnection;
137 PlainDriver: IZPostgreSQLPlainDriver;
138 Handle: PZPostgreSQLConnect; LogCategory: TZLoggingCategory;
139 const LogMessage: string;
140 ResultHandle: PZPostgreSQLResult): String;
144 Resolve problem with minor version in PostgreSql bettas
145 @param Value a minor version string like "4betta2"
146 @return a miror version number
148 function GetMinorVersion(const Value: string): Word;
151 Prepares an SQL parameter for the query.
152 @param ParameterIndex the first parameter is 1, the second is 2, ...
153 @return a string representation of the parameter.
155 function PGPrepareAnsiSQLParam(Value: TZVariant; Connection: IZPostgreSQLConnection;
156 PlainDriver: IZPostgreSQLPlainDriver; const ChunkSize: Cardinal;
157 const InParamType: TZSQLType; const oidasblob, DateTimePrefix, QuotedNumbers: Boolean;
158 ConSettings: PZConSettings): RawByteString;
162 uses ZMessages, ZDbcPostgreSqlResultSet, ZEncoding, ZDbcPostgreSqlStatement;
165 Return ZSQLType from PostgreSQL type name
166 @param Connection a connection to PostgreSQL
167 @param The TypeName is PostgreSQL type name
168 @return The ZSQLType type
170 function PostgreSQLToSQLType(Connection: IZPostgreSQLConnection;
171 TypeName: string): TZSQLType;
173 TypeName := LowerCase(TypeName);
174 if (TypeName = 'interval') or (TypeName = 'char') or (TypeName = 'bpchar')
175 or (TypeName = 'varchar') or (TypeName = 'bit') or (TypeName = 'varbit')
176 then//EgonHugeist: Highest Priority Client_Character_set!!!!
177 if (Connection.GetConSettings.CPType = cCP_UTF16) then
178 Result := stUnicodeString
181 else if TypeName = 'text' then
182 Result := stAsciiStream
183 else if TypeName = 'oid' then
185 if Connection.IsOidAsBlob() then
186 Result := stBinaryStream
190 else if TypeName = 'name' then
192 else if TypeName = 'enum' then
194 else if TypeName = 'cidr' then
196 else if TypeName = 'inet' then
198 else if TypeName = 'macaddr' then
200 else if TypeName = 'int2' then
202 else if TypeName = 'int4' then
204 else if TypeName = 'int8' then
206 else if TypeName = 'float4' then
208 else if (TypeName = 'float8') or (TypeName = 'decimal')
209 or (TypeName = 'numeric') then
211 else if TypeName = 'money' then
213 else if TypeName = 'bool' then
215 else if TypeName = 'date' then
217 else if TypeName = 'time' then
219 else if (TypeName = 'datetime') or (TypeName = 'timestamp')
220 or (TypeName = 'timestamptz') or (TypeName = 'abstime') then
221 Result := stTimestamp
222 else if TypeName = 'regproc' then
224 else if TypeName = 'bytea' then
226 if Connection.IsOidAsBlob then
229 Result := stBinaryStream;
231 else if (TypeName = 'int2vector') or (TypeName = 'oidvector') then
232 Result := stAsciiStream
233 else if (TypeName <> '') and (TypeName[1] = '_') then // ARRAY TYPES
234 Result := stAsciiStream
238 if (Connection.GetConSettings.CPType = cCP_UTF16) then
239 if Result = stAsciiStream then
240 Result := stUnicodeStream;
244 Another version of PostgreSQLToSQLType()
245 - comparing integer should be faster than AnsiString.
246 Return ZSQLType from PostgreSQL type name
247 @param Connection a connection to PostgreSQL
248 @param TypeOid is PostgreSQL type OID
249 @return The ZSQLType type
251 function PostgreSQLToSQLType(const ConSettings: PZConSettings;
252 const OIDAsBlob: Boolean; const TypeOid: Integer): TZSQLType; overload;
255 1186,18,1042,1043: { interval/char/bpchar/varchar }
256 if (ConSettings.CPType = cCP_UTF16) then
257 Result := stUnicodeString
260 25: Result := stAsciiStream; { text }
264 Result := stBinaryStream
268 19: Result := stString; { name }
269 21: Result := stShort; { int2 }
270 23: Result := stInteger; { int4 }
271 20: Result := stLong; { int8 }
272 650: Result := stString; { cidr }
273 869: Result := stString; { inet }
274 829: Result := stString; { macaddr }
275 700: Result := stFloat; { float4 }
276 701,1700: Result := stDouble; { float8/numeric. no 'decimal' any more }
277 790: Result := stDouble; { money }
278 16: Result := stBoolean; { bool }
279 1082: Result := stDate; { date }
280 1083: Result := stTime; { time }
281 1114,1184,702: Result := stTimestamp; { timestamp,timestamptz/abstime. no 'datetime' any more}
282 1560,1562: Result := stString; {bit/ bit varying string}
283 24: Result := stString; { regproc }
284 1034: Result := stAsciiStream; {aclitem[]}
290 Result := stBinaryStream;
292 22,30: Result := stAsciiStream; { int2vector/oidvector. no '_aclitem' }
293 143,629,651,719,791,1000..1028,1040,1041,1115,1182,1183,1185,1187,1231,1263,
294 1270,1561,1563,2201,2207..2211,2949,2951,3643,3644,3645,3735,3770 : { other array types }
295 Result := stAsciiStream;
300 if (ConSettings.CPType = cCP_UTF16) then
301 if Result = stAsciiStream then
302 Result := stUnicodeStream;
305 function SQLTypeToPostgreSQL(SQLType: TZSQLType; IsOidAsBlob: boolean): string;
308 stBoolean: Result := 'bool';
309 stByte, stShort, stInteger, stLong: Result := 'int';
310 stFloat, stDouble, stBigDecimal: Result := 'numeric';
311 stString, stUnicodeString, stAsciiStream, stUnicodeStream: Result := 'text';
312 stDate: Result := 'date';
313 stTime: Result := 'time';
314 stTimestamp: Result := 'timestamp';
315 stBinaryStream, stBytes:
324 Indicate what field type is a number (integer, float and etc.)
325 @param the SQLType field type value
326 @result true if field type number
328 function IsNumber(Value: TZSQLType): Boolean;
330 Result := Value in [stByte, stShort, stInteger, stLong,
331 stFloat, stDouble, stBigDecimal];
335 Encode string which probably consists of multi-byte characters.
336 Characters ' (apostraphy), low value (value zero), and \ (back slash) are encoded.
337 Since we have noticed that back slash is the second byte of some BIG5 characters
338 (each of them is two bytes in length), we need a characterset aware encoding function.
339 @param CharactersetCode the characterset in terms of enumerate code.
340 @param Value the regular string.
341 @return the encoded string.
343 function PGEscapeString(Handle: Pointer; const Value: RawByteString;
344 ConSettings: PZConSettings; WasEncoded: Boolean = False): RawByteString;
346 I, LastState: Integer;
347 SrcLength, DestLength: Integer;
348 SrcBuffer, DestBuffer: PAnsiChar;
350 function pg_CS_stat(stat: integer; character: integer;
351 CharactersetCode: TZPgCharactersetType): integer;
353 if character = 0 then
356 case CharactersetCode of
357 csUTF8, csUNICODE_PODBC:
359 if (stat < 2) and (character >= $80) then
361 if character >= $fc then
363 else if character >= $f8 then
365 else if character >= $f0 then
367 else if character >= $e0 then
369 else if character >= $c0 then
373 if (stat > 2) and (character > $7f) then
378 { Shift-JIS Support. }
382 and (character > $80)
383 and not ((character > $9f) and (character < $e0)) then
385 else if stat = 2 then
390 { Chinese Big5 Support. }
393 if (stat < 2) and (character > $A0) then
395 else if stat = 2 then
400 { Chinese GBK Support. }
403 if (stat < 2) and (character > $7F) then
405 else if stat = 2 then
411 { Korian UHC Support. }
414 if (stat < 2) and (character > $7F) then
416 else if stat = 2 then
425 if (stat < 3) and (character = $8f) then { JIS X 0212 }
429 and ((character = $8e) or
430 (character > $a0)) then { Half Katakana HighByte & Kanji HighByte }
432 else if stat = 2 then
438 { EUC_CN, EUC_KR, JOHAB Support }
439 csEUC_CN, csEUC_KR, csJOHAB:
441 if (stat < 2) and (character > $a0) then
443 else if stat = 2 then
450 if (stat < 4) and (character = $8e) then
452 else if (stat = 4) and (character > $a0) then
454 else if ((stat = 3) or (stat < 2)) and (character > $a0) then
456 else if stat = 2 then
461 { Chinese GB18030 support.Added by Bill Huang <bhuang@redhat.com> <bill_huanghb@ybb.ne.jp> }
464 if (stat < 2) and (character > $80) then
466 else if stat = 2 then
468 if (character >= $30) and (character <= $39) then
473 else if stat = 3 then
475 if (character >= $30) and (character <= $39) then
490 SrcLength := Length(Value);
491 SrcBuffer := PAnsiChar(Value);
494 for I := 1 to SrcLength do
496 LastState := pg_CS_stat(LastState,integer(SrcBuffer^),
497 TZPgCharactersetType(ConSettings.ClientCodePage.ID));
498 if CharInSet(SrcBuffer^, [#0, '''']) or ((SrcBuffer^ = '\') and (LastState = 0)) then
505 SrcBuffer := PAnsiChar(Value);
506 SetLength(Result, DestLength);
507 DestBuffer := PAnsiChar(Result);
512 for I := 1 to SrcLength do
514 LastState := pg_CS_stat(LastState,integer(SrcBuffer^),
515 TZPgCharactersetType(ConSettings.ClientCodePage.ID));
516 if CharInSet(SrcBuffer^, [#0, '''']) or ((SrcBuffer^ = '\') and (LastState = 0)) then
518 DestBuffer[0] := '\';
519 DestBuffer[1] := AnsiChar(Ord('0') + (Byte(SrcBuffer^) shr 6));
520 DestBuffer[2] := AnsiChar(Ord('0') + ((Byte(SrcBuffer^) shr 3) and $07));
521 DestBuffer[3] := AnsiChar(Ord('0') + (Byte(SrcBuffer^) and $07));
526 DestBuffer^ := SrcBuffer^;
536 add by Perger -> based on SourceForge:
537 [ 1520587 ] Fix for 1484704: bytea corrupted on post when not using utf8,
540 Converts a binary string into escape PostgreSQL format.
541 @param Value a binary stream.
542 @return a string in PostgreSQL binary string escape format.
544 function EncodeBinaryString(const Value: AnsiString): AnsiString;
547 SrcLength, DestLength: Integer;
548 SrcBuffer, DestBuffer: PAnsiChar;
550 SrcLength := Length(Value);
551 SrcBuffer := PAnsiChar(Value);
553 for I := 1 to SrcLength do
555 if (Byte(SrcBuffer^) < 32) or (Byte(SrcBuffer^) > 126)
556 or CharInSet(SrcBuffer^, ['''', '\']) then
563 SrcBuffer := PAnsiChar(Value);
564 SetLength(Result, DestLength);
565 DestBuffer := PAnsiChar(Result);
569 for I := 1 to SrcLength do
571 if (Byte(SrcBuffer^) < 32) or (Byte(SrcBuffer^) > 126)
572 or CharInSet(SrcBuffer^, ['''', '\']) then
574 DestBuffer[0] := '\';
575 DestBuffer[1] := '\';
576 DestBuffer[2] := AnsiChar(Ord('0') + (Byte(SrcBuffer^) shr 6));
577 DestBuffer[3] := AnsiChar(Ord('0') + ((Byte(SrcBuffer^) shr 3) and $07));
578 DestBuffer[4] := AnsiChar(Ord('0') + (Byte(SrcBuffer^) and $07));
583 DestBuffer^ := SrcBuffer^;
592 Converts an string from escape PostgreSQL format.
593 @param Value a string in PostgreSQL escape format.
594 @return a regular string.
596 function DecodeString(const Value: AnsiString): AnsiString;
598 SrcLength, DestLength: Integer;
599 SrcBuffer, DestBuffer: PAnsiChar;
601 SrcLength := Length(Value);
602 SrcBuffer := PAnsiChar(Value);
603 SetLength(Result, SrcLength);
605 DestBuffer := PAnsiChar(Result);
607 while SrcLength > 0 do
609 if SrcBuffer^ = '\' then
612 if CharInSet(SrcBuffer^, ['\', '''']) then
614 DestBuffer^ := SrcBuffer^;
620 DestBuffer^ := AnsiChar(((Byte(SrcBuffer[0]) - Ord('0')) shl 6)
621 or ((Byte(SrcBuffer[1]) - Ord('0')) shl 3)
622 or ((Byte(SrcBuffer[2]) - Ord('0'))));
629 DestBuffer^ := SrcBuffer^;
636 SetLength(Result, DestLength);
640 Checks for possible sql errors.
641 @param Connection a reference to database connection to execute Rollback.
642 @param PlainDriver a PostgreSQL plain driver.
643 @param Handle a PostgreSQL connection reference.
644 @param LogCategory a logging category.
645 @param LogMessage a logging message.
647 @param ResultHandle the Handle to the Result
649 function CheckPostgreSQLError(Connection: IZConnection;
650 PlainDriver: IZPostgreSQLPlainDriver;
651 Handle: PZPostgreSQLConnect; LogCategory: TZLoggingCategory;
652 const LogMessage: string;
653 ResultHandle: PZPostgreSQLResult): String;
655 ErrorMessage: string;
657 ConnectionLost: boolean;
659 function GetMessage(AMessage: PAnsiChar): String;
661 if Assigned(Connection) then
662 Result := Trim(PlainDriver.ZDbcString(AMessage, Connection.GetConSettings))
665 Result := Trim(UTF8ToString(AMessage));
668 Result := Trim(Utf8ToAnsi(AMessage));
670 Result := Trim(AMessage);
675 if Assigned(Handle) then
676 ErrorMessage := GetMessage(PlainDriver.GetErrorMessage(Handle))
680 if ErrorMessage <> '' then
682 if Assigned(ResultHandle) then
683 { StatusCode := Trim(StrPas(PlainDriver.GetResultErrorField(ResultHandle,PG_DIAG_SEVERITY)));
684 StatusCode := Trim(StrPas(PlainDriver.GetResultErrorField(ResultHandle,PG_DIAG_MESSAGE_PRIMARY)));
685 StatusCode := Trim(StrPas(PlainDriver.GetResultErrorField(ResultHandle,PG_DIAG_MESSAGE_DETAIL)));
686 StatusCode := Trim(StrPas(PlainDriver.GetResultErrorField(ResultHandle,PG_DIAG_MESSAGE_HINT)));
687 StatusCode := Trim(StrPas(PlainDriver.GetResultErrorField(ResultHandle,PG_DIAG_STATEMENT_POSITION)));
688 StatusCode := Trim(StrPas(PlainDriver.GetResultErrorField(ResultHandle,PG_DIAG_INTERNAL_POSITION)));
689 StatusCode := Trim(StrPas(PlainDriver.GetResultErrorField(ResultHandle,PG_DIAG_INTERNAL_QUERY)));
690 StatusCode := Trim(StrPas(PlainDriver.GetResultErrorField(ResultHandle,PG_DIAG_CONTEXT)));
691 StatusCode := Trim(StrPas(PlainDriver.GetResultErrorField(ResultHandle,PG_DIAG_SOURCE_FILE)));
692 StatusCode := Trim(StrPas(PlainDriver.GetResultErrorField(ResultHandle,PG_DIAG_SOURCE_LINE)));
693 StatusCode := Trim(StrPas(PlainDriver.GetResultErrorField(ResultHandle,PG_DIAG_SOURCE_FUNCTION)));
695 Result := GetMessage(PlainDriver.GetResultErrorField(ResultHandle,PG_DIAG_SQLSTATE))
702 if ErrorMessage <> '' then
704 ConnectionLost := (PlainDriver.GetStatus(Handle) = CONNECTION_BAD);
706 if Assigned(Connection) then begin
707 if Connection.GetAutoCommit and not ConnectionLost then Connection.Rollback;
708 DriverManager.LogError(LogCategory, PlainDriver.GetProtocol, LogMessage,
711 DriverManager.LogError(LogCategory, 'some PostgreSQL protocol', LogMessage,
715 if ResultHandle <> nil then PlainDriver.Clear(ResultHandle);
717 if not ( ConnectionLost and ( LogCategory = lcUnprepStmt ) ) then
718 if not (Result = '42P18') then
719 raise EZSQLException.CreateWithStatus(Result,Format(SSQLError1, [ErrorMessage]));
724 Resolve problem with minor version in PostgreSql bettas
725 @param Value a minor version string like "4betta2"
726 @return a miror version number
728 function GetMinorVersion(const Value: string): Word;
734 for I := 1 to Length(Value) do
735 if CharInSet(Value[I], ['0'..'9']) then
736 Temp := Temp + Value[I]
739 Result := StrToIntDef(Temp, 0);
743 Prepares an SQL parameter for the query.
744 @param ParameterIndex the first parameter is 1, the second is 2, ...
745 @return a string representation of the parameter.
747 function PGPrepareAnsiSQLParam(Value: TZVariant; Connection: IZPostgreSQLConnection;
748 PlainDriver: IZPostgreSQLPlainDriver; const ChunkSize: Cardinal;
749 const InParamType: TZSQLType; const oidasblob, DateTimePrefix, QuotedNumbers: Boolean;
750 ConSettings: PZConSettings): RawByteString;
754 WriteTempBlob: IZPostgreSQLBlob;
756 if DefVarManager.IsNull(Value) then
762 if SoftVarManager.GetAsBoolean(Value) then
766 stByte, stShort, stInteger, stLong, stBigDecimal, stFloat, stDouble:
768 Result := RawByteString(SoftVarManager.GetAsString(Value));
769 if QuotedNumbers then Result := #39+Result+#39;
772 Result := Connection.EncodeBinary(SoftVarManager.GetAsBytes(Value));
774 if PlainDriver.SupportsStringEscaping(Connection.ClientSettingsChanged) then
775 Result := PlainDriver.EscapeString(Connection.GetConnectionHandle,
776 PlainDriver.ZPlainString(SoftVarManager.GetAsString(Value), ConSettings), ConSettings, True)
778 Result := ZDbcPostgreSqlUtils.PGEscapeString(Connection.GetConnectionHandle,
779 PlainDriver.ZPlainString(SoftVarManager.GetAsString(Value), ConSettings), ConSettings, True);
781 if PlainDriver.SupportsStringEscaping(Connection.ClientSettingsChanged) then
782 Result := PlainDriver.EscapeString(Connection.GetConnectionHandle,
783 PlainDriver.ZPlainString(SoftVarManager.GetAsUnicodeString(Value), ConSettings), ConSettings, True)
785 Result := ZDbcPostgreSqlUtils.PGEscapeString(Connection.GetConnectionHandle,
786 PlainDriver.ZPlainString(SoftVarManager.GetAsUnicodeString(Value), ConSettings), ConSettings, True);
789 Result := RawByteString(#39+FormatDateTime('yyyy-mm-dd',
790 SoftVarManager.GetAsDateTime(Value))+#39);
791 if DateTimePrefix then Result := Result + '::date';
795 Result := RawByteString(#39+FormatDateTime('hh":"mm":"ss"."zzz',
796 SoftVarManager.GetAsDateTime(Value))+#39);
797 if DateTimePrefix then Result := Result + '::time';
801 Result := RawByteString(#39+FormatDateTime('yyyy-mm-dd hh":"mm":"ss"."zzz',
802 SoftVarManager.GetAsDateTime(Value))+#39);
803 if DateTimePrefix then Result := Result + '::timestamp';
805 stAsciiStream, stUnicodeStream, stBinaryStream:
807 TempBlob := DefVarManager.GetAsInterface(Value) as IZBlob;
808 if not TempBlob.IsEmpty then
812 if (Connection.IsOidAsBlob) or oidasblob then
814 TempStream := TempBlob.GetStream;
816 WriteTempBlob := TZPostgreSQLBlob.Create(PlainDriver, nil, 0,
817 Connection.GetConnectionHandle, 0, ChunkSize);
818 WriteTempBlob.SetStream(TempStream);
819 WriteTempBlob.WriteBlob;
820 Result := RawByteString(IntToStr(WriteTempBlob.GetBlobOid));
822 WriteTempBlob := nil;
827 Result := Connection.EncodeBinary(TempBlob.GetString);
828 stAsciiStream, stUnicodeStream:
829 if PlainDriver.SupportsStringEscaping(Connection.ClientSettingsChanged) then
830 Result := PlainDriver.EscapeString(
831 Connection.GetConnectionHandle,
832 GetValidatedAnsiStringFromBuffer(TempBlob.GetBuffer,
833 TempBlob.Length, TempBlob.WasDecoded, ConSettings),
836 Result := ZDbcPostgreSqlUtils.PGEscapeString(
837 Connection.GetConnectionHandle,
838 GetValidatedAnsiStringFromBuffer(TempBlob.GetBuffer,
839 TempBlob.Length, TempBlob.WasDecoded, ConSettings),
846 end; {if not TempBlob.IsEmpty then}