8
0
mirror of https://github.com/FirebirdSQL/firebird.git synced 2025-01-22 20:43:02 +01:00

Merge remote-tracking branch 'origin/master' into cursor-info

This commit is contained in:
Dmitry Yemanov 2022-04-22 19:29:01 +03:00
commit 4c8f31fc73
328 changed files with 15882 additions and 15666 deletions

View File

@ -7,13 +7,12 @@ jobs:
runs-on: ${{ matrix.os }} runs-on: ${{ matrix.os }}
container: ${{ matrix.container }} container: ${{ matrix.container }}
env: env:
VS_VERSION: ${{ matrix.os == 'windows-2016' && '2017' || (matrix.os == 'windows-2019' && '2019' || (matrix.os == 'windows-2022' && '2022' || '')) }} VS_VERSION: ${{ (matrix.os == 'windows-2019' && '2019' || (matrix.os == 'windows-2022' && '2022' || '')) }}
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
os: os:
- windows-2016
- windows-2019 - windows-2019
platform: [x64, x86] platform: [x64, x86]
include: include:

View File

@ -155,7 +155,6 @@ endif()
set(FB_PREFIX ${CMAKE_INSTALL_PREFIX}/${PROJECT_NAME}) set(FB_PREFIX ${CMAKE_INSTALL_PREFIX}/${PROJECT_NAME})
set(FB_IPC_NAME "FirebirdIPI") set(FB_IPC_NAME "FirebirdIPI")
set(FB_LOGFILENAME "firebird.log") set(FB_LOGFILENAME "firebird.log")
set(FB_PIPE_NAME "interbas")
set(FB_SERVICE_NAME "gds_db") set(FB_SERVICE_NAME "gds_db")
set(FB_SERVICE_PORT 3050) set(FB_SERVICE_PORT 3050)

View File

@ -42,6 +42,8 @@ source_group("ISQL files\\${EPP_TXT}" "${SSRC}/isql/${EPP}")
source_group("ISQL files\\${GEN_TXT}" "${BSRC}/isql/${GEN}") source_group("ISQL files\\${GEN_TXT}" "${BSRC}/isql/${GEN}")
source_group("JRD files" "${SSRC}/jrd/${CPP}") source_group("JRD files" "${SSRC}/jrd/${CPP}")
source_group("JRD files\\Data Access" "${SSRC}/jrd/recsrc/${CPP}") source_group("JRD files\\Data Access" "${SSRC}/jrd/recsrc/${CPP}")
source_group("JRD files\\Optimizer" "${SSRC}/jrd/optimizer/${CPP}")
source_group("JRD files\\Replication" "${SSRC}/jrd/replication/${CPP}")
source_group("JRD files\\EXTDS" "${SSRC}/jrd/extds/${CPP}") source_group("JRD files\\EXTDS" "${SSRC}/jrd/extds/${CPP}")
source_group("JRD files\\${EPP_TXT}" "${SSRC}/jrd/${EPP}") source_group("JRD files\\${EPP_TXT}" "${SSRC}/jrd/${EPP}")
source_group("JRD files\\${GEN_TXT}" "${BSRC}/jrd/${GEN}") source_group("JRD files\\${GEN_TXT}" "${BSRC}/jrd/${GEN}")

View File

@ -384,7 +384,7 @@ Filename: msiexec.exe; Parameters: "/qn /norestart /i ""{tmp}\vccrt{#msvc_runtim
#endif #endif
;Only register Firebird if we are installing AND configuring ;Only register Firebird if we are installing AND configuring
Filename: {app}\instreg.exe; Parameters: "install "; StatusMsg: {cm:instreg}; MinVersion: {#MinVer}; Components: ClientComponent; Flags: runminimized; Check: ConfigureFirebird; Filename: {app}\instreg.exe; Parameters: "install "; StatusMsg: {cm:instreg}; MinVersion: {#MinVer}; Components: ServerComponent; Flags: runminimized; Check: ConfigureFirebird;
Filename: {app}\instclient.exe; Parameters: "install fbclient"; StatusMsg: {cm:instclientCopyFbClient}; MinVersion: {#MinVer}; Components: ClientComponent; Flags: runminimized; Check: CopyFBClientLib; Filename: {app}\instclient.exe; Parameters: "install fbclient"; StatusMsg: {cm:instclientCopyFbClient}; MinVersion: {#MinVer}; Components: ClientComponent; Flags: runminimized; Check: CopyFBClientLib;
Filename: {app}\instclient.exe; Parameters: "install gds32"; StatusMsg: {cm:instclientGenGds32}; MinVersion: {#MinVer}; Components: ClientComponent; Flags: runminimized; Check: CopyGds32 Filename: {app}\instclient.exe; Parameters: "install gds32"; StatusMsg: {cm:instclientGenGds32}; MinVersion: {#MinVer}; Components: ClientComponent; Flags: runminimized; Check: CopyGds32
@ -410,7 +410,7 @@ Filename: "{#MyAppURL}/afterinstall"; Description: "After installation - What Ne
Root: HKLM; Subkey: SOFTWARE\Microsoft\Windows\CurrentVersion\Run; ValueType: string; ValueName: Firebird; ValueData: ; Flags: uninsdeletevalue; Tasks: UseApplicationTask; Check: ConfigureFirebird; Root: HKLM; Subkey: SOFTWARE\Microsoft\Windows\CurrentVersion\Run; ValueType: string; ValueName: Firebird; ValueData: ; Flags: uninsdeletevalue; Tasks: UseApplicationTask; Check: ConfigureFirebird;
;This doesn't seem to get cleared automatically by instreg on uninstall, so lets make sure of it ;This doesn't seem to get cleared automatically by instreg on uninstall, so lets make sure of it
Root: HKLM; Subkey: "SOFTWARE\Firebird Project"; Flags: uninsdeletekeyifempty; Components: ClientComponent DevAdminComponent ServerComponent Root: HKLM; Subkey: "SOFTWARE\Firebird Project"; Flags: uninsdeletekeyifempty; Components: ServerComponent
;Clean up Invalid registry entries from previous installs. ;Clean up Invalid registry entries from previous installs.
Root: HKLM; Subkey: "SOFTWARE\FirebirdSQL"; ValueType: none; Flags: deletekey; Root: HKLM; Subkey: "SOFTWARE\FirebirdSQL"; ValueType: none; Flags: deletekey;
@ -476,7 +476,7 @@ Source: {#FilesDir}\firebird.exe; DestDir: {app}; Components: ServerComponent; F
Source: {#FilesDir}\fb_lock_print.exe; DestDir: {app}; Components: ServerComponent; Flags: sharedfile ignoreversion Source: {#FilesDir}\fb_lock_print.exe; DestDir: {app}; Components: ServerComponent; Flags: sharedfile ignoreversion
Source: {#FilesDir}\ib_util.dll; DestDir: {app}; Components: ServerComponent; Flags: sharedfile ignoreversion Source: {#FilesDir}\ib_util.dll; DestDir: {app}; Components: ServerComponent; Flags: sharedfile ignoreversion
Source: {#FilesDir}\instclient.exe; DestDir: {app}; Components: ClientComponent; Flags: sharedfile ignoreversion Source: {#FilesDir}\instclient.exe; DestDir: {app}; Components: ClientComponent; Flags: sharedfile ignoreversion
Source: {#FilesDir}\instreg.exe; DestDir: {app}; Components: ClientComponent; Flags: sharedfile ignoreversion Source: {#FilesDir}\instreg.exe; DestDir: {app}; Components: ServerComponent; Flags: sharedfile ignoreversion
Source: {#FilesDir}\instsvc.exe; DestDir: {app}; Components: ServerComponent; MinVersion: {#MinVer}; Flags: sharedfile ignoreversion Source: {#FilesDir}\instsvc.exe; DestDir: {app}; Components: ServerComponent; MinVersion: {#MinVer}; Flags: sharedfile ignoreversion
Source: {#FilesDir}\isql.exe; DestDir: {app}; Components: DevAdminComponent; Flags: ignoreversion Source: {#FilesDir}\isql.exe; DestDir: {app}; Components: DevAdminComponent; Flags: ignoreversion
Source: {#FilesDir}\nbackup.exe; DestDir: {app}; Components: DevAdminComponent; Flags: ignoreversion Source: {#FilesDir}\nbackup.exe; DestDir: {app}; Components: DevAdminComponent; Flags: ignoreversion
@ -487,14 +487,25 @@ Source: {#FilesDir}\fbclient.dll; DestDir: {app}; Components: ClientComponent; F
Source: {#WOW64Dir}\fbclient.dll; DestDir: {app}\WOW64; Components: ClientComponent; Flags: overwritereadonly sharedfile promptifolder {#SkipFileIfDevStatus} Source: {#WOW64Dir}\fbclient.dll; DestDir: {app}\WOW64; Components: ClientComponent; Flags: overwritereadonly sharedfile promptifolder {#SkipFileIfDevStatus}
Source: {#WOW64Dir}\instclient.exe; DestDir: {app}\WOW64; Components: ClientComponent; Flags: sharedfile ignoreversion {#SkipFileIfDevStatus} Source: {#WOW64Dir}\instclient.exe; DestDir: {app}\WOW64; Components: ClientComponent; Flags: sharedfile ignoreversion {#SkipFileIfDevStatus}
#endif #endif
Source: {#FilesDir}\icuuc??.dll; DestDir: {app}; Components: ServerComponent; Flags: sharedfile ignoreversion Source: {#FilesDir}\icuuc??.dll; DestDir: {app}; Components: ClientComponent; Flags: sharedfile ignoreversion
Source: {#FilesDir}\icuin??.dll; DestDir: {app}; Components: ServerComponent; Flags: sharedfile ignoreversion Source: {#FilesDir}\icuin??.dll; DestDir: {app}; Components: ClientComponent; Flags: sharedfile ignoreversion
Source: {#FilesDir}\icudt??.dll; DestDir: {app}; Components: ServerComponent; Flags: sharedfile ignoreversion Source: {#FilesDir}\icudt??.dll; DestDir: {app}; Components: ClientComponent; Flags: sharedfile ignoreversion
Source: {#FilesDir}\icudt*.dat; DestDir: {app}; Components: ServerComponent; Flags: sharedfile ignoreversion Source: {#FilesDir}\icudt*.dat; DestDir: {app}; Components: ClientComponent; Flags: sharedfile ignoreversion
#if PlatformTarget == "x64"
Source: {#WOW64Dir}\icuuc??.dll; DestDir: {app}\WOW64; Components: ClientComponent; Flags: sharedfile ignoreversion
Source: {#WOW64Dir}\icuin??.dll; DestDir: {app}\WOW64; Components: ClientComponent; Flags: sharedfile ignoreversion
Source: {#WOW64Dir}\icudt??.dll; DestDir: {app}\WOW64; Components: ClientComponent; Flags: sharedfile ignoreversion
Source: {#WOW64Dir}\icudt*.dat; DestDir: {app}\WOW64; Components: ClientComponent; Flags: sharedfile ignoreversion
#endif
#if PlatformTarget =="Win32" #if PlatformTarget =="Win32"
Source: {#FilesDir}\fbrmclib.dll; DestDir: {app}; Components: ServerComponent; Flags: sharedfile ignoreversion Source: {#FilesDir}\fbrmclib.dll; DestDir: {app}; Components: ServerComponent; Flags: sharedfile ignoreversion
#endif #endif
Source: {#FilesDir}\zlib1.dll; DestDir: {app}; Components: ServerComponent; Flags: sharedfile ignoreversion
Source: {#FilesDir}\zlib1.dll; DestDir: {app}; Components: ClientComponent; Flags: sharedfile ignoreversion
#if PlatformTarget == "x64"
Source: {#WOW64Dir}\zlib1.dll; DestDir: {app}\WOW64; Components: ClientComponent; Flags: sharedfile ignoreversion
#endif
;Rules for installation of MS runtimes are simplified with MSVC10 ;Rules for installation of MS runtimes are simplified with MSVC10
;We just install the runtimes into the install dir. ;We just install the runtimes into the install dir.
@ -542,9 +553,13 @@ Source: {#WOW64Dir}\lib\*.lib; DestDir: {app}\WOW64\lib; Components: DevAdminCom
;Source: {#FilesDir}\UDF\*.txt; DestDir: {app}\UDF; Components: ServerComponent; Flags: ignoreversion; ;Source: {#FilesDir}\UDF\*.txt; DestDir: {app}\UDF; Components: ServerComponent; Flags: ignoreversion;
Source: {#FilesDir}\plugins.conf; DestDir: {app}; Components: ServerComponent; Flags: ignoreversion; Source: {#FilesDir}\plugins.conf; DestDir: {app}; Components: ServerComponent; Flags: ignoreversion;
Source: {#FilesDir}\plugins\*.dll; DestDir: {app}\plugins; Components: ServerComponent; Flags: ignoreversion; Source: {#FilesDir}\plugins\*.dll; DestDir: {app}\plugins; Components: ServerComponent; Flags: ignoreversion; Check: IsServerInstall;
Source: {#FilesDir}\plugins\chacha.dll; DestDir: {app}\plugins; Components: ClientComponent; Flags: ignoreversion; Check: IsNotServerInstall;
Source: {#FilesDir}\plugins\*.conf; DestDir: {app}\plugins; Components: ServerComponent; Flags: ignoreversion; Source: {#FilesDir}\plugins\*.conf; DestDir: {app}\plugins; Components: ServerComponent; Flags: ignoreversion;
Source: {#FilesDir}\plugins\udr\*.*; DestDir: {app}\plugins\udr; Components: ServerComponent; Flags: ignoreversion; Source: {#FilesDir}\plugins\udr\*.*; DestDir: {app}\plugins\udr; Components: ServerComponent; Flags: ignoreversion;
#if PlatformTarget == "x64"
Source: {#WOW64Dir}\plugins\chacha*.dll; DestDir: {app}\WOW64\plugins; Components: ClientComponent; Flags: ignoreversion;
#endif
Source: {#FilesDir}\misc\*.*; DestDir: {app}\misc; Components: ServerComponent; Flags: ignoreversion createallsubdirs recursesubdirs ; Source: {#FilesDir}\misc\*.*; DestDir: {app}\misc; Components: ServerComponent; Flags: ignoreversion createallsubdirs recursesubdirs ;
@ -575,7 +590,7 @@ Filename: {app}\instclient.exe; Parameters: " remove fbclient"; StatusMsg: {cm:i
Filename: {app}\wow64\instclient.exe; Parameters: " remove gds32"; StatusMsg: {cm:instclientDecLibCountGds32}; MinVersion: {#MinVer}; Flags: runminimized 32bit; RunOnceId: RemoveGDS32x86 Filename: {app}\wow64\instclient.exe; Parameters: " remove gds32"; StatusMsg: {cm:instclientDecLibCountGds32}; MinVersion: {#MinVer}; Flags: runminimized 32bit; RunOnceId: RemoveGDS32x86
Filename: {app}\wow64\instclient.exe; Parameters: " remove fbclient"; StatusMsg: {cm:instclientDecLibCountFbClient}; MinVersion: {#MinVer}; Flags: runminimized 32bit; RunOnceId: RemoveFbClientx86 Filename: {app}\wow64\instclient.exe; Parameters: " remove fbclient"; StatusMsg: {cm:instclientDecLibCountFbClient}; MinVersion: {#MinVer}; Flags: runminimized 32bit; RunOnceId: RemoveFbClientx86
#endif #endif
Filename: {app}\instreg.exe; Parameters: " remove"; StatusMsg: {cm:instreg}; MinVersion: {#MinVer}; Flags: runminimized; RunOnceId: RemoveRegistryEntry Filename: {app}\instreg.exe; Parameters: " remove"; StatusMsg: {cm:instreg}; MinVersion: {#MinVer}; Components: ServerComponent; Flags: runminimized; RunOnceId: RemoveRegistryEntry
[UninstallDelete] [UninstallDelete]
Type: files; Name: "{app}\*.lck" Type: files; Name: "{app}\*.lck"

View File

@ -890,9 +890,40 @@ begin
end; end;
function IsServerInstall: Boolean;
var
SetupType: String;
begin
// DOC NOTE - WizardSetupType is not well documented. If parameter is set to
// True the Description of the setup type is returned. (This is useless for us
// as our descriptions are I18n'ised. ) If set False the string declared in
// the TYPES section is returned. BUT LOWERCASED! Aargh!!
// To protect against future changes each side is the comparison is lowercased.
SetupType := WizardSetupType ( false );
if LowerCase( SetupType ) = LowerCase( 'ServerInstall' ) then
Result := true
else
Result := False;
end;
function IsNotServerInstall: Boolean;
begin
if IsServerInstall then
Result := False
else
Result := True;
end;
function ConfigureFirebird: boolean; function ConfigureFirebird: boolean;
begin begin
result := (InstallAndConfigure AND Configure) = Configure; if IsNotServerInstall then
Result := False
else
Result := (InstallAndConfigure AND Configure) = Configure;
end; end;

View File

@ -1,5 +1,3 @@
Firebird Binary Installer Test Harness HELP (Designed with TABS=4 and console width=120) Firebird Binary Installer Test Harness HELP (Designed with TABS=4 and console width=120)
fbit {PARAM [...]] fbit {PARAM [...]]
@ -11,15 +9,22 @@
will clean up from previous broken installs. CLEAN must the first parameter will clean up from previous broken installs. CLEAN must the first parameter
and subsequent parameters are ignored. Note: - It will run silently. and subsequent parameters are ignored. Note: - It will run silently.
By default fbit installs Firebird according to the parameters passed and then By default fbit installs Firebird according to the parameters passed and then
immediately uninstalls it. A copy of the install is made, along with the install and uninstall logs. immediately uninstalls it. A copy of the install is made, along with the install and uninstall logs.
REQUIREMENTS
============
The script will attempt to detect if the current cmd session has just built firebird.
If not you must set FBINST_EXEC in the environment prior to running this script.
Be sure to check :SET_GLOBAL_ENV for hard-coded settings
Some knowledge of InnoSetup will be useful. See %FIREBIRD%/doc/installation_scripted.txt for more info.
FBIT Specific Parameters FBIT Specific Parameters
======================== ========================
Param Name Value Passed Comment Param Name Value Passed to fbit Comment
---------- ------------ ------- ---------- -------------------- -------
HELP - Displays this screen HELP - Displays this screen
DRYRUN - Show what will be done. No changes are made DRYRUN - Show what will be done. No changes are made
NOARCHIVE - Disables copying of install dir to %USERPROFILE%\fbit NOARCHIVE - Disables copying of install dir to %USERPROFILE%\fbit
@ -28,61 +33,74 @@
SCRIPTED - Sets VERYSILENT, SP and NOMSG SCRIPTED - Sets VERYSILENT, SP and NOMSG
TESTNAME NameOfTestRun Optional. No spaces allowed. Used for storing test run details. TESTNAME NameOfTestRun Optional. No spaces allowed. Used for storing test run details.
The following parameters are set by default. They are unset automatically when a conflicting parameter is passed. The following parameters are set by default. They are unset automatically when a conflicting parameter is passed.
Default Param Value Unset by Default Param Default Value set by fbit Unset by
------------- ------------- ---------- ------------- ------------------------- ----------
INTERACTIVE True SCRIPTED INTERACTIVE True SCRIPTED
INSTALLTYPE ServerInstall CLIENT or DEVINST INSTALLTYPE ServerInstall CLIENT or DEVINST
SERVICE_TASK True APPTASK SERVICE_TASK True APPTASK
SUPERSERVER True CLASSICSERVER or SUPERCLASSIC SUPERSERVER True CLASSICSERVER or SUPERCLASSIC
Firebird Installer specific Parameters Firebird Installer specific Parameters
====================================== ======================================
Param Name Value passed Action when set Param Name Value passed to installer Action when set
---------- ------------------------- --------------- ---------- ------------------------- ---------------
COPYGDSLIB CopyFbClientAsGds32Task Copy fbclient to <SYS> and rename to gds32 COPYGDSLIB CopyFbClientAsGds32Task Copy fbclient to <SYS> and rename to gds32
FORCE FORCE Force installation FORCE FORCE Force installation
NOAUTOSTART NULL Does not set AutoStartTask NOAUTOSTART NULL Does not set AutoStartTask
NOCOPYFBLIB CopyFbClientToSysTask Does not copy fbclient to <SYS> NOCOPYFBLIB - Does not copy fbclient to <SYS>
PASSWORD /SYSDBAPASSWORD=%ISC_PASSWORD% Changes SYSDBA password from masterkey PASSWORD /SYSDBAPASSWORD=%ISC_PASSWORD% Changes SYSDBA password from masterkey
See :SET_GLOBAL_ENV See :SET_GLOBAL_ENV
Installation Tasks Installation Tasks
================== ==================
Param Name Value passed Comment Param Name Value passed to /TASKS Comment
------------- ------------ --------------- ------------- ---------------------- ---------------
APPTASK UseApplicationTask Will not install as a service APPTASK UseApplicationTask Will not install as a service
CLASSICSERVER UseClassicServerTask Will configure classic server CLASSICSERVER UseClassicServerTask Will configure classic server
SUPERCLASSIC UseSuperClassicTask Will configure super classic SUPERCLASSIC UseSuperClassicTask Will configure super classic
Installation Types Installation Types
================== ==================
Param Name Value passed Comment Param Name Value passed to /TYPE Comment
------------ ------------ ------- ------------ --------------------- -------
CLIENT ClientInstall Minimal working client install CLIENT ClientInstall Minimal working client install
DEVINST DeveloperInstall Everything but the server. DEVINST DeveloperInstall Everything but the server.
SERVER_INSTALL ServerInstall
Uninstallation Uninstallation
============== ==============
Param Name Value passed Comment Param Name Value passed to uninstaller Comment
-------------- ------------ ------- -------------- --------------------------- -------
CLEAN CLEAN Completely remove the firebird install CLEAN CLEAN Completely remove the firebird install
Reset list of shared dll's in the registry Reset list of shared dll's in the registry
Assumes installed version of Firebird matches %FIREBIRD_BASE_VER% set in fbit script.
Generic InnoSetup parameters Generic InnoSetup parameters
============================ ============================
Param Name Value passed Comment Param Name Value passed to installer Comment
---------- ------------ ------- ---------- ------------------------- -------
NOMSG SUPPRESSMSGBOXES Suppress message boxes NOMSG SUPPRESSMSGBOXES Suppress message boxes
NOCANCEL NOCANCEL Prevents user cancelling install NOCANCEL NOCANCEL Prevents user cancelling install
SILENT SILENT SILENT SILENT
SP SP- Disables the This will install... prompt SP SP- Disables the This will install... prompt
VERYSILENT VERYSILENT VERYSILENT VERYSILENT
Examples
========
o Run a scripted server install:
fbit SCRIPTED
o Clean up previous firebird install:
fbit CLEAN
o Test install of firebird client:
fbit SCRIPTED CLIENT
-------------------------- End of Fbit Help Screen ---------------------------------------- -------------------------- End of Fbit Help Screen ----------------------------------------

View File

@ -18,7 +18,7 @@
:: scripted install of Firebird. It is designed to test almost all possible :: scripted install of Firebird. It is designed to test almost all possible
:: scriptable combinations and is thus far more complicated than a typical :: scriptable combinations and is thus far more complicated than a typical
:: install script need be. However, it can be used for testing. Note that chosen :: install script need be. However, it can be used for testing. Note that chosen
:: settings :: used for each test run are saved into an .inf file, along with a :: settings used for each test run are saved into an .inf file, along with a
:: log of the install run. :: log of the install run.
@goto :MAIN %* @goto :MAIN %*
@ -27,26 +27,32 @@
::======================================================= ::=======================================================
:SET_GLOBAL_ENV :SET_GLOBAL_ENV
@call :SET_VERBOSE_IF_DEBUG_ON @call :SET_VERBOSE_IF_DEBUG_ON
::@call :SET_VERBOSE
@if defined DEBUG @echo Entering %0 @if defined DEBUG @echo Entering %0
:: Uncomment this if the default command prompt takes up too much space
::@PROMPT=fbit_prompt$G
:: FBINST_EXEC must point to the package we want to test... :: Set this to the location of the firebird installer you want to test.
if not defined FBINST_EXEC ( ::@set FBINST_EXEC=%USERPROFILE%\Desktop\Firebird-5.0.0.0000_x64.exe
rem - if we have just built firebird we can test the install immediately
if defined FBBUILD_FILE_ID ( :: if we have just built firebird we can test the install immediately
if defined FBBUILD_FILE_ID (
if defined FBBUILD_FILENAME_SUFFIX ( if defined FBBUILD_FILENAME_SUFFIX (
@set FBINST_EXEC=%FBBUILD_INSTALL_IMAGES%\Firebird-%FBBUILD_FILE_ID%%FBBUILD_FILENAME_SUFFIX%.exe @set FBINST_EXEC=%FBBUILD_INSTALL_IMAGES%\Firebird-%FBBUILD_FILE_ID%%FBBUILD_FILENAME_SUFFIX%.exe
) else ( ) else (
@set FBINST_EXEC=%FBBUILD_INSTALL_IMAGES%\Firebird-%FBBUILD_FILE_ID%.exe @set FBINST_EXEC=%FBBUILD_INSTALL_IMAGES%\Firebird-%FBBUILD_FILE_ID%.exe
) )
)
) else ( ) else (
rem FBINST_EXEC must point to the package we want to test...
if not defined FBINST_EXEC (
rem Set the actual path and filename here - or set it in the environment before running fbit. rem Set the actual path and filename here - or set it in the environment before running fbit.
@set FBINST_EXEC=%USERPROFILE%\Desktop\Firebird-4.0.0.2311_0_x64_RC1.exe set FBINST_EXEC=%USERPROFILE%\Desktop\Firebird-5.0.0.0000_0_x64_RC1.exe
)
) )
:: This should be set dynamically, perhaps. But for now it is hard-coded. :: This should be set dynamically, perhaps. But for now it is hard-coded.
@set FIREBIRD_BASE_VER=Firebird_4_0 @set FIREBIRD_BASE_VER=Firebird_5_0
:: It is possible that successive installs into the same directory may :: It is possible that successive installs into the same directory may
:: generate different uninstallers but for now we hard code the default. :: generate different uninstallers but for now we hard code the default.
@ -73,14 +79,16 @@ if not defined FBINST_EXEC (
:: to read. :: to read.
@set SHOW_FINAL_CMD= @set SHOW_FINAL_CMD=
:: change as reqd, or comment out if ISC_PASSWORD is already set in your env :: change as reqd
@set ISC_PASSWORD="secret" @if not defined ISC_PASSWORD (
@set ISC_PASSWORD="secret"
)
@set TAB= & @set TAB= &
@if not defined DRYRUN ( @if not defined DRYRUN (
if not exist %FBINSTALLLOGDIR% @mkdir %FBINSTALLLOGDIR% >nul 2>nul if not exist %FBINSTALLLOGDIR% ( @mkdir %FBINSTALLLOGDIR% >nul 2>nul )
if not exist %FBINSTALLCOPYDIR% @mkdir %FBINSTALLCOPYDIR% >nul 2>nul if not exist %FBINSTALLCOPYDIR% ( @mkdir %FBINSTALLCOPYDIR% >nul 2>nul )
) )
@if defined DEBUG @echo Leaving %0 @if defined DEBUG @echo Leaving %0
@ -92,7 +100,8 @@ if not defined FBINST_EXEC (
::======================================================= ::=======================================================
:GET_OPTS :GET_OPTS
@call :SET_VERBOSE_IF_DEBUG_ON @call :SET_VERBOSE_IF_DEBUG_ON
if defined DEBUG @echo Entering %0 ::@call :SET_VERBOSE
@if defined DEBUG @echo Entering %0
:: Automatically parse the commandline and place all valid options into ENV VARS :: Automatically parse the commandline and place all valid options into ENV VARS
:: Courtesy of this link: :: Courtesy of this link:
@ -111,22 +120,22 @@ if defined DEBUG @echo Entering %0
:: will end up as :: will end up as
:: flagwithdefault=flag :: flagwithdefault=flag
:: Basically all this means that these variables should not be passed to runtime: :: Basically all this means that these variables should not be passed to runtime:
:: INTERACTIVE INSTALL INSTALLTYPE SERVER SERVICE_TASK SUPERSERVER :: INTERACTIVE INSTALL INSTALLTYPE SERVER_INSTALL SERVICE_TASK SUPERSERVER
set "options=APPTASK: CLASSICSERVER: CLEAN: CLIENT: CMD_PARAMS: COMPONENTS: COPYGDSLIB: DEVINST: DRYRUN: FINALCMD: FULL_CMD: FORCE: HELP: INTERACTIVE:1 INSTALL:1 INSTALLTYPE:ServerInstall NOARCHIVE: NOAUTOSTART: NOCANCEL: NOCOPYFBLIB: NOMSG: NOUNINSTALL: PASSWORD: RUN_TIMESTAMP: SCRIPTED: SERVER:1 SILENT: SP: SERVICE_TASK:1 SUPERCLASSIC: SUPERSERVER:1 TASK_LIST:UseSuperServerTask TESTNAME:"" UNINSTALL: VERYSILENT: XRESULT:0" set "options=APPTASK: CLASSICSERVER: CLEAN: CLIENT: CMD_PARAMS: COMPONENTS: COPYGDSLIB: DEVINST: DRYRUN: FINALCMD: FULL_CMD: FORCE: HELP: INTERACTIVE:1 INSTALL:1 INSTALLTYPE:ServerInstall NOARCHIVE: NOAUTOSTART: NOCANCEL: NOCOPYFBLIB: NOMSG: NOUNINSTALL: PASSWORD: RUN_TIMESTAMP: SCRIPTED: SERVER_INSTALL:1 SILENT: SP: SERVICE_TASK: SUPERCLASSIC: SUPERSERVER: TASK_LIST: TESTNAME:"" UNINSTALL: VERYSILENT: XRESULT:0"
if defined VERBOSE @echo on @if defined VERBOSE @echo on
for %%O in (%options%) do ( for %%O in (%options%) do (
for /f "tokens=1,* delims=:" %%A in ("%%O") do ( for /f "tokens=1,* delims=:" %%A in ("%%O") do (
set "%%A=%%~B" set "%%A=%%~B"
) )
) )
if defined VERBOSE ( @if defined VERBOSE (
call :PRINT_VARS @call :PRINT_VARS
if NOT defined DEBUG pause if NOT defined DEBUG pause
) )
:loop :loop
if not "%~1"=="" ( @if not "%~1"=="" (
set "test=!options:*%~1:=! " set "test=!options:*%~1:=! "
if "!test!"=="!options! " ( if "!test!"=="!options! " (
echo Error: Invalid option %~1 echo Error: Invalid option %~1
@ -144,7 +153,8 @@ if not "%~1"=="" (
goto :loop goto :loop
) )
if defined DEBUG @echo Leaving %0 @if defined VERBOSE ( @call :PRINT_VARS )
@if defined DEBUG @echo Leaving %0
@call :UNSET_VERBOSE @call :UNSET_VERBOSE
@goto :EOF @goto :EOF
::======================================================= ::=======================================================
@ -198,46 +208,100 @@ rem We now have everything we need for uninstall so jump to the end
goto :SET_CMD_PARAMS goto :SET_CMD_PARAMS
) )
:: Fix up any incompatible assignments :: Fix up any incompatible assignments :::::::::::::::::::::::::::::::::::::::::
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
@if defined CLASSICSERVER ( set SUPERSERVER=& set SUPERCLASSIC=) @if defined CLIENT (
@if defined SUPERCLASSIC ( set SUPERSERVER=& set CLASSICSERVER=) set INSTALLTYPE=ClientInstall
:: Theoretically this next line is redundant set DEVINST=
@if defined SUPERSERVER ( set SUPERCLASSIC=& set CLASSICSERVER=) set SERVER_INSTALL=
set TASK_LIST=
set SERVICE_TASK=
set CLASSICSERVER=
set SUPERCLASSIC=
set SUPERSERVER=
)
@if defined DEVINST (
set INSTALLTYPE=DeveloperInstall
set CLIENT=
set SERVER_INSTALL=
set TASK_LIST=
set SERVICE_TASK=
set CLASSICSERVER=
set SUPERCLASSIC=
set SUPERSERVER=
)
@if defined CLIENT ( set INSTALLTYPE=ClientInstall & set DEVINST=& set SERVER=)
@if defined DEVINST (set INSTALLTYPE=DeveloperInstall & set SERVER=)
:: Theoretically this next line is redundant :: Theoretically this next line is redundant
@if defined SERVER (set INSTALLTYPE=ServerInstall ) @if defined SERVER_INSTALL (
set INSTALLTYPE=ServerInstall
set CLIENT=
set DEVINST=
@if defined CLASSICSERVER (
set SUPERSERVER=
set SUPERCLASSIC=
set TASK_LIST=UseClassicServerTask
) else (
@if defined SUPERCLASSIC (
set SUPERSERVER=
set CLASSICSERVER=
set TASK_LIST=UseSuperClassicTask
) else (
rem @if defined SUPERSERVER (
set SUPERCLASSIC=
set CLASSICSERVER=
set SUPERSERVER=1
set TASK_LIST=UseSuperServerTask
)
)
)
::@call :SET_VERBOSE
@call :PRINT_VARS In %0 - End of Fixup
:::::::::: End Fix Up incompatible assignments :::::::::::::::::::::::::::::::::
:: Now build our task list :: Now build our task list
@if defined CLASSICSERVER ( set TASK_LIST=UseClassicServerTask) :: At this stage, if TASK_LIST is not defined then we are not doing a server install
@if defined SUPERCLASSIC ( set TASK_LIST=UseSuperClassicTask) @if defined TASK_LIST (
:: Theoretically this next line is redundant if defined APPTASK (
@if defined SUPERSERVER ( set TASK_LIST=UseSuperServerTask)
@if defined APPTASK (
set TASK_LIST=!TASK_LIST!,UseApplicationTask set TASK_LIST=!TASK_LIST!,UseApplicationTask
) else ( set INSTALLTYPE=CustomInstall
) else (
set TASK_LIST=!TASK_LIST!,UseServiceTask set TASK_LIST=!TASK_LIST!,UseServiceTask
) )
@if NOT defined NOAUTOSTART ( if NOT defined NOAUTOSTART (
set TASK_LIST=!TASK_LIST!,AutoStartTask set TASK_LIST=!TASK_LIST!,AutoStartTask
set INSTALLTYPE=CustomInstall set INSTALLTYPE=CustomInstall
)
) )
if NOT defined NOCOPYFBLIB (
@if NOT defined NOCOPYFBLIB (
if not defined TASK_LIST (
set TASK_LIST=CopyFbClientToSysTask
) else (
set TASK_LIST=!TASK_LIST!,CopyFbClientToSysTask set TASK_LIST=!TASK_LIST!,CopyFbClientToSysTask
)
set INSTALLTYPE=CustomInstall set INSTALLTYPE=CustomInstall
) )
@if defined COPYGDSLIB ( @if defined COPYGDSLIB (
if not defined TASK_LIST (
set TASK_LIST=CopyFbClientAsGds32Task
) else (
set TASK_LIST=!TASK_LIST!,CopyFbClientAsGds32Task set TASK_LIST=!TASK_LIST!,CopyFbClientAsGds32Task
)
set INSTALLTYPE=CustomInstall set INSTALLTYPE=CustomInstall
) )
@call :PRINT_VARS In %0 - End of set TASK_LIST
:SET_CMD_PARAMS :SET_CMD_PARAMS
:: set up the CMD_PARAMS variable we will use :: set up the CMD_PARAMS variable we will use
@ -248,37 +312,40 @@ if NOT defined NOCOPYFBLIB (
:: Setting PASSWORD is only relevant for a server install :: Setting PASSWORD is only relevant for a server install
@if defined PASSWORD ( @if defined PASSWORD (
@if defined SERVER ( if defined SERVER_INSTALL (
set SYSDBAPASSWORD=%ISC_PASSWORD% set SYSDBAPASSWORD=%ISC_PASSWORD%
set CMD_PARAMS=!CMD_PARAMS! /SYSDBAPASSWORD=%SYSDBAPASSWORD% set CMD_PARAMS=!CMD_PARAMS! /SYSDBAPASSWORD=%SYSDBAPASSWORD%
set INSTALLTYPE=CustomInstall set INSTALLTYPE=CustomInstall
) )
) )
if defined NOMSG set CMD_PARAMS=!CMD_PARAMS! /SUPPRESSMSGBOXES @if defined NOMSG set CMD_PARAMS=!CMD_PARAMS! /SUPPRESSMSGBOXES
if defined SILENT set CMD_PARAMS=!CMD_PARAMS! /SILENT @if defined SILENT set CMD_PARAMS=!CMD_PARAMS! /SILENT
if defined SP set CMD_PARAMS=!CMD_PARAMS! /SP- @if defined SP set CMD_PARAMS=!CMD_PARAMS! /SP-
if defined VERYSILENT set CMD_PARAMS=!CMD_PARAMS! /VERYSILENT @if defined VERYSILENT set CMD_PARAMS=!CMD_PARAMS! /VERYSILENT
:: Setting CustomInstall clears the default COMPONENTS list so we :: Setting CustomInstall clears the default COMPONENTS list so we
:: must define it manually :: must define it manually
@if /I %INSTALLTYPE% == "CustomInstall" ( ::echo INSTALLTYPE %INSTALLTYPE%
@if defined CLIENT ( set COMPONENTS=ClientComponent) @if /I "%INSTALLTYPE%" == "CustomInstall" (
@if defined DEVINST ( set COMPONENTS=DevAdminComponent,ClientComponent) if defined CLIENT ( set COMPONENTS=ClientComponent)
if defined DEVINST ( set COMPONENTS=DevAdminComponent,ClientComponent)
if defined SERVER_INSTALL ( set COMPONENTS=ServerComponent,DevAdminComponent,ClientComponent)
) else ( ) else (
set COMPONENTS=ServerComponent,DevAdminComponent,ClientComponent set COMPONENTS=ServerComponent,DevAdminComponent,ClientComponent
) )
if defined INSTALL ( @if defined INSTALL (
if defined TASK_LIST (
set FULL_CMD=/TYPE=!INSTALLTYPE! /TASKS="!TASK_LIST!" /COMPONENTS="!COMPONENTS!" !CMD_PARAMS! set FULL_CMD=/TYPE=!INSTALLTYPE! /TASKS="!TASK_LIST!" /COMPONENTS="!COMPONENTS!" !CMD_PARAMS!
) else (
set FULL_CMD=/TYPE=!INSTALLTYPE! /COMPONENTS="!COMPONENTS!" !CMD_PARAMS!
)
) else ( ) else (
set FULL_CMD=!CMD_PARAMS! set FULL_CMD=!CMD_PARAMS!
) )
@call :PRINT_VARS In %0 - After setting COMPONENTS and FULL_CMD
@if defined VERBOSE (
@call :PRINT_VARS
if NOT defined DEBUG pause
)
@if defined DEBUG @echo Leaving %0 @if defined DEBUG @echo Leaving %0
@call :UNSET_VERBOSE @call :UNSET_VERBOSE
@goto :EOF @goto :EOF
@ -288,8 +355,10 @@ if defined INSTALL (
:PRINT_VARS :PRINT_VARS
:: if a variable is not defined we don't print it, except for critical :: if a variable is not defined we don't print it, except for critical
:: variables such as FINALCMD that MUST be defined. :: variables such as FINALCMD that MUST be defined.
@if not defined VERBOSE goto :EOF
@if not "%~1" == "" ( echo %* )
@echo Variables set during script execution are: @echo Variables set during script execution are:
@set ADIRNAME @set ADIRNAME 2>nul
@set APPTASK 2>nul @set APPTASK 2>nul
@set CLASSICSERVER 2>nul @set CLASSICSERVER 2>nul
@set CLEAN 2>nul @set CLEAN 2>nul
@ -299,12 +368,15 @@ if defined INSTALL (
@set COPYGDSLIB 2>nul @set COPYGDSLIB 2>nul
@set DEVINST 2>nul @set DEVINST 2>nul
@set DRYRUN 2>nul @set DRYRUN 2>nul
@set FBINST_EXEC @set FBINST_EXEC 2>nul
@set FIREBIRD 2>nul
@set FINALCMD 2>nul @set FINALCMD 2>nul
@set FULL_CMD @set FULL_CMD 2>nul
@set FORCE 2>nul @set FORCE 2>nul
@set INTERACTIVE 2>nul @set INTERACTIVE 2>nul
@set INSTALL 2>nul @set INSTALL 2>nul
@set ISC_USER 2>nul
@set ISC_PASSWORD 2>nul
@set MERGE_TASKS 2>nul @set MERGE_TASKS 2>nul
@set NOARCHIVE= 2>nul @set NOARCHIVE= 2>nul
@set NOAUTOSTART 2>nul @set NOAUTOSTART 2>nul
@ -315,8 +387,7 @@ if defined INSTALL (
@set PASSWORD 2>nul @set PASSWORD 2>nul
@set RUN_TIMESTAMP 2>nul @set RUN_TIMESTAMP 2>nul
@set SCRIPTED 2>nul @set SCRIPTED 2>nul
@set SERVICE_TASK 2>nul @set SERVER_INSTALL 2>nul
@set SERVER 2>nul
@set SERVICE_TASK 2>nul @set SERVICE_TASK 2>nul
@set SILENT 2>nul @set SILENT 2>nul
@set SP 2>nul @set SP 2>nul
@ -327,7 +398,7 @@ if defined INSTALL (
@set UNINSTALL 2>nul @set UNINSTALL 2>nul
@set VERYSILENT 2>nul @set VERYSILENT 2>nul
@echo. @echo.
@if NOT defined DEBUG pause
@goto :EOF @goto :EOF
::======================================================= ::=======================================================
@ -336,56 +407,65 @@ if defined INSTALL (
@echo. @echo.
@echo. @echo.
@call :SET_VERBOSE_IF_DEBUG_ON @call :SET_VERBOSE_IF_DEBUG_ON
if defined DEBUG @echo Entering %0 %* @if defined DEBUG @echo Entering %~0 %*
::@call :CHECK_ENV || (@echo Check the values in SET_ENV & goto :EOF )
@call :CHECK_ENV @call :CHECK_ENV
::@call :RESET_INSTALL_ENV @if defined _err ( goto :EOF)
@call :GET_OPTS %* @call :GET_OPTS %*
@call :SET_PARAMS %* @call :SET_PARAMS %*
::@call :SET_VERBOSE ::@call :SET_VERBOSE
@if defined VERBOSE @echo on
@if defined VERBOSE @echo FULL_CMD is %FULL_CMD% @if defined VERBOSE @echo FULL_CMD is %FULL_CMD%
@if defined VERBOSE ( if NOT defined DEBUG pause ) @if defined VERBOSE ( if NOT defined DEBUG pause )
@call :TIMESTAMP @call :TIMESTAMP
@if defined DEBUG echo After call TIMESTAMP
@set RUN_TIMESTAMP=%TIMESTAMP% @set RUN_TIMESTAMP=%TIMESTAMP%
@set INSTALL_TIMESTAMP=%TIMESTAMP% @set INSTALL_TIMESTAMP=%TIMESTAMP%
@if defined DEBUG echo Before set FINALCMD
@set FINALCMD=%FBINST_EXEC% %FULL_CMD% /DIR=%FIREBIRD% /LOG=%FBINSTALLLOGDIR%\install%RUN_TIMESTAMP%.log /SAVEINF=%FBINSTALLLOGDIR%\install%RUN_TIMESTAMP%-saved.inf
@if defined DEBUG echo After set FINALCMD
set FINALCMD=%FBINST_EXEC% %FULL_CMD% /DIR=%FIREBIRD% /LOG=%FBINSTALLLOGDIR%\install%RUN_TIMESTAMP%.log /SAVEINF=%FBINSTALLLOGDIR%\install%RUN_TIMESTAMP%-saved.inf @if defined DRYRUN (
if defined DRYRUN (
@echo DRYRUN - Not executing call %FINALCMD% @echo DRYRUN - Not executing call %FINALCMD%
) else ( ) else (
@if defined SHOW_FINAL_CMD @echo Executing %FINALCMD% @if defined DEBUG @echo DRYRUN not set
call %FINALCMD% @if defined SHOW_FINAL_CMD (@echo Executing %FINALCMD%)
@call %FINALCMD%
@if errorlevel 1 ( @if ERRORLEVEL 1 (
rem @echo Calling %FBINST_EXEC% failed with %ERRORLEVEL% rem @echo Calling %FBINST_EXEC% failed with %ERRORLEVEL%
set _err=%ERRORLEVEL% set _err=%ERRORLEVEL%
call :ISS_ERROR %_err% %FBINST_EXEC% %FULL_CMD% @call :ISS_ERROR %_err% %FBINST_EXEC% %FULL_CMD%
set /A XRESULT+=1 set /A XRESULT+=1
@goto :EOF
) else ( ) else (
@echo Calling %FBINST_EXEC%......................SUCCESS! @echo Calling %FBINST_EXEC%......................SUCCESS!
) )
@echo. @echo.
@echo Now checking system state... @echo Now checking system state...
if not defined NOCOPYFBLIB (
@if defined SERVER_INSTALL (
call :CHECKSERVICECONFIGURED
call :CHECKSERVICEINSTALLED
)
@if not defined NOCOPYFBLIB (
call :CHECKFILEEXISTS c:\windows\system32\fbclient.dll good bad err_is_fail call :CHECKFILEEXISTS c:\windows\system32\fbclient.dll good bad err_is_fail
) else ( ) else (
call :CHECKFILEEXISTS c:\windows\system32\fbclient.dll bad good no_err_is_fail call :CHECKFILEEXISTS c:\windows\system32\fbclient.dll bad good no_err_is_fail
) )
if not defined COPYGDSLIB ( @if not defined COPYGDSLIB (
call :CHECKFILEEXISTS c:\windows\system32\gds32.dll bad good no_err_is_fail call :CHECKFILEEXISTS c:\windows\system32\gds32.dll bad good no_err_is_fail
) else ( ) else (
call :CHECKFILEEXISTS c:\windows\system32\gds32.dll good bad err_is_fail call :CHECKFILEEXISTS c:\windows\system32\gds32.dll good bad err_is_fail
) )
@echo. @echo Calling COPY_INSTALL
@call :COPY_INSTALL @call :COPY_INSTALL
@echo. @echo.
) )
@echo. @echo.
@echo %0 completed with %XRESULT% errors @echo %0 completed with %XRESULT% errors
@set XRESULT=0 @set XRESULT=0
@if defined DEBUG @echo Leaving %0 @if defined DEBUG @echo Leaving %0
@call :UNSET_VERBOSE @call :UNSET_VERBOSE
@echo. @echo.
@ -401,12 +481,14 @@ if defined DRYRUN (
@call :SET_VERBOSE_IF_DEBUG_ON @call :SET_VERBOSE_IF_DEBUG_ON
::@call :SET_VERBOSE ::@call :SET_VERBOSE
@if defined DEBUG @echo Entering %0 %* @if defined DEBUG @echo Entering %0 %*
@if defined NOUNINSTALL ( echo NOUNINSTALL set. Not running uninstaller & exit /b 1)
::@call :RESET_INSTALL_ENV ::@call :RESET_INSTALL_ENV
@call :GET_OPTS %* UNINSTALL @call :GET_OPTS %* UNINSTALL
@call :SET_PARAMS @call :SET_PARAMS
::@call :SET_VERBOSE ::@call :SET_VERBOSE
@if defined VERBOSE @echo on @if defined VERBOSE @echo on
@if defined VERBOSE call :PRINT_VARS @if defined VERBOSE @call :PRINT_VARS
@if defined VERBOSE @echo FULL_CMD is %FULL_CMD% @if defined VERBOSE @echo FULL_CMD is %FULL_CMD%
@if defined NOUNINSTALL ( @if defined NOUNINSTALL (
@echo NOUNINSTALL was passed. Exiting %0. @echo NOUNINSTALL was passed. Exiting %0.
@ -418,14 +500,14 @@ if defined DRYRUN (
@if defined VERBOSE ( if NOT defined DEBUG (pause) ) @if defined VERBOSE ( if NOT defined DEBUG (pause) )
@if defined DRYRUN ( @if defined DRYRUN (
echo DRYRUN - Not executing call %FINALCMD% echo DRYRUN - Not executing call %FINALCMD%
if defined DEBUG @echo Leaving %0 @if defined DEBUG @echo Leaving %0
@call :UNSET_VERBOSE @call :UNSET_VERBOSE
@echo. @echo.
@echo. @echo.
goto :EOF goto :EOF
) )
@if defined SHOW_FINAL_CMD @echo Executing %FINALCMD% @if defined SHOW_FINAL_CMD @echo Executing %FINALCMD%
call %FINALCMD% 2>nul @call %FINALCMD% 2>nul
if errorlevel 1 ( if errorlevel 1 (
set _err=%ERRORLEVEL% set _err=%ERRORLEVEL%
) else ( ) else (
@ -433,7 +515,7 @@ if defined DRYRUN (
) )
if %_err% GEQ 1 ( if %_err% GEQ 1 (
set _err=%ERRORLEVEL% set _err=%ERRORLEVEL%
call :ISS_ERROR %_err% %UNINSTALLEXE% %FULL_CMD% @call :ISS_ERROR %_err% %UNINSTALLEXE% %FULL_CMD%
set /A XRESULT+=1 set /A XRESULT+=1
) else ( ) else (
echo Calling %FIREBIRD%\%UNINSTALLEXE% ................SUCCESS! echo Calling %FIREBIRD%\%UNINSTALLEXE% ................SUCCESS!
@ -452,23 +534,23 @@ if defined DRYRUN (
echo. echo.
echo Now checking system state... echo Now checking system state...
call :CHECKFILEEXISTS c:\windows\system32\fbclient.dll bad good no_err_is_fail @call :CHECKFILEEXISTS c:\windows\system32\fbclient.dll bad good no_err_is_fail
call :CHECKFILEEXISTS c:\windows\system32\gds32.dll bad good no_err_is_fail @call :CHECKFILEEXISTS c:\windows\system32\gds32.dll bad good no_err_is_fail
if defined CLEAN ( if defined CLEAN (
call :CHECKSHAREDDLLS @call :CHECKSHAREDDLLS
call :CHECKFILEEXISTS %FIREBIRD% bad good no_err_is_fail @call :CHECKFILEEXISTS %FIREBIRD% bad good no_err_is_fail
) )
echo. echo.
call :COPY_INSTALL @call :COPY_INSTALL
echo. echo.
) )
echo. echo.
echo %0 completed with %XRESULT% errors echo %0 completed with %XRESULT% errors
set XRESULT=0 set XRESULT=0
if defined DEBUG @echo Leaving %0 @if defined DEBUG @echo Leaving %0
call :UNSET_VERBOSE @call :UNSET_VERBOSE
@echo. @echo.
@echo. @echo.
@goto :EOF @goto :EOF
@ -477,7 +559,7 @@ call :UNSET_VERBOSE
::===================================== ::=====================================
:CHECKFILEEXISTS :CHECKFILEEXISTS
if defined DEBUG @echo Entering %0 @if defined DEBUG @echo Entering %0
@call :SET_VERBOSE_IF_DEBUG_ON @call :SET_VERBOSE_IF_DEBUG_ON
:: DIR returns an error if file not found and zero if file is returned so we :: DIR returns an error if file not found and zero if file is returned so we
@ -491,66 +573,108 @@ if defined DEBUG @echo Entering %0
:: - %3 - string to output if DIR throws an error :: - %3 - string to output if DIR throws an error
:: - %4 - flag to indicate if 0 is an error or not :: - %4 - flag to indicate if 0 is an error or not
::@call :SET_VERBOSE ::@call :SET_VERBOSE
if defined VERBOSE @echo on @if defined VERBOSE @echo on
if defined VERBOSE @echo %* @if defined VERBOSE @echo %*
dir %1 >nul 2>nul dir %1 >nul 2>nul
if errorlevel 1 ( @if errorlevel 1 (
set _err=%ERRORLEVEL% set _err=%ERRORLEVEL%
) else ( ) else (
set _err=0 set _err=0
) )
if %_err% EQU 0 ( @if %_err% EQU 0 (
@echo %TAB% %1 exists - %2 ! @echo %TAB% %1 exists - %2 !
) else ( ) else (
@echo %TAB% %1 not found - %3 ! @echo %TAB% %1 not found - %3 !
) )
if "%4"=="err_is_fail" ( @if "%4"=="err_is_fail" (
if %_err% GTR 0 ( if %_err% GTR 0 (
set /A XRESULT+=1 set /A XRESULT+=1
@echo XRESULT++ @echo XRESULT++
) )
) )
if "%4"=="no_err_is_fail" ( @if "%4"=="no_err_is_fail" (
if %_err% EQU 0 ( if %_err% EQU 0 (
set /A XRESULT+=1 set /A XRESULT+=1
@echo XRESULT++ @echo XRESULT++
) )
) )
call :RESET_ERRORLEVEL @call :RESET_ERRORLEVEL
@call :UNSET_VERBOSE @call :UNSET_VERBOSE
if defined DEBUG @echo Leaving %0 @if defined DEBUG @echo Leaving %0
@goto :EOF @goto :EOF
::===CHECKFILEEXISTS================================== ::===CHECKFILEEXISTS==================================
::===================================== ::=====================================
:CHECKSHAREDDLLS :CHECKSHAREDDLLS
if defined DEBUG @echo Entering %0 @if defined DEBUG @echo Entering %0
@call :SET_VERBOSE_IF_DEBUG_ON @call :SET_VERBOSE_IF_DEBUG_ON
@reg query HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\SharedDLLs > %TEMP%\shareddlls.txt @reg query HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\SharedDLLs > %TEMP%\shareddlls.txt
@grep --ignore-case --count firebird %TEMP%\shareddlls.txt > %TEMP%\shareddllscount.txt ::@grep --ignore-case --count firebird %TEMP%\shareddlls.txt > %TEMP%\shareddllscount.txt
type %TEMP%\shareddlls.txt | find /C /I "firebird" > %TEMP%\shareddllscount.txt
set /p SHAREDDLLSCOUNT= < %TEMP%\shareddllscount.txt set /p SHAREDDLLSCOUNT= < %TEMP%\shareddllscount.txt
if NOT defined DEBUG del /q %TEMP%\shareddll*.txt @if NOT defined DEBUG del /q %TEMP%\shareddll*.txt
if %SHAREDDLLSCOUNT% GTR 0 ( @if %SHAREDDLLSCOUNT% GTR 0 (
@echo %TAB% Oops - residue in HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\SharedDLLs @echo %TAB% Oops - residue in HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\SharedDLLs
set /A XRESULT+=1 set /A XRESULT+=1
@echo XRESULT++ @echo XRESULT++
) )
call :RESET_ERRORLEVEL @call :RESET_ERRORLEVEL
if defined DEBUG @echo Leaving %0 @if defined DEBUG @echo Leaving %0
@call :UNSET_VERBOSE @call :UNSET_VERBOSE
@goto :EOF @goto :EOF
::===CHECKSHAREDDLLS=================== ::===CHECKSHAREDDLLS===================
::=====================================
:CHECKSERVICECONFIGURED
@if defined DEBUG @echo Entering %0
@call :SET_VERBOSE_IF_DEBUG_ON
:: Add test for server arch set in firebird.conf
if defined CLASSICSERVER ( set STR_TO_TEST="servermode = classic" )
if defined SUPERCLASSIC ( set STR_TO_TEST="servermode = superclassic" )
if defined SUPERSERVER ( set STR_TO_TEST="servermode = super" )
call :CHECKSTRING %STR_TO_TEST% %FIREBIRD%\\firebird.conf
if ERRORLEVEL 1 (
@echo %TAB% %STR_TO_TEST% not set in %FIREBIRD%\\firebird.conf
set /A XRESULT+=1
@echo XRESULT++
)
@call :RESET_ERRORLEVEL
@if defined DEBUG @echo Leaving %0
@call :UNSET_VERBOSE
@goto :EOF
::===CHECKSERVICECONFIGURED===================
::=====================================
:CHECKSERVICEINSTALLED
@if defined DEBUG @echo Entering %0
@call :SET_VERBOSE_IF_DEBUG_ON
%FIREBIRD%\\instsvc.exe q
@call :RESET_ERRORLEVEL
@if defined DEBUG @echo Leaving %0
@call :UNSET_VERBOSE
@goto :EOF
::===CHECKSERVICEINSTALLED===================
::===================================== ::=====================================
:COPY_INSTALL :COPY_INSTALL
@call :SET_VERBOSE_IF_DEBUG_ON @call :SET_VERBOSE_IF_DEBUG_ON
if defined DEBUG @echo Entering %0 @if defined DEBUG @echo Entering %0
::@call :SET_VERBOSE ::@call :SET_VERBOSE
if defined VERBOSE @echo on @if defined VERBOSE @echo on
:: ADIRNAME should normally be set during install and persist for uninstall :: ADIRNAME should normally be set during install and persist for uninstall
@if not defined ADIRNAME ( @if not defined ADIRNAME (
@ -590,10 +714,13 @@ if defined VERBOSE @echo on
:CHECK_ENV :CHECK_ENV
:: TODO - add more checks for the environment declared in SET_GLOBAL_ENV :: TODO - add more checks for the environment declared in SET_GLOBAL_ENV
if not exist %FBINST_EXEC% ( if not exist %FBINST_EXEC% (
echo %~0 failed
echo Cannot find %FBINST_EXEC% echo Cannot find %FBINST_EXEC%
exit /b 1 echo Check the setting of FBINST_EXEC
set _err=1
exit /b %_err%
) )
@goto :EOF goto :EOF
::===CHECK_ENV========================= ::===CHECK_ENV=========================
::===================================== ::=====================================
@ -604,6 +731,7 @@ if not exist %FBINST_EXEC% (
:: not have the same value as the internal ERRORLEVEL. We have to execute an :: not have the same value as the internal ERRORLEVEL. We have to execute an
:: arbitrary command that cannot fail if we want to really reset the internal :: arbitrary command that cannot fail if we want to really reset the internal
:: variable. :: variable.
@set _err=
@ver > nul @ver > nul
@goto :EOF @goto :EOF
::===RESET_ERRORLEVEL================== ::===RESET_ERRORLEVEL==================
@ -620,12 +748,15 @@ if not exist %FBINST_EXEC% (
@goto :EOF @goto :EOF
::===SET_VERBOSE_IF_DEBUG_ON================ ::===SET_VERBOSE_IF_DEBUG_ON================
::===================================== ::=====================================
:SET_VERBOSE :SET_VERBOSE
@set VERBOSE=1 @set VERBOSE=1
@echo on
@goto :EOF @goto :EOF
::===SET_VERBOSE================ ::===SET_VERBOSE================
::===================================== ::=====================================
:UNSET_VERBOSE :UNSET_VERBOSE
:: Unset VERBOSE before exiting each sub-routine. :: Unset VERBOSE before exiting each sub-routine.
@ -651,50 +782,131 @@ goto :EOF
:ISS_ERROR :ISS_ERROR
@echo. @echo.
@echo InnoSetup ErrorCode %1 from calling %~2 %~3 %~4 %~5 %~6 %~7 %~8 %~9 @echo InnoSetup ErrorCode %1 from calling %~2 %~3 %~4 %~5 %~6 %~7 %~8 %~9
@echo Definition of Innosetup errorcode %1 is to be added later @echo.
@if "%1"=="1" (
@echo Setup failed to initialize.
@echo.
@goto :EOF
)
@if "%1"=="2" (
@echo The user clicked Cancel in the wizard before the actual installation
@echo started, or chose 'No' on the opening 'This will install...' message box.
@echo.
@goto :EOF
)
@if "%1" == "3" (
@echo A fatal error occurred while preparing to move to the next
@echo installation phase (for example, from displaying the pre-installation
@echo wizard pages to the actual installation process). This should never
@echo happen except under the most unusual of circumstances, such as
@echo running out of memory or Windows resources.
@echo.
@goto :EOF
)
@if "%1" == "4" (
@echo A fatal error occurred during the actual installation process.
@echo.
@goto :EOF
)
@if "%1" == "5" (
@echo The user clicked Cancel during the actual installation process,
@echo or chose Abort at an Abort-Retry-Ignore box.
@echo.
@goto :EOF
)
@if "%1" == "6" (
@echo The Setup process was forcefully terminated by the debugger
@echo (Run | Terminate was used in the Compiler IDE).
@echo.
@goto :EOF
)
@if "%1" == "7" (
@echo The Preparing to Install stage determined that Setup cannot proceed
@echo with installation. (First introduced in Inno Setup 5.4.1.)
@echo.
@goto :EOF
)
@if "%1" == "8" (
@echo The Preparing to Install stage determined that Setup cannot proceed
@echo with installation, and that the system needs to be restarted in
@echo order to correct the problem. (First introduced in Inno Setup 5.4.1.)
@echo.
@goto :EOF
)
@echo. @echo.
@goto :EOF @goto :EOF
::====================================== ::======================================
::================================================================================================================ ::==============================================================================
:: GENERIC SUPPORT ROUTINES FROM HERE TO END ====================================================================== :: GENERIC SUPPORT ROUTINES FROM HERE TO END ==================================
::================================================================================================================ ::==============================================================================
::=====================================
:CHECKSTRING
@if defined DEBUG @echo Entering %0
@call :SET_VERBOSE_IF_DEBUG_ON
::@if defined VERBOSE echo %0 - %*
for %%v in ( %* ) do (
if /I "%%v"=="" ( @goto :EOF )
)
:: === NOTE ====
:: We use the /x flag here for an exact match!
@if defined VERBOSE echo calling findstr /x /c:%1 /i %2
:: findstr /x /c:"servermode = superclassic" /i Firebird_4_0\firebird.conf
findstr /x /c:%1 /i %2
@call :RESET_ERRORLEVEL
@if defined DEBUG @echo Leaving %0
@call :UNSET_VERBOSE
@goto :EOF
::===CHECKSTRING===================
::===================================== ::=====================================
:GET_DATE :GET_DATE
if NOT defined DEBUG @echo off @if NOT defined DEBUG @echo off
echo. | date | FIND "(mm" > NUL @echo. | date | FIND "(mm" > NUL
if errorlevel 1 ((set MD=0) & call :ParseDate DD MM) else ((set MD=1) & call :ParseDate MM DD) @if errorlevel 1 ((set MD=0) & call :ParseDate DD MM) else ((set MD=1) & call :ParseDate MM DD)
@goto :EOF @goto :EOF
:ParseDate :ParseDate
for /f "tokens=1-3 delims=/.- " %%a in ("%DATE%") do ( @for /f "tokens=1-3 delims=/.- " %%a in ("%DATE%") do (
set %1=%%a @set %1=%%a
set %2=%%b @set %2=%%b
set YYYY=%%c @set YYYY=%%c
@goto:EOF) @goto:EOF)
::===================================== ::=====================================
::===================================== ::=====================================
:GET_TIME :GET_TIME
if NOT defined DEBUG @echo off @if NOT defined DEBUG @echo off
for /f "tokens=1-4 delims=:. " %%a in ("%TIME%") do ( @for /f "tokens=1-4 delims=:. " %%a in ("%TIME%") do (
set hh=%%a @set hh=%%a
set nn=%%b @set nn=%%b
set ss=%%c @set ss=%%c
set ms=%%d @set ms=%%d
@goto :EOF) @goto :EOF)
::===================================== ::=====================================
::===================================== ::=====================================
:CLEAR_DT_VARS :CLEAR_DT_VARS
if NOT defined DEBUG @echo off @if NOT defined DEBUG @echo off
set MM= @set MM=
set DD= @set DD=
set YYYY= @set YYYY=
set hh= @set hh=
set nn= @set nn=
set ss= @set ss=
set ms= @set ms=
@if defined DEBUG @echo Leaving CLEAR_DT_VARS
@goto :EOF @goto :EOF
::===================================== ::=====================================
@ -703,8 +915,8 @@ set ms=
@call :GET_DATE @call :GET_DATE
@call :GET_TIME @call :GET_TIME
@set TIMESTAMP=%YYYY%%MM%%DD%%hh%%nn%%ss% @set TIMESTAMP=%YYYY%%MM%%DD%%hh%%nn%%ss%
if defined DEBUG (@echo Timestamp set to %TIMESTAMP%) @if defined DEBUG (@echo Timestamp set to %TIMESTAMP%)
call :CLEAR_DT_VARS @call :CLEAR_DT_VARS
@goto :EOF @goto :EOF
::===================================== ::=====================================
@ -724,25 +936,22 @@ call :CLEAR_DT_VARS
:: sometimes it is useful to just tidy up! :: sometimes it is useful to just tidy up!
@if /I "%1"=="clean" ( @if /I "%1"=="clean" (
@call :RUN_UNINSTALLER SCRIPTED CLEAN @set NOUNINSTALL=
@goto :EOF call :RUN_UNINSTALLER SCRIPTED CLEAN
goto :EOF
) )
@call :RUN_INSTALLER %* @call :RUN_INSTALLER %*
@if defined _err ( echo _err is %_err% - quitting. && @goto :EOF)
@call :RUN_UNINSTALLER %* @call :RUN_UNINSTALLER %*
@if defined DEBUG @echo Leaving %0 @if defined DEBUG @echo Leaving %0
@call :UNSET_VERBOSE @call :UNSET_VERBOSE
@goto :EOF @goto :EOF
::===MAIN============================== ::===MAIN==============================
:: CONTINUE with
:: - look at setting up different test recipes and naming them.
:: - Integrate innosetup exit codes and look at error handling
:: - Tidy up the relationship between DEBUG and VERBOSE.
:: - DEBUG should turn on VERBOSE?
:: - VERBOSE should be routine specific.?
:: - DEBUG should persist for entire script run?
:: NOTHING BEYOND THIS POINT=========== :: NOTHING BEYOND THIS POINT===========

View File

@ -41,9 +41,8 @@
# #
# String # String
# ------ # ------
# Strings are also what they sound like, strings. Examples: # Strings are also what they sound like, strings. Example:
# RemoteServiceName = gds_db # RemoteServiceName = gds_db
# RemotePipeName = pipe47
# #
# Scopes # Scopes
# ------ # ------
@ -612,6 +611,18 @@
#ConnectionIdleTimeout = 0 #ConnectionIdleTimeout = 0
# ----------------------------
#
# Set number of seconds after which ON DISCONNECT trigger execution will be
# automatically cancelled by the engine. Zero means no timeout is set.
#
# Per-database configurable.
#
# Type: integer
#
#OnDisconnectTriggerTimeout = 180
# ---------------------------- # ----------------------------
# #
# How often the pages are flushed on disk # How often the pages are flushed on disk
@ -1020,6 +1031,19 @@
#GCPolicy = combined #GCPolicy = combined
# ----------------------------
# Maximum statement cache size
#
# The maximum amount of RAM used to cache unused DSQL compiled statements.
# If set to 0 (zero), statement cache is disabled.
#
# Per-database configurable.
#
# Type: integer
#
#MaxStatementCacheSize = 2M
# ---------------------------- # ----------------------------
# Security database # Security database
# #
@ -1083,18 +1107,6 @@
# #
#IpcName = FIREBIRD #IpcName = FIREBIRD
#
# The name of the pipe used as a transport channel in NetBEUI protocol.
# Has the same meaning as a port number for TCP/IP. The default value is
# compatible with IB/FB1.
#
# Per-connection configurable.
#
# Type: string
#
#RemotePipeName = interbas
# ============================ # ============================
# Settings for Unix/Linux platforms # Settings for Unix/Linux platforms
# ============================ # ============================

View File

@ -4881,16 +4881,6 @@
path = old_proto.h; path = old_proto.h;
refType = 4; refType = 4;
}; };
F616C66F0200B0CF01EF0ADE = {
isa = PBXFileReference;
path = opt.cpp;
refType = 4;
};
F616C6700200B0CF01EF0ADE = {
isa = PBXFileReference;
path = opt_proto.h;
refType = 4;
};
F616C6710200B0CF01EF0ADE = { F616C6710200B0CF01EF0ADE = {
children = ( children = (
F616C6720200B0CF01EF0ADE, F616C6720200B0CF01EF0ADE,
@ -5133,11 +5123,6 @@
path = rse.cpp; path = rse.cpp;
refType = 4; refType = 4;
}; };
F616C6A70200B0D001EF0ADE = {
isa = PBXFileReference;
path = rse.h;
refType = 4;
};
F616C6A80200B0D001EF0ADE = { F616C6A80200B0D001EF0ADE = {
isa = PBXFileReference; isa = PBXFileReference;
path = rse_proto.h; path = rse_proto.h;
@ -6767,16 +6752,6 @@
path = winvx.cpp; path = winvx.cpp;
refType = 4; refType = 4;
}; };
F616C8C00200B0D001EF0ADE = {
isa = PBXFileReference;
path = wnet.cpp;
refType = 4;
};
F616C8C10200B0D001EF0ADE = {
isa = PBXFileReference;
path = wnet_proto.h;
refType = 4;
};
F616C8C20200B0D001EF0ADE = { F616C8C20200B0D001EF0ADE = {
isa = PBXFileReference; isa = PBXFileReference;
path = xdr.cpp; path = xdr.cpp;

View File

@ -124,6 +124,9 @@ $(EXAMPLES_FB)/README:
$(CP) $(ROOT)/examples/stat/*.* $(EXAMPLES_FB)/stat/ $(CP) $(ROOT)/examples/stat/*.* $(EXAMPLES_FB)/stat/
$(CP) $(ROOT)/examples/udf/*.* $(EXAMPLES_FB)/udf/ $(CP) $(ROOT)/examples/udf/*.* $(EXAMPLES_FB)/udf/
$(CP) $(ROOT)/examples/udr/*.* $(EXAMPLES_FB)/udr/ $(CP) $(ROOT)/examples/udr/*.* $(EXAMPLES_FB)/udr/
$(CP) $(ROOT)/examples/object_pascal/*.* $(EXAMPLES_FB)/object_pascal/
$(CP) $(ROOT)/examples/object_pascal/[mM]ake* $(EXAMPLES_FB)/object_pascal/
$(CP) $(ROOT)/examples/object_pascal/common/*.* $(EXAMPLES_FB)/object_pascal/common/
# $(CP) intlemp.fdb $(EXAMPLES_FB)/empbuild/ # $(CP) intlemp.fdb $(EXAMPLES_FB)/empbuild/
$(CP) $(ROOT)/examples/readme $(EXAMPLES_FB)/README $(CP) $(ROOT)/examples/readme $(EXAMPLES_FB)/README
$(CP) $(ROOT)/examples/empbuild/employe2.sql $(EXAMPLES_FB)/empbuild/ $(CP) $(ROOT)/examples/empbuild/employe2.sql $(EXAMPLES_FB)/empbuild/

View File

@ -27,5 +27,6 @@
LD_lookup_charset LD_lookup_charset
LD_lookup_texttype LD_lookup_texttype
LD_lookup_texttype_with_status
LD_setup_attributes LD_setup_attributes
LD_version LD_version

View File

@ -77,7 +77,7 @@ AllObjects += $(Chacha_Objects)
# Engine # Engine
Engine_Objects:= $(call dirObjects,jrd) $(call dirObjects,dsql) $(call dirObjects,jrd/extds) \ Engine_Objects:= $(call dirObjects,jrd) $(call dirObjects,dsql) $(call dirObjects,jrd/extds) \
$(call dirObjects,jrd/recsrc) $(call dirObjects,jrd/replication) $(call dirObjects,jrd/trace) \ $(call dirObjects,jrd/optimizer) $(call dirObjects,jrd/recsrc) $(call dirObjects,jrd/replication) $(call dirObjects,jrd/trace) \
$(call makeObjects,lock,lock.cpp) $(call makeObjects,lock,lock.cpp)
AllObjects += $(Engine_Objects) AllObjects += $(Engine_Objects)

View File

@ -0,0 +1,49 @@
# The contents of this file are subject to the Interbase Public
# License Version 1.0 (the "License"); you may not use this file
# except in compliance with the License. You may obtain a copy
# of the License at http://www.Inprise.com/IPL.html
#
# Software distributed under the License is distributed on an
# "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express
# or implied. See the License for the specific language governing
# rights and limitations under the License.
#
# The Original Code was created by Inprise Corporation
# and its predecessors. Portions created by Inprise Corporation are
#
# Copyright (C) 2000 Inprise Corporation
# All Rights Reserved.
# Contributor(s): ______________________________________.
# Start of file prefix.darwin: $(VERSION) @PLATFORM@
# 2 Oct 2002, Nickolay Samofatov - Major Cleanup
#
# Default build from 10.9 using Clang
#
# Build instructions
# set CFLAGS='-I (ICUDIR)/icu/source/common' (ucnv.h)
# set LDFLAGS='-L(ICUDIR)/icu/source/lib' (-licuuc)
# set CXXFLAGS='-I (ICUDIR)/icu/source/common -I ICUDIR/icu/source/i18n'
# where ICUDIR is where you installed ICU
# configure using --with-builtin-tommath
# or add the relevant -I, -L for an installed version of libtommath
#DYLD_PRINT_ENV=1
#export DYLD_PRINT_ENV
#DYLD_PRINT_LIBRARIES=1
#export DYLD_PRINT_LIBRARIES
MACOSX_DEPLOYMENT_TARGET=12.0
export MACOSX_DEPLOYMENT_TARGET
PROD_FLAGS=-DDARWIN -DARM64 -pipe -O2 -MMD -fPIC -fno-common -mmacosx-version-min=12.0
DEV_FLAGS=-ggdb -DDARWIN -DARM64 -pipe -MMD -fPIC -fno-omit-frame-pointer -fno-common -Wall -fno-optimize-sibling-calls -mmacosx-version-min=12.0 -Wno-non-virtual-dtor
CXXFLAGS:=$(CXXFLAGS) -fvisibility-inlines-hidden -fvisibility=hidden -stdlib=libc++
UNDEF_PLATFORM=
LINK_LIBS+=-liconv
#MATHLIB=$(ROOT)/extern/libtommath/.libs/libtommath.a
SO_LINK_LIBS+=-liconv
include $(ROOT)/gen/darwin.defaults

View File

@ -124,6 +124,7 @@
<ClInclude Include="..\..\..\src\common\classes\ClumpletWriter.h" /> <ClInclude Include="..\..\..\src\common\classes\ClumpletWriter.h" />
<ClInclude Include="..\..\..\src\common\classes\condition.h" /> <ClInclude Include="..\..\..\src\common\classes\condition.h" />
<ClInclude Include="..\..\..\src\common\classes\DbImplementation.h" /> <ClInclude Include="..\..\..\src\common\classes\DbImplementation.h" />
<ClInclude Include="..\..\..\src\common\classes\DoublyLinkedList.h" />
<ClInclude Include="..\..\..\src\common\classes\fb_atomic.h" /> <ClInclude Include="..\..\..\src\common\classes\fb_atomic.h" />
<ClInclude Include="..\..\..\src\common\classes\fb_pair.h" /> <ClInclude Include="..\..\..\src\common\classes\fb_pair.h" />
<ClInclude Include="..\..\..\src\common\classes\fb_string.h" /> <ClInclude Include="..\..\..\src\common\classes\fb_string.h" />

View File

@ -392,6 +392,9 @@
<ClInclude Include="..\..\..\src\common\classes\DbImplementation.h"> <ClInclude Include="..\..\..\src\common\classes\DbImplementation.h">
<Filter>headers</Filter> <Filter>headers</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\..\..\src\common\classes\DoublyLinkedList.h">
<Filter>headers</Filter>
</ClInclude>
<ClInclude Include="..\..\..\src\common\classes\fb_atomic.h"> <ClInclude Include="..\..\..\src\common\classes\fb_atomic.h">
<Filter>headers</Filter> <Filter>headers</Filter>
</ClInclude> </ClInclude>

View File

@ -41,6 +41,9 @@
<ClCompile Include="..\..\..\src\dsql\DsqlCompilerScratch.cpp" /> <ClCompile Include="..\..\..\src\dsql\DsqlCompilerScratch.cpp" />
<ClCompile Include="..\..\..\src\dsql\DsqlCursor.cpp" /> <ClCompile Include="..\..\..\src\dsql\DsqlCursor.cpp" />
<ClCompile Include="..\..\..\src\dsql\DSqlDataTypeUtil.cpp" /> <ClCompile Include="..\..\..\src\dsql\DSqlDataTypeUtil.cpp" />
<ClCompile Include="..\..\..\src\dsql\DsqlRequests.cpp" />
<ClCompile Include="..\..\..\src\dsql\DsqlStatementCache.cpp" />
<ClCompile Include="..\..\..\src\dsql\DsqlStatements.cpp" />
<ClCompile Include="..\..\..\src\dsql\errd.cpp" /> <ClCompile Include="..\..\..\src\dsql\errd.cpp" />
<ClCompile Include="..\..\..\src\dsql\ExprNodes.cpp" /> <ClCompile Include="..\..\..\src\dsql\ExprNodes.cpp" />
<ClCompile Include="..\..\..\src\dsql\gen.cpp" /> <ClCompile Include="..\..\..\src\dsql\gen.cpp" />
@ -90,7 +93,6 @@
<ClCompile Include="..\..\..\src\jrd\IntlManager.cpp" /> <ClCompile Include="..\..\..\src\jrd\IntlManager.cpp" />
<ClCompile Include="..\..\..\src\jrd\intl_builtin.cpp" /> <ClCompile Include="..\..\..\src\jrd\intl_builtin.cpp" />
<ClCompile Include="..\..\..\src\jrd\jrd.cpp" /> <ClCompile Include="..\..\..\src\jrd\jrd.cpp" />
<ClCompile Include="..\..\..\src\jrd\JrdStatement.cpp" />
<ClCompile Include="..\..\..\src\jrd\KeywordsTable.cpp" /> <ClCompile Include="..\..\..\src\jrd\KeywordsTable.cpp" />
<ClCompile Include="..\..\..\src\jrd\lck.cpp" /> <ClCompile Include="..\..\..\src\jrd\lck.cpp" />
<ClCompile Include="..\..\..\src\jrd\Mapping.cpp" /> <ClCompile Include="..\..\..\src\jrd\Mapping.cpp" />
@ -100,8 +102,9 @@
<ClCompile Include="..\..\..\src\jrd\nbak.cpp" /> <ClCompile Include="..\..\..\src\jrd\nbak.cpp" />
<ClCompile Include="..\..\..\src\jrd\nodebug.cpp" /> <ClCompile Include="..\..\..\src\jrd\nodebug.cpp" />
<ClCompile Include="..\..\..\src\jrd\ods.cpp" /> <ClCompile Include="..\..\..\src\jrd\ods.cpp" />
<ClCompile Include="..\..\..\src\jrd\opt.cpp" /> <ClCompile Include="..\..\..\src\jrd\optimizer\Optimizer.cpp" />
<ClCompile Include="..\..\..\src\jrd\Optimizer.cpp" /> <ClCompile Include="..\..\..\src\jrd\optimizer\Retrieval.cpp" />
<ClCompile Include="..\..\..\src\jrd\optimizer\InnerJoin.cpp" />
<ClCompile Include="..\..\..\src\jrd\os\win32\winnt.cpp" /> <ClCompile Include="..\..\..\src\jrd\os\win32\winnt.cpp" />
<ClCompile Include="..\..\..\src\jrd\pag.cpp" /> <ClCompile Include="..\..\..\src\jrd\pag.cpp" />
<ClCompile Include="..\..\..\src\jrd\par.cpp" /> <ClCompile Include="..\..\..\src\jrd\par.cpp" />
@ -152,6 +155,7 @@
<ClCompile Include="..\..\..\src\jrd\shut.cpp" /> <ClCompile Include="..\..\..\src\jrd\shut.cpp" />
<ClCompile Include="..\..\..\src\jrd\sort.cpp" /> <ClCompile Include="..\..\..\src\jrd\sort.cpp" />
<ClCompile Include="..\..\..\src\jrd\sqz.cpp" /> <ClCompile Include="..\..\..\src\jrd\sqz.cpp" />
<ClCompile Include="..\..\..\src\jrd\Statement.cpp" />
<ClCompile Include="..\..\..\src\jrd\svc.cpp" /> <ClCompile Include="..\..\..\src\jrd\svc.cpp" />
<ClCompile Include="..\..\..\src\jrd\SysFunction.cpp" /> <ClCompile Include="..\..\..\src\jrd\SysFunction.cpp" />
<ClCompile Include="..\..\..\src\jrd\SystemPackages.cpp" /> <ClCompile Include="..\..\..\src\jrd\SystemPackages.cpp" />
@ -186,6 +190,9 @@
<ClInclude Include="..\..\..\src\dsql\DsqlCompilerScratch.h" /> <ClInclude Include="..\..\..\src\dsql\DsqlCompilerScratch.h" />
<ClInclude Include="..\..\..\src\dsql\DsqlCursor.h" /> <ClInclude Include="..\..\..\src\dsql\DsqlCursor.h" />
<ClInclude Include="..\..\..\src\dsql\DSqlDataTypeUtil.h" /> <ClInclude Include="..\..\..\src\dsql\DSqlDataTypeUtil.h" />
<ClInclude Include="..\..\..\src\dsql\DsqlRequests.h" />
<ClInclude Include="..\..\..\src\dsql\DsqlStatementCache.h" />
<ClInclude Include="..\..\..\src\dsql\DsqlStatements.h" />
<ClInclude Include="..\..\..\src\dsql\dsql_proto.h" /> <ClInclude Include="..\..\..\src\dsql\dsql_proto.h" />
<ClInclude Include="..\..\..\src\dsql\errd_proto.h" /> <ClInclude Include="..\..\..\src\dsql\errd_proto.h" />
<ClInclude Include="..\..\..\src\dsql\ExprNodes.h" /> <ClInclude Include="..\..\..\src\dsql\ExprNodes.h" />
@ -275,7 +282,6 @@
<ClInclude Include="..\..\..\src\jrd\irq.h" /> <ClInclude Include="..\..\..\src\jrd\irq.h" />
<ClInclude Include="..\..\..\src\jrd\isc_version.h" /> <ClInclude Include="..\..\..\src\jrd\isc_version.h" />
<ClInclude Include="..\..\..\src\jrd\jrd.h" /> <ClInclude Include="..\..\..\src\jrd\jrd.h" />
<ClInclude Include="..\..\..\src\jrd\JrdStatement.h" />
<ClInclude Include="..\..\..\src\jrd\jrd_proto.h" /> <ClInclude Include="..\..\..\src\jrd\jrd_proto.h" />
<ClInclude Include="..\..\..\src\jrd\KeywordsTable.h" /> <ClInclude Include="..\..\..\src\jrd\KeywordsTable.h" />
<ClInclude Include="..\..\..\src\jrd\lck.h" /> <ClInclude Include="..\..\..\src\jrd\lck.h" />
@ -296,8 +302,7 @@
<ClInclude Include="..\..\..\src\jrd\obj.h" /> <ClInclude Include="..\..\..\src\jrd\obj.h" />
<ClInclude Include="..\..\..\src\jrd\ods.h" /> <ClInclude Include="..\..\..\src\jrd\ods.h" />
<ClInclude Include="..\..\..\src\jrd\ods_proto.h" /> <ClInclude Include="..\..\..\src\jrd\ods_proto.h" />
<ClInclude Include="..\..\..\src\jrd\Optimizer.h" /> <ClInclude Include="..\..\..\src\jrd\optimizer\Optimizer.h" />
<ClInclude Include="..\..\..\src\jrd\opt_proto.h" />
<ClInclude Include="..\..\..\src\jrd\pag.h" /> <ClInclude Include="..\..\..\src\jrd\pag.h" />
<ClInclude Include="..\..\..\src\jrd\pag_proto.h" /> <ClInclude Include="..\..\..\src\jrd\pag_proto.h" />
<ClInclude Include="..\..\..\src\jrd\par_proto.h" /> <ClInclude Include="..\..\..\src\jrd\par_proto.h" />
@ -317,7 +322,6 @@
<ClInclude Include="..\..\..\src\jrd\rlck_proto.h" /> <ClInclude Include="..\..\..\src\jrd\rlck_proto.h" />
<ClInclude Include="..\..\..\src\jrd\Routine.h" /> <ClInclude Include="..\..\..\src\jrd\Routine.h" />
<ClInclude Include="..\..\..\src\jrd\rpb_chain.h" /> <ClInclude Include="..\..\..\src\jrd\rpb_chain.h" />
<ClInclude Include="..\..\..\src\jrd\rse.h" />
<ClInclude Include="..\..\..\src\jrd\RuntimeStatistics.h" /> <ClInclude Include="..\..\..\src\jrd\RuntimeStatistics.h" />
<ClInclude Include="..\..\..\src\jrd\sbm.h" /> <ClInclude Include="..\..\..\src\jrd\sbm.h" />
<ClInclude Include="..\..\..\src\jrd\scl.h" /> <ClInclude Include="..\..\..\src\jrd\scl.h" />
@ -327,6 +331,7 @@
<ClInclude Include="..\..\..\src\jrd\shut_proto.h" /> <ClInclude Include="..\..\..\src\jrd\shut_proto.h" />
<ClInclude Include="..\..\..\src\jrd\sort.h" /> <ClInclude Include="..\..\..\src\jrd\sort.h" />
<ClInclude Include="..\..\..\src\jrd\sqz.h" /> <ClInclude Include="..\..\..\src\jrd\sqz.h" />
<ClInclude Include="..\..\..\src\jrd\Statement.h" />
<ClInclude Include="..\..\..\src\jrd\status.h" /> <ClInclude Include="..\..\..\src\jrd\status.h" />
<ClInclude Include="..\..\..\src\jrd\svc.h" /> <ClInclude Include="..\..\..\src\jrd\svc.h" />
<ClInclude Include="..\..\..\src\jrd\svc_undoc.h" /> <ClInclude Include="..\..\..\src\jrd\svc_undoc.h" />

View File

@ -43,6 +43,9 @@
<Filter Include="Replication"> <Filter Include="Replication">
<UniqueIdentifier>{686cba10-1e4f-44f7-b044-972ef8327197}</UniqueIdentifier> <UniqueIdentifier>{686cba10-1e4f-44f7-b044-972ef8327197}</UniqueIdentifier>
</Filter> </Filter>
<Filter Include="Optimizer">
<UniqueIdentifier>{4acc7c23-ac25-4311-a075-813ed730cb40}</UniqueIdentifier>
</Filter>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="..\..\..\src\jrd\recsrc\WindowedStream.cpp"> <ClCompile Include="..\..\..\src\jrd\recsrc\WindowedStream.cpp">
@ -138,6 +141,15 @@
<ClCompile Include="..\..\..\src\dsql\DSqlDataTypeUtil.cpp"> <ClCompile Include="..\..\..\src\dsql\DSqlDataTypeUtil.cpp">
<Filter>DSQL</Filter> <Filter>DSQL</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\..\src\dsql\DsqlRequests.cpp">
<Filter>DSQL</Filter>
</ClCompile>
<ClCompile Include="..\..\..\src\dsql\DsqlStatementCache.cpp">
<Filter>DSQL</Filter>
</ClCompile>
<ClCompile Include="..\..\..\src\dsql\DsqlStatements.cpp">
<Filter>DSQL</Filter>
</ClCompile>
<ClCompile Include="..\..\..\src\dsql\errd.cpp"> <ClCompile Include="..\..\..\src\dsql\errd.cpp">
<Filter>DSQL</Filter> <Filter>DSQL</Filter>
</ClCompile> </ClCompile>
@ -288,9 +300,6 @@
<ClCompile Include="..\..\..\src\jrd\jrd.cpp"> <ClCompile Include="..\..\..\src\jrd\jrd.cpp">
<Filter>JRD files</Filter> <Filter>JRD files</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\..\src\jrd\JrdStatement.cpp">
<Filter>JRD files</Filter>
</ClCompile>
<ClCompile Include="..\..\..\src\jrd\KeywordsTable.cpp"> <ClCompile Include="..\..\..\src\jrd\KeywordsTable.cpp">
<Filter>JRD files</Filter> <Filter>JRD files</Filter>
</ClCompile> </ClCompile>
@ -312,12 +321,6 @@
<ClCompile Include="..\..\..\src\jrd\ods.cpp"> <ClCompile Include="..\..\..\src\jrd\ods.cpp">
<Filter>JRD files</Filter> <Filter>JRD files</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\..\src\jrd\opt.cpp">
<Filter>JRD files</Filter>
</ClCompile>
<ClCompile Include="..\..\..\src\jrd\Optimizer.cpp">
<Filter>JRD files</Filter>
</ClCompile>
<ClCompile Include="..\..\..\src\jrd\pag.cpp"> <ClCompile Include="..\..\..\src\jrd\pag.cpp">
<Filter>JRD files</Filter> <Filter>JRD files</Filter>
</ClCompile> </ClCompile>
@ -363,6 +366,9 @@
<ClCompile Include="..\..\..\src\jrd\sqz.cpp"> <ClCompile Include="..\..\..\src\jrd\sqz.cpp">
<Filter>JRD files</Filter> <Filter>JRD files</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\..\src\jrd\Statement.cpp">
<Filter>JRD files</Filter>
</ClCompile>
<ClCompile Include="..\..\..\src\jrd\svc.cpp"> <ClCompile Include="..\..\..\src\jrd\svc.cpp">
<Filter>JRD files</Filter> <Filter>JRD files</Filter>
</ClCompile> </ClCompile>
@ -507,6 +513,15 @@
<ClCompile Include="..\..\..\src\jrd\MetaName.cpp"> <ClCompile Include="..\..\..\src\jrd\MetaName.cpp">
<Filter>JRD files</Filter> <Filter>JRD files</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\..\src\jrd\optimizer\InnerJoin.cpp">
<Filter>Optimizer</Filter>
</ClCompile>
<ClCompile Include="..\..\..\src\jrd\optimizer\Optimizer.cpp">
<Filter>Optimizer</Filter>
</ClCompile>
<ClCompile Include="..\..\..\src\jrd\optimizer\Retrieval.cpp">
<Filter>Optimizer</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="..\..\..\src\jrd\recsrc\RecordSource.h"> <ClInclude Include="..\..\..\src\jrd\recsrc\RecordSource.h">
@ -545,6 +560,15 @@
<ClInclude Include="..\..\..\src\dsql\DSqlDataTypeUtil.h"> <ClInclude Include="..\..\..\src\dsql\DSqlDataTypeUtil.h">
<Filter>Header files</Filter> <Filter>Header files</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\..\..\src\dsql\DsqlRequests.h">
<Filter>Header files</Filter>
</ClInclude>
<ClInclude Include="..\..\..\src\dsql\DsqlStatementCache.h">
<Filter>Header files</Filter>
</ClInclude>
<ClInclude Include="..\..\..\src\dsql\DsqlStatements.h">
<Filter>Header files</Filter>
</ClInclude>
<ClInclude Include="..\..\..\src\dsql\errd_proto.h"> <ClInclude Include="..\..\..\src\dsql\errd_proto.h">
<Filter>Header files</Filter> <Filter>Header files</Filter>
</ClInclude> </ClInclude>
@ -827,9 +851,6 @@
<ClInclude Include="..\..\..\src\jrd\jrd_proto.h"> <ClInclude Include="..\..\..\src\jrd\jrd_proto.h">
<Filter>Header files</Filter> <Filter>Header files</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\..\..\src\jrd\JrdStatement.h">
<Filter>Header files</Filter>
</ClInclude>
<ClInclude Include="..\..\..\src\jrd\KeywordsTable.h"> <ClInclude Include="..\..\..\src\jrd\KeywordsTable.h">
<Filter>Header files</Filter> <Filter>Header files</Filter>
</ClInclude> </ClInclude>
@ -878,10 +899,7 @@
<ClInclude Include="..\..\..\src\jrd\ods_proto.h"> <ClInclude Include="..\..\..\src\jrd\ods_proto.h">
<Filter>Header files</Filter> <Filter>Header files</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\..\..\src\jrd\opt_proto.h"> <ClInclude Include="..\..\..\src\jrd\optimizer\Optimizer.h">
<Filter>Header files</Filter>
</ClInclude>
<ClInclude Include="..\..\..\src\jrd\Optimizer.h">
<Filter>Header files</Filter> <Filter>Header files</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\..\..\src\jrd\pag.h"> <ClInclude Include="..\..\..\src\jrd\pag.h">
@ -932,9 +950,6 @@
<ClInclude Include="..\..\..\src\jrd\rpb_chain.h"> <ClInclude Include="..\..\..\src\jrd\rpb_chain.h">
<Filter>Header files</Filter> <Filter>Header files</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\..\..\src\jrd\rse.h">
<Filter>Header files</Filter>
</ClInclude>
<ClInclude Include="..\..\..\src\jrd\RuntimeStatistics.h"> <ClInclude Include="..\..\..\src\jrd\RuntimeStatistics.h">
<Filter>Header files</Filter> <Filter>Header files</Filter>
</ClInclude> </ClInclude>
@ -962,6 +977,9 @@
<ClInclude Include="..\..\..\src\jrd\sqz.h"> <ClInclude Include="..\..\..\src\jrd\sqz.h">
<Filter>Header files</Filter> <Filter>Header files</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\..\..\src\jrd\Statement.h">
<Filter>Header files</Filter>
</ClInclude>
<ClInclude Include="..\..\..\src\jrd\status.h"> <ClInclude Include="..\..\..\src\jrd\status.h">
<Filter>Header files</Filter> <Filter>Header files</Filter>
</ClInclude> </ClInclude>

View File

@ -157,7 +157,6 @@
<ClCompile Include="..\..\..\src\remote\parser.cpp" /> <ClCompile Include="..\..\..\src\remote\parser.cpp" />
<ClCompile Include="..\..\..\src\remote\protocol.cpp" /> <ClCompile Include="..\..\..\src\remote\protocol.cpp" />
<ClCompile Include="..\..\..\src\remote\remote.cpp" /> <ClCompile Include="..\..\..\src\remote\remote.cpp" />
<ClCompile Include="..\..\..\src\remote\os\win32\wnet.cpp" />
<ClCompile Include="..\..\..\src\auth\trusted\AuthSspi.cpp" /> <ClCompile Include="..\..\..\src\auth\trusted\AuthSspi.cpp" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
@ -165,7 +164,6 @@
<ClInclude Include="..\..\..\src\auth\SecureRemotePassword\srp.h" /> <ClInclude Include="..\..\..\src\auth\SecureRemotePassword\srp.h" />
<ClInclude Include="..\..\..\src\remote\inet_proto.h" /> <ClInclude Include="..\..\..\src\remote\inet_proto.h" />
<ClInclude Include="..\..\..\src\remote\merge_proto.h" /> <ClInclude Include="..\..\..\src\remote\merge_proto.h" />
<ClInclude Include="..\..\..\src\remote\os\win32\wnet_proto.h" />
<ClInclude Include="..\..\..\src\remote\os\win32\xnet.h" /> <ClInclude Include="..\..\..\src\remote\os\win32\xnet.h" />
<ClInclude Include="..\..\..\src\remote\os\win32\xnet_proto.h" /> <ClInclude Include="..\..\..\src\remote\os\win32\xnet_proto.h" />
<ClInclude Include="..\..\..\src\remote\parse_proto.h" /> <ClInclude Include="..\..\..\src\remote\parse_proto.h" />

View File

@ -29,9 +29,6 @@
<ClCompile Include="..\..\..\src\remote\remote.cpp"> <ClCompile Include="..\..\..\src\remote\remote.cpp">
<Filter>REMOTE files</Filter> <Filter>REMOTE files</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\..\src\remote\os\win32\wnet.cpp">
<Filter>REMOTE files</Filter>
</ClCompile>
<ClCompile Include="..\..\..\src\auth\trusted\AuthSspi.cpp"> <ClCompile Include="..\..\..\src\auth\trusted\AuthSspi.cpp">
<Filter>AUTH files</Filter> <Filter>AUTH files</Filter>
</ClCompile> </ClCompile>
@ -64,9 +61,6 @@
<ClInclude Include="..\..\..\src\remote\remote.h"> <ClInclude Include="..\..\..\src\remote\remote.h">
<Filter>Header files</Filter> <Filter>Header files</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\..\..\src\remote\os\win32\wnet_proto.h">
<Filter>Header files</Filter>
</ClInclude>
<ClInclude Include="..\..\..\src\remote\os\win32\xnet.h"> <ClInclude Include="..\..\..\src\remote\os\win32\xnet.h">
<Filter>Header files</Filter> <Filter>Header files</Filter>
</ClInclude> </ClInclude>

View File

@ -86,6 +86,20 @@ dnl Test for special ar options?
AR_OPT_CHECK=false AR_OPT_CHECK=false
case "$build" in case "$build" in
aarch64-*-darwin*)
MAKEFILE_PREFIX=darwin_aarch64
MAKEFILE_POSTFIX=darwin
PLATFORM=DARWIN
INSTALL_PREFIX=darwin
AC_DEFINE(DARWIN, 1, [Define this if OS is DARWIN])
XE_APPEND(-framework CoreFoundation,LIBS)
EDITLINE_FLG=Y
SHRLIB_EXT=dylib
CPU_TYPE=ARM64
EXPORT_SYMBOLS_STYLE=darwin
RAW_DEVICES_FLG=N
;;
x*64-*-darwin*) x*64-*-darwin*)
MAKEFILE_PREFIX=darwin_x86_64 MAKEFILE_PREFIX=darwin_x86_64
MAKEFILE_POSTFIX=darwin MAKEFILE_POSTFIX=darwin
@ -1049,7 +1063,7 @@ AC_MSG_CHECKING(for working sem_init())
AC_RUN_IFELSE([AC_LANG_SOURCE([[#include <semaphore.h> AC_RUN_IFELSE([AC_LANG_SOURCE([[#include <semaphore.h>
main () { main () {
sem_t s; sem_t s;
exit(sem_init(&s,0,0)); return sem_init(&s,0,0);
} }
]])],[AC_DEFINE(WORKING_SEM_INIT,1,[Define this if sem_init() works on the platform]) ]])],[AC_DEFINE(WORKING_SEM_INIT,1,[Define this if sem_init() works on the platform])
AC_MSG_RESULT(yes)],[AC_MSG_RESULT(no) AC_MSG_RESULT(yes)],[AC_MSG_RESULT(no)
@ -1089,7 +1103,7 @@ if test "$ac_cv_sys_file_offset_bits" = "no"; then
AC_MSG_CHECKING(for native large file support) AC_MSG_CHECKING(for native large file support)
AC_RUN_IFELSE([AC_LANG_SOURCE([[#include <unistd.h> AC_RUN_IFELSE([AC_LANG_SOURCE([[#include <unistd.h>
main () { main () {
exit(!(sizeof(off_t) == 8)); return !(sizeof(off_t) == 8);
}]])],[ac_cv_sys_file_offset_bits=64; AC_DEFINE(_FILE_OFFSET_BITS,64) }]])],[ac_cv_sys_file_offset_bits=64; AC_DEFINE(_FILE_OFFSET_BITS,64)
AC_MSG_RESULT(yes)],[AC_MSG_RESULT(no)],[]) AC_MSG_RESULT(yes)],[AC_MSG_RESULT(no)],[])
fi fi
@ -1140,7 +1154,7 @@ main () {
char a; char a;
union { long long x; sem_t y; } b; union { long long x; sem_t y; } b;
}; };
exit((int)&((struct s*)0)->b); return (int)&((struct s*)0)->b;
}]])],[ac_cv_c_alignment=$ac_status],[ac_cv_c_alignment=$ac_status],[]) }]])],[ac_cv_c_alignment=$ac_status],[ac_cv_c_alignment=$ac_status],[])
AC_MSG_RESULT($ac_cv_c_alignment) AC_MSG_RESULT($ac_cv_c_alignment)
AC_DEFINE_UNQUOTED(FB_ALIGNMENT, $ac_cv_c_alignment, [Alignment of long]) AC_DEFINE_UNQUOTED(FB_ALIGNMENT, $ac_cv_c_alignment, [Alignment of long])
@ -1151,7 +1165,7 @@ AC_RUN_IFELSE([AC_LANG_SOURCE([[main () {
char a; char a;
double b; double b;
}; };
exit((int)&((struct s*)0)->b); return (int)&((struct s*)0)->b;
}]])],[ac_cv_c_double_align=$ac_status],[ac_cv_c_double_align=$ac_status],[]) }]])],[ac_cv_c_double_align=$ac_status],[ac_cv_c_double_align=$ac_status],[])
AC_MSG_RESULT($ac_cv_c_double_align) AC_MSG_RESULT($ac_cv_c_double_align)
AC_DEFINE_UNQUOTED(FB_DOUBLE_ALIGN, $ac_cv_c_double_align, [Alignment of double]) AC_DEFINE_UNQUOTED(FB_DOUBLE_ALIGN, $ac_cv_c_double_align, [Alignment of double])
@ -1168,7 +1182,7 @@ static int abs64Compare(SINT64 n1, SINT64 n2) {
return n1 == n2 ? 0 : n1 < n2 ? 1 : -1; return n1 == n2 ? 0 : n1 < n2 ? 1 : -1;
} }
int main() { int main() {
exit (abs64Compare(-9223372036854775808, 3652058) == 1 ? 0 : 1); return abs64Compare(-9223372036854775808, 3652058) == 1 ? 0 : 1;
}]])],[ac_cv_compare_failed=0 }]])],[ac_cv_compare_failed=0
ac_cv_compare_result=success]) ac_cv_compare_result=success])
CFLAGS="$savedflags" CFLAGS="$savedflags"
@ -1222,15 +1236,6 @@ case "$PLATFORM" in
;; ;;
win32) win32)
FB_PIPE_NAME=interbas
AC_ARG_WITH(pipe-name,
[ --with-pipe-name specify wnet pipe name (default=interbas)],
[FB_PIPE_NAME=${withval}])
AH_VERBATIM(FB_PIPE_NAME,
[/* Wnet pipe name */
#define FB_PIPE_NAME "interbas"])
AC_DEFINE_UNQUOTED(FB_PIPE_NAME,"$FB_PIPE_NAME")
AC_SUBST(FB_PIPE_NAME)
XE_PREPEND( -mthreads -lmpr -lversion -lws2_32 -lole32,LIBS) XE_PREPEND( -mthreads -lmpr -lversion -lws2_32 -lole32,LIBS)
;; ;;
@ -1294,6 +1299,8 @@ dnl # output
mkdir -p gen/\$fb_tgt/firebird/examples/extauth mkdir -p gen/\$fb_tgt/firebird/examples/extauth
mkdir -p gen/\$fb_tgt/firebird/examples/include mkdir -p gen/\$fb_tgt/firebird/examples/include
mkdir -p gen/\$fb_tgt/firebird/examples/interfaces mkdir -p gen/\$fb_tgt/firebird/examples/interfaces
mkdir -p gen/\$fb_tgt/firebird/examples/object_pascal
mkdir -p gen/\$fb_tgt/firebird/examples/object_pascal/common
mkdir -p gen/\$fb_tgt/firebird/examples/package mkdir -p gen/\$fb_tgt/firebird/examples/package
mkdir -p gen/\$fb_tgt/firebird/examples/stat mkdir -p gen/\$fb_tgt/firebird/examples/stat
mkdir -p gen/\$fb_tgt/firebird/examples/udf mkdir -p gen/\$fb_tgt/firebird/examples/udf
@ -1503,10 +1510,6 @@ esac
echo " Service name : $FB_SERVICE_NAME" echo " Service name : $FB_SERVICE_NAME"
echo " Service port : $FB_SERVICE_PORT" echo " Service port : $FB_SERVICE_PORT"
case "$PLATFORM" in
win32) echo " Pipe name : $FB_PIPE_NAME";;
esac
echo " GPRE modules : c_cxx.cpp$GPRE_LANGUAGE_MODULES" echo " GPRE modules : c_cxx.cpp$GPRE_LANGUAGE_MODULES"
echo echo

View File

@ -94,9 +94,8 @@ you only use 0/1
String String
------ ------
Strings are also what they sound like, strings. Examples: Strings are also what they sound like, strings. Example:
RootDirectory = /opt/firebird RootDirectory = /opt/firebird
RemotePipeName = "pipe47"
Configuration options Configuration options
@ -144,8 +143,7 @@ DeadThreadsCollection integer default 50
PriorityBoost integer default 5 PriorityBoost integer default 5
RemoteServiceName string default gds_db RemoteServiceName string default gds_db
RemoteServicePort integer default 3050 (TCP port number) RemoteServicePort integer default 3050 (TCP port number)
RemotePipeName string default "interbas" (Windows only?) IpcName string default "FIREBIRD" (Windows only)
IpcName string default "FirebirdIPI" (Windows only)
MaxUnflushedWrites integer MaxUnflushedWrites integer
# of writes before file writes are forcibly synched. # of writes before file writes are forcibly synched.

View File

@ -10,10 +10,6 @@ For TCP (aka INET) protocol:
<host> [ / <port>] : <file path to database or alias> <host> [ / <port>] : <file path to database or alias>
For named pipes (aka NetBEUI, aka WNET) protocol:
\\ <host> [ @ <port>] \ <file path to database or alias>
For local connections as simple as: For local connections as simple as:
<file path to database or alias> <file path to database or alias>
@ -55,11 +51,6 @@ Examples:
myserver/fb_db:mydb myserver/fb_db:mydb
localhost/fb_db:mydb localhost/fb_db:mydb
Connect via named pipes:
\\myserver\C:\db\mydb.fdb
\\myserver@fb_db\C:\db\mydb.fdb
Local connection: Local connection:
/db/mydb.fdb /db/mydb.fdb
@ -71,8 +62,7 @@ connection strings:
[ <protocol> : // [ <host> [ : <port> ] ] ] / <file path to database or alias> [ <protocol> : // [ <host> [ : <port> ] ] ] / <file path to database or alias>
Where protocol is one of: INET (means TCP), WNET (means named pipes) or XNET Where protocol is one of: INET (means TCP) or XNET (means shared memory).
(means shared memory).
Examples: Examples:
@ -114,22 +104,12 @@ Examples:
inet4://myserver/mydb inet4://myserver/mydb
inet6://myserver/mydb inet6://myserver/mydb
Connect via named pipes:
wnet://myserver/C:\db\mydb.fdb
wnet://myserver:fb_db/C:\db\mydb.fdb
Loopback connection via TCP: Loopback connection via TCP:
inet:///db/mydb.fdb inet:///db/mydb.fdb
inet://C:\db\mydb.fdb inet://C:\db\mydb.fdb
inet://mydb inet://mydb
Loopback connection via named pipes:
wnet://C:\db\mydb.fdb
wnet://mydb
Local connection via shared memory: Local connection via shared memory:
xnet://C:\db\mydb.fdb xnet://C:\db\mydb.fdb
@ -155,9 +135,7 @@ to connect locally using a specific transport protocol, please specify:
inet://<file path to database or alias> inet://<file path to database or alias>
or or
wnet://<file path to database or alias>
or
xnet://<file path to database or alias> xnet://<file path to database or alias>
Note: WNET (named pipes) and XNET (shared memory) protocols are available on Windows only. Note: XNET (shared memory) protocol is available on Windows only.

View File

@ -1673,7 +1673,7 @@ only for some specific OS you can make this place a bit simpler. In
minimum case the function should register module and all factories in minimum case the function should register module and all factories in
plugin manager:</font></p> plugin manager:</font></p>
<p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">extern <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">extern
&quot;C&quot; void FB_DLL_EXPORT FB_PLUGIN_ENTRY_POINT(IMaster* &quot;C&quot; FB_DLL_EXPORT void FB_PLUGIN_ENTRY_POINT(IMaster*
master)</font></p> master)</font></p>
<p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">{</font></p> <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">{</font></p>
<p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">IPluginManager* <p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">IPluginManager*

View File

@ -48,7 +48,7 @@ Usage:
Variable name Value Variable name Value
------------------------------------------------------------------------------ ------------------------------------------------------------------------------
NETWORK_PROTOCOL | The network protocol used by client to connect. Currently NETWORK_PROTOCOL | The network protocol used by client to connect. Currently
| used values: "TCPv4", "TCPv6", "WNET", "XNET" and NULL. | used values: "TCPv4", "TCPv6", "XNET" and NULL.
| |
WIRE_COMPRESSED | Compression status of current connection. WIRE_COMPRESSED | Compression status of current connection.
| If connection is compressed - returns "TRUE", if it is | If connection is compressed - returns "TRUE", if it is

View File

@ -11,7 +11,7 @@ Description:
Syntax: Syntax:
<declaration item> ::= <declaration item> ::=
DECLARE [VARIABLE] <variable name> <data type> [ := <value> ]; DECLARE [VARIABLE] <variable name> <data type> [ = <value> ];
| |
DECLARE [VARIABLE] CURSOR <cursor name> FOR (<query>); DECLARE [VARIABLE] CURSOR <cursor name> FOR (<query>);
| |
@ -46,8 +46,11 @@ Syntax:
Limitations: Limitations:
1) Subroutines may not be nested in another subroutine. They are only supported in the main 1) Subroutines may not be nested in another subroutine. They are only supported in the main
routine. routine.
2) Currently, a subroutine may not directly access or use variables or cursors of the 2) Currently, a subroutine may not directly access cursors of the main routine/block.
main statements. This may be allowed in the future. This may be allowed in the future.
3) Since FB 5 subroutines may use variables and parameters from the main routine/block.
4) Variables and parameters that are accessed by subroutines may have a small performance
penalty (even in the main routine) when being read.
Notes: Notes:
1) Starting in FB 4, subroutines may be recursive or call others subroutines. 1) Starting in FB 4, subroutines may be recursive or call others subroutines.

View File

@ -298,7 +298,7 @@ Factory factory;
} // anonymous namespace } // anonymous namespace
extern "C" void FB_DLL_EXPORT FB_PLUGIN_ENTRY_POINT(IMaster* m) extern "C" FB_DLL_EXPORT void FB_PLUGIN_ENTRY_POINT(IMaster* m)
{ {
master = m; master = m;
IPluginManager* pluginManager = master->getPluginManager(); IPluginManager* pluginManager = master->getPluginManager();

View File

@ -266,7 +266,7 @@ Factory factory;
} // anonymous namespace } // anonymous namespace
extern "C" void FB_DLL_EXPORT FB_PLUGIN_ENTRY_POINT(IMaster* master) extern "C" FB_DLL_EXPORT void FB_PLUGIN_ENTRY_POINT(IMaster* master)
{ {
IPluginManager* pluginManager = master->getPluginManager(); IPluginManager* pluginManager = master->getPluginManager();

View File

@ -435,13 +435,7 @@ Factory<ExtAuthServer> serverFactory;
} // anonymous namespace } // anonymous namespace
#if defined(_WIN32) extern "C" FB_DLL_EXPORT void FB_PLUGIN_ENTRY_POINT(IMaster* m)
#define FB_DLL_EXPORT __declspec(dllexport)
#else
#define FB_DLL_EXPORT
#endif
extern "C" void FB_DLL_EXPORT FB_PLUGIN_ENTRY_POINT(IMaster* m)
{ {
master = m; master = m;
IPluginManager* pluginManager = master->getPluginManager(); IPluginManager* pluginManager = master->getPluginManager();

View File

@ -105,9 +105,9 @@
<WarningLevel>Level3</WarningLevel> <WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization> <Optimization>Disabled</Optimization>
<SDLCheck>true</SDLCheck> <SDLCheck>true</SDLCheck>
<ConformanceMode>true</ConformanceMode> <ConformanceMode>false</ConformanceMode>
<AdditionalIncludeDirectories>..\..\..\src\include\;..\..\..\extern\libtomcrypt\src\headers\</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>..\..\..\src\include\;..\..\..\extern\libtomcrypt\src\headers\</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;LTM_DESC</PreprocessorDefinitions> <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;LTM_DESC;WIN32</PreprocessorDefinitions>
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
@ -121,9 +121,9 @@
<WarningLevel>Level3</WarningLevel> <WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization> <Optimization>Disabled</Optimization>
<SDLCheck>true</SDLCheck> <SDLCheck>true</SDLCheck>
<ConformanceMode>true</ConformanceMode> <ConformanceMode>false</ConformanceMode>
<AdditionalIncludeDirectories>..\..\..\src\include\;..\..\..\extern\libtomcrypt\src\headers\</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>..\..\..\src\include\;..\..\..\extern\libtomcrypt\src\headers\</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;LTM_DESC</PreprocessorDefinitions> <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;LTM_DESC;WIN32</PreprocessorDefinitions>
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
@ -139,9 +139,9 @@
<FunctionLevelLinking>true</FunctionLevelLinking> <FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions> <IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck> <SDLCheck>true</SDLCheck>
<ConformanceMode>true</ConformanceMode> <ConformanceMode>false</ConformanceMode>
<AdditionalIncludeDirectories>..\..\..\src\include\;..\..\..\extern\libtomcrypt\src\headers\</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>..\..\..\src\include\;..\..\..\extern\libtomcrypt\src\headers\</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;LTM_DESC</PreprocessorDefinitions> <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;LTM_DESC;WIN32</PreprocessorDefinitions>
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
@ -159,9 +159,9 @@
<FunctionLevelLinking>true</FunctionLevelLinking> <FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions> <IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck> <SDLCheck>true</SDLCheck>
<ConformanceMode>true</ConformanceMode> <ConformanceMode>false</ConformanceMode>
<AdditionalIncludeDirectories>..\..\..\src\include\;..\..\..\extern\libtomcrypt\src\headers\</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>..\..\..\src\include\;..\..\..\extern\libtomcrypt\src\headers\</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;LTM_DESC</PreprocessorDefinitions> <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;LTM_DESC;WIN32</PreprocessorDefinitions>
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>

View File

@ -83,31 +83,31 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<OutDir>..\..\prebuilt\$(Platform)\$(Configuration)\bin\</OutDir> <OutDir>..\..\prebuilt\$(Platform)\$(Configuration)\bin\</OutDir>
<IntDir>..\..\..\temp\$(PlatformName)\$(Configuration)\examples\$(ProjectName)\</IntDir> <IntDir>..\..\..\temp\$(PlatformName)\$(Configuration)\examples\$(ProjectName)\</IntDir>
<TargetName>fbSampleExtAuthKeygen </TargetName> <TargetName>fbSampleExtAuthKeygen</TargetName>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<OutDir>..\..\prebuilt\$(Platform)\$(Configuration)\bin\</OutDir> <OutDir>..\..\prebuilt\$(Platform)\$(Configuration)\bin\</OutDir>
<IntDir>..\..\..\temp\$(PlatformName)\$(Configuration)\examples\$(ProjectName)\</IntDir> <IntDir>..\..\..\temp\$(PlatformName)\$(Configuration)\examples\$(ProjectName)\</IntDir>
<TargetName>fbSampleExtAuthKeygen </TargetName> <TargetName>fbSampleExtAuthKeygen</TargetName>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<OutDir>..\..\prebuilt\$(Platform)\$(Configuration)\bin\</OutDir> <OutDir>..\..\prebuilt\$(Platform)\$(Configuration)\bin\</OutDir>
<IntDir>..\..\..\temp\$(PlatformName)\$(Configuration)\examples\$(ProjectName)\</IntDir> <IntDir>..\..\..\temp\$(PlatformName)\$(Configuration)\examples\$(ProjectName)\</IntDir>
<TargetName>fbSampleExtAuthKeygen </TargetName> <TargetName>fbSampleExtAuthKeygen</TargetName>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<OutDir>..\..\prebuilt\$(Platform)\$(Configuration)\bin\</OutDir> <OutDir>..\..\prebuilt\$(Platform)\$(Configuration)\bin\</OutDir>
<IntDir>..\..\..\temp\$(PlatformName)\$(Configuration)\examples\$(ProjectName)\</IntDir> <IntDir>..\..\..\temp\$(PlatformName)\$(Configuration)\examples\$(ProjectName)\</IntDir>
<TargetName>fbSampleExtAuthKeygen </TargetName> <TargetName>fbSampleExtAuthKeygen</TargetName>
</PropertyGroup> </PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile> <ClCompile>
<WarningLevel>Level3</WarningLevel> <WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization> <Optimization>Disabled</Optimization>
<SDLCheck>true</SDLCheck> <SDLCheck>true</SDLCheck>
<ConformanceMode>true</ConformanceMode> <ConformanceMode>false</ConformanceMode>
<AdditionalIncludeDirectories>..\..\..\src\include\;..\..\..\extern\libtomcrypt\src\headers\</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>..\..\..\src\include\;..\..\..\extern\libtomcrypt\src\headers\</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;LTM_DESC</PreprocessorDefinitions> <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;LTM_DESC;WIN32</PreprocessorDefinitions>
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
@ -120,9 +120,9 @@
<WarningLevel>Level3</WarningLevel> <WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization> <Optimization>Disabled</Optimization>
<SDLCheck>true</SDLCheck> <SDLCheck>true</SDLCheck>
<ConformanceMode>true</ConformanceMode> <ConformanceMode>false</ConformanceMode>
<AdditionalIncludeDirectories>..\..\..\src\include\;..\..\..\extern\libtomcrypt\src\headers\</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>..\..\..\src\include\;..\..\..\extern\libtomcrypt\src\headers\</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;LTM_DESC</PreprocessorDefinitions> <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;LTM_DESC;WIN32</PreprocessorDefinitions>
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
@ -137,9 +137,9 @@
<FunctionLevelLinking>true</FunctionLevelLinking> <FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions> <IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck> <SDLCheck>true</SDLCheck>
<ConformanceMode>true</ConformanceMode> <ConformanceMode>false</ConformanceMode>
<AdditionalIncludeDirectories>..\..\..\src\include\;..\..\..\extern\libtomcrypt\src\headers\</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>..\..\..\src\include\;..\..\..\extern\libtomcrypt\src\headers\</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;LTM_DESC</PreprocessorDefinitions> <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;LTM_DESC;WIN32</PreprocessorDefinitions>
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
@ -156,9 +156,9 @@
<FunctionLevelLinking>true</FunctionLevelLinking> <FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions> <IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck> <SDLCheck>true</SDLCheck>
<ConformanceMode>true</ConformanceMode> <ConformanceMode>false</ConformanceMode>
<AdditionalIncludeDirectories>..\..\..\src\include\;..\..\..\extern\libtomcrypt\src\headers\</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>..\..\..\src\include\;..\..\..\extern\libtomcrypt\src\headers\</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;LTM_DESC</PreprocessorDefinitions> <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;LTM_DESC;WIN32</PreprocessorDefinitions>
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>

View File

@ -145,7 +145,7 @@ int main()
/*IProvider* prov = master->getDispatcher(); /*IProvider* prov = master->getDispatcher();
IAttachment* att = NULL;*/ IAttachment* att = NULL;*/
IUtil* utl = master->getUtilInterface(); IUtil* utl = master->getUtilInterface();
IStatement* statemt = NULL; IStatement* statement = NULL;
ITransaction* tra = NULL; ITransaction* tra = NULL;
IBatch* batch = NULL; IBatch* batch = NULL;
IBatchCompletionState* cs = NULL; IBatchCompletionState* cs = NULL;
@ -185,7 +185,7 @@ int main()
if (isc_dsql_prepare(st, &tr, &stmt, 0, sqlStmt1, 3, NULL)) if (isc_dsql_prepare(st, &tr, &stmt, 0, sqlStmt1, 3, NULL))
raiseError(status, st); raiseError(status, st);
// and get it's interface // and get it's interface
if (fb_get_statement_interface(st, &statemt, &stmt)) if (fb_get_statement_interface(st, &statement, &stmt))
raiseError(status, st); raiseError(status, st);
// Message to store in a table // Message to store in a table
@ -202,7 +202,7 @@ int main()
pb->insertInt(&status, IBatch::TAG_RECORD_COUNTS, 1); pb->insertInt(&status, IBatch::TAG_RECORD_COUNTS, 1);
// create batch // create batch
batch = statemt->createBatch(&status, meta, batch = statement->createBatch(&status, meta,
pb->getBufferLength(&status), pb->getBuffer(&status)); pb->getBufferLength(&status), pb->getBuffer(&status));
// fill batch with data record by record // fill batch with data record by record
@ -223,8 +223,8 @@ int main()
batch = NULL; batch = NULL;
// unprepare statement // unprepare statement
statemt->release(); statement->release();
statemt = NULL; statement = NULL;
if (isc_dsql_free_statement(st, &stmt, DSQL_unprepare)) if (isc_dsql_free_statement(st, &stmt, DSQL_unprepare))
raiseError(status, st); raiseError(status, st);
@ -237,7 +237,7 @@ int main()
if (isc_dsql_prepare(st, &tr, &stmt, 0, sqlStmt2, 3, NULL)) if (isc_dsql_prepare(st, &tr, &stmt, 0, sqlStmt2, 3, NULL))
raiseError(status, st); raiseError(status, st);
// and get it's interface // and get it's interface
if (fb_get_statement_interface(st, &statemt, &stmt)) if (fb_get_statement_interface(st, &statement, &stmt))
raiseError(status, st); raiseError(status, st);
// Message to store in a table // Message to store in a table
@ -255,7 +255,7 @@ int main()
pb->insertInt(&status, IBatch::TAG_BLOB_POLICY, IBatch::BLOB_ID_ENGINE); pb->insertInt(&status, IBatch::TAG_BLOB_POLICY, IBatch::BLOB_ID_ENGINE);
// create batch // create batch
batch = statemt->createBatch(&status, meta, batch = statement->createBatch(&status, meta,
pb->getBufferLength(&status), pb->getBuffer(&status)); pb->getBufferLength(&status), pb->getBuffer(&status));
// create blob // create blob
@ -283,8 +283,8 @@ int main()
batch = NULL; batch = NULL;
// unprepare statement // unprepare statement
statemt->release(); statement->release();
statemt = NULL; statement = NULL;
if (isc_dsql_free_statement(st, &stmt, DSQL_drop)) if (isc_dsql_free_statement(st, &stmt, DSQL_drop))
raiseError(status, st); raiseError(status, st);
@ -312,8 +312,8 @@ int main()
batch->release(); batch->release();
if (tra) if (tra)
tra->release(); tra->release();
if (statemt) if (statement)
statemt->release(); statement->release();
// close handles if not closed // close handles if not closed
if (blb) if (blb)

View File

@ -37,14 +37,6 @@ typedef int FbSampleAtomic;
#include <firebird/Interface.h> #include <firebird/Interface.h>
#if defined(_WIN32)
#define FB_DLL_EXPORT __declspec(dllexport)
#elif defined(__APPLE__)
#define FB_DLL_EXPORT __attribute__((visibility("default")))
#else
#define FB_DLL_EXPORT
#endif
using namespace Firebird; using namespace Firebird;
#define SAMPLES_DIALECT SQL_DIALECT_V6 #define SAMPLES_DIALECT SQL_DIALECT_V6

View File

@ -40,9 +40,10 @@ you would do the following to create a project from 03.select.pas:
- Open select.lpr as a project - Open select.lpr as a project
- When prompted choose 'Simple Program' as the project template - When prompted choose 'Simple Program' as the project template
- Go into Project options and add the following paths: - Go into Project options and add the following paths:
/opt/firebird/include/Firebird ```
/usr/include/Firebird
common common
```
You can then compile and run the example through the debugger. You can then compile and run the example through the debugger.

View File

@ -100,14 +100,7 @@ public:
extern "C" extern "C"
{ {
#if defined(__WIN32__) FB_DLL_EXPORT void FB_PLUGIN_ENTRY_POINT(IMaster* m)
void __declspec(dllexport) FB_PLUGIN_ENTRY_POINT(IMaster* m);
#else
void FB_PLUGIN_ENTRY_POINT(IMaster* m)
__attribute__((visibility("default")));
#endif // __WIN32__
void FB_PLUGIN_ENTRY_POINT(IMaster* m)
{ {
master = m; master = m;
IPluginManager* pm = m->getPluginManager(); IPluginManager* pm = m->getPluginManager();

View File

@ -234,8 +234,6 @@ FB_UDR_BEGIN_TRIGGER(replicate_persons)
"select data_source from replicate_config where name = ?", "select data_source from replicate_config where name = ?",
SQL_DIALECT_CURRENT, NULL), status, statusVector); SQL_DIALECT_CURRENT, NULL), status, statusVector);
const char* table = metadata->getTriggerTable(status);
// Skip the first exclamation point, separating the module name and entry point. // Skip the first exclamation point, separating the module name and entry point.
const char* info = strchr(metadata->getEntryPoint(status), '!'); const char* info = strchr(metadata->getEntryPoint(status), '!');

Binary file not shown.

Binary file not shown.

View File

@ -1 +1 @@
2021a4 2022a

View File

@ -4,7 +4,7 @@ architectures.
The source code of zlib library was downloaded from The source code of zlib library was downloaded from
http://zlib.net/zlib1211.zip http://zlib.net/zlib1212.zip
It was built with MSVC17 compilers using commands specified at win32/Makefile.msc: It was built with MSVC17 compilers using commands specified at win32/Makefile.msc:

BIN
extern/zlib/zlib.exe vendored

Binary file not shown.

View File

@ -448,6 +448,7 @@ file(GLOB engine_src
"dsql/*.cpp" "dsql/*.cpp"
"jrd/*.cpp" "jrd/*.cpp"
"jrd/extds/*.cpp" "jrd/extds/*.cpp"
"jrd/optimizer/*.cpp"
"jrd/recsrc/*.cpp" "jrd/recsrc/*.cpp"
"jrd/replication/*.cpp" "jrd/replication/*.cpp"
"jrd/trace/*.cpp" "jrd/trace/*.cpp"

View File

@ -98,15 +98,6 @@ struct user_action
// String block: used to store a string of constant length.
class alice_str : public pool_alloc_rpt<UCHAR, alice_type_str>
{
public:
USHORT str_length;
UCHAR str_data[2];
};
// Transaction block: used to store info about a multi-database transaction. // Transaction block: used to store info about a multi-database transaction.
// Transaction Description Record // Transaction Description Record
@ -114,10 +105,10 @@ struct tdr : public pool_alloc<alice_type_tdr>
{ {
tdr* tdr_next; // next sub-transaction tdr* tdr_next; // next sub-transaction
TraNumber tdr_id; // database-specific transaction id TraNumber tdr_id; // database-specific transaction id
alice_str* tdr_fullpath; // full (possibly) remote pathname Firebird::string tdr_fullpath; // full (possibly) remote pathname
const TEXT* tdr_filename; // filename within full pathname Firebird::string tdr_filename; // filename
alice_str* tdr_host_site; // host for transaction Firebird::string tdr_host_site; // host for transaction
alice_str* tdr_remote_site; // site for remote transaction Firebird::string tdr_remote_site; // site for remote transaction
FB_API_HANDLE tdr_handle; // reconnected transaction handle FB_API_HANDLE tdr_handle; // reconnected transaction handle
FB_API_HANDLE tdr_db_handle; // re-attached database handle FB_API_HANDLE tdr_db_handle; // re-attached database handle
USHORT tdr_db_caps; // capabilities of database USHORT tdr_db_caps; // capabilities of database

View File

@ -39,6 +39,7 @@
#include "../common/classes/UserBlob.h" #include "../common/classes/UserBlob.h"
#include "../alice/alice_proto.h" #include "../alice/alice_proto.h"
#include "../common/utils_proto.h" #include "../common/utils_proto.h"
#include "../common/isc_f_proto.h"
#include <string.h> #include <string.h>
@ -54,7 +55,7 @@ DATABASE DB = STATIC FILENAME "yachts.lnk";
typedef Firebird::HalfStaticArray<TEXT, 1024> TextBuffer; typedef Firebird::HalfStaticArray<TEXT, 1024> TextBuffer;
static alice_str* alloc_string(const TEXT**); static void get_string(const TEXT**, Firebird::string&);
static USHORT get_capabilities(ISC_STATUS*); static USHORT get_capabilities(ISC_STATUS*);
static tdr* get_description(ISC_QUAD*); static tdr* get_description(ISC_QUAD*);
static void parse_fullpath(tdr*); static void parse_fullpath(tdr*);
@ -242,19 +243,15 @@ void MET_set_capabilities(ISC_STATUS* user_status, tdr* trans)
* Eat a string with a byte-encoded length. * Eat a string with a byte-encoded length.
*/ */
static alice_str* alloc_string(const TEXT** ptr) static void get_string(const TEXT** ptr, Firebird::string& str)
{ {
AliceGlobals* tdgbl = AliceGlobals::getSpecific(); AliceGlobals* tdgbl = AliceGlobals::getSpecific();
const TEXT* p = *ptr; const TEXT* p = *ptr;
const USHORT length = (USHORT) *p++; const USHORT length = (USHORT) *p++;
alice_str* string = FB_NEW_RPT(*tdgbl->getDefaultPool(), length + 1) alice_str;
memcpy(string->str_data, p, length);
string->str_data[length] = 0;
*ptr = p + length; *ptr = p + length;
return string; str.assign(p, length);
} }
@ -319,8 +316,8 @@ static tdr* get_description(ISC_QUAD* blob_id)
return NULL; return NULL;
tdr* trans = NULL; tdr* trans = NULL;
alice_str* host_site = NULL; Firebird::string host_site;
alice_str* database_path = NULL; Firebird::string database_path;
const TEXT* p = buffer.begin(); const TEXT* p = buffer.begin();
@ -336,11 +333,11 @@ static tdr* get_description(ISC_QUAD* blob_id)
switch (*p++) switch (*p++)
{ {
case TDR_HOST_SITE: case TDR_HOST_SITE:
host_site = alloc_string(&p); get_string(&p, host_site);
break; break;
case TDR_DATABASE_PATH: case TDR_DATABASE_PATH:
database_path = alloc_string(&p); get_string(&p, database_path);
break; break;
case TDR_TRANSACTION_ID: case TDR_TRANSACTION_ID:
@ -359,7 +356,7 @@ static tdr* get_description(ISC_QUAD* blob_id)
ptr->tdr_fullpath = database_path; ptr->tdr_fullpath = database_path;
parse_fullpath(ptr); parse_fullpath(ptr);
ptr->tdr_id = id; ptr->tdr_id = id;
database_path = NULL; database_path.clear();
break; break;
default: default:
@ -382,73 +379,17 @@ static tdr* get_description(ISC_QUAD* blob_id)
static void parse_fullpath(tdr* trans) static void parse_fullpath(tdr* trans)
{ {
AliceGlobals* tdgbl = AliceGlobals::getSpecific(); Firebird::PathName filename = trans->tdr_fullpath.c_str();
Firebird::PathName hostname;
// start at the end of the full pathname // Find the last remote node in the path
const TEXT* p = (TEXT*) trans->tdr_fullpath->str_data; while (ISC_analyze_tcp(filename, hostname))
const TEXT* const start = p; trans->tdr_remote_site = hostname.c_str();
while (*p)
p++;
const TEXT* const end = p;
// Check for a named pipes name - \\node\path\db or //node/path/db // At this point the filename is clear from any remote nodes
while (p > start && !(*p == '/' && p[-1] == '/') && !(*p == '\\' && p[-1] == '\\'))
{
--p;
}
if (p > start) trans->tdr_filename = filename.c_str();
{
// Increment p past slash, & search forward for end of node name
p = p + 1;
const TEXT* q = p;
while (*q && *q != '/' && *q != '\\')
q++;
if (*q)
{
trans->tdr_filename = q + 1;
trans->tdr_remote_site = FB_NEW_RPT(*tdgbl->getDefaultPool(), q - p + 1) alice_str;
fb_utils::copy_terminate((char*) trans->tdr_remote_site->str_data, (char*) p, q - p + 1);
}
}
else
{
p = end;
// If not named pipes, check the other protocols
// work backwards until we find a remote protocol specifier
while (p >= start && (*p != '^' && *p != ':' && *p != '@'))
p--;
// dimitr: make sure that the remote path is parsed correctly
// for win32 servers, i.e. the drive separator is taken into account
if ((p - 2 >= start) && p[-2] == ':' && (p[0] == ':'))
p -= 2;
trans->tdr_filename = p + 1;
// now find the last remote node in the chain
while (p > start && (*p == ':' || *p == '^' || *p == '@'))
p--;
USHORT length = 0;
for (; p >= start && (*p != '^' && *p != ':' && *p != '@'); ++length)
--p;
++p;
if (length)
{
trans->tdr_remote_site = FB_NEW_RPT(*tdgbl->getDefaultPool(), length + 1) alice_str;
TEXT* q = (TEXT *) trans->tdr_remote_site->str_data;
while (length--)
*q++ = *p++;
*q = 0;
}
}
} }

View File

@ -472,7 +472,7 @@ bool TDR_reconnect_multiple(FB_API_HANDLE handle, TraNumber id, const TEXT* name
{ {
if (ptr->tdr_state == TRA_limbo) if (ptr->tdr_state == TRA_limbo)
{ {
reconnect(ptr->tdr_db_handle, ptr->tdr_id, ptr->tdr_filename, switches); reconnect(ptr->tdr_db_handle, ptr->tdr_id, ptr->tdr_filename.c_str(), switches);
} }
} }
} }
@ -504,28 +504,23 @@ static void print_description(const tdr* trans)
AliceGlobals* tdgbl = AliceGlobals::getSpecific(); AliceGlobals* tdgbl = AliceGlobals::getSpecific();
if (!trans) if (!trans)
{
return; return;
}
if (!tdgbl->uSvc->isService()) if (!tdgbl->uSvc->isService())
{
ALICE_print(92); // msg 92: Multidatabase transaction: ALICE_print(92); // msg 92: Multidatabase transaction:
}
bool prepared_seen = false; bool prepared_seen = false;
for (const tdr* ptr = trans; ptr; ptr = ptr->tdr_next) for (const tdr* ptr = trans; ptr; ptr = ptr->tdr_next)
{ {
if (ptr->tdr_host_site) const auto host_site = ptr->tdr_host_site.nullStr();
if (host_site)
{ {
const char* pszHostSize = reinterpret_cast<const char*>(ptr->tdr_host_site->str_data);
if (!tdgbl->uSvc->isService()) if (!tdgbl->uSvc->isService())
{ {
// msg 93: Host Site: %s // msg 93: Host Site: %s
ALICE_print(93, SafeArg() << pszHostSize); ALICE_print(93, SafeArg() << host_site);
} }
tdgbl->uSvc->putLine(isc_spb_tra_host_site, pszHostSize); tdgbl->uSvc->putLine(isc_spb_tra_host_site, host_site);
} }
if (ptr->tdr_id) if (ptr->tdr_id)
@ -586,28 +581,26 @@ static void print_description(const tdr* trans)
break; break;
} }
if (ptr->tdr_remote_site) const auto remote_site = ptr->tdr_remote_site.nullStr();
if (remote_site)
{ {
const char* pszRemoteSite = reinterpret_cast<const char*>(ptr->tdr_remote_site->str_data);
if (!tdgbl->uSvc->isService()) if (!tdgbl->uSvc->isService())
{ {
// msg 101: Remote Site: %s // msg 101: Remote Site: %s
ALICE_print(101, SafeArg() << pszRemoteSite); ALICE_print(101, SafeArg() << remote_site);
} }
tdgbl->uSvc->putLine(isc_spb_tra_remote_site, pszRemoteSite); tdgbl->uSvc->putLine(isc_spb_tra_remote_site, remote_site);
} }
if (ptr->tdr_fullpath) const auto fullpath = ptr->tdr_fullpath.nullStr();
if (fullpath)
{ {
const char* pszFullpath = reinterpret_cast<const char*>(ptr->tdr_fullpath->str_data);
if (!tdgbl->uSvc->isService()) if (!tdgbl->uSvc->isService())
{ {
// msg 102: Database Path: %s // msg 102: Database Path: %s
ALICE_print(102, SafeArg() << pszFullpath); ALICE_print(102, SafeArg() << fullpath);
} }
tdgbl->uSvc->putLine(isc_spb_tra_db_path, pszFullpath); tdgbl->uSvc->putLine(isc_spb_tra_db_path, fullpath);
} }
} }
@ -649,10 +642,9 @@ static void print_description(const tdr* trans)
static SINT64 ask() static SINT64 ask()
{ {
AliceGlobals* tdgbl = AliceGlobals::getSpecific(); AliceGlobals* tdgbl = AliceGlobals::getSpecific();
if (tdgbl->uSvc->isService()) if (tdgbl->uSvc->isService())
{
return ~SINT64(0); return ~SINT64(0);
}
char response[32]; char response[32];
SINT64 switches = 0; SINT64 switches = 0;
@ -694,79 +686,56 @@ static SINT64 ask()
static void reattach_database(tdr* trans) static void reattach_database(tdr* trans)
{ {
ISC_STATUS_ARRAY status_vector; ISC_STATUS_ARRAY status_vector;
char buffer[1024]; char buffer[BUFFER_LARGE];
// sizeof(buffer) - 1 => leave space for the terminator. // sizeof(buffer) - 1 => leave space for the terminator.
const char* const end = buffer + sizeof(buffer) - 1; const char* const end = buffer + sizeof(buffer) - 1;
AliceGlobals* tdgbl = AliceGlobals::getSpecific(); AliceGlobals* tdgbl = AliceGlobals::getSpecific();
ISC_get_host(buffer, sizeof(buffer)); if (trans->tdr_fullpath.hasData())
if (trans->tdr_fullpath)
{ {
Firebird::string hostname;
ISC_get_host(hostname);
// if this is being run from the same host, // if this is being run from the same host,
// try to reconnect using the same pathname // try to reconnect using the same pathname
if (!strcmp(buffer, reinterpret_cast<const char*>(trans->tdr_host_site->str_data))) if (trans->tdr_host_site == hostname)
{
if (TDR_attach_database(status_vector, trans,
reinterpret_cast<char*>(trans->tdr_fullpath->str_data)))
{ {
if (TDR_attach_database(status_vector, trans, trans->tdr_fullpath.c_str()))
return; return;
} }
} else if (trans->tdr_host_site.hasData())
else if (trans->tdr_host_site)
{ {
// try going through the previous host with all available // try going through the previous host with all available
// protocols, using chaining to try the same method of // protocols, using chaining to try the same method of
// attachment originally used from that host // attachment originally used from that host
char* p = buffer; const Firebird::string pathname = trans->tdr_host_site + ':' + trans->tdr_fullpath;
const UCHAR* q = trans->tdr_host_site->str_data; if (TDR_attach_database(status_vector, trans, pathname.c_str()))
while (*q && p < end)
*p++ = *q++;
*p++ = ':';
q = trans->tdr_fullpath->str_data;
while (*q && p < end)
*p++ = *q++;
*p = 0;
if (TDR_attach_database(status_vector, trans, buffer))
{
return; return;
} }
}
// attaching using the old method didn't work; // attaching using the old method didn't work;
// try attaching to the remote node directly // try attaching to the remote node directly
if (trans->tdr_remote_site) if (trans->tdr_remote_site.hasData())
{
char* p = buffer;
const UCHAR* q = trans->tdr_remote_site->str_data;
while (*q && p < end)
*p++ = *q++;
*p++ = ':';
q = reinterpret_cast<const UCHAR*>(trans->tdr_filename);
while (*q && p < end)
*p++ = *q++;
*p = 0;
if (TDR_attach_database (status_vector, trans, buffer))
{ {
const Firebird::string pathname = trans->tdr_remote_site + ':' + trans->tdr_filename;
if (TDR_attach_database(status_vector, trans, pathname.c_str()))
return; return;
} }
}
} }
// we have failed to reattach; notify the user // we have failed to reattach; notify the user
// and let them try to succeed where we have failed // and let them try to succeed where we have failed
ALICE_print(86, SafeArg() << trans->tdr_id); ALICE_print(86, SafeArg() << trans->tdr_id);
// msg 86: Could not reattach to database for transaction %ld. // msg 86: Could not reattach to database for transaction %ld.
ALICE_print(87, SafeArg() << (trans->tdr_fullpath ? (char*)(trans->tdr_fullpath->str_data) : "is unknown")); ALICE_print(87, SafeArg() << (trans->tdr_fullpath.hasData() ? trans->tdr_fullpath.c_str() : "unknown"));
// msg 87: Original path: %s // msg 87: Original path: %s
if (tdgbl->uSvc->isService()) if (tdgbl->uSvc->isService())
{
ALICE_exit(FINI_ERROR, tdgbl); ALICE_exit(FINI_ERROR, tdgbl);
}
for (;;) for (;;)
{ {
@ -782,12 +751,8 @@ static void reattach_database(tdr* trans)
++p; ++p;
if (TDR_attach_database(status_vector, trans, p)) if (TDR_attach_database(status_vector, trans, p))
{ {
const size_t p_len = strlen(p); trans->tdr_fullpath.assign(p);
alice_str* string = FB_NEW_RPT(*tdgbl->getDefaultPool(), p_len + 1) alice_str; trans->tdr_filename = trans->tdr_fullpath;
strcpy(reinterpret_cast<char*>(string->str_data), p);
string->str_length = static_cast<USHORT>(p_len);
trans->tdr_fullpath = string;
trans->tdr_filename = (TEXT *) string->str_data;
return; return;
} }
ALICE_print(89); // msg 89: Attach unsuccessful. ALICE_print(89); // msg 89: Attach unsuccessful.

View File

@ -38,7 +38,7 @@
static Firebird::SimpleFactory<Auth::DebugClient> clientFactory; static Firebird::SimpleFactory<Auth::DebugClient> clientFactory;
static Firebird::SimpleFactory<Auth::DebugServer> serverFactory; static Firebird::SimpleFactory<Auth::DebugServer> serverFactory;
extern "C" void FB_PLUGIN_ENTRY_POINT(Firebird::IMaster* master) extern "C" FB_DLL_EXPORT void FB_PLUGIN_ENTRY_POINT(Firebird::IMaster* master)
{ {
Firebird::CachedMasterInterface::set(master); Firebird::CachedMasterInterface::set(master);

View File

@ -46,7 +46,7 @@ namespace Auth {
// The idea of debug plugin is to send some data from server to client, // The idea of debug plugin is to send some data from server to client,
// modify them on client and return result (which becomes login name) to the server // modify them on client and return result (which becomes login name) to the server
class DebugServer FB_FINAL : class DebugServer final :
public Firebird::StdPlugin<Firebird::IServerImpl<DebugServer, Firebird::CheckStatusWrapper> > public Firebird::StdPlugin<Firebird::IServerImpl<DebugServer, Firebird::CheckStatusWrapper> >
{ {
public: public:
@ -61,7 +61,7 @@ private:
Firebird::RefPtr<Firebird::IConfig> config; Firebird::RefPtr<Firebird::IConfig> config;
}; };
class DebugClient FB_FINAL : class DebugClient final :
public Firebird::StdPlugin<Firebird::IClientImpl<DebugClient, Firebird::CheckStatusWrapper> > public Firebird::StdPlugin<Firebird::IClientImpl<DebugClient, Firebird::CheckStatusWrapper> >
{ {
public: public:

View File

@ -55,7 +55,7 @@ public:
class PluginDatabases; class PluginDatabases;
class CachedSecurityDatabase FB_FINAL class CachedSecurityDatabase final
: public Firebird::RefCntIface<Firebird::ITimerImpl<CachedSecurityDatabase, Firebird::CheckStatusWrapper> > : public Firebird::RefCntIface<Firebird::ITimerImpl<CachedSecurityDatabase, Firebird::CheckStatusWrapper> >
{ {
public: public:

View File

@ -59,7 +59,7 @@ protected:
virtual RemotePassword* remotePasswordFactory() = 0; virtual RemotePassword* remotePasswordFactory() = 0;
}; };
template <class SHA> class SrpClientImpl FB_FINAL : public SrpClient template <class SHA> class SrpClientImpl final : public SrpClient
{ {
public: public:
explicit SrpClientImpl<SHA>(IPluginConfig* ipc) explicit SrpClientImpl<SHA>(IPluginConfig* ipc)

View File

@ -38,14 +38,6 @@
#include "../common/classes/auto.h" #include "../common/classes/auto.h"
#include "../common/classes/ParsedList.h" #include "../common/classes/ParsedList.h"
#ifndef FB_EXPORTED
#if defined(DARWIN)
#define FB_EXPORTED __attribute__((visibility("default")))
#else
#define FB_EXPORTED
#endif // OS choice (DARWIN)
#endif // FB_EXPORTED
namespace { namespace {
const unsigned int SZ_LOGIN = 31; const unsigned int SZ_LOGIN = 31;
@ -60,7 +52,7 @@ Firebird::GlobalPtr<Firebird::ConfigKeys> keys;
namespace Auth { namespace Auth {
class SrpManagement FB_FINAL : public Firebird::StdPlugin<Firebird::IManagementImpl<SrpManagement, Firebird::CheckStatusWrapper> > class SrpManagement final : public Firebird::StdPlugin<Firebird::IManagementImpl<SrpManagement, Firebird::CheckStatusWrapper> >
{ {
public: public:
explicit SrpManagement(Firebird::IPluginConfig* par) explicit SrpManagement(Firebird::IPluginConfig* par)
@ -540,12 +532,9 @@ public:
assignField(active, user->active()); assignField(active, user->active());
setField(login, user->userName()); setField(login, user->userName());
int count = 0;
checkCount(status, stmt, &count, isc_info_req_update_count);
stmt->execute(status, mainTra, up.getMetadata(), up.getBuffer(), NULL, NULL); stmt->execute(status, mainTra, up.getMetadata(), up.getBuffer(), NULL, NULL);
check(status); check(status);
if (recordsCount(status, stmt, isc_info_req_update_count) != 1)
if (!checkCount(status, stmt, &count, isc_info_req_update_count))
{ {
stmt->release(); stmt->release();
return GsecMsg22; return GsecMsg22;
@ -581,12 +570,9 @@ public:
Varfield login(dl); Varfield login(dl);
setField(login, user->userName()); setField(login, user->userName());
int count = 0;
checkCount(status, stmt, &count, isc_info_req_delete_count);
stmt->execute(status, mainTra, dl.getMetadata(), dl.getBuffer(), NULL, NULL); stmt->execute(status, mainTra, dl.getMetadata(), dl.getBuffer(), NULL, NULL);
check(status); check(status);
if (recordsCount(status, stmt, isc_info_req_delete_count) != 1)
if (!checkCount(status, stmt, &count, isc_info_req_delete_count))
{ {
stmt->release(); stmt->release();
return GsecMsg22; return GsecMsg22;
@ -739,7 +725,7 @@ private:
RemotePasswordImpl<Firebird::Sha1> server; RemotePasswordImpl<Firebird::Sha1> server;
bool checkCount(Firebird::CheckStatusWrapper* status, Firebird::IStatement* stmt, int* count, UCHAR item) int recordsCount(Firebird::CheckStatusWrapper* status, Firebird::IStatement* stmt, UCHAR item)
{ {
UCHAR buffer[33]; UCHAR buffer[33];
const UCHAR count_info[] = { isc_info_sql_records }; const UCHAR count_info[] = { isc_info_sql_records };
@ -755,17 +741,12 @@ private:
const SSHORT len = gds__vax_integer(p, 2); const SSHORT len = gds__vax_integer(p, 2);
p += 2; p += 2;
if (count_is == item) if (count_is == item)
{ return gds__vax_integer(p, len);
int newCount = gds__vax_integer(p, len);
int oldCount = *count;
*count = newCount;
return newCount == oldCount + 1;
}
p += len; p += len;
} }
} }
return false; return 0;
} }
static void check(Firebird::CheckStatusWrapper* status) static void check(Firebird::CheckStatusWrapper* status)
@ -986,7 +967,7 @@ static Firebird::SimpleFactory<Auth::SrpManagement> factory;
} // namespace Auth } // namespace Auth
extern "C" void FB_EXPORTED FB_PLUGIN_ENTRY_POINT(Firebird::IMaster* master) extern "C" FB_DLL_EXPORT void FB_PLUGIN_ENTRY_POINT(Firebird::IMaster* master)
{ {
Firebird::CachedMasterInterface::set(master); Firebird::CachedMasterInterface::set(master);
Firebird::PluginManagerInterfacePtr()->registerPluginFactory(Firebird::IPluginManager::TYPE_AUTH_USER_MANAGEMENT, Auth::RemotePassword::plugName, &Auth::factory); Firebird::PluginManagerInterfacePtr()->registerPluginFactory(Firebird::IPluginManager::TYPE_AUTH_USER_MANAGEMENT, Auth::RemotePassword::plugName, &Auth::factory);

View File

@ -244,7 +244,7 @@ private:
}; };
template <class SHA> class SrpServerImpl FB_FINAL : public SrpServer template <class SHA> class SrpServerImpl final : public SrpServer
{ {
public: public:
explicit SrpServerImpl<SHA>(IPluginConfig* ipc) explicit SrpServerImpl<SHA>(IPluginConfig* ipc)

View File

@ -35,7 +35,7 @@ namespace Auth {
// Required to stop analyzing rest of plugins before first roundtrip to server // Required to stop analyzing rest of plugins before first roundtrip to server
// if legacy login is present in DPB // if legacy login is present in DPB
class SecurityDatabaseClient FB_FINAL : class SecurityDatabaseClient final :
public Firebird::StdPlugin<Firebird::IClientImpl<SecurityDatabaseClient, Firebird::CheckStatusWrapper> > public Firebird::StdPlugin<Firebird::IClientImpl<SecurityDatabaseClient, Firebird::CheckStatusWrapper> >
{ {
public: public:

View File

@ -762,7 +762,7 @@ int SecurityDatabaseManagement::execute(Firebird::CheckStatusWrapper* st, Firebi
// register plugin // register plugin
static Firebird::SimpleFactory<Auth::SecurityDatabaseManagement> factory; static Firebird::SimpleFactory<Auth::SecurityDatabaseManagement> factory;
extern "C" void FB_PLUGIN_ENTRY_POINT(Firebird::IMaster* master) extern "C" FB_DLL_EXPORT void FB_PLUGIN_ENTRY_POINT(Firebird::IMaster* master)
{ {
Firebird::CachedMasterInterface::set(master); Firebird::CachedMasterInterface::set(master);
Firebird::PluginManagerInterfacePtr()->registerPluginFactory( Firebird::PluginManagerInterfacePtr()->registerPluginFactory(

View File

@ -33,7 +33,7 @@
namespace Auth { namespace Auth {
class SecurityDatabaseManagement FB_FINAL : class SecurityDatabaseManagement final :
public Firebird::StdPlugin<Firebird::IManagementImpl<SecurityDatabaseManagement, Firebird::CheckStatusWrapper> > public Firebird::StdPlugin<Firebird::IManagementImpl<SecurityDatabaseManagement, Firebird::CheckStatusWrapper> >
{ {
public: public:

View File

@ -125,7 +125,7 @@ namespace Auth {
GlobalPtr<PluginDatabases> instances; GlobalPtr<PluginDatabases> instances;
class SecurityDatabaseServer FB_FINAL : class SecurityDatabaseServer final :
public StdPlugin<IServerImpl<SecurityDatabaseServer, CheckStatusWrapper> > public StdPlugin<IServerImpl<SecurityDatabaseServer, CheckStatusWrapper> >
{ {
public: public:
@ -411,7 +411,7 @@ void registerLegacyServer(IPluginManager* iPlugin)
#ifdef PLUG_MODULE #ifdef PLUG_MODULE
extern "C" void FB_EXPORTED FB_PLUGIN_ENTRY_POINT(IMaster* master) extern "C" FB_DLL_EXPORT void FB_PLUGIN_ENTRY_POINT(IMaster* master)
{ {
CachedMasterInterface::set(master); CachedMasterInterface::set(master);

View File

@ -1140,7 +1140,7 @@ void put_asciz( const att_type attribute, const TEXT* string)
// We can't honor operating systems that allow longer file names. // We can't honor operating systems that allow longer file names.
if (len >= MAX_FILE_NAME_SIZE) if (len >= MAX_FILE_NAME_SIZE)
{ {
BURP_print(true, 343, SafeArg() << int(attribute) << "put_asciz()" << (MAX_FILE_NAME_SIZE - 1)); BURP_print(false, 343, SafeArg() << int(attribute) << "put_asciz()" << (MAX_FILE_NAME_SIZE - 1));
// msg 343: text for attribute @1 is too large in @2, truncating to @3 bytes // msg 343: text for attribute @1 is too large in @2, truncating to @3 bytes
len = MAX_FILE_NAME_SIZE - 1; len = MAX_FILE_NAME_SIZE - 1;
} }
@ -1961,6 +1961,7 @@ void put_boolean(att_type attribute, const FB_BOOLEAN value)
BurpGlobals* tdgbl = BurpGlobals::getSpecific(); BurpGlobals* tdgbl = BurpGlobals::getSpecific();
put(tdgbl, attribute); put(tdgbl, attribute);
put(tdgbl, (UCHAR) 1);
put(tdgbl, value ? 1u : 0u); put(tdgbl, value ? 1u : 0u);
} }

View File

@ -252,8 +252,9 @@ enum att_type {
att_SQL_dialect, // SQL dialect that it speaks att_SQL_dialect, // SQL dialect that it speaks
att_db_read_only, // Is the database ReadOnly? att_db_read_only, // Is the database ReadOnly?
att_database_linger, // Disconnection timeout att_database_linger, // Disconnection timeout
att_database_sql_security,// default sql security value att_database_sql_security_deprecated, // can be removed later
att_replica_mode, // replica mode att_replica_mode, // replica mode
att_database_sql_security, // default sql security value
// Relation attributes // Relation attributes
@ -275,6 +276,7 @@ enum att_type {
att_relation_flags, att_relation_flags,
att_relation_ext_file_name, // name of file for external tables att_relation_ext_file_name, // name of file for external tables
att_relation_type, att_relation_type,
att_relation_sql_security_deprecated, // can be removed later
att_relation_sql_security, att_relation_sql_security,
// Field attributes (used for both global and local fields) // Field attributes (used for both global and local fields)
@ -409,6 +411,7 @@ enum att_type {
att_trig_engine_name, att_trig_engine_name,
att_trig_entrypoint, att_trig_entrypoint,
att_trig_type2, att_trig_type2,
att_trig_sql_security_deprecated, // can be removed later
att_trig_sql_security, att_trig_sql_security,
// Function attributes // Function attributes
@ -433,6 +436,7 @@ enum att_type {
att_function_owner_name, att_function_owner_name,
att_function_legacy_flag, att_function_legacy_flag,
att_function_deterministic_flag, att_function_deterministic_flag,
att_function_sql_security_deprecated, // can be removed later
att_function_sql_security, att_function_sql_security,
// Function argument attributes // Function argument attributes
@ -529,6 +533,7 @@ enum att_type {
att_procedure_entrypoint, att_procedure_entrypoint,
att_procedure_package_name, att_procedure_package_name,
att_procedure_private_flag, att_procedure_private_flag,
att_procedure_sql_security_deprecated, // can be removed later
att_procedure_sql_security, att_procedure_sql_security,
// Stored procedure parameter attributes // Stored procedure parameter attributes
@ -630,6 +635,7 @@ enum att_type {
att_package_security_class, att_package_security_class,
att_package_owner_name, att_package_owner_name,
att_package_description, att_package_description,
att_package_sql_security_deprecated, // can be removed later
att_package_sql_security, att_package_sql_security,
// Database creators // Database creators

View File

@ -134,7 +134,7 @@ static ULONG unzip_read_block(BurpGlobals*, UCHAR*, FB_SIZE_T);
// Portion of data passed to crypt plugin // Portion of data passed to crypt plugin
const ULONG CRYPT_STEP = 256; const ULONG CRYPT_STEP = 256;
class DbInfo FB_FINAL : public Firebird::RefCntIface<Firebird::IDbCryptInfoImpl<DbInfo, Firebird::CheckStatusWrapper> > class DbInfo final : public Firebird::RefCntIface<Firebird::IDbCryptInfoImpl<DbInfo, Firebird::CheckStatusWrapper> >
{ {
public: public:
DbInfo(BurpGlobals* bg) DbInfo(BurpGlobals* bg)

View File

@ -192,8 +192,13 @@ static inline UCHAR get(BurpGlobals* tdgbl)
return tdgbl->get(); return tdgbl->get();
} }
static inline FB_BOOLEAN get_boolean(BurpGlobals* tdgbl) static inline FB_BOOLEAN get_boolean(BurpGlobals* tdgbl, bool deprecated)
{ {
if (!deprecated)
{
const UCHAR length = get(tdgbl);
fb_assert(length == 1);
}
return get(tdgbl) ? FB_TRUE : FB_FALSE; return get(tdgbl) ? FB_TRUE : FB_FALSE;
} }
@ -5142,10 +5147,11 @@ bool get_function(BurpGlobals* tdgbl)
bad_attribute(scan_next_attr, attribute, 89); bad_attribute(scan_next_attr, attribute, 89);
break; break;
case att_function_sql_security_deprecated:
case att_function_sql_security: case att_function_sql_security:
if (tdgbl->RESTORE_format >= 11) if (tdgbl->RESTORE_format >= 11)
{ {
X.RDB$SQL_SECURITY = get_boolean(tdgbl); X.RDB$SQL_SECURITY = get_boolean(tdgbl, attribute == att_function_sql_security_deprecated);
X.RDB$SQL_SECURITY.NULL = FALSE; X.RDB$SQL_SECURITY.NULL = FALSE;
} }
else else
@ -5274,9 +5280,10 @@ bool get_function(BurpGlobals* tdgbl)
bad_attribute(scan_next_attr, attribute, 89); bad_attribute(scan_next_attr, attribute, 89);
break; break;
case att_function_sql_security_deprecated:
case att_function_sql_security: case att_function_sql_security:
if (tdgbl->RESTORE_format >= 11) if (tdgbl->RESTORE_format >= 11)
get_boolean(tdgbl); get_boolean(tdgbl, attribute == att_function_sql_security_deprecated);
else else
bad_attribute(scan_next_attr, attribute, 89); bad_attribute(scan_next_attr, attribute, 89);
break; break;
@ -7417,10 +7424,11 @@ bool get_package(BurpGlobals* tdgbl)
X.RDB$DESCRIPTION.NULL = FALSE; X.RDB$DESCRIPTION.NULL = FALSE;
break; break;
case att_package_sql_security_deprecated:
case att_package_sql_security: case att_package_sql_security:
if (tdgbl->RESTORE_format >= 11) if (tdgbl->RESTORE_format >= 11)
{ {
X.RDB$SQL_SECURITY = get_boolean(tdgbl); X.RDB$SQL_SECURITY = get_boolean(tdgbl, attribute == att_package_sql_security_deprecated);
X.RDB$SQL_SECURITY.NULL = FALSE; X.RDB$SQL_SECURITY.NULL = FALSE;
} }
else else
@ -7634,10 +7642,11 @@ bool get_procedure(BurpGlobals* tdgbl)
bad_attribute(scan_next_attr, attribute, 290); bad_attribute(scan_next_attr, attribute, 290);
break; break;
case att_procedure_sql_security_deprecated:
case att_procedure_sql_security: case att_procedure_sql_security:
if (tdgbl->RESTORE_format >= 11) if (tdgbl->RESTORE_format >= 11)
{ {
X.RDB$SQL_SECURITY = get_boolean(tdgbl); X.RDB$SQL_SECURITY = get_boolean(tdgbl, attribute == att_procedure_sql_security_deprecated);
X.RDB$SQL_SECURITY.NULL = FALSE; X.RDB$SQL_SECURITY.NULL = FALSE;
} }
else else
@ -7759,9 +7768,10 @@ bool get_procedure(BurpGlobals* tdgbl)
bad_attribute(scan_next_attr, attribute, 290); bad_attribute(scan_next_attr, attribute, 290);
break; break;
case att_procedure_sql_security_deprecated:
case att_procedure_sql_security: case att_procedure_sql_security:
if (tdgbl->RESTORE_format >= 11) if (tdgbl->RESTORE_format >= 11)
get_boolean(tdgbl); get_boolean(tdgbl, attribute == att_procedure_sql_security_deprecated);
else else
bad_attribute(scan_next_attr, attribute, 290); bad_attribute(scan_next_attr, attribute, 290);
break; break;
@ -8443,9 +8453,10 @@ bool get_relation(BurpGlobals* tdgbl)
bad_attribute(scan_next_attr, attribute, 111); bad_attribute(scan_next_attr, attribute, 111);
break; break;
case att_relation_sql_security_deprecated:
case att_relation_sql_security: case att_relation_sql_security:
sql_security_null = false; sql_security_null = false;
sql_security = get_boolean(tdgbl); sql_security = get_boolean(tdgbl, attribute == att_relation_sql_security_deprecated);
break; break;
default: default:
@ -9784,10 +9795,11 @@ bool get_trigger(BurpGlobals* tdgbl)
bad_attribute(scan_next_attr, attribute, 134); bad_attribute(scan_next_attr, attribute, 134);
break; break;
case att_trig_sql_security_deprecated:
case att_trig_sql_security: case att_trig_sql_security:
if (tdgbl->RESTORE_format >= 11) if (tdgbl->RESTORE_format >= 11)
{ {
X.RDB$SQL_SECURITY = get_boolean(tdgbl); X.RDB$SQL_SECURITY = get_boolean(tdgbl, attribute == att_trig_sql_security_deprecated);
X.RDB$SQL_SECURITY.NULL = FALSE; X.RDB$SQL_SECURITY.NULL = FALSE;
} }
else else
@ -9930,9 +9942,10 @@ bool get_trigger(BurpGlobals* tdgbl)
bad_attribute(scan_next_attr, attribute, 134); bad_attribute(scan_next_attr, attribute, 134);
break; break;
case att_trig_sql_security_deprecated:
case att_trig_sql_security: case att_trig_sql_security:
if (tdgbl->RESTORE_format >= 11) if (tdgbl->RESTORE_format >= 11)
get_boolean(tdgbl); get_boolean(tdgbl, attribute == att_trig_sql_security_deprecated);
else else
bad_attribute(scan_next_attr, attribute, 134); bad_attribute(scan_next_attr, attribute, 134);
break; break;
@ -10226,6 +10239,8 @@ bool get_user_privilege(BurpGlobals* tdgbl)
case att_priv_obj_type: case att_priv_obj_type:
flags |= USER_PRIV_OBJECT_TYPE; flags |= USER_PRIV_OBJECT_TYPE;
object_type = (USHORT) get_int32(tdgbl); object_type = (USHORT) get_int32(tdgbl);
if ( (tdgbl->RESTORE_format < 11) && (object_type > 19) ) // FB 4 has a shift :(
object_type++;
break; break;
default: default:
@ -10297,9 +10312,6 @@ bool get_user_privilege(BurpGlobals* tdgbl)
} }
break; break;
case obj_database:
break;
default: default:
exists = true; exists = true;
break; break;
@ -11009,6 +11021,7 @@ bool restore(BurpGlobals* tdgbl, Firebird::IProvider* provider, const TEXT* file
} }
break; break;
case att_database_sql_security_deprecated:
case att_database_sql_security: case att_database_sql_security:
if (tdgbl->RESTORE_format >= 11) if (tdgbl->RESTORE_format >= 11)
{ {
@ -11017,7 +11030,7 @@ bool restore(BurpGlobals* tdgbl, Firebird::IProvider* provider, const TEXT* file
FOR (REQUEST_HANDLE req_handle5) FOR (REQUEST_HANDLE req_handle5)
X IN RDB$DATABASE X IN RDB$DATABASE
MODIFY X USING MODIFY X USING
X.RDB$SQL_SECURITY = get_boolean(tdgbl); X.RDB$SQL_SECURITY = get_boolean(tdgbl, attribute == att_database_sql_security_deprecated);
END_MODIFY; END_MODIFY;
ON_ERROR ON_ERROR
general_on_error(); general_on_error();
@ -11028,7 +11041,7 @@ bool restore(BurpGlobals* tdgbl, Firebird::IProvider* provider, const TEXT* file
END_ERROR; END_ERROR;
} }
else else
get_boolean(tdgbl); get_boolean(tdgbl, attribute == att_database_sql_security_deprecated);
} }
else else
{ {

View File

@ -664,7 +664,7 @@ bool IntlUtil::readOneChar(Jrd::CharSet* cs, const UCHAR** s, const UCHAR* end,
} }
// Transform ICU-VERSION attribute (given by the user) in COLL-VERSION (to be stored). // Add COLL-VERSION attribute.
bool IntlUtil::setupIcuAttributes(charset* cs, const string& specificAttributes, bool IntlUtil::setupIcuAttributes(charset* cs, const string& specificAttributes,
const string& configInfo, string& newSpecificAttributes) const string& configInfo, string& newSpecificAttributes)
{ {
@ -681,10 +681,19 @@ bool IntlUtil::setupIcuAttributes(charset* cs, const string& specificAttributes,
map.get("ICU-VERSION", icuVersion); map.get("ICU-VERSION", icuVersion);
string collVersion; string collVersion;
if (!UnicodeUtil::getCollVersion(icuVersion, configInfo, collVersion)) auto icu = UnicodeUtil::getCollVersion(icuVersion, configInfo, collVersion);
if (!icu)
return false; return false;
map.remove("ICU-VERSION"); if (icuVersion.isEmpty())
{
int majorVersion, minorVersion;
UnicodeUtil::getICUVersion(icu, majorVersion, minorVersion);
icuVersion.printf("%d.%d", majorVersion, minorVersion);
map.put("ICU-VERSION", icuVersion);
}
map.remove("COLL-VERSION"); map.remove("COLL-VERSION");
if (collVersion.hasData()) if (collVersion.hasData())
@ -781,16 +790,6 @@ bool IntlUtil::readAttributeChar(Jrd::CharSet* cs, const UCHAR** s, const UCHAR*
} }
void IntlUtil::getDefaultCollationAttributes(UCharBuffer& collAttributes, charset& cs)
{
string attributes("ICU-VERSION=");
attributes += Jrd::UnicodeUtil::getDefaultIcuVersion();
setupIcuAttributes(&cs, attributes, "", attributes);
collAttributes.push(reinterpret_cast<const UCHAR*>(attributes.c_str()), attributes.length());
}
static void unicodeDestroy(texttype* tt) static void unicodeDestroy(texttype* tt)
{ {
delete[] const_cast<ASCII*>(tt->texttype_name); delete[] const_cast<ASCII*>(tt->texttype_name);

View File

@ -94,7 +94,6 @@ public:
static bool setupIcuAttributes(charset* cs, const string& specificAttributes, static bool setupIcuAttributes(charset* cs, const string& specificAttributes,
const string& configInfo, string& newSpecificAttributes); const string& configInfo, string& newSpecificAttributes);
static void getDefaultCollationAttributes(UCharBuffer& collAttributes, charset& cs);
private: private:
static string escapeAttribute(Jrd::CharSet* cs, const string& s); static string escapeAttribute(Jrd::CharSet* cs, const string& s);

View File

@ -310,7 +310,7 @@ public:
RefPtr<RefCounted> attachment; RefPtr<RefCounted> attachment;
}; };
class MetadataBuilder FB_FINAL : class MetadataBuilder final :
public RefCntIface<IMetadataBuilderImpl<MetadataBuilder, CheckStatusWrapper> > public RefCntIface<IMetadataBuilderImpl<MetadataBuilder, CheckStatusWrapper> >
{ {
public: public:

View File

@ -1,6 +1,6 @@
// The content of this file is generated with help of update-ids utility Do not edit. // The content of this file is generated with help of update-ids utility Do not edit.
static const char* BUILTIN_TIME_ZONE_VERSION = "2021a4"; static const char* BUILTIN_TIME_ZONE_VERSION = "2022a";
// Do not change order of items in this array! The index corresponds to a TimeZone ID, which must be fixed! // Do not change order of items in this array! The index corresponds to a TimeZone ID, which must be fixed!
static const char* BUILTIN_TIME_ZONE_LIST[] = { static const char* BUILTIN_TIME_ZONE_LIST[] = {

View File

@ -34,7 +34,7 @@ namespace Firebird {
virtual void transliterate(IStatus* status) = 0; virtual void transliterate(IStatus* status) = 0;
}; };
class BatchCompletionState FB_FINAL : class BatchCompletionState final :
public DisposeIface<IBatchCompletionStateImpl<BatchCompletionState, CheckStatusWrapper> > public DisposeIface<IBatchCompletionStateImpl<BatchCompletionState, CheckStatusWrapper> >
{ {
public: public:

View File

@ -0,0 +1,149 @@
/*
* The contents of this file are subject to the Initial
* Developer's Public License Version 1.0 (the "License");
* you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
* http://www.ibphoenix.com/main.nfs?a=ibphoenix&page=ibp_idpl.
*
* Software distributed under the License is distributed AS IS,
* WITHOUT WARRANTY OF ANY KIND, either express or implied.
* See the License for the specific language governing rights
* and limitations under the License.
*
* The Original Code was created by Adriano dos Santos Fernandes
* for the Firebird Open Source RDBMS project.
*
* Copyright (c) 2022 Adriano dos Santos Fernandes <adrianosf@gmail.com>
* and all contributors signed below.
*
* All Rights Reserved.
* Contributor(s): ______________________________________.
*/
#ifndef CLASSES_DOUBLY_LINKED_LIST_H
#define CLASSES_DOUBLY_LINKED_LIST_H
#include "../common/classes/alloc.h"
#include <list>
#include <utility>
namespace Firebird
{
template <typename T>
class DoublyLinkedList
{
private:
using StdList = std::list<T, PoolAllocator<T>>;
public:
using Iterator = typename StdList::iterator;
using ConstIterator = typename StdList::const_iterator;
public:
explicit DoublyLinkedList(MemoryPool& p)
: stdList(p)
{
}
public:
constexpr T& front() noexcept
{
return stdList.front();
}
constexpr const T& front() const noexcept
{
return stdList.front();
}
constexpr T& back() noexcept
{
return stdList.back();
}
constexpr const T& back() const noexcept
{
return stdList.back();
}
constexpr Iterator begin() noexcept
{
return stdList.begin();
}
constexpr ConstIterator begin() const noexcept
{
return stdList.begin();
}
constexpr ConstIterator cbegin() const noexcept
{
return stdList.cbegin();
}
constexpr Iterator end() noexcept
{
return stdList.end();
}
constexpr ConstIterator end() const noexcept
{
return stdList.end();
}
constexpr ConstIterator cend() const noexcept
{
return stdList.cend();
}
constexpr bool isEmpty() const noexcept
{
return stdList.empty();
}
constexpr void clear() noexcept
{
stdList.clear();
}
constexpr void erase(Iterator pos)
{
stdList.erase(pos);
}
constexpr void erase(ConstIterator pos)
{
stdList.erase(pos);
}
constexpr void pushBack(const T& value)
{
stdList.push_back(value);
}
constexpr void pushBack(T&& value)
{
stdList.push_back(std::move(value));
}
constexpr void splice(ConstIterator pos, DoublyLinkedList<T>& other, ConstIterator it)
{
fb_assert(stdList.get_allocator() == other.stdList.get_allocator());
stdList.splice(pos, other.stdList, it);
}
constexpr void splice(ConstIterator pos, DoublyLinkedList<T>&& other, ConstIterator it)
{
fb_assert(stdList.get_allocator() == other.stdList.get_allocator());
stdList.splice(pos, std::move(other.stdList), it);
}
private:
StdList stdList;
};
} // namespace Firebird
#endif // CLASSES_DOUBLY_LINKED_LIST_H

View File

@ -355,7 +355,7 @@ namespace Firebird
virtual void finish(dsc& result) = 0; virtual void finish(dsc& result) = 0;
}; };
class WeakHashContext FB_FINAL : public HashContext class WeakHashContext final : public HashContext
{ {
public: public:
virtual void update(const void* data, FB_SIZE_T length); virtual void update(const void* data, FB_SIZE_T length);
@ -389,31 +389,31 @@ namespace Firebird
UCharBuffer buffer; UCharBuffer buffer;
}; };
class Md5HashContext FB_FINAL : public LibTomCryptHashContext class Md5HashContext final : public LibTomCryptHashContext
{ {
public: public:
Md5HashContext(MemoryPool& pool); Md5HashContext(MemoryPool& pool);
}; };
class Sha1HashContext FB_FINAL : public LibTomCryptHashContext class Sha1HashContext final : public LibTomCryptHashContext
{ {
public: public:
Sha1HashContext(MemoryPool& pool); Sha1HashContext(MemoryPool& pool);
}; };
class Sha256HashContext FB_FINAL : public LibTomCryptHashContext class Sha256HashContext final : public LibTomCryptHashContext
{ {
public: public:
Sha256HashContext(MemoryPool& pool); Sha256HashContext(MemoryPool& pool);
}; };
class Sha512HashContext FB_FINAL : public LibTomCryptHashContext class Sha512HashContext final : public LibTomCryptHashContext
{ {
public: public:
Sha512HashContext(MemoryPool& pool); Sha512HashContext(MemoryPool& pool);
}; };
class Crc32HashContext FB_FINAL : public HashContext class Crc32HashContext final : public HashContext
{ {
public: public:
Crc32HashContext(MemoryPool& pool); Crc32HashContext(MemoryPool& pool);

View File

@ -293,7 +293,7 @@ public:
// when yvalve is starting fb_shutdown(). This causes almost unavoidable segfault. // when yvalve is starting fb_shutdown(). This causes almost unavoidable segfault.
// To avoid it this class is added - it detects spontaneous (not by PluginManager) // To avoid it this class is added - it detects spontaneous (not by PluginManager)
// module unload and notifies PluginManager about this said fact. // module unload and notifies PluginManager about this said fact.
class UnloadDetectorHelper FB_FINAL : class UnloadDetectorHelper final :
public VersionedIface<IPluginModuleImpl<UnloadDetectorHelper, CheckStatusWrapper> > public VersionedIface<IPluginModuleImpl<UnloadDetectorHelper, CheckStatusWrapper> >
{ {
public: public:

View File

@ -1850,6 +1850,11 @@ public:
// Create memory pool instance // Create memory pool instance
static MemPool* createPool(MemPool* parent, MemoryStats& stats); static MemPool* createPool(MemPool* parent, MemoryStats& stats);
MemoryStats& getStatsGroup() noexcept
{
return *stats;
}
// Set statistics group for pool. Usage counters will be decremented from // Set statistics group for pool. Usage counters will be decremented from
// previously set group and added to new // previously set group and added to new
void setStatsGroup(MemoryStats& stats) noexcept; void setStatsGroup(MemoryStats& stats) noexcept;
@ -2262,6 +2267,11 @@ void MemPool::setStatsGroup(MemoryStats& newStats) noexcept
stats->increment_usage(sav_used_memory); stats->increment_usage(sav_used_memory);
} }
MemoryStats& MemoryPool::getStatsGroup() noexcept
{
return pool->getStatsGroup();
}
void MemoryPool::setStatsGroup(MemoryStats& newStats) noexcept void MemoryPool::setStatsGroup(MemoryStats& newStats) noexcept
{ {
pool->setStatsGroup(newStats); pool->setStatsGroup(newStats);

View File

@ -57,6 +57,7 @@
#endif #endif
#include <memory.h> #include <memory.h>
#include <memory>
#ifdef DEBUG_GDS_ALLOC #ifdef DEBUG_GDS_ALLOC
#define FB_NEW new(*getDefaultMemoryPool(), __FILE__, __LINE__) #define FB_NEW new(*getDefaultMemoryPool(), __FILE__, __LINE__)
@ -212,6 +213,8 @@ public:
// Get context pool for current thread of execution // Get context pool for current thread of execution
static MemoryPool* getContextPool(); static MemoryPool* getContextPool();
MemoryStats& getStatsGroup() noexcept;
// Set statistics group for pool. Usage counters will be decremented from // Set statistics group for pool. Usage counters will be decremented from
// previously set group and added to new // previously set group and added to new
void setStatsGroup(MemoryStats& stats) noexcept; void setStatsGroup(MemoryStats& stats) noexcept;
@ -456,7 +459,166 @@ namespace Firebird
typedef AutoPtr<MemoryPool> AutoMemoryPool; typedef AutoPtr<MemoryPool> AutoMemoryPool;
template <typename T>
class PoolAllocator
{
template <typename> friend class PoolAllocator;
public:
using value_type = T;
using size_type = size_t;
using pointer = T*;
using const_pointer = const T*;
using reference = T&;
using const_reference = const T&;
using void_pointer = void* ;
using const_void_pointer = const void*;
using difference_type = std::ptrdiff_t;
using is_always_equal = std::true_type;
template <typename U>
struct rebind
{
typedef PoolAllocator<U> other;
};
public:
PoolAllocator(MemoryPool& aPool) noexcept
: pool(aPool)
{}
PoolAllocator(const PoolAllocator& o) noexcept
: pool(o.pool)
{}
template <class U>
PoolAllocator(const PoolAllocator<U>& o) noexcept
: pool(o.pool)
{}
~PoolAllocator() noexcept
{}
public:
constexpr pointer allocate(size_type n, const void* hint = nullptr)
{
return static_cast<T*>(pool.allocate(n * sizeof(T) ALLOC_ARGS));
}
constexpr void deallocate(pointer p, size_type n)
{
pool.deallocate(p);
}
constexpr size_type max_size() const noexcept
{
return size_t(-1) / sizeof(T);
}
/* C++17
template <typename U, typename... Args>
constexpr void construct(U* ptr, Args&&... args)
{
if constexpr (std::is_constructible<U, MemoryPool&, Args...>::value)
new ((void*) ptr) U(pool, std::forward<Args>(args)...);
else
new ((void*) ptr) U(std::forward<Args>(args)...);
}
*/
template <
typename U,
typename... Args,
std::enable_if_t<std::is_constructible<U, MemoryPool&, Args...>::value, bool> = true
>
constexpr void construct(U* ptr, Args&&... args)
{
new ((void*) ptr) U(pool, std::forward<Args>(args)...);
}
template <
typename U,
typename... Args,
std::enable_if_t<!std::is_constructible<U, MemoryPool&, Args...>::value, bool> = true
>
constexpr void construct(U* ptr, Args&&... args)
{
new ((void*) ptr) U(std::forward<Args>(args)...);
}
template <typename U>
constexpr void destroy(U* ptr)
{
ptr->~U();
}
constexpr bool operator==(const PoolAllocator<T>& o) const noexcept
{
return &pool == &o.pool;
}
constexpr bool operator!=(const PoolAllocator<T>& o) const noexcept
{
return &pool != &o.pool;
}
private:
MemoryPool& pool;
};
} // namespace Firebird } // namespace Firebird
template <typename TAlloc>
struct std::allocator_traits<Firebird::PoolAllocator<TAlloc>>
{
using Alloc = Firebird::PoolAllocator<TAlloc>;
using allocator_type = Alloc;
using value_type = typename Alloc::value_type;
using pointer = typename Alloc::pointer;
using const_pointer = typename Alloc::const_pointer;
using void_pointer = typename Alloc::void_pointer;
using const_void_pointer = typename Alloc::const_void_pointer;
using size_type = typename Alloc::size_type;
using difference_type = typename Alloc::difference_type;
using reference = value_type&;
using const_reference = const value_type&;
using is_always_equal = typename Alloc::is_always_equal;
template <typename T>
using rebind_alloc = typename Alloc::template rebind<T>::other;
template <typename T>
using rebind_traits = allocator_traits<rebind_alloc<T>>;
static constexpr pointer allocate(Alloc& alloc, size_type size)
{
return alloc.allocate(size);
}
static constexpr void deallocate(Alloc& alloc, pointer ptr, size_type size)
{
alloc.deallocate(ptr, size);
}
template <typename T, typename... Args>
static constexpr void construct(Alloc& alloc, T* ptr, Args&&... args)
{
alloc.construct(ptr, std::forward<Args>(args)...);
}
template <typename T>
static constexpr void destroy(Alloc& alloc, T* ptr)
{
alloc.destroy(ptr);
}
static constexpr size_type max_size(const Alloc& alloc) noexcept
{
return alloc.max_size();
}
};
#endif // CLASSES_ALLOC_H #endif // CLASSES_ALLOC_H

View File

@ -110,6 +110,12 @@ public:
ensureCapacity(InitialCapacity); ensureCapacity(InitialCapacity);
} }
Array(const T* items, const size_type itemsCount)
: Storage(), count(0), capacity(this->getStorageSize()), data(this->getStorage())
{
add(items, itemsCount);
}
Array(const Array<T, Storage>& source) Array(const Array<T, Storage>& source)
: Storage(), count(0), capacity(this->getStorageSize()), data(this->getStorage()) : Storage(), count(0), capacity(this->getStorageSize()), data(this->getStorage())
{ {

View File

@ -483,6 +483,13 @@ namespace Firebird
ObjectCmp> >() ObjectCmp> >()
{ } { }
explicit SortedObjectsArray(MemoryPool& p, const SortedObjectsArray& o) :
ObjectsArray <ObjectValue, SortedArray<ObjectValue*,
ObjectStorage, const ObjectKey*, ObjectKeyOfValue,
ObjectCmp> >(p, o)
{
}
bool find(const ObjectKey& item, size_type& pos) const bool find(const ObjectKey& item, size_type& pos) const
{ {
const ObjectKey* const pItem = &item; const ObjectKey* const pItem = &item;

View File

@ -230,6 +230,10 @@
#ifdef ARM #ifdef ARM
#define FB_CPU CpuArm #define FB_CPU CpuArm
#endif /* ARM */ #endif /* ARM */
#ifdef ARM64
#define DARWIN64
#define FB_CPU CpuArm64
#endif /* ARM64 */
#ifdef __ppc__ #ifdef __ppc__
#define powerpc #define powerpc
#define FB_CPU CpuPowerPc #define FB_CPU CpuPowerPc
@ -252,8 +256,6 @@
#define API_ROUTINE __attribute__((visibility("default"))) #define API_ROUTINE __attribute__((visibility("default")))
#define API_ROUTINE_VARARG API_ROUTINE #define API_ROUTINE_VARARG API_ROUTINE
#define INTERNAL_API_ROUTINE API_ROUTINE
#define FB_EXPORTED __attribute__((visibility("default")))
#define O_DIRECT F_NOCACHE #define O_DIRECT F_NOCACHE
#endif /* Darwin Platforms */ #endif /* Darwin Platforms */
@ -603,10 +605,6 @@ extern "C" int remove(const char* path);
#define CLIB_ROUTINE #define CLIB_ROUTINE
#endif #endif
#ifndef FB_EXPORTED
#define FB_EXPORTED
#endif
#ifdef HAS_NOEXCEPT #ifdef HAS_NOEXCEPT
#define NOEXCEPT noexcept #define NOEXCEPT noexcept
#define NOEXCEPT_ARG(X) noexcept((X)) #define NOEXCEPT_ARG(X) noexcept((X))
@ -886,21 +884,6 @@ void GDS_breakpoint(int);
#define FB_CONST64(a) (a##LL) #define FB_CONST64(a) (a##LL)
#endif #endif
// Check for "final" keyword support
#ifdef CPP_11
#define FB_FINAL final
#else
#ifdef __GNUC__
#if ((__GNUC__ == 4 && __GNUC_MINOR__ >= 7) || (__GNUC__ >= 5))
#define FB_FINAL __final
#endif
#endif
// Please add support for other compilers here
#ifndef FB_FINAL
#define FB_FINAL
#endif
#endif
#define FB_UNUSED(value) do { if (value) {} } while (false) #define FB_UNUSED(value) do { if (value) {} } while (false)
#define FB_UNUSED_VAR(value) (void) value #define FB_UNUSED_VAR(value) (void) value

View File

@ -410,6 +410,8 @@ void Config::checkValues()
checkIntForHiBound(KEY_TIP_CACHE_BLOCK_SIZE, MAX_ULONG, true); checkIntForHiBound(KEY_TIP_CACHE_BLOCK_SIZE, MAX_ULONG, true);
checkIntForLoBound(KEY_INLINE_SORT_THRESHOLD, 0, true); checkIntForLoBound(KEY_INLINE_SORT_THRESHOLD, 0, true);
checkIntForLoBound(KEY_MAX_STATEMENT_CACHE_SIZE, 0, true);
} }

View File

@ -137,7 +137,6 @@ enum ConfigKey
KEY_DEADLOCK_TIMEOUT, KEY_DEADLOCK_TIMEOUT,
KEY_REMOTE_SERVICE_NAME, KEY_REMOTE_SERVICE_NAME,
KEY_REMOTE_SERVICE_PORT, KEY_REMOTE_SERVICE_PORT,
KEY_REMOTE_PIPE_NAME,
KEY_IPC_NAME, KEY_IPC_NAME,
KEY_MAX_UNFLUSHED_WRITES, KEY_MAX_UNFLUSHED_WRITES,
KEY_MAX_UNFLUSHED_WRITE_TIME, KEY_MAX_UNFLUSHED_WRITE_TIME,
@ -177,6 +176,7 @@ enum ConfigKey
KEY_ENCRYPT_SECURITY_DATABASE, KEY_ENCRYPT_SECURITY_DATABASE,
KEY_STMT_TIMEOUT, KEY_STMT_TIMEOUT,
KEY_CONN_IDLE_TIMEOUT, KEY_CONN_IDLE_TIMEOUT,
KEY_ON_DISCONNECT_TRIG_TIMEOUT,
KEY_CLIENT_BATCH_BUFFER, KEY_CLIENT_BATCH_BUFFER,
KEY_OUTPUT_REDIRECTION_FILE, KEY_OUTPUT_REDIRECTION_FILE,
KEY_EXT_CONN_POOL_SIZE, KEY_EXT_CONN_POOL_SIZE,
@ -189,6 +189,7 @@ enum ConfigKey
KEY_USE_FILESYSTEM_CACHE, KEY_USE_FILESYSTEM_CACHE,
KEY_INLINE_SORT_THRESHOLD, KEY_INLINE_SORT_THRESHOLD,
KEY_TEMP_PAGESPACE_DIR, KEY_TEMP_PAGESPACE_DIR,
KEY_MAX_STATEMENT_CACHE_SIZE,
MAX_CONFIG_KEY // keep it last MAX_CONFIG_KEY // keep it last
}; };
@ -232,7 +233,6 @@ constexpr ConfigEntry entries[MAX_CONFIG_KEY] =
{TYPE_INTEGER, "DeadlockTimeout", false, 10}, // seconds {TYPE_INTEGER, "DeadlockTimeout", false, 10}, // seconds
{TYPE_STRING, "RemoteServiceName", false, FB_SERVICE_NAME}, {TYPE_STRING, "RemoteServiceName", false, FB_SERVICE_NAME},
{TYPE_INTEGER, "RemoteServicePort", false, 0}, {TYPE_INTEGER, "RemoteServicePort", false, 0},
{TYPE_STRING, "RemotePipeName", false, FB_PIPE_NAME},
{TYPE_STRING, "IpcName", false, FB_IPC_NAME}, {TYPE_STRING, "IpcName", false, FB_IPC_NAME},
#ifdef WIN_NT #ifdef WIN_NT
{TYPE_INTEGER, "MaxUnflushedWrites", false, 100}, {TYPE_INTEGER, "MaxUnflushedWrites", false, 100},
@ -285,6 +285,7 @@ constexpr ConfigEntry entries[MAX_CONFIG_KEY] =
{TYPE_BOOLEAN, "AllowEncryptedSecurityDatabase", false, false}, {TYPE_BOOLEAN, "AllowEncryptedSecurityDatabase", false, false},
{TYPE_INTEGER, "StatementTimeout", false, 0}, {TYPE_INTEGER, "StatementTimeout", false, 0},
{TYPE_INTEGER, "ConnectionIdleTimeout", false, 0}, {TYPE_INTEGER, "ConnectionIdleTimeout", false, 0},
{TYPE_INTEGER, "OnDisconnectTriggerTimeout", false, 180},
{TYPE_INTEGER, "ClientBatchBuffer", false, 128 * 1024}, {TYPE_INTEGER, "ClientBatchBuffer", false, 128 * 1024},
#ifdef DEV_BUILD #ifdef DEV_BUILD
{TYPE_STRING, "OutputRedirectionFile", true, "-"}, {TYPE_STRING, "OutputRedirectionFile", true, "-"},
@ -304,7 +305,8 @@ constexpr ConfigEntry entries[MAX_CONFIG_KEY] =
{TYPE_STRING, "DataTypeCompatibility", false, nullptr}, {TYPE_STRING, "DataTypeCompatibility", false, nullptr},
{TYPE_BOOLEAN, "UseFileSystemCache", false, true}, {TYPE_BOOLEAN, "UseFileSystemCache", false, true},
{TYPE_INTEGER, "InlineSortThreshold", false, 1000}, // bytes {TYPE_INTEGER, "InlineSortThreshold", false, 1000}, // bytes
{TYPE_STRING, "TempTableDirectory", false, ""} {TYPE_STRING, "TempTableDirectory", false, ""},
{TYPE_INTEGER, "MaxStatementCacheSize", false, 2 * 1048576} // bytes
}; };
@ -522,9 +524,6 @@ public:
// Service port for INET // Service port for INET
CONFIG_GET_PER_DB_KEY(unsigned short, getRemoteServicePort, KEY_REMOTE_SERVICE_PORT, getInt); CONFIG_GET_PER_DB_KEY(unsigned short, getRemoteServicePort, KEY_REMOTE_SERVICE_PORT, getInt);
// Pipe name for WNET
CONFIG_GET_PER_DB_STR(getRemotePipeName, KEY_REMOTE_PIPE_NAME);
// Name for IPC-related objects // Name for IPC-related objects
CONFIG_GET_PER_DB_STR(getIpcName, KEY_IPC_NAME); CONFIG_GET_PER_DB_STR(getIpcName, KEY_IPC_NAME);
@ -606,6 +605,9 @@ public:
// set in minutes // set in minutes
CONFIG_GET_PER_DB_KEY(unsigned int, getConnIdleTimeout, KEY_CONN_IDLE_TIMEOUT, getInt); CONFIG_GET_PER_DB_KEY(unsigned int, getConnIdleTimeout, KEY_CONN_IDLE_TIMEOUT, getInt);
// set in seconds
CONFIG_GET_PER_DB_KEY(unsigned int, getOnDisconnectTrigTimeout, KEY_ON_DISCONNECT_TRIG_TIMEOUT, getInt);
CONFIG_GET_PER_DB_KEY(unsigned int, getClientBatchBuffer, KEY_CLIENT_BATCH_BUFFER, getInt); CONFIG_GET_PER_DB_KEY(unsigned int, getClientBatchBuffer, KEY_CLIENT_BATCH_BUFFER, getInt);
CONFIG_GET_GLOBAL_STR(getOutputRedirectionFile, KEY_OUTPUT_REDIRECTION_FILE); CONFIG_GET_GLOBAL_STR(getOutputRedirectionFile, KEY_OUTPUT_REDIRECTION_FILE);
@ -629,10 +631,12 @@ public:
CONFIG_GET_PER_DB_KEY(ULONG, getInlineSortThreshold, KEY_INLINE_SORT_THRESHOLD, getInt); CONFIG_GET_PER_DB_KEY(ULONG, getInlineSortThreshold, KEY_INLINE_SORT_THRESHOLD, getInt);
CONFIG_GET_PER_DB_STR(getTempPageSpaceDirectory, KEY_TEMP_PAGESPACE_DIR); CONFIG_GET_PER_DB_STR(getTempPageSpaceDirectory, KEY_TEMP_PAGESPACE_DIR);
CONFIG_GET_PER_DB_INT(getMaxStatementCacheSize, KEY_MAX_STATEMENT_CACHE_SIZE);
}; };
// Implementation of interface to access master configuration file // Implementation of interface to access master configuration file
class FirebirdConf FB_FINAL : class FirebirdConf final :
public RefCntIface<IFirebirdConfImpl<FirebirdConf, CheckStatusWrapper> > public RefCntIface<IFirebirdConfImpl<FirebirdConf, CheckStatusWrapper> >
{ {
public: public:

View File

@ -81,7 +81,7 @@ public:
sub(par.sub), line(par.line) sub(par.sub), line(par.line)
{ } { }
Parameter() Parameter()
: AutoStorage(), name(getPool()), value(getPool()), sub(0), line(0) : AutoStorage(), name(getPool()), value(getPool()), line(0)
{ } { }
SINT64 asInteger() const; SINT64 asInteger() const;

View File

@ -60,6 +60,12 @@ typedef USHORT (*pfn_INTL_keylength) (texttype* tt, USHORT len);
#define INTL_KEY_SORT 0 /* Full sort key */ #define INTL_KEY_SORT 0 /* Full sort key */
#define INTL_KEY_PARTIAL 1 /* Starting portion of sort key for equality class */ #define INTL_KEY_PARTIAL 1 /* Starting portion of sort key for equality class */
#define INTL_KEY_UNIQUE 2 /* Full key for the equality class of the string */ #define INTL_KEY_UNIQUE 2 /* Full key for the equality class of the string */
#define INTL_KEY_MULTI_STARTING 3 /* Multiple starting keys */
/* INTL_KEY_MULTI_STARTING format:
key ::= { <key_length> <key_bytes> }...
key_length ::= <key length least significant byte> <key length most significant byte>
*/
/* Returned value of INTL_BAD_KEY_LENGTH means that key error happened during /* Returned value of INTL_BAD_KEY_LENGTH means that key error happened during
key construction. When partial key is requested returned string should key construction. When partial key is requested returned string should
@ -130,6 +136,8 @@ typedef void (*pfn_INTL_tt_destroy) (texttype* tt);
(char, case, accent) which is case-insensitive, (char, case, accent) which is case-insensitive,
but accent-sensitive */ but accent-sensitive */
#define TEXTTYPE_MULTI_STARTING_KEY 8 /* Supports INTL_KEY_MULTI_STARTING */
struct texttype struct texttype
{ {
@ -346,6 +354,20 @@ typedef INTL_BOOL (*pfn_INTL_lookup_texttype) (
const ASCII* config_info const ASCII* config_info
); );
/* typedef for texttype lookup entry-point - with status buffer */
typedef INTL_BOOL (*pfn_INTL_lookup_texttype_with_status) (
char* status_buffer,
ULONG status_buffer_length,
texttype* tt,
const ASCII* texttype_name,
const ASCII* charset_name,
USHORT attributes,
const UCHAR* specific_attributes,
ULONG specific_attributes_length,
INTL_BOOL ignore_attributes,
const ASCII* config_info
);
/* typedef for charset lookup entry-point */ /* typedef for charset lookup entry-point */
typedef INTL_BOOL (*pfn_INTL_lookup_charset) ( typedef INTL_BOOL (*pfn_INTL_lookup_charset) (
charset* cs, charset* cs,
@ -371,6 +393,7 @@ typedef ULONG (*pfn_INTL_setup_attributes) (
#define TEXTTYPE_ENTRYPOINT LD_lookup_texttype #define TEXTTYPE_ENTRYPOINT LD_lookup_texttype
#define TEXTTYPE_WITH_STATUS_ENTRYPOINT LD_lookup_texttype_with_status
#define CHARSET_ENTRYPOINT LD_lookup_charset #define CHARSET_ENTRYPOINT LD_lookup_charset
#define INTL_VERSION_ENTRYPOINT LD_version #define INTL_VERSION_ENTRYPOINT LD_version
#define INTL_SETUP_ATTRIBUTES_ENTRYPOINT LD_setup_attributes #define INTL_SETUP_ATTRIBUTES_ENTRYPOINT LD_setup_attributes

View File

@ -30,13 +30,15 @@
#include "../common/classes/fb_string.h" #include "../common/classes/fb_string.h"
#include "../common/common.h" #include "../common/common.h"
enum iscProtocol {ISC_PROTOCOL_LOCAL, ISC_PROTOCOL_TCPIP, ISC_PROTOCOL_WLAN}; enum iscProtocol {ISC_PROTOCOL_LOCAL, ISC_PROTOCOL_TCPIP};
#ifndef NO_NFS #ifndef NO_NFS
bool ISC_analyze_nfs(Firebird::PathName&, Firebird::PathName&); bool ISC_analyze_nfs(Firebird::PathName&, Firebird::PathName&);
#endif #endif
bool ISC_analyze_protocol(const char*, Firebird::PathName&, Firebird::PathName&, const char*, bool needFile); #ifdef WIN_NT
bool ISC_analyze_pclan(Firebird::PathName&, Firebird::PathName&); bool ISC_analyze_pclan(Firebird::PathName&, Firebird::PathName&);
#endif
bool ISC_analyze_protocol(const char*, Firebird::PathName&, Firebird::PathName&, const char*, bool needFile);
bool ISC_analyze_tcp(Firebird::PathName&, Firebird::PathName&, bool = true); bool ISC_analyze_tcp(Firebird::PathName&, Firebird::PathName&, bool = true);
bool ISC_check_if_remote(const Firebird::PathName&, bool); bool ISC_check_if_remote(const Firebird::PathName&, bool);
iscProtocol ISC_extract_host(Firebird::PathName&, Firebird::PathName&, bool); iscProtocol ISC_extract_host(Firebird::PathName&, Firebird::PathName&, bool);

View File

@ -346,6 +346,47 @@ bool ISC_analyze_nfs(tstring& expanded_filename, tstring& node_name)
#endif #endif
#if defined(WIN_NT)
bool ISC_analyze_pclan(tstring& expanded_name, tstring& node_name)
{
/**************************************
*
* I S C _ a n a l y z e _ p c l a n
*
**************************************
*
* Functional description
* Check a file name for a SMB mount point. If so,
* decompose into node name and remote file name.
*
**************************************/
ISC_expand_share(expanded_name);
if (expanded_name.length() < 2 ||
(expanded_name[0] != '\\' && expanded_name[0] != '/') ||
(expanded_name[1] != '\\' && expanded_name[1] != '/'))
{
return false;
}
const size p = expanded_name.find_first_of("\\/", 2);
if (p == npos)
return false;
if (Config::getRemoteFileOpenAbility())
{
if (expanded_name.find(':', p + 1) == npos)
return false;
}
node_name = expanded_name.substr(2, p - 2);
expanded_name.erase(0, p + 1);
return true;
}
#endif
bool ISC_analyze_protocol(const char* protocol, tstring& expanded_name, tstring& node_name, bool ISC_analyze_protocol(const char* protocol, tstring& expanded_name, tstring& node_name,
const char* separator, bool need_file) const char* separator, bool need_file)
{ {
@ -403,57 +444,6 @@ bool ISC_analyze_protocol(const char* protocol, tstring& expanded_name, tstring&
} }
#if defined(WIN_NT)
bool ISC_analyze_pclan(tstring& expanded_name, tstring& node_name)
{
/**************************************
*
* I S C _ a n a l y z e _ p c l a n
*
**************************************
*
* Functional description
* Analyze a filename for a named pipe node name on the front.
* If one is found, extract the node name, compute the residual
* file name, and return true. Otherwise return false.
*
**************************************/
node_name.erase();
if (expanded_name.length() < 2 ||
(expanded_name[0] != '\\' && expanded_name[0] != '/') ||
(expanded_name[1] != '\\' && expanded_name[1] != '/'))
{
return false;
}
const size p = expanded_name.find_first_of("\\/", 2);
if (p == npos)
return false;
if (Config::getRemoteFileOpenAbility())
{
if (expanded_name.find(':', p + 1) == npos)
return false;
}
node_name = "\\\\";
node_name += expanded_name.substr(2, p - 2);
// If this is a loopback, substitute "." for the host name. Otherwise,
// the CreateFile on the pipe will fail.
TEXT localhost[MAXHOSTLEN];
ISC_get_host(localhost, sizeof(localhost));
if (node_name.substr(2, npos) == localhost)
{
node_name.replace(2, npos, ".");
}
expanded_name.erase(0, p + 1);
return true;
}
#endif // WIN_NT
bool ISC_analyze_tcp(tstring& file_name, tstring& node_name, bool need_file) bool ISC_analyze_tcp(tstring& file_name, tstring& node_name, bool need_file)
{ {
/************************************** /**************************************
@ -564,46 +554,22 @@ iscProtocol ISC_extract_host(Firebird::PathName& file_name,
// Always check for an explicit TCP node name // Always check for an explicit TCP node name
if (ISC_analyze_tcp(file_name, host_name)) if (ISC_analyze_tcp(file_name, host_name))
{
return ISC_PROTOCOL_TCPIP; return ISC_PROTOCOL_TCPIP;
}
#ifndef NO_NFS
if (implicit_flag) if (implicit_flag)
{ {
// Check for a file on an NFS mounted device // Check for a file on a network mount
if (ISC_analyze_nfs(file_name, host_name)) #ifdef WIN_NT
{ if (ISC_analyze_pclan(file_name, host_name))
return ISC_PROTOCOL_TCPIP; return ISC_PROTOCOL_TCPIP;
}
}
#endif #endif
#if defined(WIN_NT) #ifndef NO_NFS
// Check for an explicit named pipe node name if (ISC_analyze_nfs(file_name, host_name))
if (ISC_analyze_pclan(file_name, host_name))
{
return ISC_PROTOCOL_WLAN;
}
if (implicit_flag)
{
// Check for a file on a shared drive. First try to expand
// the path. Then check the expanded path for a TCP or named pipe.
ISC_expand_share(file_name);
if (ISC_analyze_tcp(file_name, host_name))
{
return ISC_PROTOCOL_TCPIP; return ISC_PROTOCOL_TCPIP;
#endif
} }
if (ISC_analyze_pclan(file_name, host_name))
{
return ISC_PROTOCOL_WLAN;
}
}
#endif // WIN_NT
return ISC_PROTOCOL_LOCAL; return ISC_PROTOCOL_LOCAL;
} }

View File

@ -73,7 +73,7 @@ public:
const Firebird::PathName fileName; const Firebird::PathName fileName;
#ifdef LINUX #ifdef LINUX
virtual bool getRealPath(Firebird::PathName& realPath) = 0; virtual bool getRealPath(Firebird::PathName& path) = 0;
#endif #endif
protected: protected:

View File

@ -46,18 +46,16 @@
class DlfcnModule : public ModuleLoader::Module class DlfcnModule : public ModuleLoader::Module
{ {
public: public:
DlfcnModule(MemoryPool& pool, const Firebird::PathName& aFileName, void* m) DlfcnModule(MemoryPool& pool, const Firebird::PathName& aFileName, void* m);
: ModuleLoader::Module(pool, aFileName),
module(m)
{}
~DlfcnModule(); ~DlfcnModule();
void* findSymbol(ISC_STATUS*, const Firebird::string&);
bool getRealPath(Firebird::PathName& realPath); void* findSymbol(ISC_STATUS*, const Firebird::string&) override;
bool getRealPath(Firebird::PathName& path) override;
private: private:
void* module; void* module;
Firebird::PathName realPath;
}; };
static void makeErrorStatus(ISC_STATUS* status, const char* text) static void makeErrorStatus(ISC_STATUS* status, const char* text)
@ -154,6 +152,47 @@ ModuleLoader::Module* ModuleLoader::loadModule(ISC_STATUS* status, const Firebir
return FB_NEW_POOL(*getDefaultMemoryPool()) DlfcnModule(*getDefaultMemoryPool(), linkPath, module); return FB_NEW_POOL(*getDefaultMemoryPool()) DlfcnModule(*getDefaultMemoryPool(), linkPath, module);
} }
DlfcnModule::DlfcnModule(MemoryPool& pool, const Firebird::PathName& aFileName, void* m)
: ModuleLoader::Module(pool, aFileName),
module(m),
realPath(pool)
{
#ifdef HAVE_DLINFO
char b[PATH_MAX];
#ifdef HAVE_RTLD_DI_ORIGIN
if (dlinfo(module, RTLD_DI_ORIGIN, b) == 0)
{
realPath = b;
realPath += '/';
realPath += fileName;
if (realpath(realPath.c_str(), b))
{
realPath = b;
return;
}
}
#endif
#ifdef HAVE_RTLD_DI_LINKMAP
struct link_map* lm;
if (dlinfo(module, RTLD_DI_LINKMAP, &lm) == 0)
{
if (realpath(lm->l_name, b))
{
realPath = b;
return;
}
}
#endif
#endif
// Error getting real path.
realPath.clear();
}
DlfcnModule::~DlfcnModule() DlfcnModule::~DlfcnModule()
{ {
if (module) if (module)
@ -165,7 +204,7 @@ void* DlfcnModule::findSymbol(ISC_STATUS* status, const Firebird::string& symNam
void* result = dlsym(module, symName.c_str()); void* result = dlsym(module, symName.c_str());
if (!result) if (!result)
{ {
Firebird::string newSym ='_' + symName; Firebird::string newSym = '_' + symName;
result = dlsym(module, newSym.c_str()); result = dlsym(module, newSym.c_str());
} }
@ -183,20 +222,28 @@ void* DlfcnModule::findSymbol(ISC_STATUS* status, const Firebird::string& symNam
return NULL; return NULL;
} }
const auto& libraryPath = realPath.isEmpty() ? fileName : realPath;
char symbolPathBuffer[PATH_MAX];
const char* symbolPath = symbolPathBuffer;
if (!realpath(info.dli_fname, symbolPathBuffer))
symbolPath = info.dli_fname;
const char* errText = "Actual module name does not match requested"; const char* errText = "Actual module name does not match requested";
if (PathUtils::isRelative(fileName) || PathUtils::isRelative(info.dli_fname)) if (PathUtils::isRelative(libraryPath) || PathUtils::isRelative(symbolPath))
{ {
// check only name (not path) of the library // check only name (not path) of the library
Firebird::PathName dummyDir, nm1, nm2; Firebird::PathName dummyDir, nm1, nm2;
PathUtils::splitLastComponent(dummyDir, nm1, fileName); PathUtils::splitLastComponent(dummyDir, nm1, libraryPath);
PathUtils::splitLastComponent(dummyDir, nm2, info.dli_fname); PathUtils::splitLastComponent(dummyDir, nm2, symbolPath);
if (nm1 != nm2) if (nm1 != nm2)
{ {
makeErrorStatus(status, errText); makeErrorStatus(status, errText);
return NULL; return NULL;
} }
} }
else if (fileName != info.dli_fname) else if (libraryPath != symbolPath)
{ {
makeErrorStatus(status, errText); makeErrorStatus(status, errText);
return NULL; return NULL;
@ -206,38 +253,11 @@ void* DlfcnModule::findSymbol(ISC_STATUS* status, const Firebird::string& symNam
return result; return result;
} }
bool DlfcnModule::getRealPath(Firebird::PathName& realPath) bool DlfcnModule::getRealPath(Firebird::PathName& path)
{ {
#ifdef HAVE_DLINFO if (realPath.isEmpty())
char b[PATH_MAX];
#ifdef HAVE_RTLD_DI_ORIGIN
if (dlinfo(module, RTLD_DI_ORIGIN, b) == 0)
{
realPath = b;
realPath += '/';
realPath += fileName;
if (realpath(realPath.c_str(), b))
{
realPath = b;
return true;
}
}
#endif
#ifdef HAVE_RTLD_DI_LINKMAP
struct link_map* lm;
if (dlinfo(module, RTLD_DI_LINKMAP, &lm) == 0)
{
if (realpath(lm->l_name, b))
{
realPath = b;
return true;
}
}
#endif
#endif
return false; return false;
path = realPath;
return true;
} }

View File

@ -87,26 +87,34 @@ public:
memset(&ackd, 0, sizeof(ackd)); memset(&ackd, 0, sizeof(ackd));
ackd.cbSize = sizeof(ackd); ackd.cbSize = sizeof(ackd);
const char* crtDll =
#if _MSC_VER == 1400
"msvcr80.dll";
#elif _MSC_VER == 1500
"msvcr90.dll";
#elif _MSC_VER == 1600
"msvcr100.dll";
#elif _MSC_VER == 1700
"msvcr110.dll";
#elif _MSC_VER == 1800
"msvcr120.dll";
#elif _MSC_VER >= 1900 && _MSC_VER < 2000
"vcruntime140.dll";
#else
"";
#define TO_STR(x) #x
#define ERRSTR(x) "Unknown " #x " value: " TO_STR(x) ". Specify CRT DLL name here !"
static_assert(false, ERRSTR(_MSC_VER));
// #error Specify CRT DLL name here !
#endif
// if CRT already present in some activation context then nothing to do // if CRT already present in some activation context then nothing to do
if ((*mFindActCtxSectionString) if ((*mFindActCtxSectionString)
(0, NULL, (0, NULL,
ACTIVATION_CONTEXT_SECTION_DLL_REDIRECTION, ACTIVATION_CONTEXT_SECTION_DLL_REDIRECTION,
#if _MSC_VER == 1400 crtDll, &ackd))
"msvcr80.dll",
#elif _MSC_VER == 1500
"msvcr90.dll",
#elif _MSC_VER == 1600
"msvcr100.dll",
#elif _MSC_VER == 1700
"msvcr110.dll",
#elif _MSC_VER == 1800
"msvcr120.dll",
#elif _MSC_VER >= 1900 && _MSC_VER <= 1930
"vcruntime140.dll",
#else
#error Specify CRT DLL name here !
#endif
&ackd))
{ {
return; return;
} }

View File

@ -232,7 +232,7 @@ public:
IntField u, g; IntField u, g;
}; };
class StackUserData FB_FINAL : public UserData class StackUserData final : public UserData
{ {
public: public:
void* operator new(size_t, void* memory) throw() void* operator new(size_t, void* memory) throw()
@ -241,7 +241,7 @@ public:
} }
}; };
class DynamicUserData FB_FINAL : public UserData class DynamicUserData final : public UserData
{ {
public: public:
#ifdef DEBUG_GDS_ALLOC #ifdef DEBUG_GDS_ALLOC

View File

@ -92,22 +92,24 @@ public:
// System-wide ICU have no version number at entries names // System-wide ICU have no version number at entries names
if (!majorVersion) if (!majorVersion)
{ {
fb_assert(false); // ASF: I don't think this code path is correct.
if (module->findSymbol(NULL, name, ptr)) if (module->findSymbol(NULL, name, ptr))
return; return;
} }
else else
{ {
// ICU has several schemas for entries names // ICU has several schemas for entries names
const char* patterns[] = const char* const patterns[] =
{ {
"%s_%d", "%s_%d_%d", "%s_%d%d", "%s", NULL "%s_%d", "%s_%d_%d", "%s_%d%d", "%s"
}; };
string symbol; string symbol;
for (const char** p = patterns; *p; ++p) for (auto pattern : patterns)
{ {
symbol.printf(*p, name, majorVersion, minorVersion); symbol.printf(pattern, name, majorVersion, minorVersion);
if (module->findSymbol(NULL, symbol, ptr)) if (module->findSymbol(NULL, symbol, ptr))
return; return;
} }
@ -272,8 +274,10 @@ public:
USet* (U_EXPORT2 *usetOpen)(UChar32 start, UChar32 end); USet* (U_EXPORT2 *usetOpen)(UChar32 start, UChar32 end);
void (U_EXPORT2 *ucolClose)(UCollator* coll); void (U_EXPORT2 *ucolClose)(UCollator* coll);
int32_t (U_EXPORT2 *ucolGetContractions)(const UCollator* coll, USet* conts, UErrorCode* status); int32_t (U_EXPORT2 *ucolGetContractionsAndExpansions)(const UCollator* coll, USet* contractions, USet* expansions,
UBool addPrefixes, UErrorCode* status);
const UChar* (U_EXPORT2 *ucolGetRules)(const UCollator* coll, int32_t* length); const UChar* (U_EXPORT2 *ucolGetRules)(const UCollator* coll, int32_t* length);
int32_t (U_EXPORT2 *ucolGetSortKey)(const UCollator* coll, const UChar* source, int32_t (U_EXPORT2 *ucolGetSortKey)(const UCollator* coll, const UChar* source,
int32_t sourceLength, uint8_t* result, int32_t resultLength); int32_t sourceLength, uint8_t* result, int32_t resultLength);
UCollator* (U_EXPORT2 *ucolOpen)(const char* loc, UErrorCode* status); UCollator* (U_EXPORT2 *ucolOpen)(const char* loc, UErrorCode* status);
@ -321,6 +325,7 @@ private:
getEntryPoint("ucnv_open", module, ucnv_open); getEntryPoint("ucnv_open", module, ucnv_open);
getEntryPoint("ucnv_close", module, ucnv_close); getEntryPoint("ucnv_close", module, ucnv_close);
getEntryPoint("ucnv_fromUChars", module, ucnv_fromUChars); getEntryPoint("ucnv_fromUChars", module, ucnv_fromUChars);
getEntryPoint("u_getVersion", module, u_getVersion);
getEntryPoint("u_tolower", module, u_tolower); getEntryPoint("u_tolower", module, u_tolower);
getEntryPoint("u_toupper", module, u_toupper); getEntryPoint("u_toupper", module, u_toupper);
getEntryPoint("u_strCompare", module, u_strCompare); getEntryPoint("u_strCompare", module, u_strCompare);
@ -379,8 +384,11 @@ public:
if (o) if (o)
{ {
o->vMajor = majorVersion; UVersionInfo versionInfo;
o->vMinor = minorVersion; o->u_getVersion(versionInfo);
o->vMajor = versionInfo[0];
o->vMinor = versionInfo[1];
} }
return o; return o;
@ -507,15 +515,20 @@ static ModuleLoader::Module* formatAndLoad(const char* templateName,
else else
{ {
// ICU has several schemas for placing version into file name // ICU has several schemas for placing version into file name
const char* patterns[] = const char* const patterns[] =
{ {
"%d_%d", "%d%d", NULL #ifdef WIN_NT
"%d",
#endif
"%d_%d",
"%d.%d",
"%d%d"
}; };
PathName s, filename; PathName s, filename;
for (const char** p = patterns; *p; ++p) for (auto pattern : patterns)
{ {
s.printf(*p, majorVersion, minorVersion); s.printf(pattern, majorVersion, minorVersion);
filename.printf(templateName, s.c_str()); filename.printf(templateName, s.c_str());
module = ModuleLoader::fixAndLoadModule(NULL, filename); module = ModuleLoader::fixAndLoadModule(NULL, filename);
@ -523,7 +536,9 @@ static ModuleLoader::Module* formatAndLoad(const char* templateName,
break; break;
} }
#ifndef WIN_NT
// There is no sence to try pattern "%d" for different minor versions // There is no sence to try pattern "%d" for different minor versions
// ASF: In Windows ICU 63.1 libraries use 63.dll suffix. This is handled in 'patterns' above.
if (!module && minorVersion == 0) if (!module && minorVersion == 0)
{ {
s.printf("%d", majorVersion); s.printf("%d", majorVersion);
@ -531,6 +546,7 @@ static ModuleLoader::Module* formatAndLoad(const char* templateName,
module = ModuleLoader::fixAndLoadModule(NULL, filename); module = ModuleLoader::fixAndLoadModule(NULL, filename);
} }
#endif
} }
return module; return module;
@ -1169,7 +1185,7 @@ UnicodeUtil::ICU* UnicodeUtil::loadICU(const string& icuVersion, const string& c
getVersions(configInfo, versions); getVersions(configInfo, versions);
if (versions.isEmpty()) if (versions.isEmpty())
gds__log("No versions"); gds__log("No ICU versions specified");
string version = icuVersion.isEmpty() ? versions[0] : icuVersion; string version = icuVersion.isEmpty() ? versions[0] : icuVersion;
if (version == "default") if (version == "default")
@ -1241,7 +1257,8 @@ UnicodeUtil::ICU* UnicodeUtil::loadICU(const string& icuVersion, const string& c
icu->getEntryPoint("uset_open", icu->ucModule, icu->usetOpen); icu->getEntryPoint("uset_open", icu->ucModule, icu->usetOpen);
icu->getEntryPoint("ucol_close", icu->inModule, icu->ucolClose); icu->getEntryPoint("ucol_close", icu->inModule, icu->ucolClose);
icu->getEntryPoint("ucol_getContractions", icu->inModule, icu->ucolGetContractions); icu->getEntryPoint("ucol_getContractionsAndExpansions", icu->inModule,
icu->ucolGetContractionsAndExpansions);
icu->getEntryPoint("ucol_getRules", icu->inModule, icu->ucolGetRules); icu->getEntryPoint("ucol_getRules", icu->inModule, icu->ucolGetRules);
icu->getEntryPoint("ucol_getSortKey", icu->inModule, icu->ucolGetSortKey); icu->getEntryPoint("ucol_getSortKey", icu->inModule, icu->ucolGetSortKey);
icu->getEntryPoint("ucol_open", icu->inModule, icu->ucolOpen); icu->getEntryPoint("ucol_open", icu->inModule, icu->ucolOpen);
@ -1295,6 +1312,13 @@ UnicodeUtil::ICU* UnicodeUtil::loadICU(const string& icuVersion, const string& c
} }
void UnicodeUtil::getICUVersion(ICU* icu, int& majorVersion, int& minorVersion)
{
majorVersion = icu->majorVersion;
minorVersion = icu->minorVersion;
}
UnicodeUtil::ConversionICU& UnicodeUtil::getConversionICU() UnicodeUtil::ConversionICU& UnicodeUtil::getConversionICU()
{ {
if (convIcu) if (convIcu)
@ -1311,7 +1335,7 @@ UnicodeUtil::ConversionICU& UnicodeUtil::getConversionICU()
// Try "favorite" (distributed on windows) version first // Try "favorite" (distributed on windows) version first
const int favMaj = 63; const int favMaj = 63;
const int favMin = 0; const int favMin = 1;
try try
{ {
if ((convIcu = ImplementConversionICU::create(favMaj, favMin))) if ((convIcu = ImplementConversionICU::create(favMaj, favMin)))
@ -1408,13 +1432,13 @@ string UnicodeUtil::getDefaultIcuVersion()
} }
bool UnicodeUtil::getCollVersion(const Firebird::string& icuVersion, UnicodeUtil::ICU* UnicodeUtil::getCollVersion(const Firebird::string& icuVersion,
const Firebird::string& configInfo, Firebird::string& collVersion) const Firebird::string& configInfo, Firebird::string& collVersion)
{ {
ICU* icu = loadICU(icuVersion, configInfo); ICU* icu = loadICU(icuVersion, configInfo);
if (!icu) if (!icu)
return false; return nullptr;
char version[U_MAX_VERSION_STRING_LENGTH]; char version[U_MAX_VERSION_STRING_LENGTH];
icu->uVersionToString(icu->collVersion, version); icu->uVersionToString(icu->collVersion, version);
@ -1424,7 +1448,7 @@ bool UnicodeUtil::getCollVersion(const Firebird::string& icuVersion,
else else
collVersion = version; collVersion = version;
return true; return icu;
} }
UnicodeUtil::Utf16Collation* UnicodeUtil::Utf16Collation::create( UnicodeUtil::Utf16Collation* UnicodeUtil::Utf16Collation::create(
@ -1499,12 +1523,11 @@ UnicodeUtil::Utf16Collation* UnicodeUtil::Utf16Collation::create(
tt->texttype_pad_option = (attributes & TEXTTYPE_ATTR_PAD_SPACE) ? true : false; tt->texttype_pad_option = (attributes & TEXTTYPE_ATTR_PAD_SPACE) ? true : false;
ICU* icu = loadICU(collVersion, locale, configInfo); string icuVersion;
if (!icu) if (specificAttributes.get(IntlUtil::convertAsciiToUtf16("ICU-VERSION"), icuVersion))
{ icuVersion = IntlUtil::convertUtf16ToAscii(icuVersion, &error);
gds__log("loadICU failed");
return NULL; const auto icu = loadICU(icuVersion, collVersion, locale, configInfo);
}
UErrorCode status = U_ZERO_ERROR; UErrorCode status = U_ZERO_ERROR;
HalfStaticArray<UChar, BUFFER_TINY> rulesBuffer; HalfStaticArray<UChar, BUFFER_TINY> rulesBuffer;
@ -1617,35 +1640,145 @@ UnicodeUtil::Utf16Collation* UnicodeUtil::Utf16Collation::create(
USet* contractions = icu->usetOpen(1, 0); USet* contractions = icu->usetOpen(1, 0);
// status not verified here. // status not verified here.
icu->ucolGetContractions(partialCollator, contractions, &status); icu->ucolGetContractionsAndExpansions(partialCollator, contractions, nullptr, false, &status);
int contractionsCount = icu->usetGetItemCount(contractions); int contractionsCount = icu->usetGetItemCount(contractions);
for (int contractionIndex = 0; contractionIndex < contractionsCount; ++contractionIndex) for (int contractionIndex = 0; contractionIndex < contractionsCount; ++contractionIndex)
{ {
UChar str[10]; UChar strChars[10];
UChar32 start, end; UChar32 start, end;
status = U_ZERO_ERROR; status = U_ZERO_ERROR;
int len = icu->usetGetItem(contractions, contractionIndex, &start, &end, str, sizeof(str), &status); int len = icu->usetGetItem(contractions, contractionIndex, &start, &end, strChars, sizeof(strChars), &status);
if (len >= 2) if (len >= 2)
{ {
obj->maxContractionsPrefixLength = len - 1 > obj->maxContractionsPrefixLength ? obj->maxContractionsPrefixLength = len - 1 > obj->maxContractionsPrefixLength ?
len - 1 : obj->maxContractionsPrefixLength; len - 1 : obj->maxContractionsPrefixLength;
for (int currentLen = 1; currentLen < len; ++currentLen) UCHAR key[100];
{ int keyLen = icu->ucolGetSortKey(partialCollator, strChars, len, key, sizeof(key));
string s(reinterpret_cast<const char*>(str), currentLen * 2);
if (!obj->contractionsPrefix.exist(s)) for (int prefixLen = 1; prefixLen < len; ++prefixLen)
obj->contractionsPrefix.push(s); {
const Array<USHORT> str(reinterpret_cast<USHORT*>(strChars), prefixLen);
auto keySet = obj->contractionsPrefix.get(str);
if (!keySet)
{
keySet = obj->contractionsPrefix.put(str);
UCHAR prefixKey[100];
int prefixKeyLen = icu->ucolGetSortKey(partialCollator,
strChars, prefixLen, prefixKey, sizeof(prefixKey));
keySet->add(Array<UCHAR>(prefixKey, prefixKeyLen));
}
keySet->add(Array<UCHAR>(key, keyLen));
} }
} }
} }
icu->usetClose(contractions); icu->usetClose(contractions);
ContractionsPrefixMap::Accessor accessor(&obj->contractionsPrefix);
for (bool found = accessor.getFirst(); found; found = accessor.getNext())
{
auto& keySet = accessor.current()->second;
if (keySet.getCount() <= 1)
continue;
fb_assert(accessor.current()->first.hasData());
USHORT ch = accessor.current()->first[0];
if (ch >= 0xFDD0 && ch <= 0xFDEF)
{
keySet.clear();
keySet.add(Array<UCHAR>());
continue;
}
auto firstKeyIt = keySet.begin();
auto lastKeyIt = --keySet.end();
const UCHAR* firstKeyDataIt = firstKeyIt->begin();
const UCHAR* lastKeyDataIt = lastKeyIt->begin();
const UCHAR* firstKeyDataEnd = firstKeyIt->end();
const UCHAR* lastKeyDataEnd = lastKeyIt->end();
if (*firstKeyDataIt == *lastKeyDataIt)
{
unsigned common = 0;
do
{
++common;
} while (++firstKeyDataIt != firstKeyDataEnd && ++lastKeyDataIt != lastKeyDataEnd &&
*firstKeyDataIt == *lastKeyDataIt);
Array<UCHAR> commonKey(firstKeyIt->begin(), common);
keySet.clear();
keySet.add(commonKey);
}
else
{
auto secondKeyIt = ++keySet.begin();
const UCHAR* secondKeyDataIt = secondKeyIt->begin();
const UCHAR* secondKeyDataEnd = secondKeyIt->end();
ObjectsArray<Array<UCHAR> > commonKeys;
commonKeys.add(*firstKeyIt);
while (secondKeyIt != keySet.end())
{
unsigned common = 0;
while (firstKeyDataIt != firstKeyDataEnd && secondKeyDataIt != secondKeyDataEnd &&
*firstKeyDataIt == *secondKeyDataIt)
{
++common;
++firstKeyDataIt;
++secondKeyDataIt;
}
unsigned backSize = commonKeys.back()->getCount();
if (common > backSize)
commonKeys.back()->append(secondKeyIt->begin() + backSize, common - backSize);
else if (common < backSize)
{
if (common == 0)
commonKeys.push(*secondKeyIt);
else
commonKeys.back()->resize(common);
}
if (++secondKeyIt != keySet.end())
{
++firstKeyIt;
firstKeyDataIt = firstKeyIt->begin();
secondKeyDataIt = secondKeyIt->begin();
firstKeyDataEnd = firstKeyIt->end();
secondKeyDataEnd = secondKeyIt->end();
}
}
keySet.clear();
for (auto ck : commonKeys)
keySet.add(ck);
}
}
if (obj->maxContractionsPrefixLength)
tt->texttype_flags |= TEXTTYPE_MULTI_STARTING_KEY;
return obj; return obj;
} }
@ -1696,41 +1829,17 @@ USHORT UnicodeUtil::Utf16Collation::stringToKey(USHORT srcLen, const USHORT* src
srcLenLong = pad - src + 1; srcLenLong = pad - src + 1;
} }
if (srcLenLong == 0)
return 0;
HalfStaticArray<USHORT, BUFFER_SMALL / 2> buffer; HalfStaticArray<USHORT, BUFFER_SMALL / 2> buffer;
const UCollator* coll = NULL; const UCollator* coll = NULL;
switch (key_type) switch (key_type)
{ {
case INTL_KEY_PARTIAL: case INTL_KEY_PARTIAL:
case INTL_KEY_MULTI_STARTING:
coll = partialCollator; coll = partialCollator;
// Remove last bytes of key if they are start of a contraction
// to correctly find in the index.
for (int i = MIN(maxContractionsPrefixLength, srcLenLong); i > 0; --i)
{
if (contractionsPrefix.exist(string(reinterpret_cast<const char*>(src + srcLenLong - i), i * 2)))
{
srcLenLong -= i;
break;
}
}
if (numericSort)
{
// ASF: Wee need to remove trailing numbers to return sub key that
// matches full key. Example: "abc1" becomes "abc" to match "abc10".
const USHORT* p = src + srcLenLong - 1;
for (; p >= src; --p)
{
if (!(*p >= '0' && *p <= '9'))
break;
}
srcLenLong = p - src + 1;
}
break; break;
case INTL_KEY_UNIQUE: case INTL_KEY_UNIQUE:
@ -1749,11 +1858,100 @@ USHORT UnicodeUtil::Utf16Collation::stringToKey(USHORT srcLen, const USHORT* src
return INTL_BAD_KEY_LENGTH; return INTL_BAD_KEY_LENGTH;
} }
if (srcLenLong == 0) if (key_type == INTL_KEY_MULTI_STARTING)
return 0; {
bool trailingNumbersRemoved = false;
return icu->ucolGetSortKey(coll, if (numericSort)
{
// ASF: Wee need to remove trailing numbers to return sub key that
// matches full key. Example: "abc1" becomes "abc" to match "abc10".
const USHORT* p = src + srcLenLong - 1;
for (; p >= src; --p)
{
if (!(*p >= '0' && *p <= '9'))
break;
trailingNumbersRemoved = true;
}
srcLenLong = p - src + 1;
}
if (!trailingNumbersRemoved)
{
for (int i = MIN(maxContractionsPrefixLength, srcLenLong); i > 0; --i)
{
auto keys = contractionsPrefix.get(Array<USHORT>(src + srcLenLong - i, i));
if (keys)
{
const UCHAR* dstStart = dst;
ULONG prefixLen;
srcLenLong -= i;
if (srcLenLong != 0)
{
prefixLen = icu->ucolGetSortKey(coll,
reinterpret_cast<const UChar*>(src), srcLenLong, dst + 2, dstLen - 2);
if (prefixLen == 0 || prefixLen > dstLen - 2 || prefixLen > MAX_USHORT)
return INTL_BAD_KEY_LENGTH;
fb_assert(dst[2 + prefixLen - 1] == '\0');
--prefixLen;
dstLen -= 2 + prefixLen;
}
else
prefixLen = 0;
for (const auto& keyIt : *keys)
{
const ULONG keyLen = prefixLen + keyIt.getCount();
if (keyLen > dstLen - 2 || keyLen > MAX_USHORT)
return INTL_BAD_KEY_LENGTH;
dst[0] = UCHAR(keyLen & 0xFF);
dst[1] = UCHAR(keyLen >> 8);
if (dst != dstStart)
memcpy(dst + 2, dstStart + 2, prefixLen);
memcpy(dst + 2 + prefixLen, keyIt.begin(), keyIt.getCount());
dst += 2 + keyLen;
dstLen -= 2 + keyLen;
}
return dst - dstStart;
}
}
}
ULONG keyLen = icu->ucolGetSortKey(coll,
reinterpret_cast<const UChar*>(src), srcLenLong, dst + 2, dstLen - 3);
if (keyLen == 0 || keyLen > dstLen - 3 || keyLen > MAX_USHORT)
return INTL_BAD_KEY_LENGTH;
fb_assert(dst[2 + keyLen - 1] == '\0');
--keyLen;
dst[0] = UCHAR(keyLen & 0xFF);
dst[1] = UCHAR(keyLen >> 8);
return keyLen + 2;
}
const ULONG keyLen = icu->ucolGetSortKey(coll,
reinterpret_cast<const UChar*>(src), srcLenLong, dst, dstLen); reinterpret_cast<const UChar*>(src), srcLenLong, dst, dstLen);
if (keyLen == 0 || keyLen > dstLen || keyLen > MAX_USHORT)
return INTL_BAD_KEY_LENGTH;
return keyLen;
} }
@ -1822,8 +2020,8 @@ ULONG UnicodeUtil::Utf16Collation::canonical(ULONG srcLen, const USHORT* src, UL
UnicodeUtil::ICU* UnicodeUtil::Utf16Collation::loadICU( UnicodeUtil::ICU* UnicodeUtil::Utf16Collation::loadICU(
const Firebird::string& collVersion, const Firebird::string& locale, const string& icuVersion, const string& collVersion,
const Firebird::string& configInfo) const string& locale, const string& configInfo)
{ {
ObjectsArray<string> versions; ObjectsArray<string> versions;
getVersions(configInfo, versions); getVersions(configInfo, versions);
@ -1866,7 +2064,26 @@ UnicodeUtil::ICU* UnicodeUtil::Utf16Collation::loadICU(
return icu; return icu;
} }
return NULL; string errorMsg;
if (icuVersion.isEmpty())
{
errorMsg.printf(
"An ICU library with collation version %s is required but was not found. "
"You may try to install another ICU version with this collation version "
"or look for 'gfix -icu' in Firebird documentation.",
collVersion.c_str());
}
else
{
errorMsg.printf(
"An ICU library with collation version %s is required but was not found. "
"You may try to install ICU version %s, used to register the collation in this database "
"or look for 'gfix -icu' in Firebird documentation.",
collVersion.c_str(), icuVersion.c_str());
}
(Arg::Gds(isc_random) << errorMsg).raise();
} }

View File

@ -30,7 +30,9 @@
#include "intlobj_new.h" #include "intlobj_new.h"
#include "../common/IntlUtil.h" #include "../common/IntlUtil.h"
#include "../common/os/mod_loader.h" #include "../common/os/mod_loader.h"
#include "../common/classes/array.h"
#include "../common/classes/fb_string.h" #include "../common/classes/fb_string.h"
#include "../common/classes/GenericMap.h"
#include "../common/classes/objects_array.h" #include "../common/classes/objects_array.h"
#include <unicode/ucnv.h> #include <unicode/ucnv.h>
#include <unicode/ucal.h> #include <unicode/ucal.h>
@ -56,6 +58,7 @@ public:
const UChar *src, int32_t srcLength, const UChar *src, int32_t srcLength,
UErrorCode *pErrorCode); UErrorCode *pErrorCode);
void (U_EXPORT2* u_getVersion) (UVersionInfo versionArray);
UChar32 (U_EXPORT2* u_tolower) (UChar32 c); UChar32 (U_EXPORT2* u_tolower) (UChar32 c);
UChar32 (U_EXPORT2* u_toupper) (UChar32 c); UChar32 (U_EXPORT2* u_toupper) (UChar32 c);
int32_t (U_EXPORT2* u_strCompare) (const UChar* s1, int32_t length1, int32_t (U_EXPORT2* u_strCompare) (const UChar* s1, int32_t length1,
@ -175,7 +178,8 @@ public:
static ConversionICU& getConversionICU(); static ConversionICU& getConversionICU();
static ICU* loadICU(const Firebird::string& icuVersion, const Firebird::string& configInfo); static ICU* loadICU(const Firebird::string& icuVersion, const Firebird::string& configInfo);
static bool getCollVersion(const Firebird::string& icuVersion, static void getICUVersion(ICU* icu, int& majorVersion, int& minorVersion);
static ICU* getCollVersion(const Firebird::string& icuVersion,
const Firebird::string& configInfo, Firebird::string& collVersion); const Firebird::string& configInfo, Firebird::string& collVersion);
class Utf16Collation class Utf16Collation
@ -200,8 +204,47 @@ public:
ULONG canonical(ULONG srcLen, const USHORT* src, ULONG dstLen, ULONG* dst, const ULONG* exceptions); ULONG canonical(ULONG srcLen, const USHORT* src, ULONG dstLen, ULONG* dst, const ULONG* exceptions);
private: private:
static ICU* loadICU(const Firebird::string& collVersion, const Firebird::string& locale, template <typename T>
const Firebird::string& configInfo); class ArrayComparator
{
public:
static bool greaterThan(const Firebird::Array<T>& i1, const Firebird::Array<T>& i2)
{
FB_SIZE_T minCount = MIN(i1.getCount(), i2.getCount());
int cmp = memcmp(i1.begin(), i2.begin(), minCount * sizeof(T));
if (cmp != 0)
return cmp > 0;
return i1.getCount() > i2.getCount();
}
static bool greaterThan(const Firebird::Array<T>* i1, const Firebird::Array<T>* i2)
{
return greaterThan(*i1, *i2);
}
};
typedef Firebird::SortedObjectsArray<
Firebird::Array<UCHAR>,
Firebird::InlineStorage<Firebird::Array<UCHAR>*, 3>,
Firebird::Array<UCHAR>,
Firebird::DefaultKeyValue<const Firebird::Array<UCHAR>*>,
ArrayComparator<UCHAR>
> SortKeyArray;
typedef Firebird::GenericMap<
Firebird::Pair<
Firebird::Full<
Firebird::Array<USHORT>, // UTF-16 string
SortKeyArray // sort keys
>
>,
ArrayComparator<USHORT>
> ContractionsPrefixMap;
static ICU* loadICU(const Firebird::string& icuVersion, const Firebird::string& collVersion,
const Firebird::string& locale, const Firebird::string& configInfo);
void normalize(ULONG* strLen, const USHORT** str, bool forNumericSort, void normalize(ULONG* strLen, const USHORT** str, bool forNumericSort,
Firebird::HalfStaticArray<USHORT, BUFFER_SMALL / 2>& buffer) const; Firebird::HalfStaticArray<USHORT, BUFFER_SMALL / 2>& buffer) const;
@ -212,7 +255,7 @@ public:
UCollator* compareCollator; UCollator* compareCollator;
UCollator* partialCollator; UCollator* partialCollator;
UCollator* sortCollator; UCollator* sortCollator;
Firebird::SortedObjectsArray<Firebird::string> contractionsPrefix; // UTF-16 string ContractionsPrefixMap contractionsPrefix;
unsigned maxContractionsPrefixLength; // number of characters unsigned maxContractionsPrefixLength; // number of characters
bool numericSort; bool numericSort;
}; };

View File

@ -1143,7 +1143,7 @@ Firebird::PathName getPrefix(unsigned int prefType, const char* name)
if (s.hasData() && name[0]) if (s.hasData() && name[0])
{ {
s += '/'; s += PathUtils::dir_sep;
} }
s += name; s += name;
gds__prefix(tmp, s.c_str()); gds__prefix(tmp, s.c_str());
@ -1613,6 +1613,13 @@ bool containsErrorCode(const ISC_STATUS* v, ISC_STATUS code)
return false; return false;
} }
inline bool sqlSymbolChar(char c, bool first)
{
if (c & 0x80)
return false;
return (isdigit(c) && !first) || isalpha(c) || c == '_' || c == '$';
}
const char* dpbItemUpper(const char* s, FB_SIZE_T l, Firebird::string& buf) const char* dpbItemUpper(const char* s, FB_SIZE_T l, Firebird::string& buf)
{ {
if (l && (s[0] == '"' || s[0] == '\'')) if (l && (s[0] == '"' || s[0] == '\''))
@ -1625,30 +1632,38 @@ const char* dpbItemUpper(const char* s, FB_SIZE_T l, Firebird::string& buf)
{ {
if (s[i] == end_quote) if (s[i] == end_quote)
{ {
if (++i >= l || s[i] != end_quote) if (++i >= l)
break; // delimited quote, done processing {
// skipped the escape quote, continue processing
}
if (s[i] & 0x80)
ascii = false;
buf += s[i];
}
if (ascii && s[0] == '\'') if (ascii && s[0] == '\'')
buf.upper(); buf.upper();
return buf.c_str(); return buf.c_str();
} }
if (s[i] != end_quote)
{
buf.assign(&s[i], l - i);
(Firebird::Arg::Gds(isc_quoted_str_bad) << buf).raise();
}
// skipped the escape quote, continue processing
}
else if (!sqlSymbolChar(s[i], i == 1))
ascii = false;
buf += s[i];
}
buf.assign(1, s[0]);
(Firebird::Arg::Gds(isc_quoted_str_miss) << buf).raise();
}
// non-quoted string - try to uppercase // non-quoted string - try to uppercase
for (FB_SIZE_T i = 0; i < l; ++i) for (FB_SIZE_T i = 0; i < l; ++i)
{ {
if (!(s[i] & 0x80)) if (!sqlSymbolChar(s[i], i == 0))
buf += toupper(s[i]);
else
return NULL; // contains non-ascii data return NULL; // contains non-ascii data
buf += toupper(s[i]);
} }
return buf.c_str(); return buf.c_str();

View File

@ -356,7 +356,7 @@ AggNode* AggNode::pass2(thread_db* tdbb, CompilerScratch* csb)
return this; return this;
} }
void AggNode::aggInit(thread_db* tdbb, jrd_req* request) const void AggNode::aggInit(thread_db* tdbb, Request* request) const
{ {
impure_value_ex* impure = request->getImpure<impure_value_ex>(impureOffset); impure_value_ex* impure = request->getImpure<impure_value_ex>(impureOffset);
impure->vlux_count = 0; impure->vlux_count = 0;
@ -378,7 +378,7 @@ void AggNode::aggInit(thread_db* tdbb, jrd_req* request) const
} }
} }
bool AggNode::aggPass(thread_db* tdbb, jrd_req* request) const bool AggNode::aggPass(thread_db* tdbb, Request* request) const
{ {
dsc* desc = NULL; dsc* desc = NULL;
@ -435,7 +435,7 @@ bool AggNode::aggPass(thread_db* tdbb, jrd_req* request) const
return true; return true;
} }
void AggNode::aggFinish(thread_db* /*tdbb*/, jrd_req* request) const void AggNode::aggFinish(thread_db* /*tdbb*/, Request* request) const
{ {
if (asb) if (asb)
{ {
@ -445,7 +445,7 @@ void AggNode::aggFinish(thread_db* /*tdbb*/, jrd_req* request) const
} }
} }
dsc* AggNode::execute(thread_db* tdbb, jrd_req* request) const dsc* AggNode::execute(thread_db* tdbb, Request* request) const
{ {
impure_value_ex* impure = request->getImpure<impure_value_ex>(impureOffset); impure_value_ex* impure = request->getImpure<impure_value_ex>(impureOffset);
@ -685,7 +685,7 @@ string AvgAggNode::internalPrint(NodePrinter& printer) const
return "AvgAggNode"; return "AvgAggNode";
} }
void AvgAggNode::aggInit(thread_db* tdbb, jrd_req* request) const void AvgAggNode::aggInit(thread_db* tdbb, Request* request) const
{ {
AggNode::aggInit(tdbb, request); AggNode::aggInit(tdbb, request);
@ -704,7 +704,7 @@ void AvgAggNode::aggInit(thread_db* tdbb, jrd_req* request) const
} }
} }
void AvgAggNode::aggPass(thread_db* tdbb, jrd_req* request, dsc* desc) const void AvgAggNode::aggPass(thread_db* tdbb, Request* request, dsc* desc) const
{ {
impure_value_ex* impure = request->getImpure<impure_value_ex>(impureOffset); impure_value_ex* impure = request->getImpure<impure_value_ex>(impureOffset);
if (impure->vlux_count++ == 0) // first call to aggPass() if (impure->vlux_count++ == 0) // first call to aggPass()
@ -720,7 +720,7 @@ void AvgAggNode::aggPass(thread_db* tdbb, jrd_req* request, dsc* desc) const
ArithmeticNode::add2(tdbb, desc, impure, this, blr_add); ArithmeticNode::add2(tdbb, desc, impure, this, blr_add);
} }
dsc* AvgAggNode::aggExecute(thread_db* tdbb, jrd_req* request) const dsc* AvgAggNode::aggExecute(thread_db* tdbb, Request* request) const
{ {
impure_value_ex* impure = request->getImpure<impure_value_ex>(impureOffset); impure_value_ex* impure = request->getImpure<impure_value_ex>(impureOffset);
@ -848,7 +848,7 @@ string ListAggNode::internalPrint(NodePrinter& printer) const
return "ListAggNode"; return "ListAggNode";
} }
void ListAggNode::aggInit(thread_db* tdbb, jrd_req* request) const void ListAggNode::aggInit(thread_db* tdbb, Request* request) const
{ {
AggNode::aggInit(tdbb, request); AggNode::aggInit(tdbb, request);
@ -859,7 +859,7 @@ void ListAggNode::aggInit(thread_db* tdbb, jrd_req* request) const
impure->vlu_desc.dsc_dtype = 0; impure->vlu_desc.dsc_dtype = 0;
} }
void ListAggNode::aggPass(thread_db* tdbb, jrd_req* request, dsc* desc) const void ListAggNode::aggPass(thread_db* tdbb, Request* request, dsc* desc) const
{ {
impure_value_ex* impure = request->getImpure<impure_value_ex>(impureOffset); impure_value_ex* impure = request->getImpure<impure_value_ex>(impureOffset);
@ -897,7 +897,7 @@ void ListAggNode::aggPass(thread_db* tdbb, jrd_req* request, dsc* desc) const
impure->vlu_blob->BLB_put_data(tdbb, temp, len); impure->vlu_blob->BLB_put_data(tdbb, temp, len);
} }
dsc* ListAggNode::aggExecute(thread_db* tdbb, jrd_req* request) const dsc* ListAggNode::aggExecute(thread_db* tdbb, Request* request) const
{ {
impure_value_ex* impure = request->getImpure<impure_value_ex>(impureOffset); impure_value_ex* impure = request->getImpure<impure_value_ex>(impureOffset);
@ -1000,7 +1000,7 @@ string CountAggNode::internalPrint(NodePrinter& printer) const
} }
//// TODO: Improve count(*) in local tables. //// TODO: Improve count(*) in local tables.
void CountAggNode::aggInit(thread_db* tdbb, jrd_req* request) const void CountAggNode::aggInit(thread_db* tdbb, Request* request) const
{ {
AggNode::aggInit(tdbb, request); AggNode::aggInit(tdbb, request);
@ -1008,7 +1008,7 @@ void CountAggNode::aggInit(thread_db* tdbb, jrd_req* request) const
impure->make_int64(0); impure->make_int64(0);
} }
void CountAggNode::aggPass(thread_db* /*tdbb*/, jrd_req* request, dsc* /*desc*/) const void CountAggNode::aggPass(thread_db* /*tdbb*/, Request* request, dsc* /*desc*/) const
{ {
impure_value_ex* impure = request->getImpure<impure_value_ex>(impureOffset); impure_value_ex* impure = request->getImpure<impure_value_ex>(impureOffset);
@ -1018,7 +1018,7 @@ void CountAggNode::aggPass(thread_db* /*tdbb*/, jrd_req* request, dsc* /*desc*/)
++impure->vlu_misc.vlu_int64; ++impure->vlu_misc.vlu_int64;
} }
dsc* CountAggNode::aggExecute(thread_db* /*tdbb*/, jrd_req* request) const dsc* CountAggNode::aggExecute(thread_db* /*tdbb*/, Request* request) const
{ {
impure_value_ex* impure = request->getImpure<impure_value_ex>(impureOffset); impure_value_ex* impure = request->getImpure<impure_value_ex>(impureOffset);
@ -1253,7 +1253,7 @@ string SumAggNode::internalPrint(NodePrinter& printer) const
return "SumAggNode"; return "SumAggNode";
} }
void SumAggNode::aggInit(thread_db* tdbb, jrd_req* request) const void SumAggNode::aggInit(thread_db* tdbb, Request* request) const
{ {
AggNode::aggInit(tdbb, request); AggNode::aggInit(tdbb, request);
@ -1269,7 +1269,7 @@ void SumAggNode::aggInit(thread_db* tdbb, jrd_req* request) const
} }
} }
void SumAggNode::aggPass(thread_db* tdbb, jrd_req* request, dsc* desc) const void SumAggNode::aggPass(thread_db* tdbb, Request* request, dsc* desc) const
{ {
impure_value_ex* impure = request->getImpure<impure_value_ex>(impureOffset); impure_value_ex* impure = request->getImpure<impure_value_ex>(impureOffset);
++impure->vlux_count; ++impure->vlux_count;
@ -1280,7 +1280,7 @@ void SumAggNode::aggPass(thread_db* tdbb, jrd_req* request, dsc* desc) const
ArithmeticNode::add2(tdbb, desc, impure, this, blr_add); ArithmeticNode::add2(tdbb, desc, impure, this, blr_add);
} }
dsc* SumAggNode::aggExecute(thread_db* /*tdbb*/, jrd_req* request) const dsc* SumAggNode::aggExecute(thread_db* /*tdbb*/, Request* request) const
{ {
impure_value_ex* impure = request->getImpure<impure_value_ex>(impureOffset); impure_value_ex* impure = request->getImpure<impure_value_ex>(impureOffset);
@ -1345,7 +1345,7 @@ string MaxMinAggNode::internalPrint(NodePrinter& printer) const
return "MaxMinAggNode"; return "MaxMinAggNode";
} }
void MaxMinAggNode::aggInit(thread_db* tdbb, jrd_req* request) const void MaxMinAggNode::aggInit(thread_db* tdbb, Request* request) const
{ {
AggNode::aggInit(tdbb, request); AggNode::aggInit(tdbb, request);
@ -1353,7 +1353,7 @@ void MaxMinAggNode::aggInit(thread_db* tdbb, jrd_req* request) const
impure->vlu_desc.dsc_dtype = 0; impure->vlu_desc.dsc_dtype = 0;
} }
void MaxMinAggNode::aggPass(thread_db* tdbb, jrd_req* request, dsc* desc) const void MaxMinAggNode::aggPass(thread_db* tdbb, Request* request, dsc* desc) const
{ {
impure_value_ex* impure = request->getImpure<impure_value_ex>(impureOffset); impure_value_ex* impure = request->getImpure<impure_value_ex>(impureOffset);
++impure->vlux_count; ++impure->vlux_count;
@ -1370,7 +1370,7 @@ void MaxMinAggNode::aggPass(thread_db* tdbb, jrd_req* request, dsc* desc) const
EVL_make_value(tdbb, desc, impure); EVL_make_value(tdbb, desc, impure);
} }
dsc* MaxMinAggNode::aggExecute(thread_db* /*tdbb*/, jrd_req* request) const dsc* MaxMinAggNode::aggExecute(thread_db* /*tdbb*/, Request* request) const
{ {
impure_value_ex* impure = request->getImpure<impure_value_ex>(impureOffset); impure_value_ex* impure = request->getImpure<impure_value_ex>(impureOffset);
@ -1472,7 +1472,7 @@ string StdDevAggNode::internalPrint(NodePrinter& printer) const
return "StdDevAggNode"; return "StdDevAggNode";
} }
void StdDevAggNode::aggInit(thread_db* tdbb, jrd_req* request) const void StdDevAggNode::aggInit(thread_db* tdbb, Request* request) const
{ {
AggNode::aggInit(tdbb, request); AggNode::aggInit(tdbb, request);
@ -1491,7 +1491,7 @@ void StdDevAggNode::aggInit(thread_db* tdbb, jrd_req* request) const
} }
} }
void StdDevAggNode::aggPass(thread_db* tdbb, jrd_req* request, dsc* desc) const void StdDevAggNode::aggPass(thread_db* tdbb, Request* request, dsc* desc) const
{ {
impure_value_ex* impure = request->getImpure<impure_value_ex>(impureOffset); impure_value_ex* impure = request->getImpure<impure_value_ex>(impureOffset);
++impure->vlux_count; ++impure->vlux_count;
@ -1514,7 +1514,7 @@ void StdDevAggNode::aggPass(thread_db* tdbb, jrd_req* request, dsc* desc) const
} }
} }
dsc* StdDevAggNode::aggExecute(thread_db* tdbb, jrd_req* request) const dsc* StdDevAggNode::aggExecute(thread_db* tdbb, Request* request) const
{ {
impure_value_ex* impure = request->getImpure<impure_value_ex>(impureOffset); impure_value_ex* impure = request->getImpure<impure_value_ex>(impureOffset);
StdDevImpure* impure2 = request->getImpure<StdDevImpure>(impure2Offset); StdDevImpure* impure2 = request->getImpure<StdDevImpure>(impure2Offset);
@ -1681,7 +1681,7 @@ string CorrAggNode::internalPrint(NodePrinter& printer) const
return "CorrAggNode"; return "CorrAggNode";
} }
void CorrAggNode::aggInit(thread_db* tdbb, jrd_req* request) const void CorrAggNode::aggInit(thread_db* tdbb, Request* request) const
{ {
AggNode::aggInit(tdbb, request); AggNode::aggInit(tdbb, request);
@ -1700,7 +1700,7 @@ void CorrAggNode::aggInit(thread_db* tdbb, jrd_req* request) const
} }
} }
bool CorrAggNode::aggPass(thread_db* tdbb, jrd_req* request) const bool CorrAggNode::aggPass(thread_db* tdbb, Request* request) const
{ {
impure_value_ex* impure = request->getImpure<impure_value_ex>(impureOffset); impure_value_ex* impure = request->getImpure<impure_value_ex>(impureOffset);
@ -1744,12 +1744,12 @@ bool CorrAggNode::aggPass(thread_db* tdbb, jrd_req* request) const
return true; return true;
} }
void CorrAggNode::aggPass(thread_db* /*tdbb*/, jrd_req* /*request*/, dsc* /*desc*/) const void CorrAggNode::aggPass(thread_db* /*tdbb*/, Request* /*request*/, dsc* /*desc*/) const
{ {
fb_assert(false); fb_assert(false);
} }
dsc* CorrAggNode::aggExecute(thread_db* tdbb, jrd_req* request) const dsc* CorrAggNode::aggExecute(thread_db* tdbb, Request* request) const
{ {
impure_value_ex* impure = request->getImpure<impure_value_ex>(impureOffset); impure_value_ex* impure = request->getImpure<impure_value_ex>(impureOffset);
CorrImpure* impure2 = request->getImpure<CorrImpure>(impure2Offset); CorrImpure* impure2 = request->getImpure<CorrImpure>(impure2Offset);
@ -1957,7 +1957,7 @@ string RegrAggNode::internalPrint(NodePrinter& printer) const
return "RegrAggNode"; return "RegrAggNode";
} }
void RegrAggNode::aggInit(thread_db* tdbb, jrd_req* request) const void RegrAggNode::aggInit(thread_db* tdbb, Request* request) const
{ {
AggNode::aggInit(tdbb, request); AggNode::aggInit(tdbb, request);
@ -1976,7 +1976,7 @@ void RegrAggNode::aggInit(thread_db* tdbb, jrd_req* request) const
} }
} }
bool RegrAggNode::aggPass(thread_db* tdbb, jrd_req* request) const bool RegrAggNode::aggPass(thread_db* tdbb, Request* request) const
{ {
impure_value_ex* impure = request->getImpure<impure_value_ex>(impureOffset); impure_value_ex* impure = request->getImpure<impure_value_ex>(impureOffset);
@ -2021,12 +2021,12 @@ bool RegrAggNode::aggPass(thread_db* tdbb, jrd_req* request) const
return true; return true;
} }
void RegrAggNode::aggPass(thread_db* /*tdbb*/, jrd_req* /*request*/, dsc* /*desc*/) const void RegrAggNode::aggPass(thread_db* /*tdbb*/, Request* /*request*/, dsc* /*desc*/) const
{ {
fb_assert(false); fb_assert(false);
} }
dsc* RegrAggNode::aggExecute(thread_db* tdbb, jrd_req* request) const dsc* RegrAggNode::aggExecute(thread_db* tdbb, Request* request) const
{ {
impure_value_ex* impure = request->getImpure<impure_value_ex>(impureOffset); impure_value_ex* impure = request->getImpure<impure_value_ex>(impureOffset);
@ -2226,7 +2226,7 @@ string RegrCountAggNode::internalPrint(NodePrinter& printer) const
return "RegrCountAggNode"; return "RegrCountAggNode";
} }
void RegrCountAggNode::aggInit(thread_db* tdbb, jrd_req* request) const void RegrCountAggNode::aggInit(thread_db* tdbb, Request* request) const
{ {
AggNode::aggInit(tdbb, request); AggNode::aggInit(tdbb, request);
@ -2234,7 +2234,7 @@ void RegrCountAggNode::aggInit(thread_db* tdbb, jrd_req* request) const
impure->make_int64(0); impure->make_int64(0);
} }
bool RegrCountAggNode::aggPass(thread_db* tdbb, jrd_req* request) const bool RegrCountAggNode::aggPass(thread_db* tdbb, Request* request) const
{ {
EVL_expr(tdbb, request, arg); EVL_expr(tdbb, request, arg);
if (request->req_flags & req_null) if (request->req_flags & req_null)
@ -2250,12 +2250,12 @@ bool RegrCountAggNode::aggPass(thread_db* tdbb, jrd_req* request) const
return true; return true;
} }
void RegrCountAggNode::aggPass(thread_db* /*tdbb*/, jrd_req* /*request*/, dsc* /*desc*/) const void RegrCountAggNode::aggPass(thread_db* /*tdbb*/, Request* /*request*/, dsc* /*desc*/) const
{ {
fb_assert(false); fb_assert(false);
} }
dsc* RegrCountAggNode::aggExecute(thread_db* tdbb, jrd_req* request) const dsc* RegrCountAggNode::aggExecute(thread_db* tdbb, Request* request) const
{ {
impure_value_ex* impure = request->getImpure<impure_value_ex>(impureOffset); impure_value_ex* impure = request->getImpure<impure_value_ex>(impureOffset);

View File

@ -30,7 +30,7 @@
namespace Jrd { namespace Jrd {
class AvgAggNode : public AggNode class AvgAggNode final : public AggNode
{ {
public: public:
explicit AvgAggNode(MemoryPool& pool, bool aDistinct, bool aDialect1, ValueExprNode* aArg = NULL); explicit AvgAggNode(MemoryPool& pool, bool aDistinct, bool aDialect1, ValueExprNode* aArg = NULL);
@ -53,9 +53,9 @@ public:
virtual ValueExprNode* copy(thread_db* tdbb, NodeCopier& copier) const; virtual ValueExprNode* copy(thread_db* tdbb, NodeCopier& copier) const;
virtual AggNode* pass2(thread_db* tdbb, CompilerScratch* csb); virtual AggNode* pass2(thread_db* tdbb, CompilerScratch* csb);
virtual void aggInit(thread_db* tdbb, jrd_req* request) const; virtual void aggInit(thread_db* tdbb, Request* request) const;
virtual void aggPass(thread_db* tdbb, jrd_req* request, dsc* desc) const; virtual void aggPass(thread_db* tdbb, Request* request, dsc* desc) const;
virtual dsc* aggExecute(thread_db* tdbb, jrd_req* request) const; virtual dsc* aggExecute(thread_db* tdbb, Request* request) const;
protected: protected:
virtual AggNode* dsqlCopy(DsqlCompilerScratch* dsqlScratch) /*const*/; virtual AggNode* dsqlCopy(DsqlCompilerScratch* dsqlScratch) /*const*/;
@ -65,7 +65,7 @@ private:
ULONG tempImpure; ULONG tempImpure;
}; };
class ListAggNode : public AggNode class ListAggNode final : public AggNode
{ {
public: public:
explicit ListAggNode(MemoryPool& pool, bool aDistinct, ValueExprNode* aArg = NULL, explicit ListAggNode(MemoryPool& pool, bool aDistinct, ValueExprNode* aArg = NULL,
@ -91,9 +91,9 @@ public:
virtual void getDesc(thread_db* tdbb, CompilerScratch* csb, dsc* desc); virtual void getDesc(thread_db* tdbb, CompilerScratch* csb, dsc* desc);
virtual ValueExprNode* copy(thread_db* tdbb, NodeCopier& copier) const; virtual ValueExprNode* copy(thread_db* tdbb, NodeCopier& copier) const;
virtual void aggInit(thread_db* tdbb, jrd_req* request) const; virtual void aggInit(thread_db* tdbb, Request* request) const;
virtual void aggPass(thread_db* tdbb, jrd_req* request, dsc* desc) const; virtual void aggPass(thread_db* tdbb, Request* request, dsc* desc) const;
virtual dsc* aggExecute(thread_db* tdbb, jrd_req* request) const; virtual dsc* aggExecute(thread_db* tdbb, Request* request) const;
protected: protected:
virtual AggNode* dsqlCopy(DsqlCompilerScratch* dsqlScratch) /*const*/; virtual AggNode* dsqlCopy(DsqlCompilerScratch* dsqlScratch) /*const*/;
@ -102,7 +102,7 @@ private:
NestConst<ValueExprNode> delimiter; NestConst<ValueExprNode> delimiter;
}; };
class CountAggNode : public AggNode class CountAggNode final : public AggNode
{ {
public: public:
explicit CountAggNode(MemoryPool& pool, bool aDistinct, bool aDialect1, ValueExprNode* aArg = NULL); explicit CountAggNode(MemoryPool& pool, bool aDistinct, bool aDialect1, ValueExprNode* aArg = NULL);
@ -120,15 +120,15 @@ public:
virtual void getDesc(thread_db* tdbb, CompilerScratch* csb, dsc* desc); virtual void getDesc(thread_db* tdbb, CompilerScratch* csb, dsc* desc);
virtual ValueExprNode* copy(thread_db* tdbb, NodeCopier& copier) const; virtual ValueExprNode* copy(thread_db* tdbb, NodeCopier& copier) const;
virtual void aggInit(thread_db* tdbb, jrd_req* request) const; virtual void aggInit(thread_db* tdbb, Request* request) const;
virtual void aggPass(thread_db* tdbb, jrd_req* request, dsc* desc) const; virtual void aggPass(thread_db* tdbb, Request* request, dsc* desc) const;
virtual dsc* aggExecute(thread_db* tdbb, jrd_req* request) const; virtual dsc* aggExecute(thread_db* tdbb, Request* request) const;
protected: protected:
virtual AggNode* dsqlCopy(DsqlCompilerScratch* dsqlScratch) /*const*/; virtual AggNode* dsqlCopy(DsqlCompilerScratch* dsqlScratch) /*const*/;
}; };
class SumAggNode : public AggNode class SumAggNode final : public AggNode
{ {
public: public:
explicit SumAggNode(MemoryPool& pool, bool aDistinct, bool aDialect1, ValueExprNode* aArg = NULL); explicit SumAggNode(MemoryPool& pool, bool aDistinct, bool aDialect1, ValueExprNode* aArg = NULL);
@ -150,15 +150,15 @@ public:
virtual void getDesc(thread_db* tdbb, CompilerScratch* csb, dsc* desc); virtual void getDesc(thread_db* tdbb, CompilerScratch* csb, dsc* desc);
virtual ValueExprNode* copy(thread_db* tdbb, NodeCopier& copier) const; virtual ValueExprNode* copy(thread_db* tdbb, NodeCopier& copier) const;
virtual void aggInit(thread_db* tdbb, jrd_req* request) const; virtual void aggInit(thread_db* tdbb, Request* request) const;
virtual void aggPass(thread_db* tdbb, jrd_req* request, dsc* desc) const; virtual void aggPass(thread_db* tdbb, Request* request, dsc* desc) const;
virtual dsc* aggExecute(thread_db* tdbb, jrd_req* request) const; virtual dsc* aggExecute(thread_db* tdbb, Request* request) const;
protected: protected:
virtual AggNode* dsqlCopy(DsqlCompilerScratch* dsqlScratch) /*const*/; virtual AggNode* dsqlCopy(DsqlCompilerScratch* dsqlScratch) /*const*/;
}; };
class MaxMinAggNode : public AggNode class MaxMinAggNode final : public AggNode
{ {
public: public:
enum MaxMinType enum MaxMinType
@ -181,9 +181,9 @@ public:
virtual void getDesc(thread_db* tdbb, CompilerScratch* csb, dsc* desc); virtual void getDesc(thread_db* tdbb, CompilerScratch* csb, dsc* desc);
virtual ValueExprNode* copy(thread_db* tdbb, NodeCopier& copier) const; virtual ValueExprNode* copy(thread_db* tdbb, NodeCopier& copier) const;
virtual void aggInit(thread_db* tdbb, jrd_req* request) const; virtual void aggInit(thread_db* tdbb, Request* request) const;
virtual void aggPass(thread_db* tdbb, jrd_req* request, dsc* desc) const; virtual void aggPass(thread_db* tdbb, Request* request, dsc* desc) const;
virtual dsc* aggExecute(thread_db* tdbb, jrd_req* request) const; virtual dsc* aggExecute(thread_db* tdbb, Request* request) const;
protected: protected:
virtual AggNode* dsqlCopy(DsqlCompilerScratch* dsqlScratch) /*const*/; virtual AggNode* dsqlCopy(DsqlCompilerScratch* dsqlScratch) /*const*/;
@ -192,7 +192,7 @@ public:
const MaxMinType type; const MaxMinType type;
}; };
class StdDevAggNode : public AggNode class StdDevAggNode final : public AggNode
{ {
public: public:
enum StdDevType enum StdDevType
@ -230,9 +230,9 @@ public:
virtual ValueExprNode* copy(thread_db* tdbb, NodeCopier& copier) const; virtual ValueExprNode* copy(thread_db* tdbb, NodeCopier& copier) const;
virtual AggNode* pass2(thread_db* tdbb, CompilerScratch* csb); virtual AggNode* pass2(thread_db* tdbb, CompilerScratch* csb);
virtual void aggInit(thread_db* tdbb, jrd_req* request) const; virtual void aggInit(thread_db* tdbb, Request* request) const;
virtual void aggPass(thread_db* tdbb, jrd_req* request, dsc* desc) const; virtual void aggPass(thread_db* tdbb, Request* request, dsc* desc) const;
virtual dsc* aggExecute(thread_db* tdbb, jrd_req* request) const; virtual dsc* aggExecute(thread_db* tdbb, Request* request) const;
protected: protected:
virtual AggNode* dsqlCopy(DsqlCompilerScratch* dsqlScratch) /*const*/; virtual AggNode* dsqlCopy(DsqlCompilerScratch* dsqlScratch) /*const*/;
@ -244,7 +244,7 @@ private:
ULONG impure2Offset; ULONG impure2Offset;
}; };
class CorrAggNode : public AggNode class CorrAggNode final : public AggNode
{ {
public: public:
enum CorrType enum CorrType
@ -288,10 +288,10 @@ public:
virtual ValueExprNode* copy(thread_db* tdbb, NodeCopier& copier) const; virtual ValueExprNode* copy(thread_db* tdbb, NodeCopier& copier) const;
virtual AggNode* pass2(thread_db* tdbb, CompilerScratch* csb); virtual AggNode* pass2(thread_db* tdbb, CompilerScratch* csb);
virtual void aggInit(thread_db* tdbb, jrd_req* request) const; virtual void aggInit(thread_db* tdbb, Request* request) const;
virtual bool aggPass(thread_db* tdbb, jrd_req* request) const; virtual bool aggPass(thread_db* tdbb, Request* request) const;
virtual void aggPass(thread_db* tdbb, jrd_req* request, dsc* desc) const; virtual void aggPass(thread_db* tdbb, Request* request, dsc* desc) const;
virtual dsc* aggExecute(thread_db* tdbb, jrd_req* request) const; virtual dsc* aggExecute(thread_db* tdbb, Request* request) const;
protected: protected:
virtual AggNode* dsqlCopy(DsqlCompilerScratch* dsqlScratch) /*const*/; virtual AggNode* dsqlCopy(DsqlCompilerScratch* dsqlScratch) /*const*/;
@ -304,7 +304,7 @@ private:
ULONG impure2Offset; ULONG impure2Offset;
}; };
class RegrAggNode : public AggNode class RegrAggNode final : public AggNode
{ {
public: public:
enum RegrType enum RegrType
@ -353,10 +353,10 @@ public:
virtual ValueExprNode* copy(thread_db* tdbb, NodeCopier& copier) const; virtual ValueExprNode* copy(thread_db* tdbb, NodeCopier& copier) const;
virtual AggNode* pass2(thread_db* tdbb, CompilerScratch* csb); virtual AggNode* pass2(thread_db* tdbb, CompilerScratch* csb);
virtual void aggInit(thread_db* tdbb, jrd_req* request) const; virtual void aggInit(thread_db* tdbb, Request* request) const;
virtual bool aggPass(thread_db* tdbb, jrd_req* request) const; virtual bool aggPass(thread_db* tdbb, Request* request) const;
virtual void aggPass(thread_db* tdbb, jrd_req* request, dsc* desc) const; virtual void aggPass(thread_db* tdbb, Request* request, dsc* desc) const;
virtual dsc* aggExecute(thread_db* tdbb, jrd_req* request) const; virtual dsc* aggExecute(thread_db* tdbb, Request* request) const;
protected: protected:
virtual AggNode* dsqlCopy(DsqlCompilerScratch* dsqlScratch) /*const*/; virtual AggNode* dsqlCopy(DsqlCompilerScratch* dsqlScratch) /*const*/;
@ -369,7 +369,7 @@ private:
ULONG impure2Offset; ULONG impure2Offset;
}; };
class RegrCountAggNode : public AggNode class RegrCountAggNode final : public AggNode
{ {
public: public:
explicit RegrCountAggNode(MemoryPool& pool, explicit RegrCountAggNode(MemoryPool& pool,
@ -393,10 +393,10 @@ public:
virtual void getDesc(thread_db* tdbb, CompilerScratch* csb, dsc* desc); virtual void getDesc(thread_db* tdbb, CompilerScratch* csb, dsc* desc);
virtual ValueExprNode* copy(thread_db* tdbb, NodeCopier& copier) const; virtual ValueExprNode* copy(thread_db* tdbb, NodeCopier& copier) const;
virtual void aggInit(thread_db* tdbb, jrd_req* request) const; virtual void aggInit(thread_db* tdbb, Request* request) const;
virtual bool aggPass(thread_db* tdbb, jrd_req* request) const; virtual bool aggPass(thread_db* tdbb, Request* request) const;
virtual void aggPass(thread_db* tdbb, jrd_req* request, dsc* desc) const; virtual void aggPass(thread_db* tdbb, Request* request, dsc* desc) const;
virtual dsc* aggExecute(thread_db* tdbb, jrd_req* request) const; virtual dsc* aggExecute(thread_db* tdbb, Request* request) const;
protected: protected:
virtual AggNode* dsqlCopy(DsqlCompilerScratch* dsqlScratch) /*const*/; virtual AggNode* dsqlCopy(DsqlCompilerScratch* dsqlScratch) /*const*/;

View File

@ -28,7 +28,7 @@
#include "../jrd/tra.h" #include "../jrd/tra.h"
#include "../jrd/recsrc/RecordSource.h" #include "../jrd/recsrc/RecordSource.h"
#include "../jrd/recsrc/Cursor.h" #include "../jrd/recsrc/Cursor.h"
#include "../jrd/Optimizer.h" #include "../jrd/optimizer/Optimizer.h"
#include "../jrd/blb_proto.h" #include "../jrd/blb_proto.h"
#include "../jrd/cmp_proto.h" #include "../jrd/cmp_proto.h"
#include "../jrd/evl_proto.h" #include "../jrd/evl_proto.h"
@ -170,7 +170,7 @@ BoolExprNode* BinaryBoolNode::copy(thread_db* tdbb, NodeCopier& copier) const
return node; return node;
} }
bool BinaryBoolNode::execute(thread_db* tdbb, jrd_req* request) const bool BinaryBoolNode::execute(thread_db* tdbb, Request* request) const
{ {
switch (blrOp) switch (blrOp)
{ {
@ -185,7 +185,7 @@ bool BinaryBoolNode::execute(thread_db* tdbb, jrd_req* request) const
return false; return false;
} }
bool BinaryBoolNode::executeAnd(thread_db* tdbb, jrd_req* request) const bool BinaryBoolNode::executeAnd(thread_db* tdbb, Request* request) const
{ {
// If either operand is false, then the result is false; // If either operand is false, then the result is false;
// If both are true, the result is true; // If both are true, the result is true;
@ -231,7 +231,7 @@ bool BinaryBoolNode::executeAnd(thread_db* tdbb, jrd_req* request) const
return false; return false;
} }
bool BinaryBoolNode::executeOr(thread_db* tdbb, jrd_req* request) const bool BinaryBoolNode::executeOr(thread_db* tdbb, Request* request) const
{ {
// If either operand is true, then the result is true; // If either operand is true, then the result is true;
// If both are false, the result is false; // If both are false, the result is false;
@ -643,7 +643,7 @@ void ComparativeBoolNode::pass2Boolean2(thread_db* tdbb, CompilerScratch* csb)
} }
} }
bool ComparativeBoolNode::execute(thread_db* tdbb, jrd_req* request) const bool ComparativeBoolNode::execute(thread_db* tdbb, Request* request) const
{ {
dsc* desc[2] = {NULL, NULL}; dsc* desc[2] = {NULL, NULL};
bool computed_invariant = false; bool computed_invariant = false;
@ -817,7 +817,7 @@ bool ComparativeBoolNode::execute(thread_db* tdbb, jrd_req* request) const
} }
// Perform one of the complex string functions CONTAINING, MATCHES, or STARTS WITH. // Perform one of the complex string functions CONTAINING, MATCHES, or STARTS WITH.
bool ComparativeBoolNode::stringBoolean(thread_db* tdbb, jrd_req* request, dsc* desc1, bool ComparativeBoolNode::stringBoolean(thread_db* tdbb, Request* request, dsc* desc1,
dsc* desc2, bool computedInvariant) const dsc* desc2, bool computedInvariant) const
{ {
SET_TDBB(tdbb); SET_TDBB(tdbb);
@ -1023,7 +1023,7 @@ bool ComparativeBoolNode::stringBoolean(thread_db* tdbb, jrd_req* request, dsc*
} }
// Execute SLEUTH operator. // Execute SLEUTH operator.
bool ComparativeBoolNode::sleuth(thread_db* tdbb, jrd_req* request, const dsc* desc1, bool ComparativeBoolNode::sleuth(thread_db* tdbb, Request* request, const dsc* desc1,
const dsc* desc2) const const dsc* desc2) const
{ {
SET_TDBB(tdbb); SET_TDBB(tdbb);
@ -1223,7 +1223,7 @@ void MissingBoolNode::pass2Boolean2(thread_db* tdbb, CompilerScratch* csb)
arg->getDesc(tdbb, csb, &descriptor_a); arg->getDesc(tdbb, csb, &descriptor_a);
} }
bool MissingBoolNode::execute(thread_db* tdbb, jrd_req* request) const bool MissingBoolNode::execute(thread_db* tdbb, Request* request) const
{ {
EVL_expr(tdbb, request, arg); EVL_expr(tdbb, request, arg);
@ -1298,7 +1298,7 @@ BoolExprNode* NotBoolNode::pass1(thread_db* tdbb, CompilerScratch* csb)
return BoolExprNode::pass1(tdbb, csb); return BoolExprNode::pass1(tdbb, csb);
} }
bool NotBoolNode::execute(thread_db* tdbb, jrd_req* request) const bool NotBoolNode::execute(thread_db* tdbb, Request* request) const
{ {
bool value = arg->execute(tdbb, request); bool value = arg->execute(tdbb, request);
@ -1612,7 +1612,7 @@ void RseBoolNode::pass2Boolean2(thread_db* tdbb, CompilerScratch* csb)
subQuery = FB_NEW_POOL(*tdbb->getDefaultPool()) SubQuery(rsb, rse->rse_invariants); subQuery = FB_NEW_POOL(*tdbb->getDefaultPool()) SubQuery(rsb, rse->rse_invariants);
} }
bool RseBoolNode::execute(thread_db* tdbb, jrd_req* request) const bool RseBoolNode::execute(thread_db* tdbb, Request* request) const
{ {
USHORT* invariant_flags; USHORT* invariant_flags;
impure_value* impure; impure_value* impure;

View File

@ -31,7 +31,7 @@ namespace Jrd {
class SubQuery; class SubQuery;
class BinaryBoolNode : public TypedNode<BoolExprNode, ExprNode::TYPE_BINARY_BOOL> class BinaryBoolNode final : public TypedNode<BoolExprNode, ExprNode::TYPE_BINARY_BOOL>
{ {
public: public:
BinaryBoolNode(MemoryPool& pool, UCHAR aBlrOp, BoolExprNode* aArg1 = NULL, BinaryBoolNode(MemoryPool& pool, UCHAR aBlrOp, BoolExprNode* aArg1 = NULL,
@ -54,11 +54,11 @@ public:
virtual BoolExprNode* copy(thread_db* tdbb, NodeCopier& copier) const; virtual BoolExprNode* copy(thread_db* tdbb, NodeCopier& copier) const;
virtual bool dsqlMatch(DsqlCompilerScratch* dsqlScratch, const ExprNode* other, bool ignoreMapCast) const; virtual bool dsqlMatch(DsqlCompilerScratch* dsqlScratch, const ExprNode* other, bool ignoreMapCast) const;
virtual bool sameAs(const ExprNode* other, bool ignoreStreams) const; virtual bool sameAs(const ExprNode* other, bool ignoreStreams) const;
virtual bool execute(thread_db* tdbb, jrd_req* request) const; virtual bool execute(thread_db* tdbb, Request* request) const;
private: private:
virtual bool executeAnd(thread_db* tdbb, jrd_req* request) const; virtual bool executeAnd(thread_db* tdbb, Request* request) const;
virtual bool executeOr(thread_db* tdbb, jrd_req* request) const; virtual bool executeOr(thread_db* tdbb, Request* request) const;
public: public:
UCHAR blrOp; UCHAR blrOp;
@ -67,7 +67,7 @@ public:
}; };
class ComparativeBoolNode : public TypedNode<BoolExprNode, ExprNode::TYPE_COMPARATIVE_BOOL> class ComparativeBoolNode final : public TypedNode<BoolExprNode, ExprNode::TYPE_COMPARATIVE_BOOL>
{ {
public: public:
enum DsqlFlag : UCHAR enum DsqlFlag : UCHAR
@ -106,12 +106,12 @@ public:
virtual BoolExprNode* pass1(thread_db* tdbb, CompilerScratch* csb); virtual BoolExprNode* pass1(thread_db* tdbb, CompilerScratch* csb);
virtual void pass2Boolean1(thread_db* tdbb, CompilerScratch* csb); virtual void pass2Boolean1(thread_db* tdbb, CompilerScratch* csb);
virtual void pass2Boolean2(thread_db* tdbb, CompilerScratch* csb); virtual void pass2Boolean2(thread_db* tdbb, CompilerScratch* csb);
virtual bool execute(thread_db* tdbb, jrd_req* request) const; virtual bool execute(thread_db* tdbb, Request* request) const;
private: private:
bool stringBoolean(thread_db* tdbb, jrd_req* request, dsc* desc1, dsc* desc2, bool stringBoolean(thread_db* tdbb, Request* request, dsc* desc1, dsc* desc2,
bool computedInvariant) const; bool computedInvariant) const;
bool sleuth(thread_db* tdbb, jrd_req* request, const dsc* desc1, const dsc* desc2) const; bool sleuth(thread_db* tdbb, Request* request, const dsc* desc1, const dsc* desc2) const;
BoolExprNode* createRseNode(DsqlCompilerScratch* dsqlScratch, UCHAR rseBlrOp); BoolExprNode* createRseNode(DsqlCompilerScratch* dsqlScratch, UCHAR rseBlrOp);
@ -126,7 +126,7 @@ public:
}; };
class MissingBoolNode : public TypedNode<BoolExprNode, ExprNode::TYPE_MISSING_BOOL> class MissingBoolNode final : public TypedNode<BoolExprNode, ExprNode::TYPE_MISSING_BOOL>
{ {
public: public:
explicit MissingBoolNode(MemoryPool& pool, ValueExprNode* aArg = NULL, bool aDsqlUnknown = false); explicit MissingBoolNode(MemoryPool& pool, ValueExprNode* aArg = NULL, bool aDsqlUnknown = false);
@ -151,7 +151,7 @@ public:
virtual BoolExprNode* copy(thread_db* tdbb, NodeCopier& copier) const; virtual BoolExprNode* copy(thread_db* tdbb, NodeCopier& copier) const;
virtual BoolExprNode* pass1(thread_db* tdbb, CompilerScratch* csb); virtual BoolExprNode* pass1(thread_db* tdbb, CompilerScratch* csb);
virtual void pass2Boolean2(thread_db* tdbb, CompilerScratch* csb); virtual void pass2Boolean2(thread_db* tdbb, CompilerScratch* csb);
virtual bool execute(thread_db* tdbb, jrd_req* request) const; virtual bool execute(thread_db* tdbb, Request* request) const;
public: public:
bool dsqlUnknown; bool dsqlUnknown;
@ -159,7 +159,7 @@ public:
}; };
class NotBoolNode : public TypedNode<BoolExprNode, ExprNode::TYPE_NOT_BOOL> class NotBoolNode final : public TypedNode<BoolExprNode, ExprNode::TYPE_NOT_BOOL>
{ {
public: public:
explicit NotBoolNode(MemoryPool& pool, BoolExprNode* aArg = NULL); explicit NotBoolNode(MemoryPool& pool, BoolExprNode* aArg = NULL);
@ -183,7 +183,7 @@ public:
virtual BoolExprNode* copy(thread_db* tdbb, NodeCopier& copier) const; virtual BoolExprNode* copy(thread_db* tdbb, NodeCopier& copier) const;
virtual BoolExprNode* pass1(thread_db* tdbb, CompilerScratch* csb); virtual BoolExprNode* pass1(thread_db* tdbb, CompilerScratch* csb);
virtual bool execute(thread_db* tdbb, jrd_req* request) const; virtual bool execute(thread_db* tdbb, Request* request) const;
private: private:
BoolExprNode* process(DsqlCompilerScratch* dsqlScratch, bool invert); BoolExprNode* process(DsqlCompilerScratch* dsqlScratch, bool invert);
@ -193,7 +193,7 @@ public:
}; };
class RseBoolNode : public TypedNode<BoolExprNode, ExprNode::TYPE_RSE_BOOL> class RseBoolNode final : public TypedNode<BoolExprNode, ExprNode::TYPE_RSE_BOOL>
{ {
public: public:
RseBoolNode(MemoryPool& pool, UCHAR aBlrOp, RecordSourceNode* aDsqlRse = NULL); RseBoolNode(MemoryPool& pool, UCHAR aBlrOp, RecordSourceNode* aDsqlRse = NULL);
@ -235,7 +235,7 @@ public:
virtual BoolExprNode* pass1(thread_db* tdbb, CompilerScratch* csb); virtual BoolExprNode* pass1(thread_db* tdbb, CompilerScratch* csb);
virtual void pass2Boolean1(thread_db* tdbb, CompilerScratch* csb); virtual void pass2Boolean1(thread_db* tdbb, CompilerScratch* csb);
virtual void pass2Boolean2(thread_db* tdbb, CompilerScratch* csb); virtual void pass2Boolean2(thread_db* tdbb, CompilerScratch* csb);
virtual bool execute(thread_db* tdbb, jrd_req* request) const; virtual bool execute(thread_db* tdbb, Request* request) const;
private: private:
BoolExprNode* convertNeqAllToNotAny(thread_db* tdbb, CompilerScratch* csb); BoolExprNode* convertNeqAllToNotAny(thread_db* tdbb, CompilerScratch* csb);

View File

@ -985,7 +985,7 @@ void DdlNode::executeDdlTrigger(thread_db* tdbb, DsqlCompilerScratch* dsqlScratc
const MetaName& oldNewObjectName) const MetaName& oldNewObjectName)
{ {
executeDdlTrigger(tdbb, transaction, when, action, objectName, oldNewObjectName, executeDdlTrigger(tdbb, transaction, when, action, objectName, oldNewObjectName,
*dsqlScratch->getStatement()->getSqlText()); *dsqlScratch->getDsqlStatement()->getSqlText());
} }
void DdlNode::storeGlobalField(thread_db* tdbb, jrd_tra* transaction, MetaName& name, void DdlNode::storeGlobalField(thread_db* tdbb, jrd_tra* transaction, MetaName& name,
@ -1354,7 +1354,6 @@ void CommentOnNode::checkPermission(thread_db* tdbb, jrd_tra* transaction)
switch (objType) switch (objType)
{ {
case obj_schema:
case obj_database: case obj_database:
SCL_check_database(tdbb, SCL_alter); SCL_check_database(tdbb, SCL_alter);
break; break;
@ -1577,12 +1576,6 @@ void CommentOnNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch,
status << Arg::Gds(isc_dyn_package_not_found) << Arg::Str(objNameStr); status << Arg::Gds(isc_dyn_package_not_found) << Arg::Str(objNameStr);
break; break;
case obj_schema:
tableClause = "rdb$schemas";
columnClause = "rdb$schema_name";
status << Arg::Gds(isc_dyn_schema_not_found) << Arg::Str(objNameStr);
break;
default: default:
fb_assert(false); fb_assert(false);
return; return;
@ -1741,7 +1734,7 @@ void CreateAlterFunctionNode::checkPermission(thread_db* tdbb, jrd_tra* transact
return; return;
} }
SCL_check_create_access(tdbb, SCL_object_function); SCL_check_create_access(tdbb, obj_functions);
} }
void CreateAlterFunctionNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch, void CreateAlterFunctionNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch,
@ -2342,6 +2335,8 @@ void CreateAlterFunctionNode::compile(thread_db* /*tdbb*/, DsqlCompilerScratch*
dsqlScratch->cursorNumber = 0; dsqlScratch->cursorNumber = 0;
StmtNode* stmtNode = body->dsqlPass(dsqlScratch); StmtNode* stmtNode = body->dsqlPass(dsqlScratch);
dsqlScratch->putOuterMaps();
GEN_hidden_variables(dsqlScratch); GEN_hidden_variables(dsqlScratch);
dsqlScratch->appendUChar(blr_stall); dsqlScratch->appendUChar(blr_stall);
@ -2352,7 +2347,7 @@ void CreateAlterFunctionNode::compile(thread_db* /*tdbb*/, DsqlCompilerScratch*
stmtNode->genBlr(dsqlScratch); stmtNode->genBlr(dsqlScratch);
dsqlScratch->getStatement()->setType(DsqlCompiledStatement::TYPE_DDL); dsqlScratch->getDsqlStatement()->setType(DsqlStatement::TYPE_DDL);
dsqlScratch->appendUChar(blr_end); dsqlScratch->appendUChar(blr_end);
dsqlScratch->genReturn(false); dsqlScratch->genReturn(false);
dsqlScratch->appendUChar(blr_end); dsqlScratch->appendUChar(blr_end);
@ -2747,7 +2742,7 @@ void CreateAlterProcedureNode::checkPermission(thread_db* tdbb, jrd_tra* transac
return; return;
} }
SCL_check_create_access(tdbb, SCL_object_procedure); SCL_check_create_access(tdbb, obj_procedures);
} }
void CreateAlterProcedureNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch, void CreateAlterProcedureNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch,
@ -2877,7 +2872,7 @@ bool CreateAlterProcedureNode::executeAlter(thread_db* tdbb, DsqlCompilerScratch
AutoCacheRequest requestHandle(tdbb, drq_m_prcs2, DYN_REQUESTS); AutoCacheRequest requestHandle(tdbb, drq_m_prcs2, DYN_REQUESTS);
bool modified = false; bool modified = false;
DsqlCompiledStatement* statement = dsqlScratch->getStatement(); DsqlStatement* statement = dsqlScratch->getDsqlStatement();
FOR (REQUEST_HANDLE requestHandle TRANSACTION_HANDLE transaction) FOR (REQUEST_HANDLE requestHandle TRANSACTION_HANDLE transaction)
P IN RDB$PROCEDURES P IN RDB$PROCEDURES
@ -2971,7 +2966,7 @@ bool CreateAlterProcedureNode::executeAlter(thread_db* tdbb, DsqlCompilerScratch
P.RDB$PROCEDURE_TYPE.NULL = FALSE; P.RDB$PROCEDURE_TYPE.NULL = FALSE;
P.RDB$PROCEDURE_TYPE = (USHORT) P.RDB$PROCEDURE_TYPE = (USHORT)
(statement->getFlags() & DsqlCompiledStatement::FLAG_SELECTABLE ? (statement->getFlags() & DsqlStatement::FLAG_SELECTABLE ?
prc_selectable : prc_executable); prc_selectable : prc_executable);
} }
} }
@ -3235,6 +3230,8 @@ void CreateAlterProcedureNode::compile(thread_db* /*tdbb*/, DsqlCompilerScratch*
dsqlScratch->cursorNumber = 0; dsqlScratch->cursorNumber = 0;
StmtNode* stmtNode = body->dsqlPass(dsqlScratch); StmtNode* stmtNode = body->dsqlPass(dsqlScratch);
dsqlScratch->putOuterMaps();
GEN_hidden_variables(dsqlScratch); GEN_hidden_variables(dsqlScratch);
dsqlScratch->appendUChar(blr_stall); dsqlScratch->appendUChar(blr_stall);
@ -3245,7 +3242,7 @@ void CreateAlterProcedureNode::compile(thread_db* /*tdbb*/, DsqlCompilerScratch*
stmtNode->genBlr(dsqlScratch); stmtNode->genBlr(dsqlScratch);
dsqlScratch->getStatement()->setType(DsqlCompiledStatement::TYPE_DDL); dsqlScratch->getDsqlStatement()->setType(DsqlStatement::TYPE_DDL);
dsqlScratch->appendUChar(blr_end); dsqlScratch->appendUChar(blr_end);
dsqlScratch->genReturn(true); dsqlScratch->genReturn(true);
dsqlScratch->appendUChar(blr_end); dsqlScratch->appendUChar(blr_end);
@ -3751,6 +3748,8 @@ void CreateAlterTriggerNode::compile(thread_db* /*tdbb*/, DsqlCompilerScratch* d
dsqlScratch->scopeLevel++; dsqlScratch->scopeLevel++;
StmtNode* stmtNode = body->dsqlPass(dsqlScratch); StmtNode* stmtNode = body->dsqlPass(dsqlScratch);
dsqlScratch->putOuterMaps();
GEN_hidden_variables(dsqlScratch); GEN_hidden_variables(dsqlScratch);
// dimitr: I see no reason to deny EXIT command in triggers, // dimitr: I see no reason to deny EXIT command in triggers,
@ -3774,7 +3773,7 @@ void CreateAlterTriggerNode::compile(thread_db* /*tdbb*/, DsqlCompilerScratch* d
// The statement type may have been set incorrectly when parsing // The statement type may have been set incorrectly when parsing
// the trigger actions, so reset it to reflect the fact that this // the trigger actions, so reset it to reflect the fact that this
// is a data definition statement; also reset the ddl node. // is a data definition statement; also reset the ddl node.
dsqlScratch->getStatement()->setType(DsqlCompiledStatement::TYPE_DDL); dsqlScratch->getDsqlStatement()->setType(DsqlStatement::TYPE_DDL);
} }
invalid = false; invalid = false;
@ -3944,7 +3943,7 @@ string CreateCollationNode::internalPrint(NodePrinter& printer) const
void CreateCollationNode::checkPermission(thread_db* tdbb, jrd_tra* transaction) void CreateCollationNode::checkPermission(thread_db* tdbb, jrd_tra* transaction)
{ {
SCL_check_create_access(tdbb, SCL_object_collation); SCL_check_create_access(tdbb, obj_collations);
} }
void CreateCollationNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch, void CreateCollationNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch,
@ -4312,7 +4311,7 @@ string CreateDomainNode::internalPrint(NodePrinter& printer) const
void CreateDomainNode::checkPermission(thread_db* tdbb, jrd_tra* transaction) void CreateDomainNode::checkPermission(thread_db* tdbb, jrd_tra* transaction)
{ {
SCL_check_create_access(tdbb, SCL_object_domain); SCL_check_create_access(tdbb, obj_domains);
} }
void CreateDomainNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch, void CreateDomainNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch,
@ -5450,7 +5449,7 @@ void CreateAlterExceptionNode::checkPermission(thread_db* tdbb, jrd_tra* transac
return; return;
} }
SCL_check_create_access(tdbb, SCL_object_exception); SCL_check_create_access(tdbb, obj_exceptions);
} }
void CreateAlterExceptionNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch, void CreateAlterExceptionNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch,
@ -5657,7 +5656,7 @@ void CreateAlterSequenceNode::checkPermission(thread_db* tdbb, jrd_tra* transact
return; return;
} }
SCL_check_create_access(tdbb, SCL_object_generator); SCL_check_create_access(tdbb, obj_generators);
} }
void CreateAlterSequenceNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch, void CreateAlterSequenceNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch,
@ -5976,8 +5975,13 @@ void DropSequenceNode::deleteIdentity(thread_db* tdbb, jrd_tra* transaction, con
WITH GEN.RDB$GENERATOR_NAME EQ name.c_str() WITH GEN.RDB$GENERATOR_NAME EQ name.c_str()
{ {
ERASE GEN; ERASE GEN;
if (!GEN.RDB$SECURITY_CLASS.NULL)
deleteSecurityClass(tdbb, transaction, GEN.RDB$SECURITY_CLASS);
} }
END_FOR END_FOR
deletePrivilegesByRelName(tdbb, transaction, name, obj_generator);
} }
@ -6746,6 +6750,7 @@ void RelationNode::defineConstraint(thread_db* tdbb, DsqlCompilerScratch* dsqlSc
definition.unique = constraint.type != Constraint::TYPE_FK; definition.unique = constraint.type != Constraint::TYPE_FK;
if (constraint.index->descending) if (constraint.index->descending)
definition.descending = true; definition.descending = true;
definition.inactive = false;
definition.columns = constraint.columns; definition.columns = constraint.columns;
definition.refRelation = constraint.refRelation; definition.refRelation = constraint.refRelation;
definition.refColumns = constraint.refColumns; definition.refColumns = constraint.refColumns;
@ -7389,7 +7394,7 @@ string CreateRelationNode::internalPrint(NodePrinter& printer) const
void CreateRelationNode::checkPermission(thread_db* tdbb, jrd_tra* transaction) void CreateRelationNode::checkPermission(thread_db* tdbb, jrd_tra* transaction)
{ {
SCL_check_create_access(tdbb, SCL_object_table); SCL_check_create_access(tdbb, obj_relations);
} }
void CreateRelationNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch, void CreateRelationNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch,
@ -8669,7 +8674,7 @@ void CreateAlterViewNode::checkPermission(thread_db* tdbb, jrd_tra* transaction)
return; return;
} }
SCL_check_create_access(tdbb, SCL_object_view); SCL_check_create_access(tdbb, obj_views);
} }
void CreateAlterViewNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch, void CreateAlterViewNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch,
@ -9830,6 +9835,7 @@ void CreateIndexNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch,
definition.relation = relation->dsqlName; definition.relation = relation->dsqlName;
definition.unique = unique; definition.unique = unique;
definition.descending = descending; definition.descending = descending;
definition.inactive = false;
if (columns) if (columns)
{ {
@ -10090,7 +10096,7 @@ string CreateFilterNode::internalPrint(NodePrinter& printer) const
void CreateFilterNode::checkPermission(thread_db* tdbb, jrd_tra* transaction) void CreateFilterNode::checkPermission(thread_db* tdbb, jrd_tra* transaction)
{ {
SCL_check_create_access(tdbb, SCL_object_filter); SCL_check_create_access(tdbb, obj_filters);
} }
// Define a blob filter. // Define a blob filter.
@ -10346,7 +10352,7 @@ string CreateAlterRoleNode::internalPrint(NodePrinter& printer) const
void CreateAlterRoleNode::checkPermission(thread_db* tdbb, jrd_tra* transaction) void CreateAlterRoleNode::checkPermission(thread_db* tdbb, jrd_tra* transaction)
{ {
if (createFlag) if (createFlag)
SCL_check_create_access(tdbb, SCL_object_role); SCL_check_create_access(tdbb, obj_roles);
else else
SCL_check_role(tdbb, name, SCL_alter); SCL_check_role(tdbb, name, SCL_alter);
} }
@ -10734,7 +10740,7 @@ void MappingNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch, jrd
(Arg::Gds(isc_adm_task_denied) << Arg::Gds(isc_miss_prvlg) << "CHANGE_MAPPING_RULES").raise(); (Arg::Gds(isc_adm_task_denied) << Arg::Gds(isc_miss_prvlg) << "CHANGE_MAPPING_RULES").raise();
if (from) if (from)
fromUtf8 = from->toUtf8(dsqlScratch); fromUtf8 = from->toUtf8(transaction);
if (global) if (global)
{ {
@ -11512,10 +11518,10 @@ void GrantRevokeNode::grantRevoke(thread_db* tdbb, jrd_tra* transaction, const G
const GranteeClause* userNod, const char* privs, const GranteeClause* userNod, const char* privs,
MetaName field, int options) MetaName field, int options)
{ {
SSHORT userType = userNod->first; ObjectType userType = userNod->first;
MetaName user(userNod->second); MetaName user(userNod->second);
MetaName dummyName; MetaName dummyName;
const SSHORT objType = object ? object->first : obj_type_MAX; const ObjectType objType = object ? object->first : obj_type_MAX;
const MetaName objName(object ? object->second : ""); const MetaName objName(object ? object->second : "");
bool crdb = false; bool crdb = false;
@ -11667,7 +11673,7 @@ void GrantRevokeNode::grantRevoke(thread_db* tdbb, jrd_tra* transaction, const G
break; break;
default: default:
fb_assert(object == NULL || objType >= obj_database); fb_assert(object == NULL || isDdlObject(objType));
} }
if (options == 1) // with grant option if (options == 1) // with grant option
@ -11871,10 +11877,8 @@ void GrantRevokeNode::grantRevoke(thread_db* tdbb, jrd_tra* transaction, const G
} }
default: default:
if (objType >= obj_database) if (isDdlObject(objType))
{
checkGrantorCanGrantDdl(tdbb, transaction, currentUser.c_str(), priv, objName); checkGrantorCanGrantDdl(tdbb, transaction, currentUser.c_str(), priv, objName);
}
else else
fb_assert(false); fb_assert(false);
} }
@ -12296,12 +12300,16 @@ void GrantRevokeNode::checkGrantorCanGrantDdl(thread_db* tdbb, jrd_tra* transact
WITH ((PRV.RDB$USER = UPPERCASE(grantor.c_str()) AND WITH ((PRV.RDB$USER = UPPERCASE(grantor.c_str()) AND
PRV.RDB$USER_TYPE = obj_user) OR (PRV.RDB$USER_TYPE = obj_sql_role)) AND PRV.RDB$USER_TYPE = obj_user) OR (PRV.RDB$USER_TYPE = obj_sql_role)) AND
PRV.RDB$RELATION_NAME EQ objName.c_str() AND PRV.RDB$RELATION_NAME EQ objName.c_str() AND
PRV.RDB$OBJECT_TYPE >= obj_database AND PRV.RDB$OBJECT_TYPE >= obj_database AND // it might be deleted but I believe it's more efficient
PRV.RDB$PRIVILEGE EQ privilege PRV.RDB$PRIVILEGE EQ privilege
{ {
if ( (PRV.RDB$USER_TYPE == obj_sql_role) && !attachment->att_user->roleInUse(tdbb, PRV.RDB$USER)) if ( (PRV.RDB$USER_TYPE == obj_sql_role) && !attachment->att_user->roleInUse(tdbb, PRV.RDB$USER))
continue; continue;
// Double check if the object is DDL one.
if (!isDdlObject(PRV.RDB$OBJECT_TYPE))
continue;
if (PRV.RDB$GRANT_OPTION == WITH_GRANT_OPTION) if (PRV.RDB$GRANT_OPTION == WITH_GRANT_OPTION)
{ {
grantable = true; grantable = true;

View File

@ -1129,8 +1129,8 @@ public:
virtual DdlNode* dsqlPass(DsqlCompilerScratch* dsqlScratch) virtual DdlNode* dsqlPass(DsqlCompilerScratch* dsqlScratch)
{ {
dsqlScratch->getStatement()->setType( dsqlScratch->getDsqlStatement()->setType(
legacy ? DsqlCompiledStatement::TYPE_SET_GENERATOR : DsqlCompiledStatement::TYPE_DDL); legacy ? DsqlStatement::TYPE_SET_GENERATOR : DsqlStatement::TYPE_DDL);
return this; return this;
} }
@ -2279,7 +2279,7 @@ typedef RecreateNode<CreateAlterUserNode, DropUserNode, isc_dsql_recreate_user_f
typedef Firebird::Pair<Firebird::NonPooled<char, ValueListNode*> > PrivilegeClause; typedef Firebird::Pair<Firebird::NonPooled<char, ValueListNode*> > PrivilegeClause;
typedef Firebird::Pair<Firebird::NonPooled<SSHORT, MetaName> > GranteeClause; typedef Firebird::Pair<Firebird::NonPooled<ObjectType, MetaName> > GranteeClause;
class GrantRevokeNode : public PrivilegesNode, private ExecInSecurityDb class GrantRevokeNode : public PrivilegesNode, private ExecInSecurityDb
{ {
@ -2417,8 +2417,8 @@ public:
public: public:
virtual DdlNode* dsqlPass(DsqlCompilerScratch* dsqlScratch) virtual DdlNode* dsqlPass(DsqlCompilerScratch* dsqlScratch)
{ {
dsqlScratch->getStatement()->setType( dsqlScratch->getDsqlStatement()->setType(
create ? DsqlCompiledStatement::TYPE_CREATE_DB : DsqlCompiledStatement::TYPE_DDL); create ? DsqlStatement::TYPE_CREATE_DB : DsqlStatement::TYPE_DDL);
return this; return this;
} }

View File

@ -60,15 +60,15 @@ namespace {
}; };
} }
DsqlBatch::DsqlBatch(dsql_req* req, const dsql_msg* /*message*/, IMessageMetadata* inMeta, ClumpletReader& pb) DsqlBatch::DsqlBatch(DsqlDmlRequest* req, const dsql_msg* /*message*/, IMessageMetadata* inMeta, ClumpletReader& pb)
: m_request(req), : m_dsqlRequest(req),
m_batch(NULL), m_batch(NULL),
m_meta(inMeta), m_meta(inMeta),
m_messages(m_request->getPool()), m_messages(m_dsqlRequest->getPool()),
m_blobs(m_request->getPool()), m_blobs(m_dsqlRequest->getPool()),
m_blobMap(m_request->getPool()), m_blobMap(m_dsqlRequest->getPool()),
m_blobMeta(m_request->getPool()), m_blobMeta(m_dsqlRequest->getPool()),
m_defaultBpb(m_request->getPool()), m_defaultBpb(m_dsqlRequest->getPool()),
m_messageSize(0), m_messageSize(0),
m_alignedMessage(0), m_alignedMessage(0),
m_alignment(0), m_alignment(0),
@ -168,13 +168,13 @@ DsqlBatch::~DsqlBatch()
{ {
if (m_batch) if (m_batch)
m_batch->resetHandle(); m_batch->resetHandle();
if (m_request) if (m_dsqlRequest)
m_request->req_batch = NULL; m_dsqlRequest->req_batch = NULL;
} }
Attachment* DsqlBatch::getAttachment() const Attachment* DsqlBatch::getAttachment() const
{ {
return m_request->req_dbb->dbb_attachment; return m_dsqlRequest->req_dbb->dbb_attachment;
} }
void DsqlBatch::setInterfacePtr(JBatch* interfacePtr) throw() void DsqlBatch::setInterfacePtr(JBatch* interfacePtr) throw()
@ -183,7 +183,7 @@ void DsqlBatch::setInterfacePtr(JBatch* interfacePtr) throw()
m_batch = interfacePtr; m_batch = interfacePtr;
} }
DsqlBatch* DsqlBatch::open(thread_db* tdbb, dsql_req* req, IMessageMetadata* inMetadata, DsqlBatch* DsqlBatch::open(thread_db* tdbb, DsqlDmlRequest* req, IMessageMetadata* inMetadata,
unsigned parLength, const UCHAR* par) unsigned parLength, const UCHAR* par)
{ {
SET_TDBB(tdbb); SET_TDBB(tdbb);
@ -205,15 +205,15 @@ DsqlBatch* DsqlBatch::open(thread_db* tdbb, dsql_req* req, IMessageMetadata* inM
// Sanity checks before creating batch // Sanity checks before creating batch
if (!req->req_request) if (!req->getRequest())
{ {
ERRD_post(Arg::Gds(isc_sqlerr) << Arg::Num(-504) << ERRD_post(Arg::Gds(isc_sqlerr) << Arg::Num(-504) <<
Arg::Gds(isc_unprepared_stmt)); Arg::Gds(isc_unprepared_stmt));
} }
const DsqlCompiledStatement* statement = req->getStatement(); const auto statement = req->getDsqlStatement();
if (statement->getFlags() & DsqlCompiledStatement::FLAG_ORPHAN) if (statement->getFlags() & DsqlStatement::FLAG_ORPHAN)
{ {
ERRD_post(Arg::Gds(isc_sqlerr) << Arg::Num(-901) << ERRD_post(Arg::Gds(isc_sqlerr) << Arg::Num(-901) <<
Arg::Gds(isc_bad_req_handle)); Arg::Gds(isc_bad_req_handle));
@ -221,11 +221,11 @@ DsqlBatch* DsqlBatch::open(thread_db* tdbb, dsql_req* req, IMessageMetadata* inM
switch (statement->getType()) switch (statement->getType())
{ {
case DsqlCompiledStatement::TYPE_INSERT: case DsqlStatement::TYPE_INSERT:
case DsqlCompiledStatement::TYPE_DELETE: case DsqlStatement::TYPE_DELETE:
case DsqlCompiledStatement::TYPE_UPDATE: case DsqlStatement::TYPE_UPDATE:
case DsqlCompiledStatement::TYPE_EXEC_PROCEDURE: case DsqlStatement::TYPE_EXEC_PROCEDURE:
case DsqlCompiledStatement::TYPE_EXEC_BLOCK: case DsqlStatement::TYPE_EXEC_BLOCK:
break; break;
default: default:
@ -451,7 +451,7 @@ Firebird::IBatchCompletionState* DsqlBatch::execute(thread_db* tdbb)
jrd_tra* transaction = tdbb->getTransaction(); jrd_tra* transaction = tdbb->getTransaction();
// execution timer // execution timer
thread_db::TimerGuard timerGuard(tdbb, m_request->setupTimer(tdbb), true); thread_db::TimerGuard timerGuard(tdbb, m_dsqlRequest->setupTimer(tdbb), true);
// sync internal buffers // sync internal buffers
m_messages.done(); m_messages.done();
@ -651,20 +651,20 @@ private:
} }
// execute request // execute request
m_request->req_transaction = transaction; m_dsqlRequest->req_transaction = transaction;
jrd_req* req = m_request->req_request; Request* req = m_dsqlRequest->getRequest();
fb_assert(req); fb_assert(req);
// prepare completion interface // prepare completion interface
AutoPtr<BatchCompletionState, SimpleDispose> completionState AutoPtr<BatchCompletionState, SimpleDispose> completionState
(FB_NEW BatchCompletionState(m_flags & (1 << IBatch::TAG_RECORD_COUNTS), m_detailed)); (FB_NEW BatchCompletionState(m_flags & (1 << IBatch::TAG_RECORD_COUNTS), m_detailed));
AutoSetRestore<bool> batchFlag(&req->req_batch_mode, true); AutoSetRestore<bool> batchFlag(&req->req_batch_mode, true);
const dsql_msg* message = m_request->getStatement()->getSendMsg(); const dsql_msg* message = m_dsqlRequest->getDsqlStatement()->getSendMsg();
bool startRequest = true; bool startRequest = true;
bool isExecBlock = m_request->getStatement()->getType() == DsqlCompiledStatement::TYPE_EXEC_BLOCK; bool isExecBlock = m_dsqlRequest->getDsqlStatement()->getType() == DsqlStatement::TYPE_EXEC_BLOCK;
const auto receiveMessage = isExecBlock ? m_request->getStatement()->getReceiveMsg() : nullptr; const auto receiveMessage = isExecBlock ? m_dsqlRequest->getDsqlStatement()->getReceiveMsg() : nullptr;
auto receiveMsgBuffer = isExecBlock ? m_request->req_msg_buffers[receiveMessage->msg_buffer_number] : nullptr; auto receiveMsgBuffer = isExecBlock ? m_dsqlRequest->req_msg_buffers[receiveMessage->msg_buffer_number] : nullptr;
// process messages // process messages
ULONG remains; ULONG remains;
@ -720,11 +720,11 @@ private:
} }
// map message to internal engine format // map message to internal engine format
m_request->mapInOut(tdbb, false, message, m_meta, NULL, data); m_dsqlRequest->mapInOut(tdbb, false, message, m_meta, NULL, data);
data += m_messageSize; data += m_messageSize;
remains -= m_messageSize; remains -= m_messageSize;
UCHAR* msgBuffer = m_request->req_msg_buffers[message->msg_buffer_number]; UCHAR* msgBuffer = m_dsqlRequest->req_msg_buffers[message->msg_buffer_number];
try try
{ {
// runsend data to request and collect stats // runsend data to request and collect stats

View File

@ -41,7 +41,7 @@ class ClumpletReader;
namespace Jrd { namespace Jrd {
class dsql_req; class DsqlDmlRequest;
class dsql_msg; class dsql_msg;
class thread_db; class thread_db;
class JBatch; class JBatch;
@ -50,7 +50,7 @@ class Attachment;
class DsqlBatch class DsqlBatch
{ {
public: public:
DsqlBatch(dsql_req* req, const dsql_msg* message, Firebird::IMessageMetadata* inMetadata, DsqlBatch(DsqlDmlRequest* req, const dsql_msg* message, Firebird::IMessageMetadata* inMetadata,
Firebird::ClumpletReader& pb); Firebird::ClumpletReader& pb);
~DsqlBatch(); ~DsqlBatch();
@ -61,7 +61,7 @@ public:
static const ULONG SIZEOF_BLOB_HEAD = sizeof(ISC_QUAD) + 2 * sizeof(ULONG); static const ULONG SIZEOF_BLOB_HEAD = sizeof(ISC_QUAD) + 2 * sizeof(ULONG);
static const unsigned BLOB_STREAM_ALIGN = 4; static const unsigned BLOB_STREAM_ALIGN = 4;
static DsqlBatch* open(thread_db* tdbb, dsql_req* req, Firebird::IMessageMetadata* inMetadata, static DsqlBatch* open(thread_db* tdbb, DsqlDmlRequest* req, Firebird::IMessageMetadata* inMetadata,
unsigned parLength, const UCHAR* par); unsigned parLength, const UCHAR* par);
Attachment* getAttachment() const; Attachment* getAttachment() const;
@ -101,7 +101,7 @@ private:
m_flags &= ~(1 << bit); m_flags &= ~(1 << bit);
} }
dsql_req* const m_request; DsqlDmlRequest* const m_dsqlRequest;
JBatch* m_batch; JBatch* m_batch;
Firebird::IMessageMetadata* m_meta; Firebird::IMessageMetadata* m_meta;

View File

@ -345,30 +345,24 @@ void DsqlCompilerScratch::putLocalVariables(CompoundStmtNode* parameters, USHORT
if (!(flags & DsqlCompilerScratch::FLAG_SUB_ROUTINE)) if (!(flags & DsqlCompilerScratch::FLAG_SUB_ROUTINE))
{ {
// Check not implemented sub-functions. // Check not implemented sub-functions.
for (const auto& funcPair : subFunctions)
GenericMap<Left<MetaName, DeclareSubFuncNode*> >::ConstAccessor funcAccessor(&subFunctions);
for (bool found = funcAccessor.getFirst(); found; found = funcAccessor.getNext())
{ {
if (!funcAccessor.current()->second->dsqlBlock) if (!funcPair.second->dsqlBlock)
{ {
status_exception::raise( status_exception::raise(
Arg::Gds(isc_subfunc_not_impl) << Arg::Gds(isc_subfunc_not_impl) <<
funcAccessor.current()->first.c_str()); funcPair.first.c_str());
} }
} }
// Check not implemented sub-procedures. // Check not implemented sub-procedures.
for (const auto& procPair : subProcedures)
GenericMap<Left<MetaName, DeclareSubProcNode*> >::ConstAccessor procAccessor(&subProcedures);
for (bool found = procAccessor.getFirst(); found; found = procAccessor.getNext())
{ {
if (!procAccessor.current()->second->dsqlBlock) if (!procPair.second->dsqlBlock)
{ {
status_exception::raise( status_exception::raise(
Arg::Gds(isc_subproc_not_impl) << Arg::Gds(isc_subproc_not_impl) <<
procAccessor.current()->first.c_str()); procPair.first.c_str());
} }
} }
} }
@ -430,6 +424,31 @@ void DsqlCompilerScratch::putLocalVariable(dsql_var* variable, const DeclareVari
++hiddenVarsNumber; ++hiddenVarsNumber;
} }
// Put maps in subroutines for outer variables/parameters usage.
void DsqlCompilerScratch::putOuterMaps()
{
if (!outerMessagesMap.count() && !outerVarsMap.count())
return;
appendUChar(blr_outer_map);
for (auto& pair : outerVarsMap)
{
appendUChar(blr_outer_map_variable);
appendUShort(pair.first);
appendUShort(pair.second);
}
for (auto& pair : outerMessagesMap)
{
appendUChar(blr_outer_map_message);
appendUShort(pair.first);
appendUShort(pair.second);
}
appendUChar(blr_end);
}
// Make a variable. // Make a variable.
dsql_var* DsqlCompilerScratch::makeVariable(dsql_fld* field, const char* name, dsql_var* DsqlCompilerScratch::makeVariable(dsql_fld* field, const char* name,
const dsql_var::Type type, USHORT msgNumber, USHORT itemNumber, USHORT localNumber) const dsql_var::Type type, USHORT msgNumber, USHORT itemNumber, USHORT localNumber)

View File

@ -24,6 +24,7 @@
#include "../jrd/jrd.h" #include "../jrd/jrd.h"
#include "../dsql/dsql.h" #include "../dsql/dsql.h"
#include "../dsql/DsqlStatements.h"
#include "../dsql/BlrDebugWriter.h" #include "../dsql/BlrDebugWriter.h"
#include "../common/classes/array.h" #include "../common/classes/array.h"
#include "../jrd/MetaName.h" #include "../jrd/MetaName.h"
@ -73,14 +74,13 @@ public:
public: public:
DsqlCompilerScratch(MemoryPool& p, dsql_dbb* aDbb, jrd_tra* aTransaction, DsqlCompilerScratch(MemoryPool& p, dsql_dbb* aDbb, jrd_tra* aTransaction,
DsqlCompiledStatement* aStatement, DsqlCompilerScratch* aMainScratch = NULL) DsqlStatement* aDsqlStatement = nullptr, DsqlCompilerScratch* aMainScratch = nullptr)
: BlrDebugWriter(p), : BlrDebugWriter(p),
dbb(aDbb), dbb(aDbb),
transaction(aTransaction), transaction(aTransaction),
statement(aStatement), dsqlStatement(aDsqlStatement),
flags(0), flags(0),
nestingLevel(0), nestingLevel(0),
ports(p),
relation(NULL), relation(NULL),
mainContext(p), mainContext(p),
context(&mainContext), context(&mainContext),
@ -117,10 +117,12 @@ public:
outputVariables(p), outputVariables(p),
returningClause(nullptr), returningClause(nullptr),
currCteAlias(NULL), currCteAlias(NULL),
mainScratch(aMainScratch),
outerMessagesMap(p),
outerVarsMap(p),
ctes(p), ctes(p),
cteAliases(p), cteAliases(p),
psql(false), psql(false),
mainScratch(aMainScratch),
subFunctions(p), subFunctions(p),
subProcedures(p) subProcedures(p)
{ {
@ -142,7 +144,7 @@ public:
public: public:
virtual bool isVersion4() virtual bool isVersion4()
{ {
return statement->getBlrVersion() == 4; return dsqlStatement->getBlrVersion() == 4;
} }
MemoryPool& getPool() MemoryPool& getPool()
@ -165,14 +167,14 @@ public:
transaction = value; transaction = value;
} }
DsqlCompiledStatement* getStatement() DsqlStatement* getDsqlStatement() const
{ {
return statement; return dsqlStatement;
} }
DsqlCompiledStatement* getStatement() const void setDsqlStatement(DsqlStatement* aDsqlStatement)
{ {
return statement; dsqlStatement = aDsqlStatement;
} }
void putBlrMarkers(ULONG marks); void putBlrMarkers(ULONG marks);
@ -181,6 +183,7 @@ public:
void putLocalVariables(CompoundStmtNode* parameters, USHORT locals); void putLocalVariables(CompoundStmtNode* parameters, USHORT locals);
void putLocalVariable(dsql_var* variable, const DeclareVariableNode* hostParam, void putLocalVariable(dsql_var* variable, const DeclareVariableNode* hostParam,
const MetaName& collationName); const MetaName& collationName);
void putOuterMaps();
dsql_var* makeVariable(dsql_fld*, const char*, const dsql_var::Type type, USHORT, dsql_var* makeVariable(dsql_fld*, const char*, const dsql_var::Type type, USHORT,
USHORT, USHORT); USHORT, USHORT);
dsql_var* resolveVariable(const MetaName& varName); dsql_var* resolveVariable(const MetaName& varName);
@ -269,12 +272,11 @@ private:
dsql_dbb* dbb; // DSQL attachment dsql_dbb* dbb; // DSQL attachment
jrd_tra* transaction; // Transaction jrd_tra* transaction; // Transaction
DsqlCompiledStatement* statement; // Compiled statement DsqlStatement* dsqlStatement; // DSQL statement
public: public:
unsigned flags; // flags unsigned flags; // flags
unsigned nestingLevel; // begin...end nesting level unsigned nestingLevel; // begin...end nesting level
Firebird::Array<dsql_msg*> ports; // Port messages
dsql_rel* relation; // relation created by this request (for DDL) dsql_rel* relation; // relation created by this request (for DDL)
DsqlContextStack mainContext; DsqlContextStack mainContext;
DsqlContextStack* context; DsqlContextStack* context;
@ -313,14 +315,16 @@ public:
Firebird::Array<dsql_var*> outputVariables; Firebird::Array<dsql_var*> outputVariables;
ReturningClause* returningClause; ReturningClause* returningClause;
const Firebird::string* const* currCteAlias; const Firebird::string* const* currCteAlias;
DsqlCompilerScratch* mainScratch;
Firebird::NonPooledMap<USHORT, USHORT> outerMessagesMap; // <outer, inner>
Firebird::NonPooledMap<USHORT, USHORT> outerVarsMap; // <outer, inner>
private: private:
Firebird::HalfStaticArray<SelectExprNode*, 4> ctes; // common table expressions Firebird::HalfStaticArray<SelectExprNode*, 4> ctes; // common table expressions
Firebird::HalfStaticArray<const Firebird::string*, 4> cteAliases; // CTE aliases in recursive members Firebird::HalfStaticArray<const Firebird::string*, 4> cteAliases; // CTE aliases in recursive members
bool psql; bool psql;
DsqlCompilerScratch* mainScratch; Firebird::LeftPooledMap<MetaName, DeclareSubFuncNode*> subFunctions;
Firebird::GenericMap<Firebird::Left<MetaName, DeclareSubFuncNode*> > subFunctions; Firebird::LeftPooledMap<MetaName, DeclareSubProcNode*> subProcedures;
Firebird::GenericMap<Firebird::Left<MetaName, DeclareSubProcNode*> > subProcedures;
}; };
class PsqlChanger class PsqlChanger

View File

@ -35,13 +35,13 @@ using namespace Jrd;
static const char* const SCRATCH = "fb_cursor_"; static const char* const SCRATCH = "fb_cursor_";
static const ULONG PREFETCH_SIZE = 65536; // 64 KB static const ULONG PREFETCH_SIZE = 65536; // 64 KB
DsqlCursor::DsqlCursor(dsql_req* req, ULONG flags) DsqlCursor::DsqlCursor(DsqlDmlRequest* req, ULONG flags)
: m_request(req), m_message(req->getStatement()->getReceiveMsg()), : m_dsqlRequest(req), m_message(req->getDsqlStatement()->getReceiveMsg()),
m_resultSet(NULL), m_flags(flags), m_resultSet(NULL), m_flags(flags),
m_space(req->getPool(), SCRATCH), m_space(req->getPool(), SCRATCH),
m_state(BOS), m_eof(false), m_position(0), m_cachedCount(0) m_state(BOS), m_eof(false), m_position(0), m_cachedCount(0)
{ {
TRA_link_cursor(m_request->req_transaction, this); TRA_link_cursor(m_dsqlRequest->req_transaction, this);
} }
DsqlCursor::~DsqlCursor() DsqlCursor::~DsqlCursor()
@ -52,12 +52,12 @@ DsqlCursor::~DsqlCursor()
jrd_tra* DsqlCursor::getTransaction() const jrd_tra* DsqlCursor::getTransaction() const
{ {
return m_request->req_transaction; return m_dsqlRequest->req_transaction;
} }
Attachment* DsqlCursor::getAttachment() const Attachment* DsqlCursor::getAttachment() const
{ {
return m_request->req_dbb->dbb_attachment; return m_dsqlRequest->req_dbb->dbb_attachment;
} }
void DsqlCursor::setInterfacePtr(JResultSet* interfacePtr) throw() void DsqlCursor::setInterfacePtr(JResultSet* interfacePtr) throw()
@ -71,35 +71,35 @@ void DsqlCursor::close(thread_db* tdbb, DsqlCursor* cursor)
if (!cursor) if (!cursor)
return; return;
Jrd::Attachment* const attachment = cursor->getAttachment(); const auto attachment = cursor->getAttachment();
dsql_req* const request = cursor->m_request; const auto dsqlRequest = cursor->m_dsqlRequest;
if (request->req_request) if (dsqlRequest->getRequest())
{ {
ThreadStatusGuard status_vector(tdbb); ThreadStatusGuard status_vector(tdbb);
try try
{ {
// Report some remaining fetches if any // Report some remaining fetches if any
if (request->req_fetch_baseline) if (dsqlRequest->req_fetch_baseline)
{ {
TraceDSQLFetch trace(attachment, request); TraceDSQLFetch trace(attachment, dsqlRequest);
trace.fetch(true, ITracePlugin::RESULT_SUCCESS); trace.fetch(true, ITracePlugin::RESULT_SUCCESS);
} }
if (request->req_traced && TraceManager::need_dsql_free(attachment)) if (dsqlRequest->req_traced && TraceManager::need_dsql_free(attachment))
{ {
TraceSQLStatementImpl stmt(request, NULL); TraceSQLStatementImpl stmt(dsqlRequest, NULL);
TraceManager::event_dsql_free(attachment, &stmt, DSQL_close); TraceManager::event_dsql_free(attachment, &stmt, DSQL_close);
} }
JRD_unwind_request(tdbb, request->req_request); JRD_unwind_request(tdbb, dsqlRequest->getRequest());
} }
catch (Firebird::Exception&) catch (Firebird::Exception&)
{} // no-op {} // no-op
} }
request->req_cursor = NULL; dsqlRequest->req_cursor = NULL;
TRA_unlink_cursor(request->req_transaction, cursor); TRA_unlink_cursor(dsqlRequest->req_transaction, cursor);
delete cursor; delete cursor;
} }
@ -107,7 +107,7 @@ int DsqlCursor::fetchNext(thread_db* tdbb, UCHAR* buffer)
{ {
if (!(m_flags & IStatement::CURSOR_TYPE_SCROLLABLE)) if (!(m_flags & IStatement::CURSOR_TYPE_SCROLLABLE))
{ {
m_eof = !m_request->fetch(tdbb, buffer); m_eof = !m_dsqlRequest->fetch(tdbb, buffer);
if (m_eof) if (m_eof)
{ {
@ -300,13 +300,13 @@ int DsqlCursor::fetchFromCache(thread_db* tdbb, UCHAR* buffer, FB_UINT64 positio
fb_assert(position < m_cachedCount); fb_assert(position < m_cachedCount);
UCHAR* const msgBuffer = m_request->req_msg_buffers[m_message->msg_buffer_number]; UCHAR* const msgBuffer = m_dsqlRequest->req_msg_buffers[m_message->msg_buffer_number];
const FB_UINT64 offset = position * m_message->msg_length; const FB_UINT64 offset = position * m_message->msg_length;
const FB_UINT64 readBytes = m_space.read(offset, msgBuffer, m_message->msg_length); const FB_UINT64 readBytes = m_space.read(offset, msgBuffer, m_message->msg_length);
fb_assert(readBytes == m_message->msg_length); fb_assert(readBytes == m_message->msg_length);
m_request->mapInOut(tdbb, true, m_message, NULL, buffer); m_dsqlRequest->mapInOut(tdbb, true, m_message, NULL, buffer);
m_position = position; m_position = position;
m_state = POSITIONED; m_state = POSITIONED;
@ -318,13 +318,13 @@ bool DsqlCursor::cacheInput(thread_db* tdbb, FB_UINT64 position)
fb_assert(!m_eof); fb_assert(!m_eof);
const ULONG prefetchCount = MAX(PREFETCH_SIZE / m_message->msg_length, 1); const ULONG prefetchCount = MAX(PREFETCH_SIZE / m_message->msg_length, 1);
const UCHAR* const msgBuffer = m_request->req_msg_buffers[m_message->msg_buffer_number]; const UCHAR* const msgBuffer = m_dsqlRequest->req_msg_buffers[m_message->msg_buffer_number];
while (position >= m_cachedCount) while (position >= m_cachedCount)
{ {
for (ULONG count = 0; count < prefetchCount; count++) for (ULONG count = 0; count < prefetchCount; count++)
{ {
if (!m_request->fetch(tdbb, NULL)) if (!m_dsqlRequest->fetch(tdbb, NULL))
{ {
m_eof = true; m_eof = true;
break; break;

View File

@ -27,7 +27,7 @@
namespace Jrd { namespace Jrd {
class dsql_req; class DsqlDmlRequest;
class JResultSet; class JResultSet;
class DsqlCursor class DsqlCursor
@ -35,7 +35,7 @@ class DsqlCursor
enum State { BOS, POSITIONED, EOS }; enum State { BOS, POSITIONED, EOS };
public: public:
DsqlCursor(dsql_req* req, ULONG flags); DsqlCursor(DsqlDmlRequest* req, ULONG flags);
~DsqlCursor(); ~DsqlCursor();
jrd_tra* getTransaction() const; jrd_tra* getTransaction() const;
@ -69,7 +69,7 @@ private:
int fetchFromCache(thread_db* tdbb, UCHAR* buffer, FB_UINT64 position); int fetchFromCache(thread_db* tdbb, UCHAR* buffer, FB_UINT64 position);
bool cacheInput(thread_db* tdbb, FB_UINT64 position = MAX_UINT64); bool cacheInput(thread_db* tdbb, FB_UINT64 position = MAX_UINT64);
dsql_req* const m_request; DsqlDmlRequest* const m_dsqlRequest;
const dsql_msg* const m_message; const dsql_msg* const m_message;
JResultSet* m_resultSet; JResultSet* m_resultSet;
const ULONG m_flags; const ULONG m_flags;

1125
src/dsql/DsqlRequests.cpp Normal file

File diff suppressed because it is too large Load Diff

261
src/dsql/DsqlRequests.h Normal file
View File

@ -0,0 +1,261 @@
/*
* The contents of this file are subject to the Interbase Public
* License Version 1.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy
* of the License at http://www.Inprise.com/IPL.html
*
* Software distributed under the License is distributed on an
* "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express
* or implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code was created by Inprise Corporation
* and its predecessors. Portions created by Inprise Corporation are
* Copyright (C) Inprise Corporation.
*
* All Rights Reserved.
* Contributor(s): ______________________________________.
*
* 2022.02.07 Adriano dos Santos Fernandes: Refactored from dsql.h
*/
#ifndef DSQL_REQUESTS_H
#define DSQL_REQUESTS_H
#include "firebird/Interface.h"
#include "../common/StatusArg.h"
#include "../common/classes/alloc.h"
#include "../common/classes/array.h"
#include "../common/classes/fb_string.h"
#include "../common/classes/NestConst.h"
#include "../common/classes/RefCounted.h"
#include "../jrd/jrd.h"
namespace Jrd {
class DdlNode;
class dsql_dbb;
class DsqlStatement;
class DsqlCompilerScratch;
class DsqlCursor;
class DsqlDmlStatement;
class dsql_par;
class Request;
class jrd_tra;
class Statement;
class SessionManagementNode;
class TransactionNode;
class DsqlRequest : public Firebird::PermanentStorage
{
public:
DsqlRequest(MemoryPool& pool, dsql_dbb* dbb, DsqlStatement* aStatement);
virtual ~DsqlRequest();
public:
jrd_tra* getTransaction()
{
return req_transaction;
}
Firebird::RefPtr<DsqlStatement> getDsqlStatement()
{
return dsqlStatement;
}
virtual Statement* getStatement() const
{
return nullptr;
}
virtual Request* getRequest() const
{
return nullptr;
}
virtual DsqlCursor* openCursor(thread_db* tdbb, jrd_tra** traHandle,
Firebird::IMessageMetadata* inMeta, const UCHAR* inMsg,
Firebird::IMessageMetadata* outMeta, ULONG flags)
{
Firebird::Arg::Gds(isc_no_cursor).raise();
}
virtual DsqlBatch* openBatch(thread_db* tdbb, Firebird::IMessageMetadata* inMetadata,
unsigned parLength, const UCHAR* par)
{
(Firebird::Arg::Gds(isc_sqlerr) <<
Firebird::Arg::Num(-504) <<
Firebird::Arg::Gds(isc_unprepared_stmt)
).raise();
}
virtual void execute(thread_db* tdbb, jrd_tra** traHandle,
Firebird::IMessageMetadata* inMetadata, const UCHAR* inMsg,
Firebird::IMessageMetadata* outMetadata, UCHAR* outMsg,
bool singleton) = 0;
virtual void setCursor(thread_db* tdbb, const TEXT* name);
virtual bool fetch(thread_db* tdbb, UCHAR* buffer);
virtual void setDelayedFormat(thread_db* tdbb, Firebird::IMessageMetadata* metadata);
// Get session-level timeout, milliseconds
unsigned int getTimeout();
// Set session-level timeout, milliseconds
void setTimeout(unsigned int timeOut);
// Get actual timeout, milliseconds
unsigned int getActualTimeout();
// Evaluate actual timeout value, consider config- and session-level timeout values,
// setup and start timer
TimeoutTimer* setupTimer(thread_db* tdbb);
USHORT parseMetadata(Firebird::IMessageMetadata* meta, const Firebird::Array<dsql_par*>& parameters_list);
static void destroy(thread_db* tdbb, DsqlRequest* request);
public:
dsql_dbb* req_dbb; // DSQL attachment
Firebird::RefPtr<DsqlStatement> dsqlStatement;
Firebird::Array<DsqlDmlStatement*> cursors{getPool()}; // Cursor update statements
jrd_tra* req_transaction = nullptr; // JRD transaction
Firebird::string req_cursor_name{getPool()}; // Cursor name, if any
DsqlCursor* req_cursor = nullptr; // Open cursor, if any
DsqlBatch* req_batch = nullptr; // Active batch, if any
Firebird::NonPooledMap<const dsql_par*, dsc> req_user_descs{getPool()}; // SQLDA data type
Firebird::AutoPtr<Jrd::RuntimeStatistics> req_fetch_baseline; // State of request performance counters when we reported it last time
SINT64 req_fetch_elapsed = 0; // Number of clock ticks spent while fetching rows for this request since we reported it last time
SINT64 req_fetch_rowcount = 0; // Total number of rows returned by this request
bool req_traced = false; // request is traced via TraceAPI
protected:
unsigned int req_timeout = 0; // query timeout in milliseconds, set by the user
Firebird::RefPtr<TimeoutTimer> req_timer; // timeout timer
};
class DsqlDmlRequest final : public DsqlRequest
{
public:
DsqlDmlRequest(thread_db* tdbb, MemoryPool& pool, dsql_dbb* dbb, DsqlStatement* aDsqlStatement);
// Reintroduce method to fake covariant return type with RefPtr.
auto getDsqlStatement()
{
return Firebird::RefPtr<DsqlDmlStatement>((DsqlDmlStatement*) dsqlStatement.getPtr());
}
Statement* getStatement() const override;
Request* getRequest() const override
{
return request;
}
DsqlCursor* openCursor(thread_db* tdbb, jrd_tra** traHandle,
Firebird::IMessageMetadata* inMeta, const UCHAR* inMsg,
Firebird::IMessageMetadata* outMeta, ULONG flags) override;
DsqlBatch* openBatch(thread_db* tdbb, Firebird::IMessageMetadata* inMetadata,
unsigned parLength, const UCHAR* par) override;
void execute(thread_db* tdbb, jrd_tra** traHandle,
Firebird::IMessageMetadata* inMetadata, const UCHAR* inMsg,
Firebird::IMessageMetadata* outMetadata, UCHAR* outMsg,
bool singleton) override;
void setCursor(thread_db* tdbb, const TEXT* name) override;
bool fetch(thread_db* tdbb, UCHAR* buffer) override;
void setDelayedFormat(thread_db* tdbb, Firebird::IMessageMetadata* metadata) override;
void mapInOut(Jrd::thread_db* tdbb, bool toExternal, const dsql_msg* message, Firebird::IMessageMetadata* meta,
UCHAR* dsql_msg_buf, const UCHAR* in_dsql_msg_buf = nullptr);
private:
// True, if request could be restarted
bool needRestarts();
void doExecute(thread_db* tdbb, jrd_tra** traHandle,
Firebird::IMessageMetadata* outMetadata, UCHAR* outMsg,
bool singleton);
// [Re]start part of "request restarts" algorithm
void executeReceiveWithRestarts(thread_db* tdbb, jrd_tra** traHandle,
Firebird::IMessageMetadata* outMetadata, UCHAR* outMsg,
bool singleton, bool exec, bool fetch);
public:
Firebird::Array<UCHAR*> req_msg_buffers;
private:
Firebird::RefPtr<Firebird::IMessageMetadata> delayedFormat;
Request* request = nullptr;
bool needDelayedFormat = false;
bool firstRowFetched = false;
};
class DsqlDdlRequest final : public DsqlRequest
{
public:
DsqlDdlRequest(MemoryPool& pool, dsql_dbb* dbb, DsqlCompilerScratch* aInternalScratch, DdlNode* aNode);
void execute(thread_db* tdbb, jrd_tra** traHandle,
Firebird::IMessageMetadata* inMetadata, const UCHAR* inMsg,
Firebird::IMessageMetadata* outMetadata, UCHAR* outMsg,
bool singleton) override;
private:
DsqlCompilerScratch* internalScratch;
NestConst<DdlNode> node;
};
class DsqlTransactionRequest final : public DsqlRequest
{
public:
DsqlTransactionRequest(MemoryPool& pool, dsql_dbb* dbb, DsqlStatement* aStatement, TransactionNode* aNode);
void execute(thread_db* tdbb, jrd_tra** traHandle,
Firebird::IMessageMetadata* inMetadata, const UCHAR* inMsg,
Firebird::IMessageMetadata* outMetadata, UCHAR* outMsg,
bool singleton) override;
private:
NestConst<TransactionNode> node;
};
class DsqlSessionManagementRequest final : public DsqlRequest
{
public:
DsqlSessionManagementRequest(MemoryPool& pool, dsql_dbb* dbb, DsqlStatement* aStatement,
SessionManagementNode* aNode)
: DsqlRequest(pool, dbb, aStatement),
node(aNode)
{
}
void execute(thread_db* tdbb, jrd_tra** traHandle,
Firebird::IMessageMetadata* inMetadata, const UCHAR* inMsg,
Firebird::IMessageMetadata* outMetadata, UCHAR* outMsg,
bool singleton) override;
private:
NestConst<SessionManagementNode> node;
};
} // namespace Jrd
#endif // DSQL_REQUESTS_H

View File

@ -0,0 +1,285 @@
/*
* The contents of this file are subject to the Initial
* Developer's Public License Version 1.0 (the "License");
* you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
* http://www.ibphoenix.com/main.nfs?a=ibphoenix&page=ibp_idpl.
*
* Software distributed under the License is distributed AS IS,
* WITHOUT WARRANTY OF ANY KIND, either express or implied.
* See the License for the specific language governing rights
* and limitations under the License.
*
* The Original Code was created by Adriano dos Santos Fernandes
* for the Firebird Open Source RDBMS project.
*
* Copyright (c) 2022 Adriano dos Santos Fernandes <adrianosf@gmail.com>
* and all contributors signed below.
*
* All Rights Reserved.
* Contributor(s): ______________________________________.
*/
#include "firebird.h"
#include "../dsql/DsqlStatementCache.h"
#include "../dsql/DsqlStatements.h"
#include "../jrd/Attachment.h"
#include "../jrd/Statement.h"
#include "../jrd/lck.h"
#include "../jrd/lck_proto.h"
using namespace Firebird;
using namespace Jrd;
// Class DsqlStatementCache
DsqlStatementCache::DsqlStatementCache(MemoryPool& o, Attachment* attachment)
: PermanentStorage(o),
map(o),
activeStatementList(o),
inactiveStatementList(o)
{
const auto dbb = attachment->att_database;
maxCacheSize = dbb->dbb_config->getMaxStatementCacheSize();
}
DsqlStatementCache::~DsqlStatementCache()
{
purge(JRD_get_thread_data());
}
int DsqlStatementCache::blockingAst(void* astObject)
{
#ifdef DSQL_STATEMENT_CACHE_DEBUG
printf("DsqlStatementCache::blockingAst()\n");
#endif
const auto self = static_cast<DsqlStatementCache*>(astObject);
try
{
const auto dbb = self->lock->lck_dbb;
AsyncContextHolder tdbb(dbb, FB_FUNCTION, self->lock);
self->purge(tdbb);
}
catch (const Exception&)
{} // no-op
return 0;
}
RefPtr<DsqlStatement> DsqlStatementCache::getStatement(thread_db* tdbb, const string& text, USHORT clientDialect,
bool isInternalRequest)
{
RefStrPtr key;
buildStatementKey(tdbb, key, text, clientDialect, isInternalRequest);
if (const auto entryPtr = map.get(key))
{
const auto entry = *entryPtr;
auto dsqlStatement(entry->dsqlStatement);
string verifyKey;
buildVerifyKey(tdbb, verifyKey, isInternalRequest);
FB_SIZE_T verifyPos;
if (!entry->verifyCache.find(verifyKey, verifyPos))
{
dsqlStatement->getStatement()->verifyAccess(tdbb);
entry->verifyCache.insert(verifyPos, verifyKey);
}
if (!entry->active)
{
entry->dsqlStatement->setCacheKey(key);
// Active statement has cacheKey and will tell us when it's going to be released.
entry->dsqlStatement->release();
entry->active = true;
cacheSize -= entry->size;
activeStatementList.splice(activeStatementList.end(), inactiveStatementList, entry);
}
#ifdef DSQL_STATEMENT_CACHE_DEBUG
dump();
#endif
return dsqlStatement;
}
return {};
}
void DsqlStatementCache::putStatement(thread_db* tdbb, const string& text, USHORT clientDialect,
bool isInternalRequest, RefPtr<DsqlStatement> dsqlStatement)
{
fb_assert(dsqlStatement->isDml());
const unsigned statementSize = dsqlStatement->getSize();
RefStrPtr key;
buildStatementKey(tdbb, key, text, clientDialect, isInternalRequest);
StatementEntry newStatement(getPool());
newStatement.key = key;
newStatement.size = statementSize;
newStatement.dsqlStatement = std::move(dsqlStatement);
newStatement.active = true;
string verifyKey;
buildVerifyKey(tdbb, verifyKey, isInternalRequest);
newStatement.verifyCache.add(verifyKey);
newStatement.dsqlStatement->setCacheKey(key);
// Active statement has cacheKey and will tell us when it's going to be released.
newStatement.dsqlStatement->release();
activeStatementList.pushBack(std::move(newStatement));
map.put(key, --activeStatementList.end());
if (!lock)
{
lock = FB_NEW_RPT(getPool(), 0) Lock(tdbb, 0, LCK_dsql_statement_cache, this, blockingAst);
LCK_lock(tdbb, lock, LCK_SR, LCK_WAIT);
}
#ifdef DSQL_STATEMENT_CACHE_DEBUG
dump();
#endif
}
void DsqlStatementCache::statementGoingInactive(Firebird::RefStrPtr& key)
{
const auto entryPtr = map.get(key);
if (!entryPtr)
{
fb_assert(false);
return;
}
const auto entry = *entryPtr;
fb_assert(entry->active);
entry->active = false;
entry->size = entry->dsqlStatement->getSize(); // update size
inactiveStatementList.splice(inactiveStatementList.end(), activeStatementList, entry);
cacheSize += entry->size;
if (cacheSize > maxCacheSize)
shrink();
}
void DsqlStatementCache::purge(thread_db* tdbb)
{
for (auto& entry : activeStatementList)
{
entry.dsqlStatement->addRef();
entry.dsqlStatement->resetCacheKey();
}
map.clear();
activeStatementList.clear();
inactiveStatementList.clear();
cacheSize = 0;
if (lock)
{
LCK_release(tdbb, lock);
lock.reset();
}
}
void DsqlStatementCache::purgeAllAttachments(thread_db* tdbb)
{
if (lock)
LCK_convert(tdbb, lock, LCK_EX, LCK_WAIT);
else
{
lock = FB_NEW_RPT(getPool(), 0) Lock(tdbb, 0, LCK_dsql_statement_cache, this, blockingAst);
LCK_lock(tdbb, lock, LCK_EX, LCK_WAIT);
}
purge(tdbb);
}
void DsqlStatementCache::buildStatementKey(thread_db* tdbb, RefStrPtr& key, const string& text, USHORT clientDialect,
bool isInternalRequest)
{
const auto attachment = tdbb->getAttachment();
const SSHORT charSetId = isInternalRequest ? CS_METADATA : attachment->att_charset;
key = FB_NEW_POOL(getPool()) RefString(getPool());
key->resize(1 + sizeof(charSetId) + text.length());
char* p = key->begin();
*p = (clientDialect << 1) | int(isInternalRequest);
memcpy(p + 1, &charSetId, sizeof(charSetId));
memcpy(p + 1 + sizeof(charSetId), text.c_str(), text.length());
}
void DsqlStatementCache::buildVerifyKey(thread_db* tdbb, string& key, bool isInternalRequest)
{
key.clear();
const auto attachment = tdbb->getAttachment();
if (isInternalRequest || !attachment->att_user)
return;
const auto& roles = attachment->att_user->getGrantedRoles(tdbb);
string roleStr;
for (const auto& role : roles)
{
roleStr.printf("%d,%s,", int(role.length()), role.c_str());
key += roleStr;
}
}
void DsqlStatementCache::shrink()
{
#ifdef DSQL_STATEMENT_CACHE_DEBUG
printf("DsqlStatementCache::shrink() - cacheSize: %u, maxCacheSize: %u\n\n", cacheSize, maxCacheSize);
#endif
while (cacheSize > maxCacheSize && !inactiveStatementList.isEmpty())
{
const auto& front = inactiveStatementList.front();
map.remove(front.key);
cacheSize -= front.size;
inactiveStatementList.erase(inactiveStatementList.begin());
}
#ifdef DSQL_STATEMENT_CACHE_DEBUG
dump();
#endif
}
#ifdef DSQL_STATEMENT_CACHE_DEBUG
void DsqlStatementCache::dump()
{
printf("DsqlStatementCache::dump() - cacheSize: %u, maxCacheSize: %u\n\n", cacheSize, maxCacheSize);
printf("\tactive:\n");
for (auto& entry : activeStatementList)
printf("\t\tsize: %u; text: %s\n", entry.size, entry.dsqlStatement->getSqlText()->c_str());
printf("\n\tinactive:\n");
for (auto& entry : inactiveStatementList)
printf("\t\tsize: %u; text: %s\n", entry.size, entry.dsqlStatement->getSqlText()->c_str());
printf("\n");
}
#endif

View File

@ -0,0 +1,137 @@
/*
* The contents of this file are subject to the Initial
* Developer's Public License Version 1.0 (the "License");
* you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
* http://www.ibphoenix.com/main.nfs?a=ibphoenix&page=ibp_idpl.
*
* Software distributed under the License is distributed AS IS,
* WITHOUT WARRANTY OF ANY KIND, either express or implied.
* See the License for the specific language governing rights
* and limitations under the License.
*
* The Original Code was created by Adriano dos Santos Fernandes
* for the Firebird Open Source RDBMS project.
*
* Copyright (c) 2022 Adriano dos Santos Fernandes <adrianosf@gmail.com>
* and all contributors signed below.
*
* All Rights Reserved.
* Contributor(s): ______________________________________.
*/
#ifndef DSQL_STATEMENT_CACHE_H
#define DSQL_STATEMENT_CACHE_H
///#define DSQL_STATEMENT_CACHE_DEBUG 1
#include "../common/classes/alloc.h"
#include "../common/classes/DoublyLinkedList.h"
#include "../common/classes/fb_string.h"
#include "../common/classes/GenericMap.h"
#include "../common/classes/objects_array.h"
#include "../common/classes/RefCounted.h"
namespace Jrd {
class Attachment;
class DsqlStatement;
class Lock;
class thread_db;
class DsqlStatementCache final : public Firebird::PermanentStorage
{
private:
struct StatementEntry
{
explicit StatementEntry(MemoryPool& p)
: verifyCache(p)
{
}
StatementEntry(MemoryPool& p, StatementEntry&& o)
: key(std::move(o.key)),
dsqlStatement(std::move(o.dsqlStatement)),
verifyCache(p, std::move(o.verifyCache)),
size(o.size),
active(o.active)
{
}
StatementEntry(const StatementEntry&) = delete;
StatementEntry& operator=(const StatementEntry&) = delete;
Firebird::RefStrPtr key;
Firebird::RefPtr<DsqlStatement> dsqlStatement;
Firebird::SortedObjectsArray<Firebird::string> verifyCache;
unsigned size = 0;
bool active = true;
};
class RefStrPtrComparator
{
public:
static bool greaterThan(const Firebird::RefStrPtr& i1, const Firebird::RefStrPtr& i2)
{
return *i1 > *i2;
}
};
public:
explicit DsqlStatementCache(MemoryPool& o, Attachment* attachment);
~DsqlStatementCache();
DsqlStatementCache(const DsqlStatementCache&) = delete;
DsqlStatementCache& operator=(const DsqlStatementCache&) = delete;
private:
static int blockingAst(void* astObject);
public:
bool isActive() const
{
return maxCacheSize > 0;
}
Firebird::RefPtr<DsqlStatement> getStatement(thread_db* tdbb, const Firebird::string& text,
USHORT clientDialect, bool isInternalRequest);
void putStatement(thread_db* tdbb, const Firebird::string& text, USHORT clientDialect, bool isInternalRequest,
Firebird::RefPtr<DsqlStatement> dsqlStatement);
void statementGoingInactive(Firebird::RefStrPtr& key);
void purge(thread_db* tdbb);
void purgeAllAttachments(thread_db* tdbb);
private:
void buildStatementKey(thread_db* tdbb, Firebird::RefStrPtr& key, const Firebird::string& text,
USHORT clientDialect, bool isInternalRequest);
void buildVerifyKey(thread_db* tdbb, Firebird::string& key, bool isInternalRequest);
void shrink();
#ifdef DSQL_STATEMENT_CACHE_DEBUG
void dump();
#endif
private:
Firebird::NonPooledMap<
Firebird::RefStrPtr,
Firebird::DoublyLinkedList<StatementEntry>::Iterator,
RefStrPtrComparator
> map;
Firebird::DoublyLinkedList<StatementEntry> activeStatementList;
Firebird::DoublyLinkedList<StatementEntry> inactiveStatementList;
Firebird::AutoPtr<Lock> lock;
unsigned maxCacheSize = 0;
unsigned cacheSize = 0;
};
} // namespace Jrd
#endif // DSQL_STATEMENT_CACHE_H

Some files were not shown because too many files have changed in this diff Show More