Skip to content

Commit

Permalink
disable ftBlob array binding on mormot.db.sql.postgresql
Browse files Browse the repository at this point in the history
- as reported by #147
  • Loading branch information
Arnaud Bouchez committed Feb 27, 2023
1 parent a0e916a commit 7609b12
Show file tree
Hide file tree
Showing 7 changed files with 31 additions and 12 deletions.
5 changes: 4 additions & 1 deletion src/db/mormot.db.core.pas
Original file line number Diff line number Diff line change
Expand Up @@ -1220,6 +1220,8 @@ procedure SetID(const U: RawByteString; var result: TID); overload;
// and server TOrmModel tables or fields do not match
// - boOnlyObjects will force to generate only a JSON array of raw JSON
// objects with no BATCH prefix nor verbs
// - boMayHaveBlob could be set if some BLOB are likely to appear in the datga
// so that some engines could disabled e.g. array binding
TRestBatchOption = (
boInsertOrIgnore,
boInsertOrReplace,
Expand All @@ -1228,7 +1230,8 @@ procedure SetID(const U: RawByteString; var result: TID); overload;
boPutNoCacheFlush,
boRollbackOnError,
boNoModelEncoding,
boOnlyObjects);
boOnlyObjects,
boMayHaveBlob);

/// a set of options for TRest.BatchStart() process
// - TJsonObjectDecoder will use it to compute the corresponding SQL
Expand Down
7 changes: 6 additions & 1 deletion src/db/mormot.db.sql.pas
Original file line number Diff line number Diff line change
Expand Up @@ -1243,7 +1243,8 @@ TSqlDBConnectionProperties = class
fBatchSendingAbilities: TSqlDBStatementCRUDs;
fUseCache, fStoreVoidStringAsNull, fLogSqlStatementOnException,
fRollbackOnDisconnect, fReconnectAfterConnectionError,
fEnsureColumnNameUnique, fFilterTableViewSchemaName: boolean;
fEnsureColumnNameUnique, fFilterTableViewSchemaName,
fNoBlobBindArray: boolean;
{$ifndef UNICODE}
fVariantWideString: boolean;
{$endif UNICODE}
Expand Down Expand Up @@ -1875,6 +1876,10 @@ TSqlDBConnectionProperties = class
// - as used by SqlDateToIso8601Quoted() and BindArray()
property DateTimeFirstChar: AnsiChar
read fDateTimeFirstChar write fDateTimeFirstChar;
/// if the engine do not support BindArray(ftBlob)
// - only set for TSqlDBPostgresConnectionProperties by now
property NoBlobBindArray: boolean
read fNoBlobBindArray write fNoBlobBindArray;
{$ifndef UNICODE}
/// set to true to force all variant conversion to WideString instead of
// the default faster AnsiString, for pre-Unicode version of Delphi
Expand Down
1 change: 1 addition & 0 deletions src/db/mormot.db.sql.postgres.pas
Original file line number Diff line number Diff line change
Expand Up @@ -557,6 +557,7 @@ constructor TSqlDBPostgresConnectionProperties.Create(
// JsonDecodedPrepareToSql will detect cPostgreBulkArray and set
// DecodedFieldTypesToUnnest -> fast bulk insert/delete/update
fBatchSendingAbilities := [cCreate, cDelete, cUpdate, cPostgreBulkArray];
fNoBlobBindArray := true; // no BindArray() on ftBlob
// disable MultiInsert SQL and rely on cPostgreBulkArray process for cCreate
fOnBatchInsert := nil; // see TRestStorageExternal.InternalBatchStop
end;
Expand Down
2 changes: 1 addition & 1 deletion src/mormot.commit.inc
Original file line number Diff line number Diff line change
@@ -1 +1 @@
'2.0.4974'
'2.0.4975'
4 changes: 2 additions & 2 deletions src/orm/mormot.orm.core.pas
Original file line number Diff line number Diff line change
Expand Up @@ -11168,10 +11168,10 @@ procedure TRestBatch.Reset(aTable: TOrmClass;
fBatch.AddComma;
end;
Options := Options - BATCH_OPTIONS_CLIENTONLY;
if byte(Options) <> 0 then
if word(Options) <> 0 then
begin
fBatch.AddShort('"options",');
fBatch.Add(byte(Options));
fBatch.Add(word(Options));
fBatch.AddComma;
end;
end;
Expand Down
16 changes: 11 additions & 5 deletions src/orm/mormot.orm.server.pas
Original file line number Diff line number Diff line change
Expand Up @@ -960,6 +960,7 @@ function TRestOrmServer.RecordVersionSynchronizeSlaveToBatch(Table: TOrmClass;
rec: TOrm;
deletedminid: TID;
deleted: TOrmTableDeleted;
opt: TRestBatchOptions;
{%H-}log: ISynLog;
begin
log := fRest.LogClass.Enter(
Expand Down Expand Up @@ -997,7 +998,11 @@ function TRestOrmServer.RecordVersionSynchronizeSlaveToBatch(Table: TOrmClass;
deletedminid + ORMVERSION_DELETEID_RANGE]);
if listdeleted = nil then
exit; // DB error
result := TRestBatch.Create(self, nil, 10000);
opt := [boExtendedJson]; // default options
if (listupdated.RowCount <> 0) and
(props.BlobFields <> nil) then
include(opt, boMayHaveBlob);
result := TRestBatch.Create(self, nil, 10000, opt);
result.OnWrite := OnWrite;
if (listupdated.RowCount = 0) and
(listdeleted.RowCount = 0) then
Expand Down Expand Up @@ -2030,8 +2035,9 @@ function TRestOrmServerBatchSend.IsNotAllowed: boolean;
begin
result := (fUriContext <> nil) and
(fUriContext.Command = execOrmWrite) and
not fUriContext.CanExecuteOrmWrite(BATCH_METHOD[fEncoding],
fRunTable, fRunTableIndex, fValueID, fUriContext.Call.RestAccessRights^);
not fUriContext.CanExecuteOrmWrite(
BATCH_METHOD[fEncoding], fRunTable, fRunTableIndex,
fValueID, fUriContext.Call.RestAccessRights^);
end;

procedure TRestOrmServerBatchSend.ParseCommand;
Expand Down Expand Up @@ -2411,10 +2417,10 @@ procedure TRestOrmServerBatchSend.ParseHeader;
if IdemPChar(fParse.Json, '"OPTIONS",') then
begin
inc(fParse.Json, 10);
byte(fBatchOptions) := GetNextItemCardinal(fParse.Json, ',');
word(fBatchOptions) := GetNextItemCardinal(fParse.Json, ',');
end
else
byte(fBatchOptions) := 0;
word(fBatchOptions) := 0;
end;

procedure TRestOrmServerBatchSend.ParseAndExecute;
Expand Down
8 changes: 6 additions & 2 deletions src/orm/mormot.orm.sql.pas
Original file line number Diff line number Diff line change
Expand Up @@ -1019,6 +1019,9 @@ function TRestStorageExternal.InternalBatchStart(Encoding: TRestBatchEncoding;
(Method in [mPOST..mDELETE]) and
(BATCH[Method] in fProperties.BatchSendingAbilities) then
begin
if (boMayHaveBlob in BatchOptions) and
fProperties.NoBlobBindArray then
exit; // slower but safer access with no array binding
StorageLock(true {$ifdef DEBUGSTORAGELOCK}, 'ExtBatchStart' {$endif});
// lock protected by try..finally in TRestServer.RunBatch caller
try
Expand Down Expand Up @@ -1100,8 +1103,9 @@ procedure TRestStorageExternal.InternalBatchStop;
if {%H-}Fields = nil then
begin
Decode.AssignFieldNamesTo(Fields);
SQL := JsonDecodedPrepareToSql(Decode, ExternalFields, Types,
Occasion, fBatchOptions, {array=}true);
SQL := JsonDecodedPrepareToSql(
Decode, ExternalFields, Types, Occasion, fBatchOptions,
{array=}true);
SetLength(Values, Decode.FieldCount);
ValuesMax := fBatchCount - BatchBegin;
if ValuesMax > max then
Expand Down

0 comments on commit 7609b12

Please sign in to comment.