Repository navigation
7.9.1
Added
Character sets
- Text goes through the code page of its column's charset (fields, parameters,
text BLOBs, dataset fields, array elements, SQL text, object names), not only
UTF-8 or the system code page: e.g. WIN1251 data on a Western Windows no
longer comes as?or mojibake.- Unit
FIBCharSets(FirebirdCharSetCodePage,FirebirdCharSetName,
DecodeString,EncodeString);TFIBDatabase.Capabilities:AttachmentCharSetID,
CodePage,MetadataCodePage,TextCodePage,BlobCodePage;
TFIBDatabase.ConnectionSerial;TFIBCustomDataSet.StringFieldCharSetID,
StringFieldCodePage,BlobFieldCodePage.
- Unit
- Unlike FireDAC and IBDAC (UTF-8 or the system code page only): any Firebird
charset, per column also on NONE connections; NONE/OCTETS columns kept as
bytes on UTF8 connections; array elements in the column charset; DDL and
names in UTF-8 on NONE; an error instead of?for characters the charset
can't hold.
Packages
FIBPlusFMXruntime package for Delphi 13 with the FireMonkey login dialog
FIB_FMX_DBLoginDlg, which was in no package. Its name has no version
suffix: the BPL gets one through{$LIBSUFFIX AUTO}(FIBPlusFMX370.bpl).
Timeouts
Firebird 4+ statement and idle timeouts; details in Docs/guide/timeouts.md.
TFIBDatabase.Session:StatementTimeout(ms, every statement of the
attachment) andIdleTimeout(s), sent after connect and when changed.
Applysends them again (e.g. afterALTER SESSION RESET);
ActualStatementTimeout/ActualIdleTimeoutread them from the server.
IdleTimeoutis not sent at design time.TFIBQuery.StatementTimeoutandTpFIBDataSet.StatementTimeout(ms, through
fb_dsql_set_timeout) replace the session value for one statement;
FIBNoStatementTimeoutopts a statement out of it.- For a
SELECTthe timer runs until the last row is fetched, so a dataset
browsed in a grid can fail on a later scroll. In interactive applications set
the timeouts per query, or opt the browsing datasets out. - A non-zero value the server or the client library can't apply raises
EFIBClientError(feFeatureNotSupported); 0 never raises. A value stored in
a DFM makesOpenfail on Firebird 3 and older (Open(False)returns with
Connected = False).Capabilities.SessionTimeoutsand
Capabilities.StatementTimeouttell what is available. EFIBError.ErrorCodes,HasErrorCodeandIsStatementTimeout;
keStatementTimeoutandkeCancelledinTKindIBError. An idle timeout
arrives as a lost connection.
Read consistency
Firebird 4+ read committed transactions where every statement reads one
snapshot taken at its start.
read_consistencyinTRParams(isc_tpb_read_consistency).TpFIBTransaction.TPBModetpbReadConsistencysendswrite,nowait,
read_committedandread_consistency; on a server older than Firebird 4
StartTransactionraisesEFIBClientError(feFeatureNotSupported).
tpbReadCommittedstays the default: with the server default
ReadConsistency = 1it already runs in this mode on Firebird 4+.Capabilities.ReadConsistencyandTFIBDatabase.RequireReadConsistency;
IsReadCommitedTransactionalso recognizesread_consistency.- A ReadConsistency kind in the transaction editor.
Parallel workers
Firebird 5+ parallel workers for sweep, index creation, backup and restore; the
server limits them with MaxParallelWorkers in firebird.conf (default 1).
parallel_workersinDBParamsand the typedConnectParams.ParallelWorkers
(0 removes the line). The parameter is sent to Firebird only; Firebird 3 and 4
ignore it.ParallelWorkersonTpFIBBackupService,TpFIBRestoreServiceand
TpFIBValidationService(sweep, sent only withSweepDB). It is sent only
when greater than 0; a Firebird 3 or 4 server rejects it.
Changed
FIBReleaseis renamed toFIBPatchVersion.FIBBuildDateis renamed toFIBVersionDateand uses the ISO date format.- Version constants are untyped and can be used in
{$IF}directives. TFIBDatabase.AttachmentIDisInt64, read withisc_portable_integer
(the attachment ID isBIGINTin Firebird 3+), and is 0 instead of -1 when
not connected (#34).TFIBSQLLogger.CreateStatisticsTablecreatesFIB$APP_STATISTICS.ATTACHMENT_ID
asBIGINTin dialect 3. An existing table can be updated with
ALTER TABLE FIB$APP_STATISTICS ALTER ATTACHMENT_ID TYPE BIGINT.- Protected fields of
TFIBDatabaseandTFIBTransactionare renamed from the
vprefix toF:FInternalTransaction,FAfterConnectEvents,
FBeforeDisconnectEvents,FBeforeDestroyEvents,
FBeforeStartTransactionEvents,FAfterStartTransactionEvents,
FBeforeEndTransactionEvents,FAfterEndTransactionEvents,
FDatabaseTRParams,FDatabaseTPBs. - The protected
TpFIBDatabase.CreateRCTimeris renamed to
CreateRestoreConnectTimer. - A character the target code page can't hold raises "Cannot transliterate
character between character sets" (values and SQL text) instead of being
sent as?or a look-alike, e.g.ș/țwith comma (Romanian Standard
keyboard) on WIN1250/WIN1252: use UTF8 or the Romanian Legacy keyboard. - NONE connections decode a column with its declared charset, so text written
in another code page (e.g. cp1250 into a WIN1252 column) shows as stored.
Repair by reinterpreting the bytes:
cast(cast(C as varchar(n) character set OCTETS) as varchar(n) character set WIN1250). - ISO8859_1/ISO8859_9 go through code pages 1252/1254 (
€ “ ” …instead of
the C1 controls), ASCII through the system code page. TFIBStringField.AsAnsiString(Delphi 2009+) returns the column bytes with
their code page set; calculated and lookupftStringfields use the system
code page.TFIBDatabase.FBAttachCharsetIDis a deprecated function, use
Capabilities.AttachmentCharSetID(read once at connect, -1 when not
connected or on InterBase);IsKOI8Connectis deprecated.IIBClientLibrary.ClientVersionandClientMinorVersionare deprecated
functions instead of properties, so using them gives a warning; useVersion.
Classes implementing the interface must add them.- The default client library is
fbclient.dllinstead ofgds32.dll
(TFIBDatabase.LibraryName,TpFIBServices.LibraryName). The global
IBASE_DLLis renamed toCLIENT_DLL. Whenfbclient.dllwithout a path
can't be loaded,gds32.dllis loaded, so applications shipped with
gds32.dllkeep working. Forms saved with the old default don't store
LibraryNameand get the new one. - The default
SQLDialectis 3 instead of 1: inTFIBDatabasecreated in code,
for new components dropped at design time (DefSQLDialect; a value saved in
the preferences is kept), and in the SQL editor without a database. Forms
always storeSQLDialect, so they keep their value. On a dialect 1 database
the dialect is lowered to 1 at connect, as before. - The packages for Delphi 2007 and later write DCU files to
$(BDSCOMMONDIR)\Dcu\FIBPlus\$(Platform)\$(Config)instead of
.\$(Platform)\$(Config): the folder next to the packages was shared by all
Delphi versions, so they overwrote each other's DCU files.
Removed
SUPPORT_KOI8_CHARSETandStdFuncs.ConvertToCodePage/ConvertFromCodePage.SqlTxtRtns.IBStdCharacterSets,IBStdCharSetsCountand
IBStdCollationsCount: useFIBCharSets.FirebirdCharSetName.
Fixed
TFIBSQLLogger.StatisticsParamshad no effect. The parameters left out are
not written bySaveStatisticsToFile, andSaveStatisticsToDBwrites NULL
in their columns (MAXTIME_PARAMSfollowsfspMaxTimeExecute).TFIBSQLLogger.SaveStatisticsToDBandCreateStatisticsTableroll back
when a statement fails, instead of committing the rows inserted before it
or leaving the transaction active.- Array fields kept the descriptor of a previous connection.
TpFIBScripter:CONNECT,CREATE DATABASEandDROP DATABASEreplaced
theLibraryNameof the database with the default library. It is changed
only bySET CLIENTLIB.- Locate, filters, sorting and bookmarks on string fields of a non-system code
page; lookup fields with a Unicode result field. UseExecuteBlock: apostrophes in literals not doubled, non-ASCII text sent
in the system code page.UseExecuteBlock: dates, times and timestamps are written as ISO literals
(they depended on the locale); TIME / TIMESTAMP WITH TIME ZONE values keep
their zone (they were moved to the session zone); memo, GUID and emulated
BOOLEAN values and memo text of a column charset on a NONE connection are
written correctly. More than 255 records, or a block over 64K bytes (counted
in bytes, not characters), failed with "Token unknown". A record posted without
changes withUpdateOnlyModifiedFieldsfailed with "Token unknown"; an insert
without values writesDEFAULT VALUES. Deleted records stayed pending after
the apply.OnUpdateErrorwas called twice for a failed block, and the records
of a skipped block lost their pending state. A record that does not fit in a
block, and array and binary BLOB fields, now raise a clear error.- Text BLOB parameters set before
Preparesent without their charset; NONE
and OCTETS text BLOBs decoded as UTF-8 on UTF8 connections. - A string parameter replaced by
AsIntegerbeforePreparesent the string. - Multi-byte charset values (SJIS, GBK, ...) cut in the middle of a character.
DisableEncodingSQLTextsent queries with parameters with an empty SQL text.CharacterSetreturnedUNKNOWNfor KOI8R/U, WIN1258, TIS620, GBK, CP943C
and GB18030.GetExportDataScriptwroteftFMTBcdvalues with the locale decimal
separator.GetExportDataScriptwrote dates in the locale format, left memo values
unquoted and GUID values as text instead of the 16 bytes of the column.StrUtil.FastCopyread before the string forIndex < 1; it now calls
Copyon Delphi 2009+.- The
FIBPlus_XE3package did not compile: it contained the XML export units,
which are not in the repository. TpFIBScripterskipped the sessionSETstatements (STATEMENT TIMEOUT,
SESSION IDLE TIMEOUT,BIND,TIME ZONE,DECFLOAT,ROLE,TRUSTED ROLE,OPTIMIZE,SEARCH_PATH) without an error; it now sends them to the
server, so an old script that contains them now runs them. They have the new
TStmtTypevaluesSetSession.Locatewith a Currency key on NUMERIC(10..18) columns with a scale did not
find values above 2^53 (e.g. 12345678901234.5678).pfImportDefaultValues:CURRENT_TIME(n),CURRENT_TIMESTAMP(n),
LOCALTIME(n)andLOCALTIMESTAMP(n)defaults failed with a conversion error
on insert. The value keeps the fractional digits of the default, as the
server does:CURRENT_TIMEandLOCALTIMEwithout a precision no longer get
milliseconds.- A BOOLEAN parameter set with
AsString := 'true'/'false'beforePrepare
raised "Invalid data conversion". AsQuadassigned after a longAsStringwas replaced by the string at the
execute.- User transaction kinds saved in the transaction editor shifted to another
kind when a predefined kind was added. DBParamByDPBwith a code above 83 (such asisc_dpb_config) read an empty
value and wrote a parameter with a name out of the table range.TpFIBDatabase: an alias did not read back itsCLIENT_LIBinto
LibraryName. Aliases saved by earlier versions usually holdgds32.dll,
see the upgrading guide.TpFIBDatabase.OnErrorRestoreConnectgot an uninitializedDoRaise.TpFIBDatabase.InRestoreConnectstayedTrueafter a successful restore or
a reconnect during the wait, andTransactionIDreturned 0 for transactions
started after it. It was cleared while the timer waited again after a failed
attempt, and the timer kept running whenOnErrorRestoreConnectchose to
stop.TpFIBDatabase.ApplyUpdatesraised an access violation for an empty array
and read invalid memory for a dataset that is not aTFIBCustomDataSet.TpFIBDatabasesaved the schema cache (AutoSaveToFile) onForceClose
when not connected.TpFIBDatabase.WaitForRestoreConnectread 0 andlaWaitRestoredid nothing
until code assigned the property; the default 30000 now applies. Forms
saved by earlier versions without a value set store
WaitForRestoreConnect = 0, which keeps the timer off.TpFIBNRestoreService.Restoreread one element past the end of the file
array.TpFIBBackupServiceandTpFIBRestoreService: aname=lengthline sent a
length cut to as many digits as the name has characters.- Service
Paramsentries (ServiceParamBySPB, login dialog) were looked up
case-sensitively, andpasswordalso matchedpassword_enc. FixLimboTransactionErrorsraised an access violation after
FetchLimboTransactionInforeturned entries.LimboTransactionInfoCount
andUserInfoCountreturned -1 for an empty list;LimboTransactionInfo
andUserInforaiseEListErrorfor an index out of range instead of
returningnil.FixLimboTransactionErrorsrolled back the transactions with
RecoverTwoPhaseGlobal; it now sends them to two-phase recovery.TpFIBSecurityService:SecAdminwas sent only when its value changed, so
setting it again on the nextAddUserorModifyUserhad no effect, and a
failed call cleared the properties. SettingSecAdminis now always sent;
the properties,SecAdminincluded, are cleared only after a successful
call.TpFIBQuery.ExecProcedurewrote two spaces betweenEXECUTEandPROCEDURE.BatchOutputRawFileignored itsVersionargument and always wrote version 3.TFIBTimeFieldandTFIBDateTimeFieldwithShowMsecwrote milliseconds
without leading zeros: 5 ms showed as.5instead of.005.RecordFieldAsFloatread past the last record forRecNumber = RecordCount,
and on a filtered dataset for a visible number past the end; it returns 0.TBlobSwapSupportcould not be assigned (TFIBDatabase.BlobSwapSupport).AutoUpdateOptions.Assigndid not copyUseExecuteBlock,UseReturningFields
andUseRowsClause, and leftKeyFieldListempty. Assigning the
AutoUpdateOptionsproperty replaced the object instead of copying it, which
leaked the old one and freed the shared one twice.CharacterSetof a text BLOB column returned the charset with the BLOB
subtype as ID (OCTETS), and numeric columns returnedNONE,OCTETSor
ASCII; columns that are not CHAR, VARCHAR or text BLOB returnUNKNOWN.TFIBSQLMonitor.Releaseraised an access violation before the first traced
event, and the monitor was never freed while no monitor reader was active.
Queries traced from several threads could free the SQL monitor writer thread
while another thread used it; freeing the last monitor could hang; messages
left at shutdown leaked.- SQL monitor: the fields of a fetch trace are on separate indented lines, as
the parameters of an execute trace; a failed prepare names the query with
its full owner path, as a failed execute. TpFibErrorHandler: assigningErrorLexemsdid not copyExceptionand
At; lexems of another length than the default cut the exception message
in the wrong place;ExceptionNamekept the value of an earlier exception.Database.SQLLogger := nilleft the logger attached, so statistics were
still collected; moving a logger to another database left it on the first.TSIBfibEventAlerter: the error for too long event names said they were
truncated; they are not.TpFIBScripter:StopStatementNowas not set by a pause at the last
statement and kept the value of an earlier run;ExecuteScript(0)raised an
access violation.TpFIBScripter:OnExecuteErrorgot an undefinedDoRollBackfor
CONNECT,CREATE DATABASEandCOMMIT, and was not called for
DROP DATABASE; a failedCOMMITis kept when the handler setsDoRollBack
toFalse.TpFIBScripter: a resumed run lost theINSERTused byREINSERT,
SET SQL DIALECTandSET NAMES; a pause set beforeINPUTwas ignored.TpFIBScripterwithUseExecBlockForDML: an error in the last
EXECUTE BLOCKalways propagated, withoutOnExecuteError.TpFIBScripterwithUseExecBlockForDML:OnExecuteErrorand
AfterStatementExecuteof a block reported the statement after the block,
which ran even whenStopwas set; they report the last statement of the
block, andAfterStatementExecuteis called once per block.TpFIBScripterwithUseExecBlockForDML: after a pause, and after
ExecuteStatementoutside a run, the pending block was sent only by the next
run, even of another script.TpFIBScripterwithUseExecBlockForDML: a statement too long for a block
was dropped;EXECUTE BLOCKandEXECUTE PROCEDUREstatements were nested
into a block.TpFIBClientDataSet.TransactionIsActivealways raised "Invalid argument":
TpFIBDataSetdid not return the transaction state to the client. After a
failedCommitorRollBack, the next execute without a command text ran
the commit or rollback again instead of the dataset's SQL.