8
0
mirror of https://github.com/FirebirdSQL/firebird.git synced 2025-01-22 17:23:03 +01:00

Merge branch 'master' into ExternalConnectionsPool

This commit is contained in:
hvlad 2018-05-25 13:42:38 +03:00 committed by GitHub
commit 2930edb9c0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
197 changed files with 5281 additions and 2090 deletions

3
.gitignore vendored
View File

@ -15,6 +15,7 @@ libtool
*.log
*.bak
*.tmp
*.d
src/dsql/parse.cpp
.vscode/.browse.VC.db
extern/decNumber/libdecFloat.a
extern/decNumber/libdecFloat*.a

View File

@ -811,6 +811,17 @@
#
#EventMemSize = 64K
# ----------------------------
#
# File to redirect stdout and stderr output of server
#
# Default '/dev/null' for *nix and 'nul' for Windows
# Empty value or '-' keeps stdout and stderr as is.
#
# Type: string
#
#OutputRedirectionFile = /dev/null
# ===========================
# Engine Settings

View File

@ -228,6 +228,8 @@ checkLibraries() {
then
checkLibrary tomcrypt
fi
checkLibrary icudata
}
@ -237,7 +239,7 @@ checkLibraries() {
grepProcess() {
processList=$1
eol=\$
ps $psOptions | egrep "\<($processList)($eol|[[:space:]])" | grep -v grep
ps $psOptions | egrep "\<($processList)($eol|[[:space:]])" | grep -v grep | grep -v -w '\-path'
}

View File

@ -1,7 +1,7 @@
#!/bin/sh
# install - install a program, script, or datafile
scriptversion=2013-12-25.23; # UTC
scriptversion=2016-01-11.22; # UTC
# This originates from X11R5 (mit/util/scripts/install.sh), which was
# later released in X11R6 (xc/config/util/install.sh) with the
@ -496,6 +496,6 @@ done
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-time-zone: "UTC"
# time-stamp-time-zone: "UTC0"
# time-stamp-end: "; # UTC"
# End:

View File

@ -35,12 +35,18 @@
ROOT=$(shell cd ..; pwd)
ifeq ($(CROSS_OUT), Y)
export CROSS:=CrossBuild
endif
include make.defaults
ifeq ($(CROSS_OUT), Y)
include make.crossPlatform
else
include make.platform
endif
include make.rules
include make.shared.variables
@ -185,7 +191,11 @@ $(TOMMATH_LIB): $(TOM_Objs)
.PHONY: tomcrypt
TOMCRYPT_LIB=$(LIB)/libtomcrypt.a
TOM_Objs=$(addprefix ../extern/libtomcrypt/,$(call doObjects,$(call dirFiles,../extern/libtomcrypt)))
TOM_Src:=hashes/md5.c hashes/sha1.c hashes/sha2/sha256.c hashes/sha2/sha512.c misc/crypt/crypt_argchk.c
TOM_Src:=$(addprefix ../extern/libtomcrypt/src/, $(TOM_Src))
TOM_Objs=$(call doObjects,$(TOM_Src))
tomcrypt: $(TOMCRYPT_LIB)
@ -194,10 +204,10 @@ $(TOMCRYPT_LIB): $(TOM_Objs)
$(STATICLIB_LINK) $@ $^
#___________________________________________________________________________
# main build target for both debug abd release builds
# main build target for both debug and release builds
#
.PHONY: cross1 cross2 boot yvalve engine fbintl gpre utilities plugins rest codes ids examples cross_rest
.PHONY: cross1 cross2 boot yvalve engine fbintl gpre utilities plugins rest codes ids examples cross_rest preliminaryCheck
master_process:
ln -sf $(SRC_ROOT)/include/gen/autoconfig.auto $(SRC_ROOT)/include/gen/autoconfig.h
@ -205,6 +215,7 @@ master_process:
$(MAKE) export_lists
$(MAKE) external
$(MAKE) updateCloopInterfaces
$(MAKE) preliminaryCheck
$(MAKE) boot
$(MAKE) yvalve
ifeq ($(IsDeveloper), Y)
@ -264,6 +275,8 @@ cross2:
$(MAKE) prerequisites
$(MAKE) tommath
$(MAKE) tomcrypt
$(MAKE) -C $(ROOT)/extern/decNumber
ln -sf $(ROOT)/extern/decNumber/libdecFloat$(CROSS).a $(LIB)
$(MAKE) yvalve
$(MAKE) engine
$(MAKE) fbintl
@ -273,6 +286,26 @@ cross2:
$(MAKE) -f Makefile.plugins_examples
$(MAKE) cross_rest
#___________________________________________________________________________
# preliminary checks - make sure platform is OK to build FB
#
STD_SIZES:=$(SRC_ROOT)/misc/ods.txt
RUN_SIZES:=$(GEN_ROOT)/ods.txt
ODS_H:=$(SRC_ROOT)/jrd/ods.h
ODS_AWK:=$(SRC_ROOT)/misc/ods.awk
ODS_TEST_CPP:=$(GEN_ROOT)/odstest.cpp
ODS_TEST:=$(GEN_ROOT)/odstest$(EXEC_EXT)
preliminaryCheck: $(STD_SIZES) $(RUN_SIZES)
diff -u $^
$(RUN_SIZES): $(ODS_H) $(ODS_AWK)
awk -f $(ODS_AWK) <$(ODS_H) >$(ODS_TEST_CPP)
$(CXX) -o $(ODS_TEST) $(WCXXFLAGS) $(ODS_TEST_CPP)
$(ODS_TEST) >$(RUN_SIZES)
#___________________________________________________________________________
# static library - various common code, used in different FB projects
#
@ -535,7 +568,7 @@ udf_compat: $(UDF_BACKWARD_COMPATIBILITY) $(COMPAT_SQL)
$(UDF_BACKWARD_COMPATIBILITY): $(COMPAT_Objects)
$(LIB_LINK) $(LIB_LINK_OPTIONS) $(call LIB_LINK_SONAME,$(UDF_BACKWARD_COMPATIBILITY_BASENAME)) \
$(LINK_UDR_PLUGIN_SYMBOLS) $(LIB_PATH_OPTS) $(UNDEF_FLAGS) -o $@ $^ $(THR_LIBS)
$(LINK_UDR_PLUGIN_SYMBOLS) $(LIB_PATH_OPTS) $(UNDEF_FLAGS) -o $@ $^ $(THR_LIBS) $(UDR_SUPPORT_LIBS)
$(COMPAT_SQL): $(SRC_COMPAT_SQL)
cp $^ $@

View File

@ -20,7 +20,10 @@ HOST_TAG64:=linux-x86
endif
NDK_TOOLCHAIN_VERSION:=$(shell echo $(TOOLCHAIN_DIR) | awk -F - '{print $$NF;}')
CROSS_PLATFORM:=$(NDK)/platforms/android-24/arch-arm
CROSS_PLATFORM:=$(NDK)/platforms
ALEVEL:=$(shell for i in `seq 256`; do [ -d $(CROSS_PLATFORM)/android-$${i} ] && adir=$${i}; done; echo $${adir})
CROSS_PLATFORM:=$(CROSS_PLATFORM)/android-$(ALEVEL)/arch-arm
CROSS_PREFIX:=$(NDK)/toolchains/$(TOOLCHAIN_DIR)/prebuilt/$(HOST_TAG64)/bin/arm-linux-androideabi-
CXX:=$(CROSS_PREFIX)g++
@ -34,12 +37,20 @@ OBJDUMP:=$(CROSS_PREFIX)objdump
RANLIB:=$(CROSS_PREFIX)ranlib
STRIP:=$(CROSS_PREFIX)strip
COMMON_FLAGS=-ggdb -DFB_SEND_FLAGS=MSG_NOSIGNAL -DLINUX -DANDROID -DARM -pipe -MMD -fPIC -fmessage-length=0 \
-I$(ROOT)/extern/libtommath --sysroot=$(CROSS_PLATFORM) \
-I$(CROSS_PLATFORM)/usr/include -I$(ROOT)/gen/cross \
-I$(NDK)/sources/cxx-stl/gnu-libstdc++/$(NDK_TOOLCHAIN_VERSION)/include \
-I$(NDK)/sources/cxx-stl/gnu-libstdc++/$(NDK_TOOLCHAIN_VERSION)/libs/armeabi/include
export CXX
export CC
export AR
CROSS_FLAGS=--sysroot=$(CROSS_PLATFORM) \
-I$(CROSS_PLATFORM)/usr/include -I$(ROOT)/gen/cross \
-I$(NDK)/sources/cxx-stl/gnu-libstdc++/$(NDK_TOOLCHAIN_VERSION)/include \
-I$(NDK)/sources/cxx-stl/gnu-libstdc++/$(NDK_TOOLCHAIN_VERSION)/libs/armeabi/include
export CROSS_FLAGS
COMMON_FLAGS=-ggdb -DFB_SEND_FLAGS=MSG_NOSIGNAL -DLINUX -DANDROID -DARM -pipe -MMD -fPIC -fmessage-length=0 \
-I$(ROOT)/extern/libtommath -I$(ROOT)/extern/libtomcrypt/src/headers \
$(CROSS_FLAGS)
OPTIMIZE_FLAGS=-fno-omit-frame-pointer
WARN_FLAGS=-Wall -Wno-switch -Wno-parentheses -Wno-unknown-pragmas -Wno-unused-variable
@ -53,7 +64,8 @@ CROSS_CONFIG=android.arme
LDFLAGS += --sysroot=$(CROSS_PLATFORM) -L$(NDK)/sources/cxx-stl/gnu-libstdc++/$(NDK_TOOLCHAIN_VERSION)/libs/armeabi \
-L$(NDK)/sources/cxx-stl/gnu-libstdc++/libs/armeabi
DroidLibs := -lm -ldl -lsupc++
DroidLibs := -lm -ldl -lsupc++ $(DECLIB)
UDR_SUPPORT_LIBS := -lgnustl_shared
LINK_LIBS = $(DroidLibs)
SO_LINK_LIBS = $(DroidLibs)

View File

@ -133,7 +133,7 @@ CAS_OPTIONS=@CAS_OPTIONS@
# multiple-precision integer library
MATHLIB=@MATHLIB@
DECLIB=-ldecFloat
DECLIB=-ldecFloat$(CROSS)
# crypt library
CRYPTLIB=@CRYPTLIB@
@ -291,6 +291,7 @@ LINK_UDR_PLUGIN_SYMBOLS = $(call LIB_LINK_MAPFILE,$(UDR_PLUGIN_VERS))
LINK_EMPTY_SYMBOLS = $(call LIB_LINK_MAPFILE,$(EMPTY_VERS))
LINK_PLUGIN_SYMBOLS = $(call LIB_LINK_MAPFILE,$(PLUGIN_VERS))
LINK_EXEC_EXPORT=-rdynamic
UDR_SUPPORT_LIBS=
LIB_PLATFORM_RPATH = -Wl,-rpath,$(1)

View File

@ -74,7 +74,7 @@ WCXXFLAGS = $(WFLAGS) $(THR_FLAGS) $(RTTI_FLAG) $(CXXFLAGS) $(GLOB_OPTIONS)
GPRE_FLAGS= -m -z -n
JRD_GPRE_FLAGS = -n -z -gds_cxx -ids
ISQL_GPRE_FLAGS = -m -z -n -ocxx
OBJECT_GPRE_FLAGS = -m -z -n -ocxx
.SUFFIXES: .c .e .epp .cpp
@ -87,7 +87,10 @@ $(OBJ)/jrd/%.cpp: $(SRC_ROOT)/jrd/%.epp
$(GPRE_CURRENT) $(JRD_GPRE_FLAGS) $(firstword $<) $@
$(OBJ)/isql/%.cpp: $(SRC_ROOT)/isql/%.epp
$(GPRE_CURRENT) $(ISQL_GPRE_FLAGS) $< $@
$(GPRE_CURRENT) $(OBJECT_GPRE_FLAGS) $< $@
$(OBJ)/burp/%.cpp: $(SRC_ROOT)/burp/%.epp
$(GPRE_CURRENT) $(OBJECT_GPRE_FLAGS) $< $@
$(OBJ)/%.cpp: $(SRC_ROOT)/%.epp
$(GPRE_CURRENT) $(GPRE_FLAGS) $(firstword $<) $@

View File

@ -20,10 +20,9 @@
#LD=@CXX@
#PROD_FLAGS=-ggdb -O3 -fno-omit-frame-pointer -DLINUX -pipe -MMD -fPIC
#DEV_FLAGS=-ggdb -DLINUX -DDEBUG_GDS_ALLOC -pipe -MMD -p -fPIC -Wall -Wno-switch
COMMON_FLAGS=-DLINUX -DARM -pipe -MMD -fPIC -fsigned-char -fmessage-length=0 -DFB_SEND_FLAGS=MSG_NOSIGNAL
PROD_FLAGS=-O3 -DLINUX -DARM -pipe -p -MMD -fPIC -fsigned-char -fmessage-length=0
DEV_FLAGS=-ggdb -DLINUX -DARM -pipe -p -MMD -fPIC -Wall -fsigned-char -fmessage-length=0 -Wno-non-virtual-dtor
PROD_FLAGS=$(COMMON_FLAGS) -O3
DEV_FLAGS=$(COMMON_FLAGS) -p -ggdb -Wall -Wno-non-virtual-dtor
CXXFLAGS := $(CXXFLAGS) -std=c++11

View File

@ -25,6 +25,7 @@
<ClCompile Include="..\..\..\src\common\CharSet.cpp" />
<ClCompile Include="..\..\..\src\common\classes\alloc.cpp" />
<ClCompile Include="..\..\..\src\common\classes\BaseStream.cpp" />
<ClCompile Include="..\..\..\src\common\classes\BlobWrapper.cpp" />
<ClCompile Include="..\..\..\src\common\classes\BlrWriter.cpp" />
<ClCompile Include="..\..\..\src\common\classes\ClumpletReader.cpp" />
<ClCompile Include="..\..\..\src\common\classes\ClumpletWriter.cpp" />
@ -110,6 +111,7 @@
<ClInclude Include="..\..\..\src\common\classes\auto.h" />
<ClInclude Include="..\..\..\src\common\classes\BaseStream.h" />
<ClInclude Include="..\..\..\src\common\classes\BatchCompletionState.h" />
<ClInclude Include="..\..\..\src\common\classes\BlobWrapper.h" />
<ClInclude Include="..\..\..\src\common\classes\BlrReader.h" />
<ClInclude Include="..\..\..\src\common\classes\BlrWriter.h" />
<ClInclude Include="..\..\..\src\common\classes\ByteChunk.h" />

View File

@ -222,6 +222,9 @@
<ClCompile Include="..\..\..\src\common\classes\TomCryptHash.cpp">
<Filter>classes</Filter>
</ClCompile>
<ClCompile Include="..\..\..\src\common\classes\BlobWrapper.cpp">
<Filter>classes</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\..\src\common\xdr_proto.h">
@ -542,5 +545,8 @@
<ClInclude Include="..\..\..\src\common\classes\BatchCompletionState.h">
<Filter>headers</Filter>
</ClInclude>
<ClInclude Include="..\..\..\src\common\classes\BlobWrapper.h">
<Filter>headers</Filter>
</ClInclude>
</ItemGroup>
</Project>

View File

@ -25,6 +25,7 @@
<ClCompile Include="..\..\..\src\common\CharSet.cpp" />
<ClCompile Include="..\..\..\src\common\classes\alloc.cpp" />
<ClCompile Include="..\..\..\src\common\classes\BaseStream.cpp" />
<ClCompile Include="..\..\..\src\common\classes\BlobWrapper.cpp" />
<ClCompile Include="..\..\..\src\common\classes\BlrWriter.cpp" />
<ClCompile Include="..\..\..\src\common\classes\ClumpletReader.cpp" />
<ClCompile Include="..\..\..\src\common\classes\ClumpletWriter.cpp" />
@ -106,6 +107,7 @@
<ClInclude Include="..\..\..\src\common\classes\auto.h" />
<ClInclude Include="..\..\..\src\common\classes\BaseStream.h" />
<ClInclude Include="..\..\..\src\common\classes\BatchCompletionState.h" />
<ClInclude Include="..\..\..\src\common\classes\BlobWrapper.h" />
<ClInclude Include="..\..\..\src\common\classes\BlrReader.h" />
<ClInclude Include="..\..\..\src\common\classes\BlrWriter.h" />
<ClInclude Include="..\..\..\src\common\classes\ByteChunk.h" />

View File

@ -222,6 +222,9 @@
<ClCompile Include="..\..\..\src\common\classes\TomCryptHash.cpp">
<Filter>classes</Filter>
</ClCompile>
<ClCompile Include="..\..\..\src\common\classes\BlobWrapper.cpp">
<Filter>classes</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\..\src\common\xdr_proto.h">
@ -542,5 +545,8 @@
<ClInclude Include="..\..\..\src\common\classes\BatchCompletionState.h">
<Filter>headers</Filter>
</ClInclude>
<ClInclude Include="..\..\..\src\common\classes\BlobWrapper.h">
<Filter>headers</Filter>
</ClInclude>
</ItemGroup>
</Project>

View File

@ -25,6 +25,7 @@
<ClCompile Include="..\..\..\src\common\CharSet.cpp" />
<ClCompile Include="..\..\..\src\common\classes\alloc.cpp" />
<ClCompile Include="..\..\..\src\common\classes\BaseStream.cpp" />
<ClCompile Include="..\..\..\src\common\classes\BlobWrapper.cpp" />
<ClCompile Include="..\..\..\src\common\classes\BlrWriter.cpp" />
<ClCompile Include="..\..\..\src\common\classes\ClumpletReader.cpp" />
<ClCompile Include="..\..\..\src\common\classes\ClumpletWriter.cpp" />
@ -106,6 +107,7 @@
<ClInclude Include="..\..\..\src\common\classes\auto.h" />
<ClInclude Include="..\..\..\src\common\classes\BaseStream.h" />
<ClInclude Include="..\..\..\src\common\classes\BatchCompletionState.h" />
<ClInclude Include="..\..\..\src\common\classes\BlobWrapper.h" />
<ClInclude Include="..\..\..\src\common\classes\BlrReader.h" />
<ClInclude Include="..\..\..\src\common\classes\BlrWriter.h" />
<ClInclude Include="..\..\..\src\common\classes\ByteChunk.h" />

View File

@ -222,6 +222,9 @@
<ClCompile Include="..\..\..\src\common\classes\TomCryptHash.cpp">
<Filter>classes</Filter>
</ClCompile>
<ClCompile Include="..\..\..\src\common\classes\BlobWrapper.cpp">
<Filter>classes</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\..\src\common\xdr_proto.h">
@ -542,5 +545,8 @@
<ClInclude Include="..\..\..\src\common\classes\BatchCompletionState.h">
<Filter>headers</Filter>
</ClInclude>
<ClInclude Include="..\..\..\src\common\classes\BlobWrapper.h">
<Filter>headers</Filter>
</ClInclude>
</ItemGroup>
</Project>

View File

@ -55,10 +55,7 @@ goto :EOF
:BOOT_PROCESS
@echo.
@set GPRE=%FB_BIN_DIR%\gpre_boot -lang_internal
@for %%i in (array, blob) do @call :PREPROCESS yvalve %%i
@for %%i in (metd, DdlNodes, PackageNodes) do @call :PREPROCESS dsql %%i -gds_cxx
@for %%i in (gpre_meta) do @call :PREPROCESS gpre/std %%i
@for %%i in (backup, restore, OdsDetection) do @call :PREPROCESS burp %%i
@for %%i in (backup, restore, OdsDetection) do @call :PREPROCESS burp %%i -ocxx -m
@for %%i in (extract, isql, show) do @call :PREPROCESS isql %%i -ocxx
@for %%i in (dba) do @call :PREPROCESS utilities/gstat %%i
@ -76,7 +73,7 @@ goto :EOF
@set GPRE=%FB_BIN_DIR%\gpre
@for %%i in (alice_meta) do @call :PREPROCESS alice %%i
@for %%i in (LegacyManagement) do @call :PREPROCESS auth/SecurityDatabase %%i
@for %%i in (backup, restore, OdsDetection) do @call :PREPROCESS burp %%i
@for %%i in (backup, restore, OdsDetection) do @call :PREPROCESS burp %%i -ocxx -m
@for %%i in (array, blob) do @call :PREPROCESS yvalve %%i
@for %%i in (metd) do @call :PREPROCESS dsql %%i -gds_cxx
@for %%i in (DdlNodes, PackageNodes) do @call :PREPROCESS dsql %%i -gds_cxx

View File

@ -249,6 +249,18 @@ dnl CPU_TYPE=ppc64
libdir=/usr/lib64
;;
riscv64*-*-linux*)
MAKEFILE_PREFIX=linux_riscv64
INSTALL_PREFIX=linux
PLATFORM=LINUX
AC_DEFINE(LINUX, 1, [Define this if OS is Linux])
EDITLINE_FLG=Y
SHRLIB_EXT=so
STD_EDITLINE=true
STD_ICU=true
libdir=/usr/lib64
;;
powerpc64le-*-linux*)
MAKEFILE_PREFIX=linux_powerpc64el
INSTALL_PREFIX=linux
@ -1211,7 +1223,6 @@ dnl ### GEN ### directories for databases and misc
dnl # output
mkdir -p gen/\$fb_tgt/include
mkdir -p gen/\$fb_tgt/intl
mkdir -p gen/\$fb_tgt/firebird/UDF
mkdir -p gen/\$fb_tgt/firebird/bin
mkdir -p gen/\$fb_tgt/firebird/plugins
mkdir -p gen/\$fb_tgt/firebird/examples/api
@ -1238,11 +1249,6 @@ dnl ### TEMP ### directories for generated .cpp, .o and .d by module name
done
src/misc/writeBuildNum.sh createMakeVersion gen/Make.Version
dnl # sql files for UDF declarations
for sql_file in ib_udf.sql fbudf/fbudf.sql ib_udf2.sql; do
cp src/extlib/\$sql_file gen/\$fb_tgt/firebird/UDF
done
done
dnl # rebuild version header if needed

View File

@ -3,27 +3,16 @@
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
<title></title>
<meta name="generator" content="LibreOffice 5.2.7.2 (Linux)"/>
<meta name="generator" content="LibreOffice 5.4.5.1 (Linux)"/>
<meta name="author" content="alex "/>
<meta name="created" content="00:00:00"/>
<meta name="changed" content="2017-10-19T18:08:13.851823604"/>
<meta name="created" content="2013-05-31T00:00:00.010003100"/>
<meta name="changed" content="2018-05-10T18:16:59.126724786"/>
<meta name="created" content="00:00:00">
<meta name="created" content="00:00:00">
<meta name="changed" content="2017-10-12T20:21:46.080329427">
<meta name="created" content="00:00:00">
<meta name="changed" content="2017-10-10T12:13:42.449014488">
<meta name="created" content="00:00:00">
<meta name="changed" content="2017-07-27T13:17:58.205479048">
<meta name="created" content="00:00:00">
<meta name="changed" content="2017-07-26T10:39:38.045248271">
<meta name="changed" content="2017-10-16T18:57:56.725603578"/>
<meta name="created" content="00:00:00">
<meta name="changed" content="2017-02-02T17:00:07.121995034">
<meta name="created" content="2013-05-31T00:00:00.010003100">
<meta name="changed" content="2017-01-31T17:08:57.272616325">
<meta name="CHANGEDBY" content="Alex Peshkoff">
<meta name="CHANGEDBY" content="Alex Peshkoff">
<meta name="CHANGEDBY" content="Alex Peshkoff">
<meta name="CHANGEDBY" content="Alex Peshkoff">
<style type="text/css">
@page { size: 21.59cm 27.94cm; margin: 2.01cm }
h1 { color: #000000 }
@ -44,10 +33,9 @@ independent</b></font> <font size="4" style="font-size: 14pt">that
means that to define/use them one need not use language specific
constructions like </font><font size="4" style="font-size: 14pt"><i>class</i></font>
<font size="4" style="font-size: 14pt">in C++, interface may be
defined using any language </font><font size="4" style="font-size: 14pt">able
to call functions using C calling conventions and </font><font size="4" style="font-size: 14pt">having
concepts of array and pointer to procedure/function. Next interfaces
are </font><span style="font-variant: normal"><font size="4" style="font-size: 14pt"><span style="font-style: normal"><b>versioned</b></span></font></span>
defined using any language able to call functions using C calling
conventions and having concepts of array and pointer to
procedure/function. Next interfaces are </font><span style="font-variant: normal"><font size="4" style="font-size: 14pt"><span style="font-style: normal"><b>versioned</b></span></font></span>
<font size="4" style="font-size: 14pt">i.e. we support different
versions of same interface. Binary layout of interfaces is designed
to support that features very efficient (there is no need in
@ -1326,13 +1314,12 @@ implementation into dynamic library (.dll in windows or .so in linux)
later referenced as </font><font size="4" style="font-size: 14pt"><i>plugin
module</i></font> <font size="4" style="font-size: 14pt">or just
</font><font size="4" style="font-size: 14pt"><i>module</i></font><font size="4" style="font-size: 14pt">.
In most cases single plugin is place</font><font size="4" style="font-size: 14pt">d</font><font size="4" style="font-size: 14pt">
in</font><font size="4" style="font-size: 14pt">to</font><font size="4" style="font-size: 14pt">
dynamic library but in common case </font><font size="4" style="font-size: 14pt">multiple
plugins may coexist in single dynamic library</font><font size="4" style="font-size: 14pt">.
One of that interfaces <a href="#PluginModule">IPluginModule</a>
is module-wide (as more or less clear from it's name), others are
per plugin. Also each plugin module should contain special exported
In most cases single plugin is placed</font> <font size="4" style="font-size: 14pt">into</font>
<font size="4" style="font-size: 14pt">dynamic library but in common
case multiple plugins may coexist in single dynamic library. One of
that interfaces <a href="#PluginModule">IPluginModule</a> is
module-wide (as more or less clear from it's name), others are per
plugin. Also each plugin module should contain special exported
entrypoint firebird_plugin() which name is defined in include file
firebird/Interfaces.h as FB_PLUGIN_ENTRY_POINT.</font></p>
<p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">In
@ -1844,17 +1831,15 @@ parameters in single statement execution.</font></p>
<li/>
<p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">void
addBlob(StatusType* status, unsigned</font> <font size="4" style="font-size: 14pt">length,
const void* inBuffer, ISC_QUAD* blobId, </font><font size="4" style="font-size: 14pt">unsigned
bpbLength, const unsigned char* bpb</font><font size="4" style="font-size: 14pt">)
adds single blob having length bytes from inBuffer to the batch,
blob identifier is located at blobId address. </font><font size="4" style="font-size: 14pt">If
blob should be created with non-default parameters BPB may be passed
(format matches one used in <a href="#Attachment">Attachment</a>::createBlob).</font><font size="4" style="font-size: 14pt">Total
size of inline blobs that can be added to the batch </font><font size="4" style="font-size: 14pt">(including
const void* inBuffer, ISC_QUAD* blobId, unsigned bpbLength, const
unsigned char* bpb) adds single blob having length bytes from
inBuffer to the batch, blob identifier is located at blobId address.
If blob should be created with non-default parameters BPB may be
passed (format matches one used in <a href="#Attachment">Attachment</a>::createBlob).Total
size of inline blobs that can be added to the batch (including
optional BPBs, blob headers, segment sizes and taking into an
accoount alignment) </font><font size="4" style="font-size: 14pt">is
limited by BUFFER_BYTES_SIZE <a href="#Batch_PB">parameter</a> of
batch creation (affects all blob-oriented methods except
accoount alignment) is limited by BUFFER_BYTES_SIZE <a href="#Batch_PB">parameter</a>
of batch creation (affects all blob-oriented methods except
registerBlob()). </font>
</p>
<li/>
@ -2381,7 +2366,7 @@ with execution of SQL statements.</font></p>
<li/>
<p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">unsigned
getMessageLength(StatusType* status) - returns length of message
buffer (use it to allocate memory for the buffer).</font></font></p>
buffer (use it to allocate memory for the buffer).</font></p>
<li/>
<p><font face="Liberation Serif, serif"><font size="4" style="font-size: 14pt"><span style="background: #ffffff">unsigned
getAlignment(StatusType* status) returns alignment required for
@ -2780,7 +2765,7 @@ interface replaces (partially) isc_stmt_handle.</font></p>
outMetadata, void* outBuffer) executes any SQL statement except
returning multiple rows of data. Partial analogue of
isc_dsql_execute2() - in and out XSLQDAs replaced with input and
output messages with appropriate buffers.</font></font></p>
output messages with appropriate buffers.</font></p>
<li/>
<p style="margin-bottom: 0cm"><font face="Liberation Serif, serif"><font size="4" style="font-size: 14pt">IResultSet*
openCursor(StatusType* status, ITransaction* transaction,
@ -3771,7 +3756,9 @@ interface is main interface of database crypt key holder plugin.</font></p>
interface (if provided by user with <a href="#Provider">Provider</a>::setDbCryptCallback()
call). This call is always performed at database attach moment, and
some holders may reject attachment if satisfactory key was not
provided.</font></p>
provided. </font><font size="4" style="font-size: 14pt">Return value
of 0 means that key holder can not provide a key to crypt plugin,
non-zero can.</font></p>
<li/>
<p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">ICryptKeyCallback*
keyHandle(StatusType* status, const char* keyName) is intended
@ -3787,12 +3774,12 @@ interface is main interface of database crypt key holder plugin.</font></p>
<li/>
<p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">FB_BOOLEAN
useOnlyOwnKeys(StatusType* status) informs firebird engine
whether a key, provided by key holder, can be used in other attachments.
Makes sense only for SuperServer only it can share database crypt keys
between attachments. Returning FB_TRUE from this method enforces
firebird to make sure that this particular key holder (and therefore
in turn attachment related to it) provides correct crypt key for
any other attachment to this database.</font></p>
whether a key, provided by key holder, can be used in other
attachments. Makes sense only for SuperServer only it can share
database crypt keys between attachments. Returning FB_TRUE from this
method enforces firebird to make sure that this particular key
holder (and therefore in turn attachment related to it) provides
correct crypt key for any other attachment to this database.</font></p>
<li/>
<p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">ICryptKeyCallback*
chainHandle(StatusType* status) support of a chain of key

View File

@ -116,23 +116,25 @@ DECFLOAT (FB 4.0)
Alex Peshkoff <peshkoff@mail.ru>
Syntax rules:
DECFLOAT
DECFLOAT(16)
DECFLOAT(34)
Storage:
64-bit / 128-bit, format according to IEEE 754.
64-bit / 128-bit, format according to IEEE 754 Decimal64/Decimal128
Example(s):
1. DECLARE VARIABLE VAR1 DECFLOAT(34);
2. CREATE TABLE TABLE1 (FIELD1 DECFLOAT(16));
Note(s):
1. A number of standard functions can be used with DECFLOAT datatype. It is:
1. If no precision has been specified in the type declaration, the precision is 34.
2. A number of standard functions can be used with DECFLOAT datatype. It is:
ABS, CEILING, EXP, FLOOR, LN, LOG, LOG10, POWER, SIGN, SQRT.
Agregate functions SUM, AVG, MAX and MIN also work with DECFLOAT data.
All statistics aggregates (like but not limited to STDDEV or CORR) work with DECFLOAT data.
2. Firebird supports four functions, specially designed to support DECFLOAT data:
3. Firebird supports four functions, specially designed to support DECFLOAT data:
- COMPARE_DECFLOAT - compares two DECFLOAT values to be equal, different or unordered.
Returns SMALLINT value which can be as follows:
0 - values are equal
@ -155,18 +157,18 @@ DECFLOAT (FB 4.0)
DECFLOAT values are ordered as follows:
-nan < -snan < -inf < -0.1 < -0.10 < -0 < 0 < 0.10 < 0.1 < inf < snan < nan
3. Firebird supports new session control operator SET DECFLOAT. It has following forms:
4. Firebird supports new session control operator SET DECFLOAT. It has following forms:
SET DECFLOAT ROUND <mode> - controls rounding mode used in operations with DECFLOAT
values. Valid modes are: CEILING (towards +infinity), UP (away from 0), HALF_UP
(to nearest, if equidistant - up), HALF_EVEN (to nearest, if equidistant - ensure
last digit in the result to be even), HALF_DOWN (to nearest, if equidistant - down),
DOWN (towards 0), FLOOR (towards -infinity), REROUND (up if digit to be rounded is
0 or 5, down in other cases).
0 or 5, down in other cases). HALF_UP rounding is used by default.
SET DECFLOAT TRAPS TO <comma-separated traps list - may be empty> - controls which
exceptional conditions cause a trap. Valid traps are: Division_by_zero, Inexact,
Invalid_operation, Overflow and Underflow. By default traps are set to:
Division_by_zero, Invalid_operation, Overflow, Underflow.
Division_by_zero, Invalid_operation, Overflow.
SET DECFLOAT BIND <bind-type> - controls how are DECFLOAT values represented in outer
world (i.e. in messages or in XSQLDA). Valid binding types are: NATIVE (use IEEE754
@ -177,10 +179,11 @@ DECFLOAT (FB 4.0)
native format. One can choose between strings (ideal precision, but poor support
for further processing), floating point values (ideal support for further processing
but poor precision) or scaled integers (good support for further processing and
required precision but range of values is very limited). When using is a tool like
generic purporse GUI client choice of CHAR binding is OK in most cases.
required precision but range of values is very limited). When using in a tool like
generic purporse GUI client choice of CHAR binding is OK in most cases. By default
NATIVE binding is used.
4. The length of DECFLOAT literals are limited to 1024 characters. For longer values, you will
5. The length of DECFLOAT literals are limited to 1024 characters. For longer values, you will
need to use the scientific notation. For example, the 0.0<1020 zeroes>11 cannot be used
as a literal, instead you can use the equivalent in scientific notation: 1.1E-1022.
Similarly 10<1022 zeroes>0 can be presented as 1.0E1024.

View File

@ -2,21 +2,24 @@
SQL keywords introduced in different server versions
----------------------------------------------------
An asterisk (*) mark shows that a keyword doesn't exist in the SQL specification
and hence should be considered a non-standard language extention.
Deviations from the standard:
* : keyword does not exist in the SQL:2016 specification and should be
considered a non-standard language extention.
(1) : reserved word in SQL:2016, non-reserved in Firebird
(2) : non-reserved word in SQL:2016, reserved word in Firebird
Firebird 1.0
------------
Added as reserved words:
CURRENT_USER
CURRENT_ROLE
BREAK *
DESCRIPTOR
FIRST
CURRENT_ROLE
CURRENT_USER
DESCRIPTOR (2)
FIRST (2)
RECREATE *
SKIP *
SKIP
SUBSTRING
Firebird 1.5
@ -24,42 +27,42 @@ Firebird 1.5
Added as reserved words:
CURRENT_CONNECTION *
CURRENT_TRANSACTION *
BIGINT
CASE
CURRENT_CONNECTION *
CURRENT_TRANSACTION *
RELEASE
ROW_COUNT
SAVEPOINT
Added as non-reserved words:
COALESCE
COALESCE (1)
DELETING *
INSERTING *
LAST
LEAVE
LEAVE *
LOCK *
NULLIF
NULLIF (1)
NULLS
STATEMENT
UPDATING *
USING
USING (1)
Moved from reserved words to non-reserved:
BREAK *
DESCRIPTOR
FIRST
SKIP *
SUBSTRING
SKIP (1)
SUBSTRING (1)
Firebird 2.0
------------
Added as reserved words:
BIT_LENGTH
BIT_LENGTH *
BOTH
CHAR_LENGTH
CHARACTER_LENGTH
@ -90,7 +93,7 @@ Firebird 2.0
SCALAR_ARRAY *
SEQUENCE
RESTART
RETURNING *
RETURNING
Moved from reserved words to non-reserved:
@ -129,49 +132,49 @@ Firebird 2.1
Added as non-reserved words:
ABS
ABS (1)
ACCENT *
ACOS *
ALWAYS *
ACOS (1)
ALWAYS
ASCII_CHAR *
ASCII_VAL *
ASIN *
ATAN *
ASIN (1)
ATAN (1)
ATAN2 *
BIN_AND *
BIN_OR *
BIN_SHL *
BIN_SHR *
BIN_XOR *
CEIL
CEILING
COS *
COSH *
CEIL (1)
CEILING (1)
COS (1)
COSH (1)
COT *
DATEADD *
DATEDIFF *
DECODE *
EXP
FLOOR
EXP (1)
FLOOR (1)
GEN_UUID *
GENERATED
HASH *
LIST *
LN
LOG *
LOG10 *
LN (1)
LOG (1)
LOG10 (1)
LPAD *
MATCHED
MATCHING *
MAXVALUE *
MAXVALUE
MILLISECOND *
MINVALUE *
MOD
OVERLAY
MINVALUE
MOD (1)
OVERLAY (1)
PAD
PI *
PLACING
POWER
POWER (1)
PRESERVE
RAND *
REPLACE *
@ -179,12 +182,12 @@ Firebird 2.1
ROUND *
RPAD *
SIGN *
SIN *
SINH *
SIN (1)
SINH (1)
SPACE
SQRT
TAN *
TANH *
SQRT (1)
TAN (1)
TANH (1)
TEMPORARY
TRUNC *
WEEK *
@ -210,11 +213,10 @@ Firebird 2.5
MIDDLENAME *
MAPPING *
OS_NAME *
SOURCE *
SOURCE
TWO_PHASE *
UUID_TO_CHAR *
Firebird 3.0
------------
@ -224,10 +226,8 @@ Firebird 3.0
CORR
COVAR_POP
COVAR_SAMP
DELETING *
DETERMINISTIC
FALSE
INSERTING *
OFFSET
OVER
RDB$RECORD_VERSION *
@ -243,15 +243,22 @@ Firebird 3.0
RETURN
ROW
SCROLL
SQLSTATE *
SQLSTATE
STDDEV_POP
STDDEV_SAMP
TRUE
UNKNOWN
UPDATING *
VAR_POP
VAR_SAMP
Moved from non-reserved words to reserved:
DELETING *
INSERTING *
RDB$GET_CONTEXT *
RDB$SET_CONTEXT *
UPDATING *
Added as non-reserved words:
ABSOLUTE
@ -262,53 +269,72 @@ Firebird 3.0
CONTINUE
DDL *
DECRYPT *
DENSE_RANK
DENSE_RANK (1)
ENCRYPT *
ENGINE *
FIRST_VALUE
IDENTITY
FIRST_VALUE (1)
IDENTITY (1)
INCREMENT
LAST_VALUE
LAG
LEAD
LAST_VALUE (1)
LAG (1)
LEAD (1)
LINGER *
NAME
NTH_VALUE
NTH_VALUE (1)
PACKAGE *
PARTITION
PARTITION (1)
PLUGIN *
PRIOR
RANK
RANK (1)
RELATIVE
ROW_NUMBER
ROW_NUMBER (1)
SERVERWIDE *
TAGS *
TRUSTED *
USAGE
Firebird 4.0
------------
Added as reserved words:
UNBOUNDED
WINDOW
BINARY
DECFLOAT
RDB$ERROR *
RDB$ROLE_IN_USE *
RDB$SYSTEM_PRIVILEGE *
UNBOUNDED (2)
VARBINARY
WINDOW
Added as non-reserved words:
CUME_DIST *
BIND *
COMPARE_DECFLOAT *
CUME_DIST (1)
DEFINER
EXCLUDE
FIRST_DAY *
FOLLOWING
NTILE *
IDLE *
INVOKER
LAST_DAY *
MESSAGE *
NATIVE *
NORMALIZE_DECFLOAT *
NTILE (1)
OTHERS
PERCENT_RANK *
OVERRIDING
PERCENT_RANK (1)
PRECEDING
PRIVILEGE *
RANGE *
RDB$ROLE_IN_USE *
RDB$SYSTEM_PRIVILEGE *
SYSTEM *
QUANTIZE *
RANGE (1)
RESET *
SECURITY
SESSION
SQL (1)
SYSTEM (1)
TIES
TOTALORDER *
TRAPS *

View File

@ -56,6 +56,8 @@ public:
pluginManager = NULL;
}
void threadDetach() {};
private:
IPluginManager* pluginManager;
};

View File

@ -58,6 +58,8 @@ public:
pluginManager = NULL;
}
void threadDetach() {};
private:
IPluginManager* pluginManager;
};

View File

@ -47,6 +47,7 @@ Type
// TPluginModule implementation
procedure doClean; override;
procedure threadDetach; override;
end;
TMyCrypt = class(IDbCryptPluginImpl)
@ -71,6 +72,7 @@ Type
procedure setKey(status: IStatus; length: Cardinal; sources: IKeyHolderPluginPtr; keyName: PAnsiChar); override;
procedure encrypt(status: IStatus; length: Cardinal; src, dst: Pointer); override;
procedure decrypt(status: IStatus; length: Cardinal; src, dst: Pointer); override;
procedure setInfo(status: IStatus; info: IDbCryptInfo); override;
private
procedure pxor(length: Cardinal; mem: Pointer);
@ -114,6 +116,10 @@ begin
FRegistered := False;
end;
procedure TMyPluginModule.threadDetach;
begin
end;
procedure TMyPluginModule.registerMe;
begin
if not FRegistered then
@ -179,6 +185,13 @@ begin
Result := FOwner;
end;
procedure TMyCrypt.setInfo(status: IStatus; info: IDbCryptInfo);
begin
status.init;
// do nothing in this trivial sample
end;
procedure TMyCrypt.decrypt(status: IStatus; length: Cardinal; src, dst: Pointer);
begin
status.init;

View File

@ -153,6 +153,91 @@ FB_UDR_BEGIN_FUNCTION(sum_args)
FB_UDR_END_FUNCTION
/***
create function mult (
a decfloat(34) not null,
b decimal(34,6) not null
) returns decfloat(34) not null
external name 'udrcpp_example!mult'
engine udr;
***/
FB_UDR_BEGIN_FUNCTION(mult)
// Without InMessage/OutMessage definitions, messages will be byte-based.
FB_UDR_CONSTRUCTOR
{
AutoRelease<IMessageMetadata> inMetadata(metadata->getInputMetadata(status));
aOffset = inMetadata->getOffset(status, 0);
bOffset = inMetadata->getOffset(status, 1);
AutoRelease<IMessageMetadata> outMetadata(metadata->getOutputMetadata(status));
outOffset = outMetadata->getOffset(status, 0);
outNullOffset = outMetadata->getNullOffset(status, 0);
df34 = master->getUtilInterface()->getDecFloat34(status);
}
// This function requires the INTEGER parameters and return value, otherwise it will crash.
// Metadata is inspected dynamically (in execute). This is not the fastest method.
FB_UDR_EXECUTE_FUNCTION
{
struct ExampleBCD
{
unsigned char bcd[IDecFloat34::BCD_SIZE];
int sign, exp;
void load(void* from, IDecFloat34* df34)
{
df34->toBcd((FB_DEC34*) from, &sign, bcd, &exp);
}
void store(void* to, IDecFloat34* df34) const
{
df34->fromBcd(sign, bcd, exp, (FB_DEC34*) to);
}
};
ExampleBCD a, b, rc;
a.load(in + aOffset, df34);
b.load(in + bOffset, df34);
// multiply (trivial example - a lot of features are missing)
rc.sign = a.sign ^ b.sign;
rc.exp = a.exp + b.exp;
unsigned char buf[2 * IDecFloat34::BCD_SIZE + 1];
memset(buf, 0, sizeof(buf));
for (unsigned i = IDecFloat34::BCD_SIZE; i--;)
{
for (unsigned j = IDecFloat34::BCD_SIZE; j--;)
{
unsigned char v = a.bcd[i] * b.bcd[j] + buf[i + j + 1];
buf[i + j + 1] = v % 10;
buf[i + j] += v / 10;
}
}
unsigned offset = 0;
for (; offset < IDecFloat34::BCD_SIZE; ++offset)
{
if (buf[offset])
break;
}
memcpy(rc.bcd, buf + offset, sizeof rc.bcd);
rc.exp += (IDecFloat34::BCD_SIZE - offset);
rc.store(out + outOffset, df34);
*(ISC_SHORT*) (out + outNullOffset) = FB_FALSE;
}
unsigned aOffset, bOffset, outOffset, outNullOffset;
IDecFloat34* df34;
FB_UDR_END_FUNCTION
//------------------------------------------------------------------------------

View File

@ -882,6 +882,8 @@ void PascalGenerator::generate()
{
fprintf(out, "{ %s }\n\n", AUTOGEN_MSG);
fprintf(out, "{$IFDEF FPC}\n{$MODE DELPHI}\n{$OBJECTCHECKS OFF}\n{$ENDIF}\n\n");
fprintf(out, "unit %s;\n\n", unitName.c_str());
fprintf(out, "interface\n\n");
fprintf(out, "uses Classes");

View File

@ -1,5 +1,10 @@
{ This file was autogenerated by cloop - Cross Language Object Oriented Programming }
{$IFDEF FPC}
{$MODE DELPHI}
{$OBJECTCHECKS OFF}
{$ENDIF}
unit CalcPascalApi;
interface

View File

@ -1,11 +1,11 @@
LIBRARY=libdecFloat.a
LIBRARY=libdecFloat$(CROSS).a
$(LIBRARY): $(wildcard *.c) $(wildcard *.h) Makefile
$(RM) -f *.o
$(CC) -c -O3 -fPIC $(subst decCommon.c,,$(subst decBasic.c,,$(wildcard *.c)))
$(CC) $(CROSS_FLAGS) -c -O3 -fPIC $(subst decCommon.c,,$(subst decBasic.c,,$(wildcard *.c)))
$(AR) crs $(LIBRARY) *.o
$(RM) -f *.o
.PHONY: clean
clean:
$(RM) -f *.o $(LIBRARY)
$(RM) -f *.o *.a

View File

@ -1,5 +1,6 @@
lib/
temp/
*.o
*.d
*.l*
.libs/

View File

@ -1820,6 +1820,8 @@ C --
PARAMETER (GDS__vld_plugins = 335545203)
INTEGER*4 GDS__db_crypt_key
PARAMETER (GDS__db_crypt_key = 335545204)
INTEGER*4 GDS__no_keyholder_plugin
PARAMETER (GDS__no_keyholder_plugin = 335545205)
INTEGER*4 GDS__gfix_db_name
PARAMETER (GDS__gfix_db_name = 335740929)
INTEGER*4 GDS__gfix_invalid_sw

View File

@ -1815,6 +1815,8 @@ const
gds_vld_plugins = 335545203;
isc_db_crypt_key = 335545204;
gds_db_crypt_key = 335545204;
isc_no_keyholder_plugin = 335545205;
gds_no_keyholder_plugin = 335545205;
isc_gfix_db_name = 335740929;
gds_gfix_db_name = 335740929;
isc_gfix_invalid_sw = 335740930;

View File

@ -29,7 +29,6 @@ set(epp_boot_internal_files
burp/backup.epp
burp/restore.epp
burp/OdsDetection.epp
utilities/gstat/dba.epp
)
set(epp_boot_ocxx_files
isql/extract.epp
@ -42,6 +41,7 @@ set(epp_boot_files
utilities/stats.epp
yvalve/array.epp
yvalve/blob.epp
utilities/gstat/dba.epp
)
set(epp_boot_gds_files
dsql/metd.epp
@ -53,7 +53,7 @@ set(epp_boot_gds_files
jrd/fun.epp
jrd/grant.epp
jrd/ini.epp
jrd/met.epp
jrd/met.epp
jrd/scl.epp
jrd/Function.epp
)
@ -69,12 +69,12 @@ set(epp_master_files
if (NOT CMAKE_CROSSCOMPILING)
epp_process(boot epp_boot_internal_files ${GPRE_BOOT_CMD} -lang_internal -n -m)
epp_process(boot epp_boot_internal_files ${GPRE_BOOT_CMD} -lang_internal -n -ids -ocxx -m)
epp_process(boot epp_boot_ocxx_files ${GPRE_BOOT_CMD} -lang_internal -n -ids -ocxx)
epp_process(boot epp_boot_files ${GPRE_BOOT_CMD} -n -m)
epp_process(boot epp_boot_gds_files ${GPRE_BOOT_CMD} -n -ids -gds_cxx)
epp_process(master epp_boot_internal_files ${BOOT_GPRE_CMD} -n -m)
epp_process(master epp_boot_internal_files ${BOOT_GPRE_CMD} -n -m -ids -ocxx -m)
epp_process(master epp_boot_ocxx_files ${BOOT_GPRE_CMD} -n -ids -ocxx)
epp_process(master epp_boot_files ${BOOT_GPRE_CMD} -n -m)
epp_process(master epp_boot_gds_files ${BOOT_GPRE_CMD} -n -ids -gds_cxx)
@ -469,9 +469,9 @@ set(engine_src ${engine_src}
lock/lock.cpp
utilities/gsec/gsec.cpp
utilities/gstat/ppg.cpp
utilities/nbackup/nbackup.cpp
utilities/nbackup/nbackup.cpp
# parse
${GENERATED_DIR}/dsql/parse.cpp
${GENERATED_DIR}/dsql/parse.cpp
)
add_src_apple(engine_src
jrd/os/posix/unix.cpp
@ -487,7 +487,7 @@ set(engine_generated_src
jrd/Function.epp
jrd/grant.epp
jrd/ini.epp
jrd/met.epp
jrd/met.epp
jrd/scl.epp
utilities/gstat/dba.epp
)
@ -910,7 +910,7 @@ add_custom_target(copy_files
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${GENERATED_DIR}/security.fdb ${output_dir}/security4.fdb
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${GENERATED_DIR}/help.fdb ${output_dir}/help/help.fdb
# configs, text files
COMMAND sed "/@UDF_COMMENT@/d" < ${CMAKE_SOURCE_DIR}/builds/install/misc/firebird.conf.in > ${output_dir}/firebird.conf
COMMAND sed "/@UDF_COMMENT@/d" < ${CMAKE_SOURCE_DIR}/builds/install/misc/firebird.conf.in > ${output_dir}/firebird.conf
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_SOURCE_DIR}/builds/install/misc/databases.conf.in ${output_dir}/databases.conf
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_SOURCE_DIR}/builds/install/misc/fbintl.conf ${output_dir}/intl/fbintl.conf
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_SOURCE_DIR}/builds/install/misc/plugins.conf ${output_dir}/plugins.conf
@ -934,7 +934,7 @@ add_custom_target(copy_files
COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_SOURCE_DIR}/examples/udr ${output_dir}/examples/udr
COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_SOURCE_DIR}/examples/stat ${output_dir}/examples/stat
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_SOURCE_DIR}/examples/functions.c ${output_dir}/examples/functions.c
# headers
# headers
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_SOURCE_DIR}/src/extlib/ib_util.h ${output_dir}/include/ib_util.h
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_SOURCE_DIR}/src/include/gen/iberror.h ${output_dir}/include/iberror.h
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_SOURCE_DIR}/src/yvalve/perf.h ${output_dir}/include/perf.h
@ -986,7 +986,7 @@ if (WIN32)
# installers
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_SOURCE_DIR}/builds/install/arch-specific/win32/install_classic.bat ${output_dir}/install_classic.bat
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_SOURCE_DIR}/builds/install/arch-specific/win32/install_super.bat ${output_dir}/install_super.bat
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_SOURCE_DIR}/builds/install/arch-specific/win32/uninstall.bat ${output_dir}/uninstall.bat
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_SOURCE_DIR}/builds/install/arch-specific/win32/uninstall.bat ${output_dir}/uninstall.bat
# examples
COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_SOURCE_DIR}/examples/build_unix ${output_dir}/examples/build_unix
COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_SOURCE_DIR}/examples/build_win32 ${output_dir}/examples/build_win32
@ -995,7 +995,7 @@ if (WIN32)
COMMAND echo "#pragma message(\"Non-production version of ibase.h.\")" > ${output_dir}/include/ibase.tmp
COMMAND echo "#pragma message(\"Using raw, unprocessed concatenation of header files.\")" >> ${output_dir}/include/ibase.tmp
)
set(files
set(files
${CMAKE_SOURCE_DIR}/src/misc/ibase_header.txt
${CMAKE_SOURCE_DIR}/src/include/types_pub.h
${CMAKE_SOURCE_DIR}/src/common/dsc_pub.h

View File

@ -199,7 +199,7 @@ private:
}
else
{
sql.printf("GRANT %s TO \"%s\"", ADMIN_ROLE, userName.c_str());
sql.printf("GRANT DEFAULT %s TO \"%s\"", ADMIN_ROLE, userName.c_str());
}
att->execute(&statusWrapper, tra, sql.length(), sql.c_str(),

View File

@ -64,8 +64,11 @@ namespace
DATABASE DB = STATIC FILENAME "yachts.lnk";
#define DB tdgbl->db_handle
#define fbTrans tdgbl->tr_handle
#define gds_trans tdgbl->tr_handle
#define isc_status tdgbl->status_vector
#define fbStatus (&tdgbl->status_vector)
#define isc_status (&tdgbl->status_vector)
#define gds_status (&tdgbl->status_vector)
void detectRuntimeODS()
@ -91,7 +94,7 @@ void detectRuntimeODS()
// and rdb$field_name = 'RDB$SYSTEM_FLAG';
int count = 0;
isc_req_handle req_handle = 0;
Firebird::IRequest* req_handle = nullptr;
FOR (REQUEST_HANDLE req_handle)
RFR IN RDB$RELATION_FIELDS
WITH (RFR.RDB$RELATION_NAME = 'RDB$RELATIONS' OR RFR.RDB$RELATION_NAME = 'RDB$RELATION_FIELDS')
@ -106,7 +109,7 @@ void detectRuntimeODS()
if (count != 2)
return;
isc_req_handle req_handle2 = 0;
Firebird::IRequest* req_handle2 = nullptr;
for (const rel_field_t* rel = relations; rel->relation; ++rel)
{
FOR (REQUEST_HANDLE req_handle2)
@ -125,7 +128,7 @@ void detectRuntimeODS()
if (tdgbl->runtimeODS < DB_VERSION_DDL8)
return;
isc_req_handle req_handle3 = 0;
Firebird::IRequest* req_handle3 = nullptr;
for (const rel_field_t* rf = rel_fields; rf->relation; ++rf)
{
FOR (REQUEST_HANDLE req_handle3)

View File

@ -57,11 +57,12 @@
#include "../common/prett_proto.h"
#endif
#include "../common/classes/UserBlob.h"
#include "../common/classes/BlobWrapper.h"
#include "../common/classes/MsgPrint.h"
#include "../burp/OdsDetection.h"
using MsgFormat::SafeArg;
using Firebird::FbLocalStatus;
// For service APIs the follow DB handle is a value stored
@ -72,8 +73,11 @@ using MsgFormat::SafeArg;
DATABASE DB = STATIC FILENAME "yachts.lnk" RUNTIME * dbb_file;
#define DB tdgbl->db_handle
#define fbTrans tdgbl->tr_handle
#define gds_trans tdgbl->tr_handle
#define isc_status tdgbl->status_vector
#define fbStatus (&tdgbl->status_vector)
#define isc_status (&tdgbl->status_vector)
#define gds_status (&tdgbl->status_vector)
namespace // unnamed, private
{
@ -84,18 +88,12 @@ namespace // unnamed, private
inline void put(BurpGlobals* tdgbl, const UCHAR c)
{
if (--(tdgbl->io_cnt) >= 0)
*(tdgbl->io_ptr)++ = c;
else
MVOL_write(c, &tdgbl->io_cnt, &tdgbl->io_ptr);
tdgbl->put(c);
}
inline void put(BurpGlobals* tdgbl, const att_type c)
{
if (--tdgbl->io_cnt >= 0)
*(tdgbl->io_ptr)++ = UCHAR(c);
else
MVOL_write(UCHAR(c), &tdgbl->io_cnt, &tdgbl->io_ptr);
put(tdgbl, UCHAR(c));
}
inline const UCHAR* put_block(BurpGlobals* tdgbl, const UCHAR* p, ULONG n)
@ -173,7 +171,7 @@ const UCHAR source_items[] =
isc_info_blob_total_length,
isc_info_blob_num_segments
};
const SCHAR db_info_items[] =
const UCHAR db_info_items[] =
{
isc_info_db_sql_dialect,
isc_info_page_size,
@ -184,12 +182,12 @@ const SCHAR db_info_items[] =
isc_info_db_read_only,
isc_info_end
};
const SCHAR limbo_tpb[] =
const UCHAR limbo_tpb[] =
{
isc_tpb_version1,
isc_tpb_ignore_limbo
};
const SCHAR limbo_nau_tpb[] =
const UCHAR limbo_nau_tpb[] =
{
isc_tpb_version1,
isc_tpb_ignore_limbo,
@ -211,17 +209,12 @@ int BACKUP_backup(const TEXT* dbb_file, const TEXT* file_name)
* Backup a database.
*
**************************************/
ISC_STATUS_ARRAY status_vector;
FbLocalStatus status_vector;
BurpGlobals* tdgbl = BurpGlobals::getSpecific();
tdgbl->gbl_database_file_name = dbb_file;
tdgbl->io_ptr = NULL;
tdgbl->io_cnt = 0;
tdgbl->relations = NULL;
tdgbl->runtimeODS = 0;
gds_trans = 0;
BURP_verbose(130);
@ -229,23 +222,23 @@ int BACKUP_backup(const TEXT* dbb_file, const TEXT* file_name)
if (tdgbl->gbl_sw_ignore_limbo)
{
if (isc_start_transaction(status_vector, &gds_trans, 1, &DB,
sizeof(limbo_nau_tpb), limbo_nau_tpb))
gds_trans = DB->startTransaction(&status_vector, sizeof(limbo_nau_tpb), limbo_nau_tpb);
if (status_vector->getState() & Firebird::IStatus::STATE_ERRORS)
{
isc_start_transaction(status_vector, &gds_trans, 1, &DB, sizeof(limbo_tpb), limbo_tpb);
gds_trans = DB->startTransaction(&status_vector, sizeof(limbo_tpb), limbo_tpb);
}
}
else
{
EXEC SQL SET TRANSACTION NO_AUTO_UNDO;
if (isc_status[1])
if (isc_status->getState() & Firebird::IStatus::STATE_ERRORS)
EXEC SQL SET TRANSACTION;
}
if (!gds_trans)
{
EXEC SQL SET TRANSACTION NAME gds_trans NO_AUTO_UNDO;
if (isc_status[1])
if (isc_status->getState() & Firebird::IStatus::STATE_ERRORS)
EXEC SQL SET TRANSACTION NAME gds_trans;
}
@ -276,7 +269,7 @@ int BACKUP_backup(const TEXT* dbb_file, const TEXT* file_name)
tdgbl->action->act_file = tdgbl->gbl_sw_files;
}
MVOL_init_write(file_name, &tdgbl->io_cnt, &tdgbl->io_ptr);
MVOL_init_write(file_name);
// Write database record
@ -412,7 +405,7 @@ int BACKUP_backup(const TEXT* dbb_file, const TEXT* file_name)
// Finish up
put(tdgbl, (UCHAR) rec_end);
FB_UINT64 cumul_count = MVOL_fini_write(&tdgbl->io_cnt, &tdgbl->io_ptr);
FB_UINT64 cumul_count = MVOL_fini_write();
tdgbl->action->act_action = ACT_backup_fini;
BURP_verbose(176, SafeArg() << cumul_count);
// msg 176 closing file, committing, and finishing. %ld bytes written
@ -465,7 +458,7 @@ void compress(const UCHAR* data, ULONG length)
{
for (q = p + 2; q < end && (q[-2] != q[-1] || q[-1] != q[0]); q++)
;
USHORT run = (q < end) ? q - p - 2 : end - p;
ULONG run = (q < end) ? q - p - 2 : end - p;
if (run)
{
for (; run > 127; run -= 127)
@ -827,125 +820,34 @@ SINT64 get_gen_id( const TEXT* name, SSHORT name_len)
* Read id for a generator;
*
**************************************/
UCHAR blr_buffer[100]; // enough to fit blr
BurpGlobals* tdgbl = BurpGlobals::getSpecific();
FB_API_HANDLE gen_id_reqh = 0;
UCHAR* blr = blr_buffer;
// If this is ODS 10 (IB version 6.0) or greater, build BLR to retrieve
// the 64-bit value of the generator. If not, build BLR to retrieve the
// 32-bit value, which we will cast to the expected INT64 format.
if (tdgbl->runtimeODS >= DB_VERSION_DDL10)
try
{
// build the blr with the right relation name and 64-bit results.
add_byte(blr, blr_version5);
add_byte(blr, blr_begin);
add_byte(blr, blr_message);
add_byte(blr, 0);
add_word(blr, 1);
add_byte(blr, blr_int64);
add_byte(blr, 0);
add_byte(blr, blr_send);
add_byte(blr, 0);
add_byte(blr, blr_assignment);
add_byte(blr, blr_gen_id);
add_byte(blr, name_len);
while (name_len--)
{
const UCHAR c = *name++;
add_byte(blr, c);
}
add_byte(blr, blr_literal);
add_byte(blr, blr_long);
add_byte(blr, 0);
add_word(blr, 0);
add_word(blr, 0);
add_byte(blr, blr_parameter);
add_byte(blr, 0);
add_word(blr, 0);
add_byte(blr, blr_end);
add_byte(blr, blr_eoc);
BurpGlobals* tdgbl = BurpGlobals::getSpecific();
Firebird::string nm, sql;
nm.assign(name, name_len);
BURP_makeSymbol(tdgbl, nm);
sql = "select first(1) gen_id(" + nm + ", 0) from rdb$database";
BurpSql getGenerator(tdgbl, sql.c_str());
FB_MESSAGE(GetGen, Firebird::ThrowStatusWrapper, (FB_BIGINT, id));
GetGen getGen(&tdgbl->throwStatus, Firebird::MasterInterfacePtr());
getGenerator.singleSelect(tdgbl->tr_handle, &getGen);
return getGen->id;
}
else
catch (const Firebird::FbException& ex)
{
// build the blr with the right relation name and 32-bit results
add_byte(blr, blr_version4);
add_byte(blr, blr_begin);
add_byte(blr, blr_message);
add_byte(blr, 0);
add_word(blr, 1);
add_byte(blr, blr_long);
add_byte(blr, 0);
add_byte(blr, blr_send);
add_byte(blr, 0);
add_byte(blr, blr_assignment);
add_byte(blr, blr_gen_id);
add_byte(blr, name_len);
while (name_len--)
{
const UCHAR c = *name++;
add_byte(blr, c);
}
add_byte(blr, blr_literal);
add_byte(blr, blr_long);
add_byte(blr, 0);
add_word(blr, 0);
add_word(blr, 0);
add_byte(blr, blr_parameter);
add_byte(blr, 0);
add_word(blr, 0);
add_byte(blr, blr_end);
add_byte(blr, blr_eoc);
}
Firebird::IStatus* st = ex.getStatus();
const SSHORT blr_length = blr - blr_buffer;
#ifdef DEBUG
if (debug_on)
fb_print_blr(blr_buffer, blr_length, NULL, NULL, 0);
#endif
ISC_STATUS_ARRAY status_vector;
if (isc_compile_request(status_vector, &DB, &gen_id_reqh, blr_length, (const char*) blr_buffer))
{
// if there's no gen_id, never mind ...
return 0;
}
if (st->getErrors()[1] == isc_dsql_error)
return 0;
// use the same gds_trans generated by gpre
if (isc_start_request(status_vector, &gen_id_reqh, &gds_trans, 0))
{
BURP_error_redirect(status_vector, 25);
BURP_error_redirect(st, 25);
// msg 25 Failed in put_blr_gen_id
}
SINT64 read_msg1;
if (tdgbl->runtimeODS >= DB_VERSION_DDL10)
{
if (isc_receive(status_vector, &gen_id_reqh, 0, sizeof(read_msg1), &read_msg1, 0))
{
BURP_error_redirect(status_vector, 25);
// msg 25 Failed in put_blr_gen_id
}
}
else
{
SLONG read_msg0;
if (isc_receive(status_vector, &gen_id_reqh, 0, sizeof(read_msg0), &read_msg0, 0))
{
BURP_error_redirect(status_vector, 25);
// msg 25 Failed in put_blr_gen_id
}
read_msg1 = (SINT64) read_msg0;
}
isc_release_request(status_vector, &gen_id_reqh);
return read_msg1;
return 0; // warning silencer
}
@ -1107,16 +1009,16 @@ void put_array( burp_fld* field, burp_rel* relation, ISC_QUAD* blob_id)
xdr_buffer.lstr_allocated = xdr_buffer.lstr_length;
}
ISC_STATUS_ARRAY status_vector;
ULONG return_length = 0;
if (isc_get_slice(status_vector, &DB, &gds_trans, blob_id, blr_length, (const char*) blr_buffer,
0, // param length for subset of an array handling
NULL, // param for subset of an array handling
slice_length, slice, (SLONG*) &return_length))
FbLocalStatus status_vector;
unsigned return_length = DB->getSlice(&status_vector, gds_trans, blob_id, blr_length, blr_buffer,
0, nullptr, // parameters for subset of an array handling
slice_length, slice);
if (!status_vector.isSuccess())
{
BURP_print(false, 81, field->fld_name);
// msg 81 error accessing blob field %s -- continuing
BURP_print_status(false, status_vector);
BURP_print_status(false, &status_vector);
#ifdef DEBUG
PRETTY_print_sdl(blr_buffer, NULL, NULL, 0);
#endif
@ -1179,7 +1081,7 @@ void put_array( burp_fld* field, burp_rel* relation, ISC_QUAD* blob_id)
lstring xdr_slice;
xdr_slice.lstr_allocated = xdr_slice.lstr_length = return_length;
xdr_slice.lstr_address = slice;
return_length = CAN_slice(&xdr_buffer, &xdr_slice, TRUE, /*blr_length,*/ blr_buffer);
return_length = CAN_slice(&xdr_buffer, &xdr_slice, true, blr_buffer);
put(tdgbl, att_xdr_array);
put(tdgbl, (UCHAR) (return_length));
put(tdgbl, (UCHAR) (return_length >> 8));
@ -1244,31 +1146,31 @@ void put_blob( burp_fld* field, ISC_QUAD& blob_id)
* This is for user data blobs.
*
**************************************/
ISC_STATUS_ARRAY status_vector;
FbLocalStatus status_vector;
BurpGlobals* tdgbl = BurpGlobals::getSpecific();
// If the blob is null, don't store it. It will be restored as null.
if (UserBlob::blobIsNull(blob_id))
if (BlobWrapper::blobIsNull(blob_id))
return;
// Open the blob and get it's vital statistics
UserBlob blob(status_vector);
BlobWrapper blob(&status_vector);
if (!blob.open(DB, gds_trans, blob_id))
{
BURP_print(false, 81, field->fld_name);
// msg 81 error accessing blob field %s -- continuing
BURP_print_status(false, status_vector);
BURP_print_status(false, &status_vector);
return;
}
UCHAR blob_info[32];
if (!blob.getInfo(sizeof(blob_items), blob_items, sizeof(blob_info), blob_info))
{
BURP_error_redirect(status_vector, 20);
BURP_error_redirect(&status_vector, 20);
// msg 20 isc_blob_info failed
}
@ -1342,13 +1244,9 @@ void put_blob( burp_fld* field, ISC_QUAD& blob_id)
while (segments > 0)
{
FB_SIZE_T segment_length;
blob.getSegment(max_segment, buffer, segment_length);
const ISC_STATUS status = blob.getCode();
// Handle the errors. For stream blob isc_segment is not error here.
if (status && (status != isc_segment || blob_type == 0))
if (!blob.getSegment(max_segment, buffer, segment_length))
{
BURP_error_redirect(status_vector, 22);
BURP_error_redirect(&status_vector, 22);
// msg 22 isc_get_segment failed
}
@ -1362,7 +1260,7 @@ void put_blob( burp_fld* field, ISC_QUAD& blob_id)
}
if (!blob.close())
BURP_error_redirect(status_vector, 23);
BURP_error_redirect(&status_vector, 23);
// msg 23 isc_close_blob failed
if (buffer != static_buffer)
@ -1383,28 +1281,28 @@ bool put_blr_blob( att_type attribute, ISC_QUAD& blob_id)
* Return true if the blob was present, false otherwise.
*
**************************************/
ISC_STATUS_ARRAY status_vector;
FbLocalStatus status_vector;
BurpGlobals* tdgbl = BurpGlobals::getSpecific();
// If the blob is null, don't store it. It will be restored as null.
if (UserBlob::blobIsNull(blob_id))
if (BlobWrapper::blobIsNull(blob_id))
return false;
// Open the blob and get it's vital statistics
UserBlob blob(status_vector);
BlobWrapper blob(&status_vector);
if (!blob.open(DB, gds_trans, blob_id))
{
BURP_error_redirect(status_vector, 24);
BURP_error_redirect(&status_vector, 24);
// msg 24 isc_open_blob failed
}
UCHAR blob_info[32];
if (!blob.getInfo(sizeof(blr_items), blr_items, sizeof(blob_info), blob_info))
{
BURP_error_redirect(status_vector, 20);
BURP_error_redirect(&status_vector, 20);
// msg 20 isc_blob_info failed
}
@ -1433,7 +1331,7 @@ bool put_blr_blob( att_type attribute, ISC_QUAD& blob_id)
BURP_print(true, 79, SafeArg() << int(item));
// msg 79 don't understand blob info item %ld
if (!blob.close())
BURP_error_redirect(status_vector, 23);
BURP_error_redirect(&status_vector, 23);
// msg 23 isc_close_blob failed
return false;
}
@ -1442,7 +1340,7 @@ bool put_blr_blob( att_type attribute, ISC_QUAD& blob_id)
if (!length)
{
if (!blob.close())
BURP_error_redirect(status_vector, 23);
BURP_error_redirect(&status_vector, 23);
// msg 23 isc_close_blob failed
return false;
}
@ -1475,7 +1373,7 @@ bool put_blr_blob( att_type attribute, ISC_QUAD& blob_id)
if (!blob.close())
{
BURP_error_redirect(status_vector, 23);
BURP_error_redirect(&status_vector, 23);
// msg 23 isc_close_blob failed
}
@ -1498,17 +1396,9 @@ void put_data(burp_rel* relation)
* Write relation meta-data and data.
*
**************************************/
burp_fld* field;
ISC_STATUS_ARRAY status_vector;
BurpGlobals* tdgbl = BurpGlobals::getSpecific();
// CVC: A signed short isn't enough if the engine allows near 32K fields,
// each being char(1) ASCII in the worst case. Looking at BLR generation
// below, it's clear an extreme case won't compile => blr_length >= 32K.
// However, SSHORT is the limit for request_length in isc_compile_request.
SSHORT field_count = 1;
USHORT field_count = 1; // eof field
burp_fld* field;
for (field = relation->rel_fields; field; field = field->fld_next)
{
if (!(field->fld_flags & FLD_computed))
@ -1529,7 +1419,7 @@ void put_data(burp_rel* relation)
add_word(blr, field_count); // Number of fields, counting eof
RCRD_OFFSET offset = 0;
SSHORT count = 0; // This is param count.
USHORT count = 0; // This is param count.
for (field = relation->rel_fields; field; field = field->fld_next)
{
@ -1665,7 +1555,7 @@ void put_data(burp_rel* relation)
RCRD_OFFSET record_length = offset;
RCRD_OFFSET eof_offset = FB_ALIGN(offset, sizeof(SSHORT));
// To be used later for the buffer size to receive data
const FLD_LENGTH length = (USHORT) (eof_offset + sizeof(SSHORT));
const RCRD_LENGTH length = (RCRD_LENGTH) (eof_offset + sizeof(SSHORT));
// Build FOR loop, body, and eof handler
@ -1719,7 +1609,7 @@ void put_data(burp_rel* relation)
add_byte(blr, blr_end);
add_byte(blr, blr_eoc);
SSHORT blr_length = blr - blr_buffer;
unsigned blr_length = blr - blr_buffer;
#ifdef DEBUG
if (debug_on)
@ -1728,10 +1618,11 @@ void put_data(burp_rel* relation)
// Compile request
FB_API_HANDLE request = 0;
if (isc_compile_request(status_vector, &DB, &request, blr_length, (const SCHAR*) blr_buffer))
FbLocalStatus status_vector;
Firebird::IRequest* request = DB->compileRequest(&status_vector, blr_length, blr_buffer);
if (!status_vector.isSuccess())
{
BURP_error_redirect(status_vector, 27);
BURP_error_redirect(&status_vector, 27);
// msg 27 isc_compile_request failed
fb_print_blr(blr_buffer, blr_length, NULL, NULL, 0);
}
@ -1741,9 +1632,10 @@ void put_data(burp_rel* relation)
BURP_verbose(142, relation->rel_name);
// msg 142 writing data for relation %s
if (isc_start_request(status_vector, &request, &gds_trans, 0))
request->start(&status_vector, gds_trans, 0);
if (!status_vector.isSuccess())
{
BURP_error_redirect(status_vector, 28);
BURP_error_redirect(&status_vector, 28);
// msg 28 isc_start_request failed
}
@ -1766,9 +1658,10 @@ void put_data(burp_rel* relation)
ULONG records = 0;
while (true)
{
if (isc_receive(status_vector, &request, 0, length, buffer, 0))
request->receive(&status_vector, 0, 0, length, buffer);
if (!status_vector.isSuccess())
{
BURP_error_redirect(status_vector, 29);
BURP_error_redirect(&status_vector, 29);
// msg 29 isc_receive failed
}
if (!*eof)
@ -1783,7 +1676,7 @@ void put_data(burp_rel* relation)
const UCHAR* p;
if (tdgbl->gbl_sw_transportable)
{
record_length = CAN_encode_decode(relation, &xdr_buffer, buffer, TRUE);
record_length = CAN_encode_decode(relation, &xdr_buffer, buffer, true);
put_int32(att_xdr_length, record_length);
p = xdr_buffer.lstr_address;
}
@ -1825,8 +1718,9 @@ void put_data(burp_rel* relation)
BURP_verbose(108, SafeArg() << records);
// msg 108 %ld records written
if (isc_release_request(status_vector, &request))
BURP_error_redirect(status_vector, 30);
request->free(&status_vector);
if (!status_vector.isSuccess())
BURP_error_redirect(&status_vector, 30);
// msg 30 isc_release_request failed
}
@ -2255,12 +2149,12 @@ bool put_source_blob(att_type attribute, att_type old_attribute, ISC_QUAD& blob_
* Include the NULL character to separate each segment.
*
**************************************/
ISC_STATUS_ARRAY status_vector;
FbLocalStatus status_vector;
BurpGlobals* tdgbl = BurpGlobals::getSpecific();
// If the blob is null, don't store it. It will be restored as null.
if (UserBlob::blobIsNull(blob_id))
if (BlobWrapper::blobIsNull(blob_id))
return false;
if (tdgbl->gbl_sw_old_descriptions && attribute != att_field_query_header)
@ -2268,18 +2162,18 @@ bool put_source_blob(att_type attribute, att_type old_attribute, ISC_QUAD& blob_
// Open the blob and get it's vital statistics
UserBlob blob(status_vector);
BlobWrapper blob(&status_vector);
if (!blob.open(DB, gds_trans, blob_id))
{
BURP_error_redirect(status_vector, 24);
BURP_error_redirect(&status_vector, 24);
// msg 24 isc_open_blob failed
}
UCHAR blob_info[48];
if (!blob.getInfo(sizeof(source_items), source_items, sizeof(blob_info), blob_info))
{
BURP_error_redirect(status_vector, 20);
BURP_error_redirect(&status_vector, 20);
// msg 20 isc_blob_info failed
}
@ -2314,7 +2208,7 @@ bool put_source_blob(att_type attribute, att_type old_attribute, ISC_QUAD& blob_
// msg 79 don't understand blob info item %ld
if (!blob.close())
{
BURP_error_redirect(status_vector, 23);
BURP_error_redirect(&status_vector, 23);
// msg 23 isc_close_blob failed
}
return false;
@ -2325,7 +2219,7 @@ bool put_source_blob(att_type attribute, att_type old_attribute, ISC_QUAD& blob_
{
if (!blob.close())
{
BURP_error_redirect(status_vector, 23);
BURP_error_redirect(&status_vector, 23);
// msg 23 isc_close_blob failed
}
return false;
@ -2360,7 +2254,7 @@ bool put_source_blob(att_type attribute, att_type old_attribute, ISC_QUAD& blob_
}
if (!blob.close())
BURP_error_redirect(status_vector, 23);
BURP_error_redirect(&status_vector, 23);
// msg 23 isc_close_blob failed
if (buffer != static_buffer)
@ -2420,7 +2314,7 @@ void write_character_sets()
* each user defined character set.
*
**************************************/
isc_req_handle req_handle1 = 0;
Firebird::IRequest* req_handle1 = nullptr;
BurpGlobals* tdgbl = BurpGlobals::getSpecific();
@ -2518,7 +2412,7 @@ void write_check_constraints()
* each check constraint.
*
**************************************/
isc_req_handle req_handle1 = 0;
Firebird::IRequest* req_handle1 = nullptr;
BurpGlobals* tdgbl = BurpGlobals::getSpecific();
@ -2552,7 +2446,7 @@ void write_collations()
* each user defined collation
*
**************************************/
isc_req_handle req_handle1 = 0;
Firebird::IRequest* req_handle1 = nullptr;
BurpGlobals* tdgbl = BurpGlobals::getSpecific();
@ -2652,28 +2546,29 @@ void write_database( const TEXT* dbb_file)
* the database itself.
*
**************************************/
ISC_STATUS_ARRAY status_vector;
SCHAR buffer[256];
isc_req_handle req_handle1 = 0;
FbLocalStatus status_vector;
UCHAR buffer[256];
Firebird::IRequest* req_handle1 = nullptr;
BurpGlobals* tdgbl = BurpGlobals::getSpecific();
put(tdgbl, (UCHAR) rec_physical_db);
if (isc_database_info(status_vector, &DB, sizeof(db_info_items), db_info_items,
sizeof(buffer), buffer))
DB->getInfo(&status_vector, sizeof(db_info_items), db_info_items,
sizeof(buffer), buffer);
if (!status_vector.isSuccess())
{
BURP_error_redirect(status_vector, 31);
BURP_error_redirect(&status_vector, 31);
// msg 31 isc_database_info failed
}
USHORT page_size = 0, forced_writes, no_reserve, SQL_dialect, db_read_only;
ULONG sweep_interval, page_buffers;
USHORT length = 0;
for (const SCHAR* d = buffer; *d != isc_info_end; d += length)
for (const UCHAR* d = buffer; *d != isc_info_end; d += length)
{
const UCHAR item = *d++;
length = (USHORT) isc_vax_integer(d, 2);
length = (USHORT) gds__vax_integer(d, 2);
d += 2;
switch (item)
{
@ -2681,27 +2576,27 @@ void write_database( const TEXT* dbb_file)
break;
case isc_info_page_size:
page_size = (USHORT) isc_vax_integer(d, length);
page_size = (USHORT) gds__vax_integer(d, length);
put_int32(att_page_size, page_size);
break;
case isc_info_sweep_interval:
sweep_interval = isc_vax_integer(d, length);
sweep_interval = gds__vax_integer(d, length);
put_int32(att_sweep_interval, sweep_interval);
break;
case isc_info_forced_writes:
forced_writes = (USHORT) isc_vax_integer(d, length);
forced_writes = (USHORT) gds__vax_integer(d, length);
put_int32(att_forced_writes, forced_writes);
break;
case isc_info_no_reserve:
if (no_reserve = (USHORT) isc_vax_integer(d, length))
if (no_reserve = (USHORT) gds__vax_integer(d, length))
put_int32(att_no_reserve, no_reserve);
break;
case isc_info_set_page_buffers:
if (page_buffers = isc_vax_integer(d, length))
if (page_buffers = gds__vax_integer(d, length))
put_int32(att_page_buffers, page_buffers);
break;
@ -2709,17 +2604,17 @@ void write_database( const TEXT* dbb_file)
break; // parameter and returns isc_info_error. skip it
case isc_info_db_sql_dialect:
SQL_dialect = (USHORT) isc_vax_integer(d, length);
SQL_dialect = (USHORT) gds__vax_integer(d, length);
put_int32(att_SQL_dialect, SQL_dialect);
break;
case isc_info_db_read_only:
if (db_read_only = (USHORT) isc_vax_integer(d, length))
if (db_read_only = (USHORT) gds__vax_integer(d, length))
put_int32(att_db_read_only, db_read_only);
break;
default:
BURP_error_redirect(status_vector, 31);
BURP_error_redirect(&status_vector, 31);
// msg 31 isc_database_info failed
break;
}
@ -2787,7 +2682,7 @@ void write_exceptions()
*
**************************************/
TEXT temp[GDS_NAME_LEN];
isc_req_handle req_handle1 = 0;
Firebird::IRequest* req_handle1 = nullptr;
BurpGlobals* tdgbl = BurpGlobals::getSpecific();
@ -2851,7 +2746,7 @@ void write_field_dimensions()
* each array field dimension.
*
**************************************/
isc_req_handle req_handle1 = 0;
Firebird::IRequest* req_handle1 = nullptr;
BurpGlobals* tdgbl = BurpGlobals::getSpecific();
@ -2886,7 +2781,7 @@ void write_filters()
*
**************************************/
TEXT temp[GDS_NAME_LEN];
isc_req_handle req_handle1 = 0;
Firebird::IRequest* req_handle1 = nullptr;
BurpGlobals* tdgbl = BurpGlobals::getSpecific();
@ -2928,7 +2823,7 @@ void write_functions()
**************************************/
GDS_NAME func;
TEXT temp[GDS_NAME_LEN * 2];
isc_req_handle req_handle1 = 0;
Firebird::IRequest* req_handle1 = nullptr;
BurpGlobals* tdgbl = BurpGlobals::getSpecific();
@ -3182,7 +3077,7 @@ void write_generators()
* Write any defined generators.
*
**************************************/
isc_req_handle req_handle1 = 0;
Firebird::IRequest* req_handle1 = nullptr;
TEXT temp[GDS_NAME_LEN];
BurpGlobals* tdgbl = BurpGlobals::getSpecific();
@ -3291,7 +3186,7 @@ void write_global_fields()
*
**************************************/
TEXT temp[GDS_NAME_LEN];
isc_req_handle req_handle1 = 0;
Firebird::IRequest* req_handle1 = nullptr;
BurpGlobals* tdgbl = BurpGlobals::getSpecific();
@ -3522,7 +3417,7 @@ void write_packages()
*
**************************************/
TEXT temp[GDS_NAME_LEN];
isc_req_handle req_handle1 = 0;
Firebird::IRequest* req_handle1 = nullptr;
BurpGlobals* tdgbl = BurpGlobals::getSpecific();
@ -3589,7 +3484,7 @@ void write_procedures()
**************************************/
GDS_NAME proc;
TEXT temp[GDS_NAME_LEN * 2];
isc_req_handle req_handle1 = 0;
Firebird::IRequest* req_handle1 = nullptr;
BurpGlobals* tdgbl = BurpGlobals::getSpecific();
@ -3779,7 +3674,7 @@ void write_ref_constraints()
* each referential constraint.
*
**************************************/
isc_req_handle req_handle1 = 0;
Firebird::IRequest* req_handle1 = nullptr;
BurpGlobals* tdgbl = BurpGlobals::getSpecific();
@ -3815,7 +3710,7 @@ void write_rel_constraints()
*
**************************************/
TEXT temp[GDS_NAME_LEN];
isc_req_handle req_handle1 = 0;
Firebird::IRequest* req_handle1 = nullptr;
BurpGlobals* tdgbl = BurpGlobals::getSpecific();
@ -3859,7 +3754,7 @@ void write_relations()
*
**************************************/
TEXT temp[GDS_NAME_LEN];
isc_req_handle req_handle1 = 0;
Firebird::IRequest* req_handle1 = nullptr;
BurpGlobals* tdgbl = BurpGlobals::getSpecific();
@ -3989,7 +3884,7 @@ void write_relations()
void write_secclasses()
{
TEXT temp[GDS_NAME_LEN];
isc_req_handle req_handle1 = 0;
Firebird::IRequest* req_handle1 = nullptr;
BurpGlobals* tdgbl = BurpGlobals::getSpecific();
@ -4025,7 +3920,7 @@ void write_shadow_files()
*
**************************************/
BASED ON RDB$FILES.RDB$FILE_NAME temp;
isc_req_handle req_handle1 = 0;
Firebird::IRequest* req_handle1 = nullptr;
BurpGlobals* tdgbl = BurpGlobals::getSpecific();
@ -4066,7 +3961,7 @@ void write_sql_roles()
* each SQL roles.
*
**************************************/
isc_req_handle req_handle1 = 0;
Firebird::IRequest* req_handle1 = nullptr;
TEXT temp[GDS_NAME_LEN];
BurpGlobals* tdgbl = BurpGlobals::getSpecific();
@ -4135,7 +4030,7 @@ void write_mapping()
* each names mapping.
*
**************************************/
isc_req_handle req_handle = 0;
Firebird::IRequest* req_handle = nullptr;
TEXT temp[GDS_NAME_LEN];
BurpGlobals* tdgbl = BurpGlobals::getSpecific();
@ -4218,7 +4113,7 @@ void write_triggers()
*
**************************************/
TEXT temp[GDS_NAME_LEN];
isc_req_handle req_handle1 = 0;
Firebird::IRequest* req_handle1 = nullptr;
BurpGlobals* tdgbl = BurpGlobals::getSpecific();
@ -4335,7 +4230,7 @@ void write_trigger_messages()
*
**************************************/
TEXT temp[GDS_NAME_LEN];
isc_req_handle req_handle1 = 0;
Firebird::IRequest* req_handle1 = nullptr;
BurpGlobals* tdgbl = BurpGlobals::getSpecific();
@ -4374,7 +4269,7 @@ void write_types()
* each type.
*
**************************************/
isc_req_handle req_handle1 = 0;
Firebird::IRequest* req_handle1 = nullptr;
BurpGlobals* tdgbl = BurpGlobals::getSpecific();
@ -4414,7 +4309,7 @@ void write_user_privileges()
*
**************************************/
TEXT temp[GDS_NAME_LEN];
isc_req_handle req_handle1 = 0;
Firebird::IRequest* req_handle1 = nullptr;
BurpGlobals* tdgbl = BurpGlobals::getSpecific();

View File

@ -65,6 +65,7 @@
#include <ctype.h>
#endif
#include "../common/utils_proto.h"
#include "../common/status.h"
#ifdef HAVE_UNISTD_H
#include <unistd.h>
@ -82,6 +83,7 @@
#endif
using MsgFormat::SafeArg;
using Firebird::FbLocalStatus;
const char* fopen_write_type = "w";
const char* fopen_read_type = "r";
@ -102,7 +104,7 @@ enum gbak_action
//FDESC = 3 // CVC: Unused
};
static void close_out_transaction(gbak_action, isc_tr_handle*);
static void close_out_transaction(gbak_action, Firebird::ITransaction**);
//static void enable_signals();
//static void excp_handler();
static SLONG get_number(const SCHAR*);
@ -272,8 +274,8 @@ static int svc_api_gbak(Firebird::UtilSvc* uSvc, const Switches& switches)
const Firebird::string* dbName = flag_restore ? &files[1] : &files[0];
ISC_STATUS_ARRAY status;
FB_API_HANDLE svc_handle = 0;
FbLocalStatus status;
Firebird::IService* svc_handle = nullptr;
try
{
@ -317,21 +319,22 @@ static int svc_api_gbak(Firebird::UtilSvc* uSvc, const Switches& switches)
spb.insertString(isc_spb_command_line, options);
if (isc_service_attach(status, 0, service.c_str(), &svc_handle,
spb.getBufferLength(), reinterpret_cast<const char*>(spb.getBuffer())))
svc_handle = Firebird::DispatcherPtr()->attachServiceManager(&status, service.c_str(),
spb.getBufferLength(), spb.getBuffer());
if (!status.isSuccess())
{
BURP_print_status(true, status);
BURP_print_status(true, &status);
BURP_print(true, 83);
// msg 83 Exiting before completion due to errors
return FINI_ERROR;
}
char thd[10];
UCHAR thd[10];
// 'isc_action_svc_restore/isc_action_svc_backup'
// 'isc_spb_verbose'
// 'isc_spb_verbint'
char* thd_ptr = thd;
UCHAR* thd_ptr = thd;
if (flag_restore)
*thd_ptr++ = isc_action_svc_restore;
else
@ -344,41 +347,43 @@ static int svc_api_gbak(Firebird::UtilSvc* uSvc, const Switches& switches)
{
*thd_ptr++ = isc_spb_verbint;
//stream verbint_val into a SPB
put_vax_long(reinterpret_cast<UCHAR*>(thd_ptr), verbint_val);
put_vax_long(thd_ptr, verbint_val);
thd_ptr += sizeof(SLONG);
}
const USHORT thdlen = thd_ptr - thd;
fb_assert(thdlen <= sizeof(thd));
if (isc_service_start(status, &svc_handle, NULL, thdlen, thd))
svc_handle->start(&status, thdlen, thd);
if (!status.isSuccess())
{
BURP_print_status(true, status);
isc_service_detach(status, &svc_handle);
BURP_print_status(true, &status);
svc_handle->release();
BURP_print(true, 83); // msg 83 Exiting before completion due to errors
return FINI_ERROR;
}
const char sendbuf[] = { isc_info_svc_line };
char respbuf[1024];
const char* sl;
const UCHAR sendbuf[] = { isc_info_svc_line };
UCHAR respbuf[1024];
const UCHAR* sl;
do {
if (isc_service_query(status, &svc_handle, NULL, 0, NULL,
sizeof(sendbuf), sendbuf,
sizeof(respbuf), respbuf))
svc_handle->query(&status, 0, NULL,
sizeof(sendbuf), sendbuf,
sizeof(respbuf), respbuf);
if (!status.isSuccess())
{
BURP_print_status(true, status);
isc_service_detach(status, &svc_handle);
BURP_print_status(true, &status);
svc_handle->release();
BURP_print(true, 83); // msg 83 Exiting before completion due to errors
return FINI_ERROR;
}
char* p = respbuf;
UCHAR* p = respbuf;
sl = p;
if (*p++ == isc_info_svc_line)
{
const ISC_USHORT len = (ISC_USHORT) isc_vax_integer(p, sizeof(ISC_USHORT));
const ISC_USHORT len = (ISC_USHORT) gds__vax_integer(p, sizeof(ISC_USHORT));
p += sizeof(ISC_USHORT);
if (!len)
{
@ -395,18 +400,16 @@ static int svc_api_gbak(Firebird::UtilSvc* uSvc, const Switches& switches)
}
} while (*sl == isc_info_svc_line);
isc_service_detach(status, &svc_handle);
svc_handle->release();
return FINI_OK;
}
catch (const Firebird::Exception& e)
{
Firebird::StaticStatusVector s;
e.stuffException(s);
BURP_print_status(true, s.begin());
FbLocalStatus s;
e.stuffException(&s);
BURP_print_status(true, &s);
if (svc_handle)
{
isc_service_detach(status, &svc_handle);
}
svc_handle->release();
BURP_print(true, 83); // msg 83 Exiting before completion due to errors
return FINI_ERROR;
}
@ -723,6 +726,41 @@ int gbak(Firebird::UtilSvc* uSvc)
}
tdgbl->gbl_sw_sql_role = argv[itr];
break;
case IN_SW_BURP_KEYHOLD:
if (++itr >= argc)
{
BURP_error(381, true);
// KeyHolder parameter missing
}
if (tdgbl->gbl_sw_keyholder)
BURP_error(334, true, SafeArg() << in_sw_tab->in_sw_name);
tdgbl->gbl_sw_keyholder = argv[itr];
break;
case IN_SW_BURP_CRYPT:
if (++itr >= argc)
{
BURP_error(377, true);
// CryptPlugin parameter missing
}
if (tdgbl->gbl_sw_crypt)
BURP_error(334, true, SafeArg() << in_sw_tab->in_sw_name);
tdgbl->gbl_sw_crypt = argv[itr];
break;
case IN_SW_BURP_KEYNAME:
if (++itr >= argc)
{
BURP_error(375, true);
// Key name parameter missing
}
if (tdgbl->gbl_sw_keyname)
BURP_error(334, true, SafeArg() << in_sw_tab->in_sw_name);
tdgbl->gbl_sw_keyname = argv[itr];
break;
case IN_SW_BURP_ZIP:
if (tdgbl->gbl_sw_zip)
BURP_error(334, true, SafeArg() << in_sw_tab->in_sw_name);
tdgbl->gbl_sw_zip = true;
break;
case IN_SW_BURP_FA:
if (tdgbl->gbl_sw_blk_factor)
BURP_error(333, true, SafeArg() << in_sw_tab->in_sw_name << tdgbl->gbl_sw_blk_factor);
@ -1199,6 +1237,8 @@ int gbak(Firebird::UtilSvc* uSvc)
}
else if (tdgbl->gbl_sw_old_descriptions)
errNum = IN_SW_BURP_OL;
else if (tdgbl->gbl_sw_zip)
errNum = IN_SW_BURP_ZIP;
if (errNum != IN_SW_BURP_0)
{
@ -1285,10 +1325,8 @@ int gbak(Firebird::UtilSvc* uSvc)
{
// Non-burp exception was caught
tdgbl->burp_throw = false;
Firebird::StaticStatusVector s;
e.stuffException(s);
fb_utils::copyStatus(tdgbl->status_vector, ISC_STATUS_LENGTH, s.begin(), s.getCount());
BURP_print_status(true, tdgbl->status_vector);
e.stuffException(&tdgbl->status_vector);
BURP_print_status(true, &tdgbl->status_vector);
if (! tdgbl->uSvc->isService())
{
BURP_print(true, 83); // msg 83 Exiting before completion due to errors
@ -1315,14 +1353,17 @@ int gbak(Firebird::UtilSvc* uSvc)
}
// Detach from database to release system resources
if (tdgbl->db_handle != 0)
if (tdgbl->db_handle)
{
close_out_transaction(action, &tdgbl->tr_handle);
close_out_transaction(action, &tdgbl->global_trans);
if (isc_detach_database(tdgbl->status_vector, &tdgbl->db_handle))
{
BURP_print_status(true, tdgbl->status_vector);
}
tdgbl->db_handle->detach(&tdgbl->status_vector);
if (tdgbl->status_vector->getState() & Firebird::IStatus::STATE_ERRORS)
BURP_print_status(true, &tdgbl->status_vector);
else
tdgbl->db_handle = NULL;
}
// Close the status output file
@ -1428,7 +1469,7 @@ void BURP_error(USHORT errcode, bool abort, const char* str)
}
void BURP_error_redirect(const ISC_STATUS* status_vector, USHORT errcode, const SafeArg& arg)
void BURP_error_redirect(Firebird::IStatus* status_vector, USHORT errcode, const SafeArg& arg)
{
/**************************************
*
@ -1516,26 +1557,24 @@ void BURP_msg_get(USHORT number, TEXT* output_msg, const SafeArg& arg)
strcpy(output_msg, buffer);
}
void BURP_output_version(void* arg1, const TEXT* arg2)
void OutputVersion::callback(Firebird::CheckStatusWrapper* status, const char* text)
{
/**************************************
*
* B U R P _ o u t p u t _ v e r s i o n
* O u t p u t V e r s i o n :: c a l l b a c k
*
**************************************
*
* Functional description
* Callback routine for access method
* printing (specifically show version);
* printing (specifically show version)
* will accept.
*
**************************************/
burp_output(false, static_cast<const char*>(arg1), arg2);
burp_output(false, format, text);
}
void BURP_print(bool err, USHORT number, const SafeArg& arg)
{
/**************************************
@ -1577,7 +1616,7 @@ void BURP_print(bool err, USHORT number, const char* str)
}
void BURP_print_status(bool err, const ISC_STATUS* status_vector)
void BURP_print_status(bool err, Firebird::IStatus* status_vector)
{
/**************************************
*
@ -1592,7 +1631,7 @@ void BURP_print_status(bool err, const ISC_STATUS* status_vector)
**************************************/
if (status_vector)
{
const ISC_STATUS* vector = status_vector;
const ISC_STATUS* vector = status_vector->getErrors();
if (err)
{
@ -1622,7 +1661,7 @@ void BURP_print_status(bool err, const ISC_STATUS* status_vector)
}
void BURP_print_warning(const ISC_STATUS* status_vector)
void BURP_print_warning(Firebird::IStatus* status)
{
/**************************************
*
@ -1635,14 +1674,10 @@ void BURP_print_warning(const ISC_STATUS* status_vector)
* to allow redirecting output.
*
**************************************/
if (status_vector)
if (status && (status->getState() & Firebird::IStatus::STATE_WARNINGS))
{
// skip the error, assert that one does not exist
fb_assert(status_vector[0] == isc_arg_gds);
fb_assert(status_vector[1] == 0);
// print the warning message
const ISC_STATUS* vector = &status_vector[2];
const ISC_STATUS* vector = status->getWarnings();
SCHAR s[1024];
if (fb_interpret(s, sizeof(s), &vector))
@ -1716,7 +1751,7 @@ void BURP_verbose(USHORT number, const char* str)
}
static void close_out_transaction(gbak_action action, isc_tr_handle* handle)
static void close_out_transaction(gbak_action action, Firebird::ITransaction** tPtr)
{
/**************************************
*
@ -1731,31 +1766,38 @@ static void close_out_transaction(gbak_action action, isc_tr_handle* handle)
* returned to the system.
*
**************************************/
if (*handle != 0)
if (*tPtr)
{
ISC_STATUS_ARRAY status_vector;
FbLocalStatus status_vector;
if (action == RESTORE)
{
// Even if the restore failed, commit the transaction so that
// a partial database is at least recovered.
isc_commit_transaction(status_vector, handle);
if (status_vector[1])
(*tPtr)->commit(&status_vector);
if (!status_vector.isSuccess())
{
// If we can't commit - have to roll it back, as
// we need to close all outstanding transactions before
// we can detach from the database.
isc_rollback_transaction(status_vector, handle);
if (status_vector[1])
BURP_print_status(false, status_vector);
(*tPtr)->rollback(&status_vector);
if (!status_vector.isSuccess())
BURP_print_status(false, &status_vector);
else
*tPtr = nullptr;
}
else
*tPtr = nullptr;
}
else
{
// A backup shouldn't touch any data - we ensure that
// by never writing data during a backup, but let's double
// ensure it by doing a rollback
if (isc_rollback_transaction(status_vector, handle))
BURP_print_status(false, status_vector);
(*tPtr)->rollback(&status_vector);
if (!status_vector.isSuccess())
BURP_print_status(false, &status_vector);
else
*tPtr = nullptr;
}
}
}
@ -1810,40 +1852,102 @@ static gbak_action open_files(const TEXT* file1,
*
**************************************/
BurpGlobals* tdgbl = BurpGlobals::getSpecific();
ISC_STATUS_ARRAY temp_status;
ISC_STATUS* status_vector = temp_status;
FbLocalStatus status_vector;
// try to attach the database using the first file_name
if (sw_replace != IN_SW_BURP_C && sw_replace != IN_SW_BURP_R)
{
if (!isc_attach_database(status_vector,
(SSHORT) 0, file1,
&tdgbl->db_handle,
dpb.getBufferLength(),
reinterpret_cast<const char*>(dpb.getBuffer())))
Firebird::DispatcherPtr provider;
// provide crypt key(s) for engine
if (tdgbl->gbl_sw_keyholder)
{
tdgbl->gbl_database_file_name = file1;
provider->setDbCryptCallback(&status_vector, MVOL_get_crypt(tdgbl));
if (!status_vector.isSuccess())
{
BURP_print_status(true, &status_vector);
return QUIT;
}
}
tdgbl->db_handle = provider->attachDatabase(&status_vector, file1,
dpb.getBufferLength(), dpb.getBuffer());
if (!(status_vector->getState() & Firebird::IStatus::STATE_ERRORS))
{
if (sw_replace != IN_SW_BURP_B)
{
// msg 13 REPLACE specified, but the first file %s is a database
BURP_error(13, true, file1);
if (isc_detach_database(status_vector, &tdgbl->db_handle)) {
BURP_print_status(true, status_vector);
}
tdgbl->db_handle->detach(&status_vector);
if (status_vector->getState() & Firebird::IStatus::STATE_ERRORS)
BURP_print_status(true, &status_vector);
else
tdgbl->db_handle = NULL;
return QUIT;
}
if (tdgbl->gbl_sw_version)
{
// msg 139 Version(s) for database "%s"
BURP_print(false, 139, file1);
isc_version(&tdgbl->db_handle, BURP_output_version, (void*) "\t%s\n");
OutputVersion outputVersion("\t%s\n");
Firebird::UtilInterfacePtr()->getFbVersion(&status_vector, tdgbl->db_handle, &outputVersion);
}
BURP_verbose(166, file1); // msg 166: readied database %s for backup
if (tdgbl->gbl_sw_keyholder)
{
unsigned char info[] = {fb_info_crypt_key, fb_info_crypt_plugin};
unsigned char buffer[(1 + 2 + MAX_SQL_IDENTIFIER_SIZE) * 2 + 2];
unsigned int len;
tdgbl->db_handle->getInfo(&status_vector, sizeof(info), info, sizeof(buffer), buffer);
UCHAR* p = buffer;
while(p)
{
switch(*p++)
{
case fb_info_crypt_key:
len = gds__vax_integer(p, 2);
if (len < sizeof(tdgbl->gbl_hdr_keybuffer))
{
memcpy(tdgbl->gbl_hdr_keybuffer, p + 2, len);
tdgbl->gbl_hdr_keybuffer[len] = 0;
if (!tdgbl->gbl_sw_keyname)
tdgbl->gbl_sw_keyname = tdgbl->gbl_hdr_keybuffer;
}
break;
case fb_info_crypt_plugin:
len = gds__vax_integer(p, 2);
if (len < sizeof(tdgbl->gbl_hdr_cryptbuffer))
{
memcpy(tdgbl->gbl_hdr_cryptbuffer, p + 2, len);
tdgbl->gbl_hdr_cryptbuffer[len] = 0;
if (!tdgbl->gbl_sw_crypt)
tdgbl->gbl_sw_crypt = tdgbl->gbl_hdr_cryptbuffer;
}
break;
default:
p = NULL;
continue;
}
p += (2 + len);
}
}
}
else if (sw_replace == IN_SW_BURP_B ||
(status_vector[1] != isc_io_error && status_vector[1] != isc_bad_db_format))
(status_vector->getErrors()[1] != isc_io_error && status_vector->getErrors()[1] != isc_bad_db_format))
{
BURP_print_status(true, status_vector);
BURP_print_status(true, &status_vector);
return QUIT;
}
}
@ -1919,7 +2023,7 @@ static gbak_action open_files(const TEXT* file1,
{
Firebird::string nm = tdgbl->toSystem(fil->fil_name);
#ifdef WIN_NT
if ((fil->fil_fd = MVOL_open(nm.c_str(), MODE_WRITE, CREATE_ALWAYS)) ==
if ((fil->fil_fd = NT_tape_open(nm.c_str(), MODE_WRITE, CREATE_ALWAYS)) ==
INVALID_HANDLE_VALUE)
#else
if ((fil->fil_fd = os_utils::open(nm.c_str(), MODE_WRITE, open_mask)) == -1)
@ -1965,10 +2069,12 @@ static gbak_action open_files(const TEXT* file1,
}
else
{
if (isc_detach_database(status_vector, &tdgbl->db_handle))
{
BURP_print_status(false, status_vector);
}
tdgbl->db_handle->detach(&status_vector);
if (status_vector->getState() & Firebird::IStatus::STATE_ERRORS)
BURP_print_status(true, &status_vector);
else
tdgbl->db_handle = NULL;
}
return flag;
@ -2027,7 +2133,7 @@ static gbak_action open_files(const TEXT* file1,
// open first file
Firebird::string nm = tdgbl->toSystem(fil->fil_name);
#ifdef WIN_NT
if ((fil->fil_fd = MVOL_open(nm.c_str(), MODE_READ, OPEN_EXISTING)) ==
if ((fil->fil_fd = NT_tape_open(nm.c_str(), MODE_READ, OPEN_EXISTING)) ==
INVALID_HANDLE_VALUE)
#else
if ((fil->fil_fd = os_utils::open(nm.c_str(), MODE_READ)) == INVALID_HANDLE_VALUE)
@ -2073,7 +2179,7 @@ static gbak_action open_files(const TEXT* file1,
tdgbl->action->act_file = fil;
Firebird::string nm = tdgbl->toSystem(fil->fil_name);
#ifdef WIN_NT
if ((fil->fil_fd = MVOL_open(nm.c_str(), MODE_READ, OPEN_EXISTING)) ==
if ((fil->fil_fd = NT_tape_open(nm.c_str(), MODE_READ, OPEN_EXISTING)) ==
INVALID_HANDLE_VALUE)
#else
if ((fil->fil_fd = os_utils::open(nm.c_str(), MODE_READ)) == INVALID_HANDLE_VALUE)
@ -2139,49 +2245,71 @@ static gbak_action open_files(const TEXT* file1,
BURP_error(262, true, *file2);
// msg 262 size specification either missing or incorrect for file %s
if ((sw_replace == IN_SW_BURP_C || sw_replace == IN_SW_BURP_R) &&
!isc_attach_database(status_vector,
(SSHORT) 0, *file2,
&tdgbl->db_handle,
dpb.getBufferLength(),
reinterpret_cast<const char*>(dpb.getBuffer())))
if (sw_replace == IN_SW_BURP_C || sw_replace == IN_SW_BURP_R)
{
if (sw_replace == IN_SW_BURP_C)
Firebird::DispatcherPtr provider;
// provide crypt key(s) for engine
if (tdgbl->gbl_sw_keyholder)
{
if (isc_detach_database(status_vector, &tdgbl->db_handle)) {
BURP_print_status(true, status_vector);
}
BURP_error(14, true, *file2);
// msg 14 database %s already exists. To replace it, use the -R switch
}
else
{
isc_drop_database(status_vector, &tdgbl->db_handle);
if (tdgbl->db_handle)
tdgbl->gbl_database_file_name = *file2;
provider->setDbCryptCallback(&status_vector, MVOL_get_crypt(tdgbl));
if (!status_vector.isSuccess())
{
ISC_STATUS_ARRAY status_vector2;
if (isc_detach_database(status_vector2, &tdgbl->db_handle)) {
BURP_print_status(false, status_vector2);
}
// Complain only if the drop database entrypoint is available.
// If it isn't, the database will simply be overwritten.
if (status_vector[1] != isc_unavailable)
BURP_error(233, true, *file2);
// msg 233 Cannot drop database %s, might be in use
BURP_print_status(true, &status_vector);
return QUIT;
}
}
}
if (sw_replace == IN_SW_BURP_R && status_vector[1] == isc_adm_task_denied)
{
// if we got an error from attach database and we have replace switch set
// then look for error from attach returned due to not owner, if we are
// not owner then return the error status back up
BURP_error(274, true);
// msg # 274 : Cannot restore over current database, must be sysdba
// or owner of the existing database.
tdgbl->db_handle = provider->attachDatabase(&status_vector, *file2,
dpb.getBufferLength(), dpb.getBuffer());
if (!(status_vector->getState() & Firebird::IStatus::STATE_ERRORS))
{
if (sw_replace == IN_SW_BURP_C)
{
tdgbl->db_handle->detach(&status_vector);
if (status_vector->getState() & Firebird::IStatus::STATE_ERRORS)
BURP_print_status(true, &status_vector);
else
tdgbl->db_handle = NULL;
BURP_error(14, true, *file2);
// msg 14 database %s already exists. To replace it, use the -R switch
}
else
{
tdgbl->db_handle->dropDatabase(&status_vector);
if (status_vector->getState() & Firebird::IStatus::STATE_ERRORS)
{
Firebird::FbLocalStatus status2;
tdgbl->db_handle->detach(&status2);
if (status2->getState() & Firebird::IStatus::STATE_ERRORS)
BURP_print_status(true, &status2);
else
tdgbl->db_handle = NULL;
BURP_error(233, true, *file2);
// msg 233 Cannot drop database %s, might be in use
}
else
tdgbl->db_handle = NULL;
}
}
else if (sw_replace == IN_SW_BURP_R && status_vector->getErrors()[1] == isc_adm_task_denied)
{
// if we got an error from attach database and we have replace switch set
// then look for error from attach returned due to not owner, if we are
// not owner then return the error status back up
BURP_error(274, true);
// msg # 274 : Cannot restore over current database, must be sysdba
// or owner of the existing database.
}
}
// check the file size specification
@ -2458,18 +2586,18 @@ void BurpGlobals::read_stats(SINT64* stats)
if (!db_handle)
return;
const char info[] =
const UCHAR info[] =
{
isc_info_reads,
isc_info_writes
};
ISC_STATUS_ARRAY status = {0};
char buffer[sizeof(info) * (1 + 2 + 8) + 2];
FbLocalStatus status;
UCHAR buffer[sizeof(info) * (1 + 2 + 8) + 2];
isc_database_info(status, &db_handle, sizeof(info), info, sizeof(buffer), buffer);
db_handle->getInfo(&status, sizeof(info), info, sizeof(buffer), buffer);
char* p = buffer, *const e = buffer + sizeof(buffer);
UCHAR* p = buffer, *const e = buffer + sizeof(buffer);
while (p < e)
{
int flag = -1;
@ -2490,7 +2618,7 @@ void BurpGlobals::read_stats(SINT64* stats)
if (flag != -1)
{
const int len = isc_vax_integer(p + 1, 2);
const int len = gds__vax_integer(p + 1, 2);
stats[flag] = isc_portable_integer((ISC_UCHAR*) p + 1 + 2, len);
p += len + 3;
}
@ -2603,3 +2731,21 @@ UnicodeCollationHolder::~UnicodeCollationHolder()
// cs should be deleted by texttype_fn_destroy call above
delete tt;
}
void BURP_makeSymbol(BurpGlobals* tdgbl, Firebird::string& name) // add double quotes to string
{
if (tdgbl->gbl_dialect < SQL_DIALECT_V6)
return;
const char dq = '"';
for (unsigned p = 0; p < name.length(); ++p)
{
if (name[p] == dq)
{
name.insert(p, 1, dq);
++p;
}
}
name.insert(0u, 1, dq);
name += dq;
}

View File

@ -31,8 +31,11 @@
#include <stdio.h>
#include "../jrd/ibase.h"
#include "firebird/Interface.h"
#include "firebird/Message.h"
#include "../common/dsc.h"
#include "../burp/misc_proto.h"
#include "../burp/mvol_proto.h"
#include "../yvalve/gds_proto.h"
#include "../common/ThreadData.h"
#include "../common/UtilSvc.h"
@ -40,6 +43,9 @@
#include "../common/classes/fb_pair.h"
#include "../common/classes/MetaName.h"
#include "../../jrd/SimilarToMatcher.h"
#include "../common/status.h"
#include "../common/sha.h"
#include "../common/classes/ImplementHelper.h"
#ifdef HAVE_UNISTD_H
#include <unistd.h>
@ -49,6 +55,14 @@
#include <fcntl.h>
#endif
#if defined(HAVE_ZLIB_H)
#define WIRE_COMPRESS_SUPPORT 1
#endif
#ifdef WIRE_COMPRESS_SUPPORT
#include <zlib.h>
//#define COMPRESS_DEBUG 1
#endif // WIRE_COMPRESS_SUPPORT
static inline UCHAR* BURP_alloc(ULONG size)
{
@ -204,10 +218,6 @@ Version 11: FB4.0.
const int ATT_BACKUP_FORMAT = 11;
// format version number for ranges for arrays
//const int GDS_NDA_VERSION = 1; // Not used
// max array dimension
const int MAX_DIMENSION = 16;
@ -230,6 +240,10 @@ enum att_type {
att_backup_blksize, // backup block size
att_backup_file, // database file name
att_backup_volume, // backup volume number
att_backup_keyname, // name of crypt key
att_backup_zip, // zipped backup file
att_backup_hash, // hash of crypt key
att_backup_crypt, // name of crypt plugin
// Database attributes
@ -660,12 +674,14 @@ struct burp_fld
SSHORT fld_type;
SSHORT fld_sub_type;
FLD_LENGTH fld_length;
FLD_LENGTH fld_total_len; // including additional 2 bytes for VARYING CHAR
SSHORT fld_scale;
SSHORT fld_position;
SSHORT fld_parameter;
SSHORT fld_missing_parameter;
SSHORT fld_id;
RCRD_OFFSET fld_offset;
RCRD_OFFSET fld_missing_offset;
RCRD_OFFSET fld_old_offset;
SSHORT fld_number;
SSHORT fld_system_flag;
@ -694,6 +710,8 @@ struct burp_fld
ISC_QUAD fld_default_source;
SSHORT fld_character_set_id;
SSHORT fld_collation_id;
RCRD_OFFSET fld_sql;
RCRD_OFFSET fld_null;
};
enum fld_flags_vals {
@ -913,6 +931,8 @@ public:
// Global switches and data
struct BurpCrypt;
class BurpGlobals : public Firebird::ThreadData
{
public:
@ -928,7 +948,6 @@ public:
// this is VERY dirty hack to keep current behaviour
memset (&gbl_database_file_name, 0,
&veryEnd - reinterpret_cast<char*>(&gbl_database_file_name));
memset(status_vector, 0, sizeof(status_vector));
gbl_stat_flags = 0;
gbl_stat_header = false;
@ -955,6 +974,7 @@ public:
bool gbl_sw_deactivate_indexes;
bool gbl_sw_kill;
USHORT gbl_sw_blk_factor;
USHORT gbl_dialect;
const SCHAR* gbl_sw_fix_fss_data;
USHORT gbl_sw_fix_fss_data_id;
const SCHAR* gbl_sw_fix_fss_metadata;
@ -965,6 +985,12 @@ public:
bool gbl_sw_mode;
bool gbl_sw_mode_val;
bool gbl_sw_overwrite;
bool gbl_sw_zip;
const SCHAR* gbl_sw_keyholder;
const SCHAR* gbl_sw_crypt;
const SCHAR* gbl_sw_keyname;
SCHAR gbl_hdr_keybuffer[MAX_SQL_IDENTIFIER_SIZE + 1];
SCHAR gbl_hdr_cryptbuffer[MAX_SQL_IDENTIFIER_SIZE + 1];
const SCHAR* gbl_sw_sql_role;
const SCHAR* gbl_sw_user;
const SCHAR* gbl_sw_password;
@ -973,12 +999,44 @@ public:
burp_fil* gbl_sw_files;
burp_fil* gbl_sw_backup_files;
gfld* gbl_global_fields;
unsigned gbl_network_protocol;
burp_act* action;
BurpCrypt* gbl_crypt;
ULONG io_buffer_size;
redirect_vals sw_redirect;
bool burp_throw;
UCHAR* io_ptr;
int io_cnt;
UCHAR* blk_io_ptr;
int blk_io_cnt;
void put(const UCHAR c)
{
if (gbl_io_cnt <= 0)
MVOL_write(this);
--gbl_io_cnt;
*gbl_io_ptr++ = c;
}
UCHAR get()
{
if (gbl_io_cnt <= 0)
MVOL_read(this);
--gbl_io_cnt;
return *gbl_io_ptr++;
}
#ifdef WIRE_COMPRESS_SUPPORT
z_stream gbl_stream;
#endif
UCHAR* gbl_io_ptr;
int gbl_io_cnt;
UCHAR* gbl_compress_buffer;
UCHAR* gbl_crypt_buffer;
ULONG gbl_crypt_left;
UCHAR* gbl_decompress;
burp_rel* relations;
burp_pkg* packages;
burp_prc* procedures;
@ -1001,11 +1059,15 @@ public:
SCHAR mvol_old_file [MAX_FILE_NAME_SIZE];
int mvol_volume_count;
bool mvol_empty_file;
isc_db_handle db_handle;
isc_tr_handle tr_handle;
isc_tr_handle global_trans;
TEXT mvol_keyname_buffer[MAX_FILE_NAME_SIZE];
const TEXT* mvol_keyname;
TEXT mvol_crypt_buffer[MAX_FILE_NAME_SIZE];
const TEXT* mvol_crypt;
TEXT gbl_key_hash[(Firebird::Sha1::HASH_SIZE + 1) * 4 / 3 + 1]; // take into an account base64
Firebird::IAttachment* db_handle;
Firebird::ITransaction* tr_handle;
Firebird::ITransaction* global_trans;
DESC file_desc;
ISC_STATUS_ARRAY status_vector;
int exit_code;
UCHAR* head_of_mem_list;
FILE* output_file;
@ -1015,59 +1077,61 @@ public:
// burp_fld* v3_cvt_fld_list;
// The handles_get... are for restore.
isc_req_handle handles_get_character_sets_req_handle1;
isc_req_handle handles_get_chk_constraint_req_handle1;
isc_req_handle handles_get_collation_req_handle1;
isc_req_handle handles_get_exception_req_handle1;
isc_req_handle handles_get_field_dimensions_req_handle1;
isc_req_handle handles_get_field_req_handle1;
isc_req_handle handles_get_fields_req_handle1;
isc_req_handle handles_get_fields_req_handle2;
isc_req_handle handles_get_fields_req_handle3;
isc_req_handle handles_get_fields_req_handle4;
isc_req_handle handles_get_fields_req_handle5;
isc_req_handle handles_get_fields_req_handle6;
isc_req_handle handles_get_files_req_handle1;
isc_req_handle handles_get_filter_req_handle1;
isc_req_handle handles_get_function_arg_req_handle1;
isc_req_handle handles_get_function_req_handle1;
isc_req_handle handles_get_global_field_req_handle1;
isc_req_handle handles_get_index_req_handle1;
isc_req_handle handles_get_index_req_handle2;
isc_req_handle handles_get_index_req_handle3;
isc_req_handle handles_get_index_req_handle4;
isc_req_handle handles_get_package_req_handle1;
isc_req_handle handles_get_procedure_prm_req_handle1;
isc_req_handle handles_get_procedure_req_handle1;
isc_req_handle handles_get_ranges_req_handle1;
isc_req_handle handles_get_ref_constraint_req_handle1;
isc_req_handle handles_get_rel_constraint_req_handle1;
isc_req_handle handles_get_relation_req_handle1;
isc_req_handle handles_get_security_class_req_handle1;
isc_req_handle handles_get_sql_roles_req_handle1;
isc_req_handle handles_get_mapping_req_handle1;
isc_req_handle handles_get_trigger_message_req_handle1;
isc_req_handle handles_get_trigger_message_req_handle2;
isc_req_handle handles_get_trigger_old_req_handle1;
isc_req_handle handles_get_trigger_req_handle1;
isc_req_handle handles_get_type_req_handle1;
isc_req_handle handles_get_user_privilege_req_handle1;
isc_req_handle handles_get_view_req_handle1;
Firebird::IRequest* handles_get_character_sets_req_handle1;
Firebird::IRequest* handles_get_chk_constraint_req_handle1;
Firebird::IRequest* handles_get_collation_req_handle1;
Firebird::IRequest* handles_get_exception_req_handle1;
Firebird::IRequest* handles_get_field_dimensions_req_handle1;
Firebird::IRequest* handles_get_field_req_handle1;
Firebird::IRequest* handles_get_fields_req_handle1;
Firebird::IRequest* handles_get_fields_req_handle2;
Firebird::IRequest* handles_get_fields_req_handle3;
Firebird::IRequest* handles_get_fields_req_handle4;
Firebird::IRequest* handles_get_fields_req_handle5;
Firebird::IRequest* handles_get_fields_req_handle6;
Firebird::IRequest* handles_get_files_req_handle1;
Firebird::IRequest* handles_get_filter_req_handle1;
Firebird::IRequest* handles_get_function_arg_req_handle1;
Firebird::IRequest* handles_get_function_req_handle1;
Firebird::IRequest* handles_get_global_field_req_handle1;
Firebird::IRequest* handles_get_index_req_handle1;
Firebird::IRequest* handles_get_index_req_handle2;
Firebird::IRequest* handles_get_index_req_handle3;
Firebird::IRequest* handles_get_index_req_handle4;
Firebird::IRequest* handles_get_package_req_handle1;
Firebird::IRequest* handles_get_procedure_prm_req_handle1;
Firebird::IRequest* handles_get_procedure_req_handle1;
Firebird::IRequest* handles_get_ranges_req_handle1;
Firebird::IRequest* handles_get_ref_constraint_req_handle1;
Firebird::IRequest* handles_get_rel_constraint_req_handle1;
Firebird::IRequest* handles_get_relation_req_handle1;
Firebird::IRequest* handles_get_security_class_req_handle1;
Firebird::IRequest* handles_get_sql_roles_req_handle1;
Firebird::IRequest* handles_get_mapping_req_handle1;
Firebird::IRequest* handles_get_trigger_message_req_handle1;
Firebird::IRequest* handles_get_trigger_message_req_handle2;
Firebird::IRequest* handles_get_trigger_old_req_handle1;
Firebird::IRequest* handles_get_trigger_req_handle1;
Firebird::IRequest* handles_get_type_req_handle1;
Firebird::IRequest* handles_get_user_privilege_req_handle1;
Firebird::IRequest* handles_get_view_req_handle1;
// The handles_put.. are for backup.
isc_req_handle handles_put_index_req_handle1;
isc_req_handle handles_put_index_req_handle2;
isc_req_handle handles_put_index_req_handle3;
isc_req_handle handles_put_index_req_handle4;
isc_req_handle handles_put_index_req_handle5;
isc_req_handle handles_put_index_req_handle6;
isc_req_handle handles_put_index_req_handle7;
isc_req_handle handles_put_relation_req_handle1;
isc_req_handle handles_put_relation_req_handle2;
isc_req_handle handles_store_blr_gen_id_req_handle1;
isc_req_handle handles_write_function_args_req_handle1;
isc_req_handle handles_write_function_args_req_handle2;
isc_req_handle handles_write_procedure_prms_req_handle1;
isc_req_handle handles_fix_security_class_name_req_handle1;
Firebird::IRequest* handles_put_index_req_handle1;
Firebird::IRequest* handles_put_index_req_handle2;
Firebird::IRequest* handles_put_index_req_handle3;
Firebird::IRequest* handles_put_index_req_handle4;
Firebird::IRequest* handles_put_index_req_handle5;
Firebird::IRequest* handles_put_index_req_handle6;
Firebird::IRequest* handles_put_index_req_handle7;
Firebird::IRequest* handles_put_relation_req_handle1;
Firebird::IRequest* handles_put_relation_req_handle2;
Firebird::IRequest* handles_store_blr_gen_id_req_handle1;
Firebird::IRequest* handles_write_function_args_req_handle1;
Firebird::IRequest* handles_write_function_args_req_handle2;
Firebird::IRequest* handles_write_procedure_prms_req_handle1;
Firebird::IRequest* handles_fix_security_class_name_req_handle1;
bool hdr_forced_writes;
TEXT database_security_class[GDS_NAME_LEN]; // To save database security class for deferred update
@ -1089,6 +1153,9 @@ public:
char veryEnd;
//starting after this members must be initialized in constructor explicitly
Firebird::FbLocalStatus status_vector;
Firebird::ThrowLocalStatus throwStatus;
Firebird::Array<Firebird::Pair<Firebird::NonPooled<Firebird::MetaName, Firebird::MetaName> > >
defaultCollations;
Firebird::UtilSvc* uSvc;
@ -1162,4 +1229,49 @@ enum burp_messages_vals {
// BLOB buffer
typedef Firebird::HalfStaticArray<UCHAR, 1024> BlobBuffer;
class BurpSql : public Firebird::AutoStorage
{
public:
BurpSql(BurpGlobals* g, const char* sql)
: Firebird::AutoStorage(),
tdgbl(g), stmt(nullptr)
{
stmt = tdgbl->db_handle->prepare(&tdgbl->throwStatus, tdgbl->tr_handle, 0, sql, 3, 0);
}
template <typename M>
void singleSelect(Firebird::ITransaction* trans, M* msg)
{
stmt->execute(&tdgbl->throwStatus, tdgbl->tr_handle, nullptr, nullptr, msg->getMetadata(), msg->getData());
}
template <typename M>
void execute(Firebird::ITransaction* trans, M* msg)
{
stmt->execute(&tdgbl->throwStatus, tdgbl->tr_handle, msg->getMetadata(), msg->getData(), nullptr, nullptr);
}
void execute(Firebird::ITransaction* trans)
{
stmt->execute(&tdgbl->throwStatus, tdgbl->tr_handle, nullptr, nullptr, nullptr, nullptr);
}
private:
BurpGlobals* tdgbl;
Firebird::IStatement* stmt;
};
class OutputVersion : public Firebird::IVersionCallbackImpl<OutputVersion, Firebird::CheckStatusWrapper>
{
public:
OutputVersion(const char* printFormat)
: format(printFormat)
{ }
void callback(Firebird::CheckStatusWrapper* status, const char* text);
private:
const char* format;
};
#endif // BURP_BURP_H

View File

@ -26,15 +26,19 @@
#include "../common/ThreadData.h"
#include "../common/classes/MsgPrint.h"
#include "../common/classes/fb_string.h"
#include "../common/UtilSvc.h"
class BurpGlobals;
int BURP_main(Firebird::UtilSvc*);
int gbak(Firebird::UtilSvc*);
void BURP_abort();
void BURP_error(USHORT, bool, const MsgFormat::SafeArg& arg = MsgFormat::SafeArg());
void BURP_error(USHORT, bool, const char* str);
void BURP_error_redirect(const ISC_STATUS*, USHORT, const MsgFormat::SafeArg& arg = MsgFormat::SafeArg());
void BURP_error_redirect(Firebird::IStatus*, USHORT, const MsgFormat::SafeArg& arg = MsgFormat::SafeArg());
void BURP_makeSymbol(BurpGlobals*, Firebird::string&);
void BURP_msg_partial(bool, USHORT, const MsgFormat::SafeArg& arg = MsgFormat::SafeArg());
void BURP_msg_put(bool, USHORT, const MsgFormat::SafeArg& arg);
const int BURP_MSG_GET_SIZE = 128; // Use it for buffers passed to this function.
@ -42,8 +46,8 @@ void BURP_msg_get(USHORT, TEXT*, const MsgFormat::SafeArg& arg = MsgFormat::Safe
void BURP_output_version(void*, const TEXT*);
void BURP_print(bool err, USHORT, const MsgFormat::SafeArg& arg = MsgFormat::SafeArg());
void BURP_print(bool err, USHORT, const char* str);
void BURP_print_status(bool err, const ISC_STATUS* status);
void BURP_print_warning(const ISC_STATUS*);
void BURP_print_status(bool err, Firebird::IStatus* status);
void BURP_print_warning(Firebird::IStatus* status);
void BURP_verbose(USHORT, const MsgFormat::SafeArg& arg = MsgFormat::SafeArg());
void BURP_verbose(USHORT, const char* str);

View File

@ -91,8 +91,12 @@ const int IN_SW_BURP_FETCHPASS = 45; // fetch default password from file to us
const int IN_SW_BURP_VERBINT = 46; // verbose but with specific interval
const int IN_SW_BURP_STATS = 47; // print statistics
const int IN_SW_BURP_ZIP = 48; // backup file in .zip format
const int IN_SW_BURP_KEYHOLD = 49; // name of KeyHolder plugin
const int IN_SW_BURP_KEYNAME = 50; // name of crypt key
const int IN_SW_BURP_CRYPT = 51; // name of crypt plugin
/**************************************************************************/
// used 0BCDEFGILMNOPRSTUVYZ available AHJQWX
static const char* const BURP_SW_MODE_RO = "READ_ONLY";
static const char* const BURP_SW_MODE_RW = "READ_WRITE";
@ -111,6 +115,8 @@ static const Switches::in_sw_tab_t reference_burp_in_sw_table[] =
// msg 73: @1CREATE_DATABASE create database from backup file
{IN_SW_BURP_CO, isc_spb_bkp_convert, "CONVERT", 0, 0, 0, false, true, 254, 2, NULL, boBackup},
// msg 254: @1CO(NVERT) backup external files as tables
{IN_SW_BURP_CRYPT, isc_spb_bkp_crypt, "CRYPT", 0, 0, 0, false, false, 373, 3, NULL, boGeneral},
// msg 373:@1CRY(PT) plugin name
{IN_SW_BURP_E, isc_spb_bkp_expand, "EXPAND", 0, 0, 0, false, true, 97, 1, NULL, boBackup},
// msg 97: @1EXPAND no data compression
{IN_SW_BURP_FA, isc_spb_bkp_factor, "FACTOR", 0, 0, 0, false, false, 181, 2, NULL, boBackup},
@ -125,10 +131,14 @@ static const Switches::in_sw_tab_t reference_burp_in_sw_table[] =
// msg 303: @1FIX_FSS_METADATA fix malformed UNICODE_FSS metadata
{IN_SW_BURP_G, isc_spb_bkp_no_garbage_collect, "GARBAGE_COLLECT", 0, 0, 0, false, true, 177, 1, NULL, boBackup},
// msg 177:@1GARBAGE_COLLECT inhibit garbage collection
{IN_SW_BURP_I, isc_spb_res_deactivate_idx, "INACTIVE", 0, 0, 0, false, true, 78, 1, NULL, boRestore},
{IN_SW_BURP_I, isc_spb_res_deactivate_idx, "INACTIVE", 0, 0, 0, false, true, 78, 1, NULL, boRestore},
// msg 78:@1INACTIVE deactivate indexes during restore
{IN_SW_BURP_IG, isc_spb_bkp_ignore_checksums, "IGNORE", 0, 0, 0, false, true, 178, 2, NULL, boBackup},
{IN_SW_BURP_IG, isc_spb_bkp_ignore_checksums, "IGNORE", 0, 0, 0, false, true, 178, 2, NULL, boBackup},
// msg 178:@1IGNORE ignore bad checksums
{IN_SW_BURP_KEYHOLD, isc_spb_bkp_keyholder, "KEYHOLDER", 0, 0, 0, false, false, 382, 4, NULL, boGeneral},
// msg 382:@1KEYHOLDER name of a key holder plugin
{IN_SW_BURP_KEYNAME, isc_spb_bkp_keyname, "KEYNAME", 0, 0, 0, false, false, 372, 4, NULL, boGeneral},
// msg 372:@1KEYNAME name of a key to be used for encryption
{IN_SW_BURP_K, isc_spb_res_no_shadow, "KILL", 0, 0, 0, false, true, 172, 1, NULL, boRestore},
// msg 172:@1KILL restore without creating shadows
{IN_SW_BURP_L, isc_spb_bkp_ignore_limbo, "LIMBO", 0, 0, 0, false, true, 98, 1, NULL, boBackup},
@ -167,13 +177,13 @@ static const Switches::in_sw_tab_t reference_burp_in_sw_table[] =
// msg 355: @1SKIP_DATA skip data for table
{IN_SW_BURP_STATS, isc_spb_bkp_stat, "STATISTICS", 0, 0, 0, false, false, 361, 2, NULL, boGeneral},
// msg 361: @1ST(ATISTICS) TDRW show statistics:
{-1, 0, " ", 0, 0, 0, false, false, 362, 0, NULL, boGeneral},
{-1, 0, " ", 0, 0, 0, false, false, 362, 0, NULL, boGeneral},
// msg 362: T time from start
{-1, 0, " ", 0, 0, 0, false, false, 363, 0, NULL, boGeneral},
{-1, 0, " ", 0, 0, 0, false, false, 363, 0, NULL, boGeneral},
// msg 363: D delta time
{-1, 0, " ", 0, 0, 0, false, false, 364, 0, NULL, boGeneral},
{-1, 0, " ", 0, 0, 0, false, false, 364, 0, NULL, boGeneral},
// msg 364: R page reads
{-1, 0, " ", 0, 0, 0, false, false, 365, 0, NULL, boGeneral},
{-1, 0, " ", 0, 0, 0, false, false, 365, 0, NULL, boGeneral},
// msg 365: W page writes
{IN_SW_BURP_T, 0, "TRANSPORTABLE", 0, 0, 0, false, false, 175, 1, NULL, boBackup},
// msg 175: @1TRANSPORTABLE transportable backup -- data in XDR format
@ -197,6 +207,8 @@ static const Switches::in_sw_tab_t reference_burp_in_sw_table[] =
// msg 109: @1Y redirect/suppress output (file path or OUTPUT_SUPPRESS)
{IN_SW_BURP_Z, 0, "Z", 0, 0, 0, false, false, 104, 1, NULL, boGeneral},
// msg 104: @1Z print version number
{IN_SW_BURP_ZIP, isc_spb_bkp_zip, "ZIP", 0, 0, 0, false, true, 374, 3, NULL, boBackup},
// msg 104: @1ZIP backup file is in zip compressed format
/**************************************************************************/
// The next two 'virtual' switches are hidden from user and are needed
// for services API

View File

@ -24,8 +24,8 @@
#ifndef BURP_CANON_PROTO_H
#define BURP_CANON_PROTO_H
ULONG CAN_encode_decode (burp_rel*, lstring*, UCHAR*, int);
ULONG CAN_slice (lstring*, lstring*, int, /*USHORT,*/ UCHAR*);
ULONG CAN_encode_decode (burp_rel* relation, lstring* buffer, UCHAR* data, bool direction, bool useMissingOffset = false);
ULONG CAN_slice (lstring* buffer, lstring* slice, bool direction, UCHAR* sdl);
#endif // BURP_CANON_PROTO_H

View File

@ -42,11 +42,11 @@
#include "../common/xdr_proto.h"
#include "../common/gdsassert.h"
#include "../common/StatusHolder.h"
#include "../common/status.h"
#include "fb_types.h"
// TMN: Currently we can't include remote/remote.h because we'd get
// conflicting blk_t definitions (we are gonna fix this, in due time).
using Firebird::FbLocalStatus;
static bool_t burp_getbytes(XDR*, SCHAR *, u_int);
static bool_t burp_putbytes(XDR*, const SCHAR*, u_int);
@ -63,7 +63,7 @@ static xdr_t::xdr_ops burp_ops =
const int increment = 1024;
ULONG CAN_encode_decode(burp_rel* relation, lstring* buffer, UCHAR* data, bool_t direction)
ULONG CAN_encode_decode(burp_rel* relation, lstring* buffer, UCHAR* data, bool direction, bool useMissingOffset)
{
/**************************************
*
@ -203,17 +203,21 @@ ULONG CAN_encode_decode(burp_rel* relation, lstring* buffer, UCHAR* data, bool_t
{
if (field->fld_flags & FLD_computed)
continue;
offset = FB_ALIGN(offset, sizeof(SSHORT));
UCHAR* p = data + offset;
UCHAR* p = data + field->fld_missing_offset;
if (!useMissingOffset)
{
offset = FB_ALIGN(offset, sizeof(SSHORT));
p = data + offset;
offset += sizeof(SSHORT);
}
if (!xdr_short(xdrs, (SSHORT*) p))
return FALSE;
offset += sizeof(SSHORT);
}
return (xdrs->x_private - xdrs->x_base);
}
ULONG CAN_slice(lstring* buffer, lstring* slice, bool_t direction, /*USHORT sdl_length,*/ UCHAR* sdl)
ULONG CAN_slice(lstring* buffer, lstring* slice, bool direction, UCHAR* sdl)
{
/**************************************
*
@ -422,8 +426,7 @@ static bool_t xdr_slice(XDR* xdrs, lstring* slice, /*USHORT sdl_length,*/ const
sdl_info info;
{
Firebird::LocalStatus ls;
Firebird::CheckStatusWrapper s(&ls);
FbLocalStatus s;
if (SDL_info(&s, sdl, &info, 0))
return FALSE;
}

View File

@ -119,12 +119,12 @@ void MISC_free_burp( void *free)
// in a function visible to all gbak components.
// Given a request, if it's non-zero (compiled), deallocate it but
// without caring about a possible error.
void MISC_release_request_silent(isc_req_handle& req_handle)
void MISC_release_request_silent(Firebird::IRequest*& req_handle)
{
if (req_handle)
{
ISC_STATUS_ARRAY req_status;
isc_release_request(req_status, &req_handle);
req_handle->release();
req_handle = nullptr;
}
}

View File

@ -26,7 +26,7 @@
UCHAR* MISC_alloc_burp(ULONG);
void MISC_free_burp(void*);
void MISC_release_request_silent(isc_req_handle& req_handle);
void MISC_release_request_silent(Firebird::IRequest*& req_handle);
int MISC_symbol_length(const TEXT*, ULONG);
void MISC_terminate(const TEXT*, TEXT*, ULONG, ULONG);

File diff suppressed because it is too large Load Diff

View File

@ -24,24 +24,27 @@
#ifndef BURP_MVOL_PROTO_H
#define BURP_MVOL_PROTO_H
#include "../burp/burp.h"
#include "firebird/Interface.h"
#include "std_desc.h"
class BurpGlobals;
FB_UINT64 MVOL_fini_read();
FB_UINT64 MVOL_fini_write(int*, UCHAR**);
FB_UINT64 MVOL_fini_write();
void MVOL_init(ULONG);
void MVOL_init_read(const char*, USHORT*, int*, UCHAR**);
void MVOL_init_write(const char*, int*, UCHAR**);
void MVOL_init_read(const char*, USHORT*);
void MVOL_init_write(const char*);
bool MVOL_split_hdr_write();
bool MVOL_split_hdr_read();
int MVOL_read(int*, UCHAR**);
void MVOL_read(BurpGlobals*);
UCHAR* MVOL_read_block(BurpGlobals*, UCHAR*, ULONG);
void MVOL_skip_block(BurpGlobals*, ULONG);
UCHAR MVOL_write(const UCHAR, int*, UCHAR**);
void MVOL_write(BurpGlobals*);
const UCHAR* MVOL_write_block(BurpGlobals*, const UCHAR*, ULONG);
Firebird::ICryptKeyCallback* MVOL_get_crypt(BurpGlobals*);
#if defined WIN_NT
DESC MVOL_open(const char*, ULONG, ULONG);
DESC NT_tape_open(const char*, ULONG, ULONG);
#endif

File diff suppressed because it is too large Load Diff

View File

@ -33,21 +33,23 @@
#include "CsConvert.h"
#include "IntlUtil.h"
namespace Firebird {
template <>
inline void SimpleDelete<charset>::clear(charset* cs)
{
Firebird::IntlUtil::finiCharset(cs);
delete cs;
}
}
namespace Jrd {
class CharSet
{
public:
class Delete
{
public:
static void clear(charset* cs)
{
Firebird::IntlUtil::finiCharset(cs);
delete cs;
}
};
static CharSet* createInstance(Firebird::MemoryPool& pool, USHORT id, charset* cs);
protected:

View File

@ -45,6 +45,9 @@ extern "C"
using namespace Firebird;
const DecimalStatus DecimalStatus::DEFAULT(FB_DEC_Errors);
const DecimalBinding DecimalBinding::DEFAULT;
namespace {
struct Dec2fb
@ -359,7 +362,9 @@ Decimal64 Decimal64::floor(DecimalStatus decSt) const
int Decimal64::compare(DecimalStatus decSt, Decimal64 tgt) const
{
DecimalContext context(this, decSt);
DecimalStatus cmpStatus(decSt);
cmpStatus.decExtFlag &= ~DEC_IEEE_754_Invalid_operation;
DecimalContext context(this, cmpStatus);
decDouble r;
decDoubleCompare(&r, &dec, &tgt.dec, &context);
return decDoubleToInt32(&r, &context, DEC_ROUND_HALF_UP);

View File

@ -55,6 +55,8 @@ struct DecimalStatus
: decExtFlag(exc), roundingMode(DEC_ROUND_HALF_UP)
{ }
static const DecimalStatus DEFAULT;
USHORT decExtFlag, roundingMode;
};
@ -64,12 +66,15 @@ struct DecimalBinding
: bind(DEC_NATIVE), numScale(0)
{ }
static const DecimalBinding DEFAULT;
enum Bind { DEC_NATIVE, DEC_TEXT, DEC_DOUBLE, DEC_NUMERIC };
Bind bind;
SCHAR numScale;
};
class DecimalFixed;
class Decimal64
@ -132,6 +137,8 @@ public:
UCHAR* getBytes();
int compare(DecimalStatus decSt, Decimal128Base tgt) const;
void setScale(DecimalStatus decSt, int scale);
bool isInf() const;
bool isNan() const;
int sign() const;
@ -146,8 +153,6 @@ public:
#endif
private:
void setScale(DecimalStatus decSt, int scale);
decQuad dec;
};

View File

@ -98,7 +98,7 @@ THREAD_ENTRY_DECLARE threadStart(THREAD_ENTRY_PARAM arg)
#ifdef USE_POSIX_THREADS
#define START_THREAD
void Thread::start(ThreadEntryPoint* routine, void* arg, int priority_arg, Handle* p_handle)
ThreadId Thread::start(ThreadEntryPoint* routine, void* arg, int priority_arg, Handle* p_handle)
{
/**************************************
*
@ -180,6 +180,8 @@ void Thread::start(ThreadEntryPoint* routine, void* arg, int priority_arg, Handl
#endif
*p_handle = thread;
}
return getId();
}
void Thread::waitForCompletion(Handle& thread)
@ -208,6 +210,11 @@ ThreadId Thread::getId()
#endif
}
bool Thread::isCurrent(const ThreadId threadId)
{
return getId() == threadId;
}
void Thread::sleep(unsigned milliseconds)
{
#if defined(HAVE_NANOSLEEP)
@ -252,7 +259,7 @@ void Thread::yield()
#ifdef WIN_NT
#define START_THREAD
void Thread::start(ThreadEntryPoint* routine, void* arg, int priority_arg, Handle* p_handle)
ThreadId Thread::start(ThreadEntryPoint* routine, void* arg, int priority_arg, Handle* p_handle)
{
/**************************************
*
@ -316,6 +323,8 @@ void Thread::start(ThreadEntryPoint* routine, void* arg, int priority_arg, Handl
{
CloseHandle(handle);
}
return thread_id;
}
void Thread::waitForCompletion(Handle& handle)
@ -342,6 +351,11 @@ ThreadId Thread::getId()
return GetCurrentThreadId();
}
bool Thread::isCurrent(const ThreadId threadId)
{
return GetCurrentThreadId() == threadId;
}
void Thread::sleep(unsigned milliseconds)
{
SleepEx(milliseconds, FALSE);
@ -356,7 +370,7 @@ void Thread::yield()
#ifndef START_THREAD
void Thread::start(ThreadEntryPoint* routine, void* arg, int priority_arg, Handle* p_handle)
ThreadId Thread::start(ThreadEntryPoint* routine, void* arg, int priority_arg, Handle* p_handle)
{
/**************************************
*
@ -368,7 +382,8 @@ void Thread::start(ThreadEntryPoint* routine, void* arg, int priority_arg, Handl
* Wrong attempt to start a new thread.
*
**************************************/
fb_assert(false);
return 0;
}
void Thread::waitForCompletion(Handle&)

View File

@ -75,9 +75,10 @@ public:
typedef pthread_t Handle;
#endif
static void start(ThreadEntryPoint* routine, void* arg, int priority_arg, Handle* p_handle = NULL);
static ThreadId start(ThreadEntryPoint* routine, void* arg, int priority_arg, Handle* p_handle = NULL);
static void waitForCompletion(Handle& handle);
static void kill(Handle& handle);
static bool isCurrent(const ThreadId threadId);
static ThreadId getId();

View File

@ -145,6 +145,7 @@ public:
virtual bool finished() { return false; }
virtual void initStatus() { }
virtual bool utf8FileNames() { return false; }
virtual Firebird::ICryptKeyCallback* getCryptCallback() { return NULL; }
};

View File

@ -30,6 +30,8 @@
#ifndef FB_UTILFACE
#define FB_UTILFACE
#include "firebird/Interface.h"
#include "../common/classes/alloc.h"
#include "../common/classes/array.h"
#include "../common/classes/fb_string.h"
@ -74,6 +76,7 @@ public:
virtual bool finished() = 0;
virtual unsigned int getAuthBlock(const unsigned char** bytes) = 0;
virtual bool utf8FileNames() = 0;
virtual Firebird::ICryptKeyCallback* getCryptCallback() = 0;
void setDataMode(bool value)
{

View File

@ -0,0 +1,271 @@
/*
* 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 Claudio Valderrama on 16-Mar-2007
* for the Firebird Open Source RDBMS project.
*
* Copyright (c) 2007 Claudio Valderrama
* and all contributors signed below.
*
* All Rights Reserved.
* Contributor(s): ______________________________________.
* Alex Peshkoff, 2017
*
*/
#include "firebird.h"
#include "BlobWrapper.h"
#include "../jrd/ibase.h"
#include "firebird/Interface.h"
static const USHORT SEGMENT_LIMIT = 65535;
using namespace Firebird;
bool BlobWrapper::open(IAttachment* db, ITransaction* trans, ISC_QUAD& blobid,
USHORT bpb_len, const UCHAR* bpb)
{
if (m_direction != dir_none)
return false;
if (bpb_len > 0 && !bpb || blobIsNull(blobid))
return false;
m_blob = db->openBlob(m_status, trans, &blobid, bpb_len, bpb);
if (m_status->isEmpty())
{
m_direction = dir_read;
return true;
}
return false;
}
bool BlobWrapper::create(IAttachment* db, ITransaction* trans, ISC_QUAD& blobid,
USHORT bpb_len, const UCHAR* bpb)
{
if (m_direction != dir_none)
return false;
if (bpb_len > 0 && !bpb)
return false;
blobid.gds_quad_high = blobid.gds_quad_low = 0;
m_blob = db->createBlob(m_status, trans, &blobid, bpb_len, bpb);
if (m_status->isEmpty())
{
m_direction = dir_write;
return true;
}
return false;
}
bool BlobWrapper::close(bool force_internal_SV)
{
bool rc = false;
if (m_blob)
{
m_blob->close(force_internal_SV ? &m_default_status : m_status);
rc = (force_internal_SV ? &m_default_status : m_status)->isEmpty();
if (rc)
m_blob = nullptr;
m_direction = dir_none;
}
return rc;
}
bool BlobWrapper::getSegment(FB_SIZE_T len, void* buffer, FB_SIZE_T& real_len)
{
real_len = 0;
if (!m_blob || m_direction != dir_read)
return false;
if (len && !buffer)
return false;
unsigned ilen = len > SEGMENT_LIMIT ? SEGMENT_LIMIT : static_cast<unsigned>(len);
unsigned olen = 0;
bool eof = m_blob->getSegment(m_status, ilen, buffer, &olen) == Firebird::IStatus::RESULT_NO_DATA;
if (m_status->isEmpty() && !eof)
{
real_len = olen;
return true;
}
return false;
}
bool BlobWrapper::getData(FB_SIZE_T len, void* buffer, FB_SIZE_T& real_len,
bool use_sep, const UCHAR separator)
{
#ifdef DEV_BUILD
if (!m_blob || m_direction != dir_read)
return false;
if (!len || !buffer)
return false;
#endif
bool rc = false;
real_len = 0;
char* buf2 = static_cast<char*>(buffer);
while (len)
{
unsigned olen = 0;
bool eof = m_blob->getSegment(m_status, len, buf2, &olen) == Firebird::IStatus::RESULT_NO_DATA;
if (m_status->isEmpty() && !eof)
{
len -= olen;
buf2 += olen;
real_len += olen;
if (len && use_sep) // Append the segment separator.
{
--len;
*buf2++ = separator;
++real_len;
}
rc = true;
}
else
break;
}
return rc;
}
bool BlobWrapper::putSegment(FB_SIZE_T len, const void* buffer)
{
#ifdef DEV_BUILD
if (!m_blob || m_direction != dir_write)
return false;
if (len > 0 && !buffer)
return false;
#endif
unsigned ilen = len > SEGMENT_LIMIT ? SEGMENT_LIMIT : static_cast<unsigned>(len);
m_blob->putSegment(m_status, ilen, buffer);
return m_status->isEmpty();
}
bool BlobWrapper::putSegment(FB_SIZE_T len, const void* buffer, FB_SIZE_T& real_len)
{
#ifdef DEV_BUILD
if (!m_blob || m_direction == dir_read)
return false;
if (len > 0 && !buffer)
return false;
#endif
real_len = 0;
unsigned ilen = len > SEGMENT_LIMIT ? SEGMENT_LIMIT : static_cast<unsigned>(len);
m_blob->putSegment(m_status, ilen, buffer);
if (!m_status->isEmpty())
return false;
real_len = ilen;
return true;
}
bool BlobWrapper::putData(FB_SIZE_T len, const void* buffer, FB_SIZE_T& real_len)
{
if (!m_blob || m_direction == dir_read)
return false;
if (len > 0 && !buffer)
return false;
real_len = 0;
m_blob->putSegment(m_status, len, buffer);
if (!m_status->isEmpty())
return false;
real_len = len;
return true;
}
bool BlobWrapper::getInfo(FB_SIZE_T items_size, const UCHAR* items,
FB_SIZE_T info_size, UCHAR* blob_info) const
{
if (!m_blob || m_direction != dir_read)
return false;
m_blob->getInfo(m_status, items_size, items, info_size, blob_info);
return m_status->isEmpty();
}
bool BlobWrapper::getSize(SLONG* size, SLONG* seg_count, SLONG* max_seg) const
{
/**************************************
*
* g e t B l o b S i z e
*
**************************************
*
* Functional description
* Get the size, number of segments, and max
* segment length of a blob. Return true
* if it happens to succeed.
* This is a clone of gds__blob_size.
*
**************************************/
static const UCHAR blob_items[] =
{
isc_info_blob_max_segment,
isc_info_blob_num_segments,
isc_info_blob_total_length
};
UCHAR buffer[64];
if (!getInfo(sizeof(blob_items), blob_items, sizeof(buffer), buffer))
return false;
const UCHAR* p = buffer;
const UCHAR* const end = buffer + sizeof(buffer);
for (UCHAR item = *p++; item != isc_info_end && p < end; item = *p++)
{
const USHORT l = gds__vax_integer(p, 2);
p += 2;
const SLONG n = gds__vax_integer(p, l);
p += l;
switch (item)
{
case isc_info_blob_max_segment:
if (max_seg)
*max_seg = n;
break;
case isc_info_blob_num_segments:
if (seg_count)
*seg_count = n;
break;
case isc_info_blob_total_length:
if (size)
*size = n;
break;
default:
return false;
}
}
return true;
}

View File

@ -0,0 +1,95 @@
/*
* 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 Claudio Valderrama on 16-Mar-2007
* for the Firebird Open Source RDBMS project.
*
* Copyright (c) 2007 Claudio Valderrama
* and all contributors signed below.
*
* All Rights Reserved.
* Contributor(s): ______________________________________.
* Alex Peshkoff, 2017
*
*/
#ifndef FB_USER_BLOB_H
#define FB_USER_BLOB_H
#include "firebird/Interface.h"
#include <memory.h>
#include "../common/status.h"
class BlobWrapper
{
public:
explicit BlobWrapper(Firebird::CheckStatusWrapper* status)
: m_status(status ? status : &m_default_status), m_blob(nullptr), m_direction(dir_none)
{ }
~BlobWrapper()
{
close(true);
}
bool open(Firebird::IAttachment* db, Firebird::ITransaction* trans, ISC_QUAD& blobid,
USHORT bpb_len = 0, const UCHAR* bpb = nullptr);
bool create(Firebird::IAttachment* db, Firebird::ITransaction* trans, ISC_QUAD& blobid,
USHORT bpb_len = 0, const UCHAR* bpb = nullptr);
bool close(bool force_internal_SV = false);
bool getSegment(FB_SIZE_T len, void* buffer, FB_SIZE_T& real_len);
bool getData(FB_SIZE_T len, void* buffer, FB_SIZE_T& real_len, bool use_sep = false, const UCHAR separator = '\0');
bool putSegment(FB_SIZE_T len, const void* buffer);
bool putSegment(FB_SIZE_T len, const void* buffer, FB_SIZE_T& real_len);
bool putData(FB_SIZE_T len, const void* buffer, FB_SIZE_T& real_len);
bool putData(FB_SIZE_T len, const void* buffer)
{
FB_SIZE_T dummy;
return putData(len, buffer, dummy);
}
bool isOpen() const
{
return m_blob != 0 && m_direction != dir_none;
}
ISC_STATUS getCode() const
{
return m_status->getErrors()[1];
}
bool getInfo(FB_SIZE_T items_size, const UCHAR* items, FB_SIZE_T info_size, UCHAR* blob_info) const;
bool getSize(SLONG* size, SLONG* seg_count, SLONG* max_seg) const;
static bool blobIsNull(const ISC_QUAD& blobid)
{
return blobid.gds_quad_high == 0 && blobid.gds_quad_low == 0;
}
private:
enum b_direction
{
dir_none,
dir_read,
dir_write
};
Firebird::FbLocalStatus m_default_status;
Firebird::CheckStatusWrapper* const m_status;
Firebird::IBlob* m_blob;
b_direction m_direction;
};
#endif // FB_USER_BLOB_H

View File

@ -334,7 +334,9 @@ ClumpletReader::ClumpletType ClumpletReader::getClumpletType(UCHAR tag) const
case isc_spb_res_fix_fss_metadata:
case isc_spb_bkp_stat:
case isc_spb_bkp_skip_data:
//case isc_spb_res_skip_data: // same value
case isc_spb_bkp_keyholder:
case isc_spb_bkp_keyname:
case isc_spb_bkp_crypt:
return StringSpb;
case isc_spb_bkp_factor:
case isc_spb_bkp_length:

View File

@ -49,6 +49,7 @@ static const UCHAR CpuAlpha = 14;
static const UCHAR CpuArm64 = 15;
static const UCHAR CpuPowerPc64el = 16;
static const UCHAR CpuM68k = 17;
static const UCHAR CpuRiscV64 = 18;
static const UCHAR OsWindows = 0;
static const UCHAR OsLinux = 1;
@ -89,7 +90,8 @@ const char* hardware[] = {
"Alpha",
"ARM64",
"PowerPC64el",
"M68k"
"M68k",
"RiscV64"
};
const char* operatingSystem[] = {
@ -116,22 +118,23 @@ const char* compiler[] = {
// This table lists pre-fb3 implementation codes
const UCHAR backwardTable[FB_NELEM(hardware) * FB_NELEM(operatingSystem)] =
{
// Intel AMD Sparc PPC PPC64 MIPSEL MIPS ARM IA64 s390 s390x SH SHEB HPPA Alpha ARM64 PowerPC64el
/* Windows */ 50, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
/* Linux */ 60, 66, 65, 69, 86, 71, 72, 75, 76, 79, 78, 80, 81, 82, 83, 84, 85,
/* Darwin */ 70, 73, 0, 63, 77, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
/* Solaris */ 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
/* HPUX */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0,
/* AIX */ 0, 0, 0, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
/* MVS */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
/* FreeBSD */ 61, 67, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
/* NetBSD */ 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
// Intel AMD Sparc PPC PPC64 MIPSEL MIPS ARM IA64 s390 s390x SH SHEB HPPA Alpha ARM64 PPC64el M68k RiscV64
/* Windows */ 50, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
/* Linux */ 60, 66, 65, 69, 86, 71, 72, 75, 76, 79, 78, 80, 81, 82, 83, 84, 85, 87, 88,
/* Darwin */ 70, 73, 0, 63, 77, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
/* Solaris */ 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
/* HPUX */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 0, 0,
/* AIX */ 0, 0, 0, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
/* MVS */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
/* FreeBSD */ 61, 67, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
/* NetBSD */ 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
const UCHAR backEndianess[FB_NELEM(hardware)] =
{
// Intel AMD Sparc PPC PPC64 MIPSEL MIPS ARM IA64 s390 s390x SH SHEB HPPA Alpha ARM64 PowerPC64el M68k
0, 0, 1, 1, 1, 0, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 1
// Intel AMD Sparc PPC PPC64 MIPSEL MIPS ARM IA64 s390 s390x SH SHEB HPPA Alpha ARM64 PPC64el M68k RiscV64
0, 0, 1, 1, 1, 0, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 1, 0,
};
} // anonymous namespace

View File

@ -41,7 +41,6 @@ public:
DbImplementation (UCHAR p_cpu, UCHAR p_os, UCHAR p_cc, UCHAR p_flags)
: di_cpu(p_cpu), di_os(p_os), di_cc(p_cc), di_flags(p_flags)
{ }
DbImplementation (UCHAR p_compatImpl);
~DbImplementation() { }
private:

View File

@ -222,14 +222,6 @@ inline bool isinf(double x)
{
return (!_finite (x) && !isnan(x));
}
#else
#ifndef isinf
template <typename F>
inline bool isinf(F x)
{
return !isnan(x) && isnan(x - x);
}
#endif // isinf
#endif // WIN_NT
namespace Firebird {

View File

@ -30,6 +30,7 @@
#define FB_COMMON_CLASSES_GET_PLUGINS
#include "../common/classes/ImplementHelper.h"
#include "../common/classes/auto.h"
#include "../common/config/config.h"
#include "../common/StatusHolder.h"
@ -142,6 +143,28 @@ private:
}
};
// template required to use AutoPtr for plugins
template <typename P>
class ReleasePlugin
{
public:
static void clear(P* ptr)
{
if (ptr)
PluginManagerInterfacePtr()->releasePlugin(ptr);
}
};
template <typename P>
class AutoPlugin : public AutoPtr<P, ReleasePlugin>
{
public:
AutoPlugin(P* p = nullptr)
: AutoPtr<P, ReleasePlugin>(p)
{ }
};
} // namespace Firebird

View File

@ -313,7 +313,7 @@ public:
typedef void VoidNoParam();
explicit UnloadDetectorHelper(MemoryPool&)
: cleanup(NULL), flagOsUnload(false)
: cleanup(NULL), thdDetach(NULL), flagOsUnload(false)
{ }
void registerMe()
@ -348,6 +348,11 @@ public:
cleanup = function;
}
void setThreadDetach(VoidNoParam* function)
{
thdDetach = function;
}
void doClean()
{
flagOsUnload = false;
@ -359,8 +364,15 @@ public:
}
}
void threadDetach()
{
if (thdDetach)
thdDetach();
}
private:
VoidNoParam* cleanup;
VoidNoParam* thdDetach;
bool flagOsUnload;
};

View File

@ -130,6 +130,13 @@ namespace Firebird
return ptr;
}
void moveFrom(RefPtr& r)
{
assign(NULL);
ptr = r.ptr;
r.ptr = NULL;
}
T* operator=(T* p)
{
return assign(p);

View File

@ -31,6 +31,7 @@
#include "firebird.h"
#include "fb_tls.h"
#include "init.h"
#include "../ThreadStart.h"
#include "SyncObject.h"
#include "Synchronize.h"
@ -182,6 +183,37 @@ void Synchronize::shutdown()
}
class ThreadSyncInstance : public ThreadSync
{
typedef InstanceControl::InstanceLink<ThreadSyncInstance, InstanceControl::PRIORITY_REGULAR> Link;
public:
ThreadSyncInstance(const char* desc)
: ThreadSync(desc)
{
m_link = FB_NEW Link(this);
}
virtual ~ThreadSyncInstance()
{
if (m_link)
{
m_link->remove();
delete m_link;
}
}
// Used at InstanceControl::dtor
void dtor()
{
m_link = nullptr;
delete this;
}
private:
Link* m_link;
};
/// ThreadSync
TLS_DECLARE(ThreadSync*, threadIndex);
@ -210,7 +242,7 @@ ThreadSync* ThreadSync::getThread(const char* desc)
if (!thread)
{
thread = FB_NEW ThreadSync(desc);
thread = FB_NEW ThreadSyncInstance(desc);
fb_assert(thread == findThread());
}
@ -220,6 +252,12 @@ ThreadSync* ThreadSync::getThread(const char* desc)
void ThreadSync::setThread(ThreadSync* thread)
{
if (thread != NULL)
{
ThreadSync* other = findThread();
fb_assert(other == NULL);
}
TLS_SET(threadIndex, thread);
}

View File

@ -224,12 +224,6 @@ public:
// previously set group and added to new
void setStatsGroup(MemoryStats& stats) FB_NOTHROW;
// Just a helper for AutoPtr.
static void clear(MemoryPool* pool)
{
deletePool(pool);
}
// Initialize and finalize global memory pool
static void init();
static void cleanup();
@ -451,7 +445,14 @@ namespace Firebird
explicit AutoStorage(MemoryPool& p) : PermanentStorage(p) { }
};
typedef AutoPtr<MemoryPool, MemoryPool> AutoMemoryPool;
template <>
inline void SimpleDelete<MemoryPool>::clear(MemoryPool* pool)
{
if (pool)
MemoryPool::deletePool(pool);
}
typedef AutoPtr<MemoryPool> AutoMemoryPool;
} // namespace Firebird

View File

@ -46,6 +46,15 @@ public:
}
};
template <>
inline void SimpleDelete<FILE>::clear(FILE* f)
{
if (f) {
fclose(f);
}
}
template <typename What>
class ArrayDelete
{
@ -56,6 +65,7 @@ public:
}
};
template <typename T>
class SimpleRelease
{
@ -84,24 +94,24 @@ public:
};
template <typename Where, typename Clear = SimpleDelete<Where> >
template <typename Where, template <typename W> class Clear = SimpleDelete >
class AutoPtr
{
private:
Where* ptr;
public:
AutoPtr<Where, Clear>(Where* v = NULL)
AutoPtr(Where* v = NULL)
: ptr(v)
{}
~AutoPtr()
{
Clear::clear(ptr);
Clear<Where>::clear(ptr);
}
AutoPtr<Where, Clear>& operator= (Where* v)
AutoPtr& operator= (Where* v)
{
Clear::clear(ptr);
Clear<Where>::clear(ptr);
ptr = v;
return *this;
}
@ -157,14 +167,24 @@ public:
{
if (v != ptr)
{
Clear::clear(ptr);
Clear<Where>::clear(ptr);
ptr = v;
}
}
private:
AutoPtr<Where, Clear>(AutoPtr<Where, Clear>&);
void operator=(AutoPtr<Where, Clear>&);
AutoPtr(AutoPtr&);
void operator=(AutoPtr&);
};
template <typename Where>
class AutoDispose : public AutoPtr<Where, SimpleDispose>
{
public:
AutoDispose(Where* v = nullptr)
: AutoPtr<Where, SimpleDispose>(v)
{ }
};
@ -259,19 +279,6 @@ private:
};
// One more typical class for AutoPtr cleanup
class FileClose
{
public:
static void clear(FILE *f)
{
if (f) {
fclose(f);
}
}
};
} //namespace Firebird
#endif // CLASSES_AUTO_PTR_H

View File

@ -93,7 +93,7 @@ namespace
return;
#ifdef DEBUG_GDS_ALLOC
Firebird::AutoPtr<FILE, Firebird::FileClose> file;
Firebird::AutoPtr<FILE> file;
{ // scope
Firebird::PathName name = "memdebug.log";
@ -227,12 +227,37 @@ namespace Firebird
{
MutexLockGuard guard(*StaticMutex::mutex, "InstanceControl::InstanceList::InstanceList");
next = instanceList;
prev = nullptr;
if (instanceList)
instanceList->prev = this;
instanceList = this;
}
InstanceControl::InstanceList::~InstanceList()
{
delete next;
fb_assert(next == nullptr);
fb_assert(prev == nullptr);
}
void InstanceControl::InstanceList::remove()
{
MutexLockGuard guard(*StaticMutex::mutex, FB_FUNCTION);
unlist();
}
void InstanceControl::InstanceList::unlist()
{
if (instanceList == this)
instanceList = next;
if (next)
next->prev = this->prev;
if (prev)
prev->next = this->next;
prev = nullptr;
next = nullptr;
}
void InstanceControl::destructors()
@ -299,8 +324,13 @@ namespace Firebird
}
} while (nextPriority != currentPriority);
delete instanceList;
instanceList = 0;
while (instanceList)
{
InstanceList* item = instanceList;
item->unlist();
delete item;
}
}
void InstanceControl::registerGdsCleanup(FPTR_VOID cleanup)

View File

@ -71,10 +71,16 @@ public:
virtual ~InstanceList();
static void destructors();
// remove self from common list under StaticMutex protection
void remove();
private:
InstanceList* next;
DtorPriority priority;
virtual void dtor() = 0;
void unlist();
InstanceList* next;
InstanceList* prev;
DtorPriority priority;
};
template <typename T, InstanceControl::DtorPriority P = InstanceControl::PRIORITY_REGULAR>
@ -90,6 +96,11 @@ public:
fb_assert(link);
}
void remove()
{
InstanceList::remove();
}
void dtor()
{
fb_assert(link);

View File

@ -296,7 +296,7 @@ public:
const bool at_begin = (m_begin == m_curr);
m_curr++;
while (Marker::isMarked(m_curr) && m_curr < m_end)
while (m_curr < m_end && Marker::isMarked(m_curr))
m_curr++;
if (m_curr == m_end)

View File

@ -139,6 +139,10 @@
#define FB_CPU CpuArm64
#endif /* ARM64 */
#ifdef RISCV64
#define FB_CPU CpuRiscV64
#endif /* RISCV64 */
#ifdef sparc
#define FB_CPU CpuUltraSparc
#define RISC_ALIGNMENT

View File

@ -203,6 +203,15 @@ const Config::ConfigEntry Config::entries[MAX_CONFIG_KEY] =
{TYPE_INTEGER, "StatementTimeout", (ConfigValue) 0},
{TYPE_INTEGER, "ConnectionIdleTimeout", (ConfigValue) 0},
{TYPE_INTEGER, "ClientBatchBuffer", (ConfigValue) (128 * 1024)},
#ifdef DEV_BUILD
{TYPE_STRING, "OutputRedirectionFile", (ConfigValue) "-"},
#else
#ifdef WIN_NT
{TYPE_STRING, "OutputRedirectionFile", (ConfigValue) "nul"},
#else
{TYPE_STRING, "OutputRedirectionFile", (ConfigValue) "/dev/null"},
#endif
#endif
{TYPE_INTEGER, "ExtConnPoolSize", (ConfigValue) 0},
{TYPE_INTEGER, "ExtConnPoolLifeTime", (ConfigValue) 7200}
};
@ -841,6 +850,12 @@ unsigned int Config::getClientBatchBuffer() const
return get<unsigned int>(KEY_CLIENT_BATCH_BUFFER);
}
const char* Config::getOutputRedirectionFile()
{
const char* file = (const char*) (getDefaultConfig()->values[KEY_OUTPUT_REDIRECTION_FILE]);
return file;
}
int Config::getExtConnPoolSize()
{
return getDefaultConfig()->get<int>(KEY_EXT_CONN_POOL_SIZE);

View File

@ -146,6 +146,7 @@ public:
KEY_STMT_TIMEOUT,
KEY_CONN_IDLE_TIMEOUT,
KEY_CLIENT_BATCH_BUFFER,
KEY_OUTPUT_REDIRECTION_FILE,
KEY_EXT_CONN_POOL_SIZE,
KEY_EXT_CONN_POOL_LIFETIME,
MAX_CONFIG_KEY // keep it last
@ -365,6 +366,8 @@ public:
unsigned int getClientBatchBuffer() const;
static const char* getOutputRedirectionFile();
static int getExtConnPoolSize();
static int getExtConnPoolLifeTime();

View File

@ -109,7 +109,7 @@ public:
}
private:
AutoPtr<FILE, FileClose> file;
AutoPtr<FILE> file;
Firebird::PathName fileName;
unsigned int l;
};

View File

@ -1466,6 +1466,8 @@ void dsc::getSqlInfo(SLONG* sqlLength, SLONG* sqlSubType, SLONG* sqlScale, SLONG
case dtype_dec_fixed:
*sqlType = SQL_DEC_FIXED;
*sqlScale = dsc_scale;
if (dsc_sub_type)
*sqlSubType = dsc_sub_type;
break;
default:

View File

@ -173,7 +173,7 @@ typedef struct dsc
bool isDecOrInt() const
{
return isDecFloat() || isExact();
return isDecFloat() || isDecFixed() || isExact();
}
bool isApprox() const

View File

@ -2207,12 +2207,14 @@ SharedMemoryBase::SharedMemoryBase(const TEXT* filename, ULONG length, IpcObject
if (file_handle == INVALID_HANDLE_VALUE)
{
if ((err == ERROR_SHARING_VIOLATION))
if ((err == ERROR_SHARING_VIOLATION) || (err == ERROR_ACCESS_DENIED))
{
if (!init_flag) {
CloseHandle(event_handle);
}
goto retry;
if (retry_count < 200) // 2 sec
goto retry;
}
CloseHandle(event_handle);

View File

@ -101,7 +101,7 @@ public:
"msvcr110.dll",
#elif _MSC_VER == 1800
"msvcr120.dll",
#elif _MSC_VER >= 1900 && _MSC_VER <= 1912
#elif _MSC_VER >= 1900 && _MSC_VER < 1920
"vcruntime140.dll",
#else
#error Specify CRT DLL name here !

116
src/common/status.h Normal file
View File

@ -0,0 +1,116 @@
/*
* PROGRAM: Firebird exceptions classes
* MODULE: status.h
* DESCRIPTION: Status vector filling and parsing.
*
* 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 Mike Nordell
* for the Firebird Open Source RDBMS project.
*
* Copyright (c) 2001 Mike Nordell <tamlin at algonet.se>
* and all contributors signed below.
*
* All Rights Reserved.
* Contributor(s): ______________________________________.
*
*/
#ifndef COMMON_STATUS_H
#define COMMON_STATUS_H
#include "../common/StatusHolder.h"
#include "../common/utils_proto.h"
const int MAX_ERRMSG_LEN = 128;
const int MAX_ERRSTR_LEN = 1024;
namespace Firebird
{
template <class SW>
class LocalStatusWrapper
{
public:
LocalStatusWrapper()
: localStatusVector(&localStatus)
{ }
explicit LocalStatusWrapper(Firebird::MemoryPool& p)
: localStatus(p), localStatusVector(&localStatus)
{ }
SW* operator->()
{
return &localStatusVector;
}
SW* operator&()
{
return &localStatusVector;
}
ISC_STATUS operator[](unsigned n) const
{
fb_assert(n < fb_utils::statusLength(localStatusVector.getErrors()));
return localStatusVector.getErrors()[n];
}
const SW* operator->() const
{
return &localStatusVector;
}
const SW* operator&() const
{
return &localStatusVector;
}
void check() const
{
if (localStatusVector.isDirty())
{
if (localStatus.getState() & Firebird::IStatus::STATE_ERRORS)
raise();
}
}
void copyTo(SW* to) const
{
fb_utils::copyStatus(to, &localStatusVector);
}
void raise() const
{
Firebird::status_exception::raise(&localStatus);
}
bool isEmpty() const
{
return localStatusVector.isEmpty();
}
bool isSuccess() const
{
return localStatusVector.isEmpty();
}
private:
Firebird::LocalStatus localStatus;
SW localStatusVector;
};
typedef LocalStatusWrapper<CheckStatusWrapper> FbLocalStatus;
typedef LocalStatusWrapper<ThrowStatusWrapper> ThrowLocalStatus;
}
#endif // COMMON_STATUS_H

View File

@ -50,9 +50,6 @@
# include <unicode/utf_old.h>
#endif
// The next major ICU version after 4.8 is 49.
#define ICU_NEW_VERSION_MEANING 49
using namespace Firebird;
@ -121,7 +118,7 @@ public:
namespace Jrd {
static void formatFilename(PathName& filename, const char* templateName,
static ModuleLoader::Module* formatAndLoad(const char* templateName,
int majorVersion, int minorVersion);
@ -229,10 +226,7 @@ private:
ImplementConversionICU(int aMajorVersion, int aMinorVersion)
: BaseICU(aMajorVersion, aMinorVersion)
{
PathName filename;
formatFilename(filename, ucTemplate, aMajorVersion, aMinorVersion);
module = ModuleLoader::fixAndLoadModule(filename);
module = formatAndLoad(ucTemplate, aMajorVersion, aMinorVersion);
if (!module)
return;
@ -342,16 +336,27 @@ static const char* const COLL_30_VERSION = "41.128.4.4"; // ICU 3.0 collator ver
static GlobalPtr<UnicodeUtil::ICUModules> icuModules;
static void formatFilename(PathName& filename, const char* templateName,
static ModuleLoader::Module* formatAndLoad(const char* templateName,
int majorVersion, int minorVersion)
{
string s;
if (majorVersion >= ICU_NEW_VERSION_MEANING)
s.printf("%d", majorVersion);
else
s.printf("%d%d", majorVersion, minorVersion);
// ICU has several schemas for placing version into file name
const char* patterns[] =
{
"%d", "%d_%d", "%d%d", NULL
};
filename.printf(templateName, s.c_str());
PathName s, filename;
for (const char** p = patterns; *p; ++p)
{
s.printf(*p, majorVersion, minorVersion);
filename.printf(templateName, s.c_str());
ModuleLoader::Module* module = ModuleLoader::fixAndLoadModule(filename);
if (module)
return module;
}
return nullptr;
}
@ -974,17 +979,14 @@ UnicodeUtil::ICU* UnicodeUtil::loadICU(const string& icuVersion, const string& c
continue;
string configVersion;
if (majorVersion >= ICU_NEW_VERSION_MEANING)
configVersion.printf("%d.%d", majorVersion, minorVersion);
if (version != configVersion)
{
minorVersion = 0;
configVersion.printf("%d", majorVersion);
if (version != configVersion)
continue;
}
else
configVersion.printf("%d.%d", majorVersion, minorVersion);
if (version != configVersion)
continue;
ReadLockGuard readGuard(icuModules->lock, "UnicodeUtil::loadICU");
@ -992,27 +994,20 @@ UnicodeUtil::ICU* UnicodeUtil::loadICU(const string& icuVersion, const string& c
if (icuModules->modules.get(version, icu))
return icu;
PathName filename;
formatFilename(filename, ucTemplate, majorVersion, minorVersion);
icu = FB_NEW_POOL(*getDefaultMemoryPool()) ICU(majorVersion, minorVersion);
icu->ucModule = ModuleLoader::fixAndLoadModule(filename);
icu->ucModule = formatAndLoad(ucTemplate, majorVersion, minorVersion);
if (!icu->ucModule)
{
gds__log("failed to load module %s", filename.c_str());
gds__log("failed to load UC icu module version %s", configVersion.c_str());
delete icu;
continue;
}
formatFilename(filename, inTemplate, majorVersion, minorVersion);
icu->inModule = ModuleLoader::fixAndLoadModule(filename);
icu->inModule = formatAndLoad(inTemplate, majorVersion, minorVersion);
if (!icu->inModule)
{
gds__log("failed to load module %s", filename.c_str());
gds__log("failed to load IN icu module version %s", configVersion.c_str());
delete icu;
continue;
}
@ -1137,26 +1132,25 @@ UnicodeUtil::ConversionICU& UnicodeUtil::getConversionICU()
LocalStatus ls;
CheckStatusWrapper lastError(&ls);
string version;
const int majorArray[] = {5, 4, 3, 6, 0};
for (const int* major = majorArray; *major; ++major)
for (int major = 4; major <= 79; ++major)
{
for (int minor = 20; minor--; ) // from 19 down to 0
{
if ((*major == favMaj) && (minor == favMin))
if ((major == favMaj) && (minor == favMin))
{
continue;
}
try
{
if ((convIcu = ImplementConversionICU::create(*major, minor)))
if ((convIcu = ImplementConversionICU::create(major, minor)))
return *convIcu;
}
catch (const Exception& ex)
{
ex.stuffException(&lastError);
version.printf("Error loading ICU library version %d.%d", *major, minor);
version.printf("Error loading ICU library version %d.%d", major, minor);
}
}
}
@ -1176,7 +1170,7 @@ string UnicodeUtil::getDefaultIcuVersion()
string rc;
UnicodeUtil::ConversionICU& icu(UnicodeUtil::getConversionICU());
if (icu.vMajor >= ICU_NEW_VERSION_MEANING)
if (icu.vMajor >= 10 && icu.vMinor == 0)
rc.printf("%d", icu.vMajor);
else
rc.printf("%d.%d", icu.vMajor, icu.vMinor);

View File

@ -90,7 +90,7 @@ static bool isItSqlRole(thread_db* tdbb, jrd_tra* transaction, const MetaName& i
static int getGrantorOption(thread_db* tdbb, jrd_tra* transaction, const MetaName& grantor,
int grantorType, const MetaName& roleName);
static MetaName getIndexRelationName(thread_db* tdbb, jrd_tra* transaction,
const MetaName& indexName);
const MetaName& indexName, bool& systemIndex);
static const char* getRelationScopeName(const rel_t type);
static void makeRelationScopeName(string& to, const MetaName& name, const rel_t type);
static void checkRelationType(const rel_t type, const MetaName& name);
@ -539,14 +539,17 @@ static void makeRelationScopeName(string& to, const MetaName& name, const rel_t
// Get relation name of an index.
static MetaName getIndexRelationName(thread_db* tdbb, jrd_tra* transaction,
const MetaName& indexName)
const MetaName& indexName, bool& systemIndex)
{
systemIndex = false;
AutoCacheRequest request(tdbb, drq_l_index_relname, DYN_REQUESTS);
FOR(REQUEST_HANDLE request TRANSACTION_HANDLE transaction)
IDX IN RDB$INDICES
WITH IDX.RDB$INDEX_NAME EQ indexName.c_str()
{
systemIndex = IDX.RDB$SYSTEM_FLAG == 1;
return IDX.RDB$RELATION_NAME;
}
END_FOR
@ -849,6 +852,12 @@ static void updateRdbFields(const TypeClause* type,
fieldSubTypeNull = FALSE;
fieldSubType = type->subType;
}
if (DTYPE_IS_DECFLOAT(type->dtype))
{
fieldPrecisionNull = FALSE;
fieldPrecision = type->precision;
}
}
if (type->dtype == dtype_varying)
@ -1361,9 +1370,10 @@ bool CommentOnNode::checkPermission(thread_db* tdbb, jrd_tra* transaction)
break;
case obj_index:
relationName = getIndexRelationName(tdbb, transaction, objName.identifier);
bool systemIndex;
relationName = getIndexRelationName(tdbb, transaction, objName.identifier, systemIndex);
dscName.makeText(relationName.length(), CS_METADATA, (UCHAR*) relationName.c_str());
SCL_check_relation(tdbb, &dscName, SCL_alter);
SCL_check_relation(tdbb, &dscName, SCL_alter, systemIndex);
break;
case obj_sql_role:
@ -1873,6 +1883,7 @@ bool CreateAlterFunctionNode::executeAlter(thread_db* tdbb, DsqlCompilerScratch*
FUN.RDB$DETERMINISTIC_FLAG.NULL = FALSE;
FUN.RDB$DETERMINISTIC_FLAG = deterministic ? TRUE : FALSE;
FUN.RDB$RETURN_ARGUMENT = 0;
if (ssDefiner.specified)
{
@ -3566,6 +3577,26 @@ DdlNode* CreateAlterTriggerNode::dsqlPass(DsqlCompilerScratch* dsqlScratch)
bool CreateAlterTriggerNode::checkPermission(thread_db* tdbb, jrd_tra* transaction)
{
if (!create)
{
AutoRequest requestHandle;
FOR (REQUEST_HANDLE requestHandle TRANSACTION_HANDLE transaction)
TRG IN RDB$TRIGGERS
WITH TRG.RDB$TRIGGER_NAME EQ name.c_str()
{
if (!type.specified && !TRG.RDB$TRIGGER_TYPE.NULL)
type = TRG.RDB$TRIGGER_TYPE;
if (relationName.isEmpty() && !TRG.RDB$RELATION_NAME.NULL)
relationName = TRG.RDB$RELATION_NAME;
}
END_FOR
if (!type.specified)
status_exception::raise(Arg::Gds(isc_dyn_trig_not_found) << Arg::Str(name));
}
if (relationName.hasData())
{
dsc dscName;
@ -3590,26 +3621,6 @@ void CreateAlterTriggerNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlS
// run all statements under savepoint control
AutoSavePoint savePoint(tdbb, transaction);
if (!create)
{
AutoRequest requestHandle;
FOR (REQUEST_HANDLE requestHandle TRANSACTION_HANDLE transaction)
TRG IN RDB$TRIGGERS
WITH TRG.RDB$TRIGGER_NAME EQ name.c_str()
{
if (!type.specified && !TRG.RDB$TRIGGER_TYPE.NULL)
type = TRG.RDB$TRIGGER_TYPE;
if (relationName.isEmpty() && !TRG.RDB$RELATION_NAME.NULL)
relationName = TRG.RDB$RELATION_NAME;
}
END_FOR
if (!type.specified)
status_exception::raise(Arg::Gds(isc_dyn_trig_not_found) << Arg::Str(name));
}
compile(tdbb, dsqlScratch);
blrData = dsqlScratch->getBlrData();
@ -9674,7 +9685,7 @@ bool CreateIndexNode::checkPermission(thread_db* tdbb, jrd_tra* transaction)
dsc dscName;
const MetaName &relationName = relation->dsqlName;
dscName.makeText(relationName.length(), CS_METADATA, (UCHAR*) relationName.c_str());
SCL_check_relation(tdbb, &dscName, SCL_alter);
SCL_check_relation(tdbb, &dscName, SCL_alter, false);
return true;
}
@ -9742,12 +9753,13 @@ string AlterIndexNode::internalPrint(NodePrinter& printer) const
bool AlterIndexNode::checkPermission(thread_db* tdbb, jrd_tra* transaction)
{
MetaName relationName = getIndexRelationName(tdbb, transaction, name);
bool systemIndex;
MetaName relationName = getIndexRelationName(tdbb, transaction, name, systemIndex);
dsc dscName;
dscName.makeText(relationName.length(), CS_METADATA, (UCHAR*) relationName.c_str());
SCL_check_relation(tdbb, &dscName, SCL_alter);
SCL_check_relation(tdbb, &dscName, SCL_alter, systemIndex);
return true;
}
@ -9804,7 +9816,8 @@ string SetStatisticsNode::internalPrint(NodePrinter& printer) const
bool SetStatisticsNode::checkPermission(thread_db* tdbb, jrd_tra* transaction)
{
MetaName relationName = getIndexRelationName(tdbb, transaction, name);
bool systemIndex;
MetaName relationName = getIndexRelationName(tdbb, transaction, name, systemIndex);
dsc dscName;
dscName.makeText(relationName.length(), CS_METADATA, (UCHAR*) relationName.c_str());
@ -9885,12 +9898,13 @@ string DropIndexNode::internalPrint(NodePrinter& printer) const
bool DropIndexNode::checkPermission(thread_db* tdbb, jrd_tra* transaction)
{
MetaName relationName = getIndexRelationName(tdbb, transaction, name);
bool systemIndex;
MetaName relationName = getIndexRelationName(tdbb, transaction, name, systemIndex);
dsc dscName;
dscName.makeText(relationName.length(), CS_METADATA, (UCHAR*) relationName.c_str());
SCL_check_relation(tdbb, &dscName, SCL_alter);
SCL_check_relation(tdbb, &dscName, SCL_alter, systemIndex);
return true;
}
@ -11362,12 +11376,22 @@ void GrantRevokeNode::grantRevoke(thread_db* tdbb, jrd_tra* transaction, const G
ERRD_post(Arg::Gds(isc_dsql_cant_grant_option) << Arg::Str("system privileges"));
break;
case obj_udf:
ERRD_post(Arg::Gds(isc_dsql_cant_grant_option) << Arg::Str("functions"));
break;
case obj_package_header:
ERRD_post(Arg::Gds(isc_dsql_cant_grant_option) << Arg::Str("packages"));
break;
default:
break;
}
}
if (grantor && !tdbb->getAttachment()->locksmith(tdbb, USE_GRANTED_BY_CLAUSE))
const Attachment* attachment = tdbb->getAttachment();
if (grantor && !attachment->locksmith(tdbb, USE_GRANTED_BY_CLAUSE))
{
const Firebird::MetaName& owner(tdbb->getDatabase()->dbb_owner);
@ -11377,7 +11401,7 @@ void GrantRevokeNode::grantRevoke(thread_db* tdbb, jrd_tra* transaction, const G
(Arg::PrivateDyn(295) << DBA_USER_NAME << owner).raise();
}
MetaName currentUser(tdbb->getAttachment()->att_user->getUserName());
MetaName currentUser(attachment->att_user->getUserName());
MetaName grantorRevoker(grantor ? *grantor : currentUser);
if (!isGrant && !privs) // REVOKE ALL ON ALL
@ -11393,7 +11417,7 @@ void GrantRevokeNode::grantRevoke(thread_db* tdbb, jrd_tra* transaction, const G
PRIV.RDB$USER_TYPE = userType AND
PRIV.RDB$GRANTOR NOT MISSING
{
if (tdbb->getAttachment()->att_user->locksmith(tdbb, GRANT_REVOKE_ON_ANY_OBJECT) ||
if (attachment->att_user->locksmith(tdbb, GRANT_REVOKE_ON_ANY_OBJECT) ||
grantorRevoker == PRIV.RDB$GRANTOR)
{
ERASE PRIV;
@ -11446,6 +11470,8 @@ void GrantRevokeNode::grantRevoke(thread_db* tdbb, jrd_tra* transaction, const G
for (const char* pr = privileges; *pr; ++pr)
{
bool duplicate = false;
MetaName newField = field;
int newOptions = options;
priv[0] = *pr;
FOR(REQUEST_HANDLE request TRANSACTION_HANDLE transaction)
@ -11459,23 +11485,22 @@ void GrantRevokeNode::grantRevoke(thread_db* tdbb, jrd_tra* transaction, const G
(PRIV.RDB$FIELD_NAME EQUIV NULLIF(field.c_str(), '') OR
(PRIV.RDB$OBJECT_TYPE EQ obj_sql_role))
{
if (PRIV.RDB$GRANT_OPTION.NULL ||
PRIV.RDB$GRANT_OPTION ||
PRIV.RDB$GRANT_OPTION == options)
{
duplicate = true;
}
else if (!PRIV.RDB$FIELD_NAME.NULL)
field = PRIV.RDB$FIELD_NAME; // Keep DEFAULT ROLE while adding ADMIN OPTION
// It means we have such privilege without grant option but
// user grants it with grant option. We should re-grant existing privilege.
const bool addGrantOption = (!PRIV.RDB$GRANT_OPTION.NULL && !PRIV.RDB$GRANT_OPTION &&
PRIV.RDB$GRANT_OPTION != options);
if (duplicate && objType == obj_sql_role && field == "D" &&
PRIV.RDB$FIELD_NAME.NULL)
{
// We have to reset duplicate to add DEFAULT ROLE and keep options to prevent reset of ADMIN OPTION
duplicate = false;
options = PRIV.RDB$GRANT_OPTION;
}
// It means we have such granted role but without DEFAULT but user grants with DEFAULT.
// We should re-grant it.
const bool addDefaultRole = (objType == obj_sql_role && field == "D" && PRIV.RDB$FIELD_NAME.NULL);
if (addGrantOption && !addDefaultRole) // Save DEFAULT option for re-grant
newField = PRIV.RDB$FIELD_NAME;
if (addDefaultRole && !addGrantOption) // Add grant option was requested
newOptions = PRIV.RDB$GRANT_OPTION;
duplicate = !addGrantOption && !addDefaultRole;
if (!duplicate)
ERASE PRIV;
@ -11515,38 +11540,55 @@ void GrantRevokeNode::grantRevoke(thread_db* tdbb, jrd_tra* transaction, const G
// As long as only locksmith can use GRANTED BY, no need specially checking
// for privileges of current user. AP-2008
if (objType == 0)
switch (objType)
{
// Relation or view because we cannot distinguish at this point.
checkGrantorCanGrant(tdbb, transaction,
tdbb->getAttachment()->att_user->getUserName().c_str(), priv, objName,
field, true);
}
else if (objType >= obj_database)
{
checkGrantorCanGrantDdl(tdbb, transaction,
tdbb->getAttachment()->att_user->getUserName().c_str(), priv, objName);
case obj_relation:
{
// Relation or view because we cannot distinguish at this point.
checkGrantorCanGrantRelation(tdbb, transaction, currentUser.c_str(), priv, objName,
field, true);
break;
}
case obj_exception:
case obj_generator:
{
checkGrantorCanGrantObject(tdbb, transaction, currentUser.c_str(), priv, objName, objType);
break;
}
default:
if (objType >= obj_database)
{
checkGrantorCanGrantDdl(tdbb, transaction, currentUser.c_str(), priv, objName);
}
// Prevent silent eating checks. In this case we can remove RDB$TRIGGER_9 (trigger1)
// but add every object type above in switch
// else
// fb_assert(false);
}
}
storePrivilege(tdbb, transaction, objName, user, field, pr, userType, objType,
options, grantorRevoker);
storePrivilege(tdbb, transaction, objName, user, newField, pr, userType, objType,
newOptions, grantorRevoker);
}
}
else // REVOKE
{
const bool revokeRoleDefault = (objType == obj_sql_role) && field.hasData();
MetaName curField;
int curOptions = options;
const bool revokeDefaultRole = (objType == obj_sql_role) && field.hasData();
const bool revokeGrantOption = options;
AutoCacheRequest request(tdbb, (field.hasData() ? drq_e_grant1 : drq_e_grant2), DYN_REQUESTS);
// This var must be identical for request (1) and if below (2)
const bool withField = field.hasData() && objType != obj_sql_role;
AutoCacheRequest request(tdbb, (withField ? drq_e_grant1 : drq_e_grant2), DYN_REQUESTS); // (1)
for (const char* pr = privileges; (priv[0] = *pr); ++pr)
{
bool grantErased = false;
bool badGrantor = false;
if (field.hasData() && objType != obj_sql_role)
if (withField) // (2)
{
FOR(REQUEST_HANDLE request TRANSACTION_HANDLE transaction)
PRIV IN RDB$USER_PRIVILEGES
@ -11560,8 +11602,21 @@ void GrantRevokeNode::grantRevoke(thread_db* tdbb, jrd_tra* transaction, const G
{
if (grantorRevoker == PRIV.RDB$GRANTOR)
{
MetaName newField = NULL;
int newOptions = 0;
if (!revokeGrantOption && !PRIV.RDB$GRANT_OPTION.NULL)
newOptions = PRIV.RDB$GRANT_OPTION;
if (!revokeDefaultRole && !PRIV.RDB$FIELD_NAME.NULL)
newField = PRIV.RDB$FIELD_NAME;
ERASE PRIV;
grantErased = true;
if (revokeDefaultRole || revokeGrantOption)
{
storePrivilege(tdbb, transaction, objName, user, newField, pr, userType, objType,
newOptions, grantorRevoker);
}
}
else
badGrantor = true;
@ -11588,14 +11643,25 @@ void GrantRevokeNode::grantRevoke(thread_db* tdbb, jrd_tra* transaction, const G
((objType == obj_sql_role) && (PRIV.RDB$PRIVILEGE[0] == 'M') && // This is ROLE to USER grant
(currentUser != user) && // And current user does not revoke his own grant
((isItSqlRole(tdbb, transaction, objName, owner) && // Pick up role owner name
(tdbb->getAttachment()->locksmith(tdbb, GRANT_REVOKE_ON_ANY_OBJECT) || // God-like check
(attachment->locksmith(tdbb, GRANT_REVOKE_ON_ANY_OBJECT) || // God-like check
(owner == currentUser))) || // Current user is role owner
(getGrantorOption(tdbb, transaction, currentUser, obj_user, objName) == 2)))) // or has ADMIN option
{
curOptions = PRIV.RDB$GRANT_OPTION;
curField = PRIV.RDB$FIELD_NAME;
MetaName newField = NULL;
int newOptions = 0;
if (!revokeGrantOption && !PRIV.RDB$GRANT_OPTION.NULL)
newOptions = PRIV.RDB$GRANT_OPTION;
if (!revokeDefaultRole && !PRIV.RDB$FIELD_NAME.NULL)
newField = PRIV.RDB$FIELD_NAME;
ERASE PRIV;
grantErased = true;
if (revokeDefaultRole || revokeGrantOption)
{
storePrivilege(tdbb, transaction, objName, user, newField, pr, userType, objType,
newOptions, grantorRevoker);
}
}
else
badGrantor = true;
@ -11603,25 +11669,7 @@ void GrantRevokeNode::grantRevoke(thread_db* tdbb, jrd_tra* transaction, const G
END_FOR
}
if (grantErased)
{
if (revokeRoleDefault)
{
// Add role grant again without default
storePrivilege(tdbb, transaction, objName, user, NULL, pr, userType, objType,
curOptions, grantorRevoker);
}
else if (options)
{
// Add the privilege without the grant option. There is a modify trigger on the
// rdb$user_privileges which disallows the table from being updated. It would have
// to be changed such that only the grant_option field can be updated.
storePrivilege(tdbb, transaction, objName, user, curField, pr, userType, objType,
0, grantorRevoker);
}
}
else
if (!grantErased)
{
if (badGrantor)
{
@ -11641,7 +11689,7 @@ void GrantRevokeNode::grantRevoke(thread_db* tdbb, jrd_tra* transaction, const G
}
// Check if the grantor has grant privilege on the relation/field.
void GrantRevokeNode::checkGrantorCanGrant(thread_db* tdbb, jrd_tra* transaction,
void GrantRevokeNode::checkGrantorCanGrantRelation(thread_db* tdbb, jrd_tra* transaction,
const char* grantor, const char* privilege, const MetaName& relationName,
const MetaName& fieldName, bool topLevel)
{
@ -11825,13 +11873,13 @@ void GrantRevokeNode::checkGrantorCanGrant(thread_db* tdbb, jrd_tra* transaction
{
if (fieldName == G_FLD.RDB$FIELD_NAME)
{
checkGrantorCanGrant(tdbb, transaction, grantor, privilege,
checkGrantorCanGrantRelation(tdbb, transaction, grantor, privilege,
G_VIEW.RDB$RELATION_NAME, G_FLD.RDB$BASE_FIELD, false);
}
}
else
{
checkGrantorCanGrant(tdbb, transaction, grantor, privilege,
checkGrantorCanGrantRelation(tdbb, transaction, grantor, privilege,
G_VIEW.RDB$RELATION_NAME, G_FLD.RDB$BASE_FIELD, false);
}
}
@ -11919,7 +11967,9 @@ void GrantRevokeNode::checkGrantorCanGrantRole(thread_db* tdbb, jrd_tra* transac
void GrantRevokeNode::checkGrantorCanGrantDdl(thread_db* tdbb, jrd_tra* transaction,
const MetaName& grantor, const char* privilege, const MetaName& objName)
{
if (tdbb->getAttachment()->locksmith(tdbb, GRANT_REVOKE_ANY_DDL_RIGHT))
const Attachment* attachment = tdbb->getAttachment();
if (attachment->locksmith(tdbb, GRANT_REVOKE_ANY_DDL_RIGHT))
return;
AutoCacheRequest request(tdbb, drq_l_grant_option, DYN_REQUESTS);
@ -11927,23 +11977,62 @@ void GrantRevokeNode::checkGrantorCanGrantDdl(thread_db* tdbb, jrd_tra* transact
FOR (REQUEST_HANDLE request TRANSACTION_HANDLE transaction)
PRV IN RDB$USER_PRIVILEGES
WITH PRV.RDB$USER = UPPERCASE(grantor.c_str()) AND
PRV.RDB$USER_TYPE = obj_user 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$RELATION_NAME EQ objName.c_str() AND
PRV.RDB$OBJECT_TYPE >= obj_database AND
PRV.RDB$PRIVILEGE EQ privilege
{
grantable = PRV.RDB$GRANT_OPTION == WITH_GRANT_OPTION;
if ( (PRV.RDB$USER_TYPE == obj_sql_role) && !attachment->att_user->roleInUse(tdbb, PRV.RDB$USER))
continue;
if (PRV.RDB$GRANT_OPTION == WITH_GRANT_OPTION)
grantable = true;
}
END_FOR
if (!grantable)
{
// no .. privilege with grant option on DDL ..
status_exception::raise(Arg::PrivateDyn(174) << privilege << objName.c_str());
// no @1 privilege with grant option on DDL @2
status_exception::raise(Arg::PrivateDyn(299) << privilege << objName.c_str());
}
}
// Check if the grantor has grant option on generator privilege
void GrantRevokeNode::checkGrantorCanGrantObject(thread_db* tdbb, jrd_tra* transaction, const char* grantor,
const char* privilege, const Firebird::MetaName& objName, SSHORT objType)
{
const Attachment* attachment = tdbb->getAttachment();
if (attachment->locksmith(tdbb, GRANT_REVOKE_ON_ANY_OBJECT))
return;
AutoCacheRequest request(tdbb, drq_l_grant_object, DYN_REQUESTS);
bool grantable = false;
FOR (REQUEST_HANDLE request TRANSACTION_HANDLE transaction)
PRV IN RDB$USER_PRIVILEGES
WITH ((PRV.RDB$USER = UPPERCASE(grantor) 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$OBJECT_TYPE = objType AND
PRV.RDB$PRIVILEGE EQ privilege
{
if ( (PRV.RDB$USER_TYPE == obj_sql_role) && !attachment->att_user->roleInUse(tdbb, PRV.RDB$USER))
continue;
if (PRV.RDB$GRANT_OPTION == WITH_GRANT_OPTION)
grantable = true;
}
END_FOR
if (!grantable)
{
// no @1 privilege with grant option on object @2
status_exception::raise(Arg::PrivateDyn(300) << privilege << objName.c_str());
}
}
void GrantRevokeNode::storePrivilege(thread_db* tdbb, jrd_tra* transaction, const MetaName& object,
const MetaName& user, const MetaName& field, const TEXT* privilege, SSHORT userType,
SSHORT objType, int option, const MetaName& grantor)
@ -12065,7 +12154,7 @@ void AlterDatabaseNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratc
{
checkClauses(tdbb);
// Take a LCK_alter_database lock to prevent altering of the database from
// Take a LCK_alter_database lock to prevent altering of the database from
// parallel transactions
if (!transaction->tra_alter_db_lock)

View File

@ -2269,13 +2269,15 @@ private:
void modifyPrivileges(thread_db* tdbb, jrd_tra* transaction, SSHORT option, const GranteeClause* user);
void grantRevoke(thread_db* tdbb, jrd_tra* transaction, const GranteeClause* object,
const GranteeClause* userNod, const char* privs, Firebird::MetaName field, int options);
static void checkGrantorCanGrant(thread_db* tdbb, jrd_tra* transaction, const char* grantor,
static void checkGrantorCanGrantRelation(thread_db* tdbb, jrd_tra* transaction, const char* grantor,
const char* privilege, const Firebird::MetaName& relationName,
const Firebird::MetaName& fieldName, bool topLevel);
static void checkGrantorCanGrantRole(thread_db* tdbb, jrd_tra* transaction,
const Firebird::MetaName& grantor, const Firebird::MetaName& roleName);
static void checkGrantorCanGrantDdl(thread_db* tdbb, jrd_tra* transaction,
const Firebird::MetaName& grantor, const char* privilege, const Firebird::MetaName& objName);
static void checkGrantorCanGrantObject(thread_db* tdbb, jrd_tra* transaction, const char* grantor,
const char* privilege, const Firebird::MetaName& objName, SSHORT objType);
static void storePrivilege(thread_db* tdbb, jrd_tra* transaction,
const Firebird::MetaName& object, const Firebird::MetaName& user,
const Firebird::MetaName& field, const TEXT* privilege, SSHORT userType,

View File

@ -87,12 +87,6 @@ DsqlBatch::DsqlBatch(dsql_req* req, const dsql_msg* /*message*/, IMessageMetadat
m_alignment = m_meta->getAlignment(&st);
check(&st);
if (m_messageSize > RAM_BATCH) // hops - message does not fit in our buffer
{
ERRD_post(Arg::Gds(isc_sqlerr) << Arg::Num(-104) <<
Arg::Gds(isc_batch_msg_long) << Arg::Num(m_messageSize) << Arg::Num(RAM_BATCH));
}
for (pb.rewind(); !pb.isEof(); pb.moveNext())
{
UCHAR t = pb.getClumpTag();
@ -146,7 +140,6 @@ DsqlBatch::DsqlBatch(dsql_req* req, const dsql_msg* /*message*/, IMessageMetadat
switch (t)
{
case SQL_BLOB:
case SQL_ARRAY:
{
BlobMeta bm;
bm.offset = m_meta->getOffset(&st, i);
@ -160,9 +153,9 @@ DsqlBatch::DsqlBatch(dsql_req* req, const dsql_msg* /*message*/, IMessageMetadat
}
// allocate data buffers
m_messages.setBuf(m_bufferSize);
m_messages.setBuf(m_bufferSize, MAX(m_alignedMessage * 2, RAM_BATCH));
if (m_blobMeta.hasData())
m_blobs.setBuf(m_bufferSize);
m_blobs.setBuf(m_bufferSize, RAM_BATCH);
// assign initial default BPB
setDefBpb(FB_NELEM(initBlobParameters), initBlobParameters);
@ -270,6 +263,7 @@ void DsqlBatch::add(thread_db* tdbb, ULONG count, const void* inBuffer)
return;
m_messages.align(m_alignment);
m_messages.put(inBuffer, (count - 1) * m_alignedMessage + m_messageSize);
DEB_BATCH(fprintf(stderr, "Put to batch %d messages\n", count));
}
void DsqlBatch::blobCheckMeta()
@ -419,6 +413,7 @@ void DsqlBatch::addBlobStream(thread_db* tdbb, unsigned length, const void* inBu
m_lastBlob = MAX_ULONG;
// store stream for further processing
DEB_BATCH(fprintf(stderr, "Store stream %d\n", length));
fb_assert(m_blobs.getSize() % BLOB_STREAM_ALIGN == 0);
m_blobs.put(inBuffer, length);
}
@ -539,13 +534,13 @@ private:
// parse blob header
fb_assert(intptr_t(flow.data) % BLOB_STREAM_ALIGN == 0);
ISC_QUAD* batchBlobId = reinterpret_cast<ISC_QUAD*>(flow.data);
ISC_QUAD batchBlobId = *reinterpret_cast<ISC_QUAD*>(flow.data);
ULONG* blobSize = reinterpret_cast<ULONG*>(flow.data + sizeof(ISC_QUAD));
ULONG* bpbSize = reinterpret_cast<ULONG*>(flow.data + sizeof(ISC_QUAD) + sizeof(ULONG));
flow.newHdr(*blobSize);
ULONG currentBpbSize = *bpbSize;
if (batchBlobId->gds_quad_high == 0 && batchBlobId->gds_quad_low == 0)
if (batchBlobId.gds_quad_high == 0 && batchBlobId.gds_quad_low == 0)
{
// Sanity check
if (*bpbSize)
@ -591,7 +586,9 @@ private:
bid engineBlobId;
blob = blb::create2(tdbb, transaction, &engineBlobId, bpb->getCount(),
bpb->begin(), true);
registerBlob(reinterpret_cast<ISC_QUAD*>(&engineBlobId), batchBlobId);
//DEB_BATCH(fprintf(stderr, "B-ID: (%x,%x)\n", batchBlobId.gds_quad_high, batchBlobId.gds_quad_low));
registerBlob(reinterpret_cast<ISC_QUAD*>(&engineBlobId), &batchBlobId);
}
}
@ -657,7 +654,7 @@ private:
fb_assert(req);
// prepare completion interface
AutoPtr<BatchCompletionState, SimpleDispose<BatchCompletionState> > completionState
AutoPtr<BatchCompletionState, SimpleDispose> completionState
(FB_NEW BatchCompletionState(m_flags & (1 << IBatch::TAG_RECORD_COUNTS), m_detailed));
AutoSetRestore<bool> batchFlag(&req->req_batch, true);
const dsql_msg* message = m_request->getStatement()->getSendMsg();
@ -702,6 +699,9 @@ private:
continue;
ISC_QUAD* id = reinterpret_cast<ISC_QUAD*>(&data[m_blobMeta[i].offset]);
if (id->gds_quad_high == 0 && id->gds_quad_low == 0)
continue;
ISC_QUAD newId;
if (!m_blobMap.get(*id, newId))
{
@ -719,9 +719,9 @@ private:
remains -= m_messageSize;
UCHAR* msgBuffer = m_request->req_msg_buffers[message->msg_buffer_number];
DEB_BATCH(fprintf(stderr, "\n\n+++ Send\n\n"));
try
{
// runsend data to request and collect stats
ULONG before = req->req_records_inserted + req->req_records_updated +
req->req_records_deleted;
EXE_send(tdbb, req, message->msg_number, message->msg_length, msgBuffer);
@ -753,6 +753,15 @@ private:
m_messages.remained(remains, alignedData - data);
}
DEB_BATCH(fprintf(stderr, "Sent %d messages\n", completionState->getSize(tdbb->tdbb_status_vector)));
// make sure all blobs were used in messages
if (m_blobMap.count())
{
DEB_BATCH(fprintf(stderr, "BLOBs %d were not used in messages\n", m_blobMap.count()));
ERR_post_warning(Arg::Warning(isc_random) << "m_blobMap.count() BLOBs were not used in messages"); // !!!!!!! new warning
}
// reset to initial state
cancel(tdbb);
@ -762,14 +771,11 @@ private:
void DsqlBatch::cancel(thread_db* tdbb)
{
m_messages.clear();
if (m_blobMeta.hasData())
{
m_blobs.clear();
m_setBlobSize = false;
m_lastBlob = MAX_ULONG;
memset(&m_genId, 0, sizeof(m_genId));
m_blobMap.clear();
}
m_blobs.clear();
m_setBlobSize = false;
m_lastBlob = MAX_ULONG;
memset(&m_genId, 0, sizeof(m_genId));
m_blobMap.clear();
}
void DsqlBatch::genBlobId(ISC_QUAD* blobId)
@ -779,13 +785,13 @@ void DsqlBatch::genBlobId(ISC_QUAD* blobId)
memcpy(blobId, &m_genId, sizeof(m_genId));
}
void DsqlBatch::DataCache::setBuf(ULONG size)
void DsqlBatch::DataCache::setBuf(ULONG size, ULONG cacheCapacity)
{
m_limit = size;
// create ram cache
fb_assert(!m_cache);
m_cache = FB_NEW_POOL(getPool()) Cache;
fb_assert(m_cacheCapacity == 0);
fb_assert(cacheCapacity >= RAM_BATCH);
m_cacheCapacity = cacheCapacity;
}
void DsqlBatch::DataCache::put3(const void* data, ULONG dataSize, ULONG offset)
@ -797,9 +803,9 @@ void DsqlBatch::DataCache::put3(const void* data, ULONG dataSize, ULONG offset)
if (offset >= m_used)
{
// data in cache
UCHAR* to = m_cache->begin();
UCHAR* to = m_cache.begin();
to += (offset - m_used);
fb_assert(to < m_cache->end());
fb_assert(to < m_cache.end());
memcpy(to, data, dataSize);
}
else
@ -811,7 +817,7 @@ void DsqlBatch::DataCache::put3(const void* data, ULONG dataSize, ULONG offset)
void DsqlBatch::DataCache::put(const void* d, ULONG dataSize)
{
if (m_used + (m_cache ? m_cache->getCount() : 0) + dataSize > m_limit)
if (m_limit && (m_used + m_cache.getCount() + dataSize > m_limit))
{
ERRD_post(Arg::Gds(isc_sqlerr) << Arg::Num(-104) <<
Arg::Gds(isc_batch_too_big));
@ -823,17 +829,17 @@ void DsqlBatch::DataCache::put(const void* d, ULONG dataSize)
const ULONG K = 4;
// ensure ram cache presence
fb_assert(m_cache);
fb_assert(m_cacheCapacity);
// swap to secondary cache if needed
if (m_cache->getCount() + dataSize > m_cache->getCapacity())
if (m_cache.getCount() + dataSize > m_cacheCapacity)
{
// store data in the end of ram cache if needed
// avoid copy in case of huge buffer passed
ULONG delta = m_cache->getCapacity() - m_cache->getCount();
if (dataSize - delta < m_cache->getCapacity() / K)
ULONG delta = m_cacheCapacity - m_cache.getCount();
if (dataSize - delta < m_cacheCapacity / K)
{
m_cache->append(data, delta);
m_cache.append(data, delta);
data += delta;
dataSize -= delta;
}
@ -842,13 +848,13 @@ void DsqlBatch::DataCache::put(const void* d, ULONG dataSize)
if (!m_space)
m_space = FB_NEW_POOL(getPool()) TempSpace(getPool(), TEMP_NAME);
const FB_UINT64 writtenBytes = m_space->write(m_used, m_cache->begin(), m_cache->getCount());
fb_assert(writtenBytes == m_cache->getCount());
m_used += m_cache->getCount();
m_cache->clear();
const FB_UINT64 writtenBytes = m_space->write(m_used, m_cache.begin(), m_cache.getCount());
fb_assert(writtenBytes == m_cache.getCount());
m_used += m_cache.getCount();
m_cache.clear();
// in a case of huge buffer write directly to tempspace
if (dataSize > m_cache->getCapacity() / K)
if (dataSize > m_cacheCapacity / K)
{
const FB_UINT64 writtenBytes = m_space->write(m_used, data, dataSize);
fb_assert(writtenBytes == dataSize);
@ -857,7 +863,7 @@ void DsqlBatch::DataCache::put(const void* d, ULONG dataSize)
}
}
m_cache->append(data, dataSize);
m_cache.append(data, dataSize);
}
void DsqlBatch::DataCache::align(ULONG alignment)
@ -873,16 +879,14 @@ void DsqlBatch::DataCache::align(ULONG alignment)
void DsqlBatch::DataCache::done()
{
fb_assert(m_cache);
if (m_cache->getCount() && m_used)
if (m_cache.getCount() && m_used)
{
fb_assert(m_space);
const FB_UINT64 writtenBytes = m_space->write(m_used, m_cache->begin(), m_cache->getCount());
fb_assert(writtenBytes == m_cache->getCount());
m_used += m_cache->getCount();
m_cache->clear();
const FB_UINT64 writtenBytes = m_space->write(m_used, m_cache.begin(), m_cache.getCount());
fb_assert(writtenBytes == m_cache.getCount());
m_used += m_cache.getCount();
m_cache.clear();
}
}
@ -891,26 +895,26 @@ ULONG DsqlBatch::DataCache::get(UCHAR** buffer)
if (m_used > m_got)
{
// get data from tempspace
ULONG dlen = m_cache->getCount();
ULONG delta = m_cache->getCapacity() - dlen;
ULONG dlen = m_cache.getCount();
ULONG delta = m_cacheCapacity - dlen;
if (delta > m_used - m_got)
delta = m_used - m_got;
UCHAR* buf = m_cache->getBuffer(dlen + delta);
UCHAR* buf = m_cache.getBuffer(dlen + delta);
buf += dlen;
const FB_UINT64 readBytes = m_space->read(m_got, buf, delta);
fb_assert(readBytes == delta);
m_got += delta;
}
if (m_cache->getCount())
if (m_cache.getCount())
{
if (m_shift)
m_cache->removeCount(0, m_shift);
m_cache.removeCount(0, m_shift);
// return buffer full of data
*buffer = m_cache->begin();
*buffer = m_cache.begin();
fb_assert(intptr_t(*buffer) % FB_ALIGNMENT == 0);
return m_cache->getCount();
return m_cache.getCount();
}
// no more data
@ -926,9 +930,9 @@ ULONG DsqlBatch::DataCache::reget(ULONG remains, UCHAR** buffer, ULONG alignment
a = alignment - a;
remains += a;
}
fb_assert(remains < m_cache->getCount());
fb_assert(remains < m_cache.getCount());
m_cache->removeCount(0, m_cache->getCount() - remains);
m_cache.removeCount(0, m_cache.getCount() - remains);
ULONG size = get(buffer);
size -= a;
*buffer += a;
@ -949,25 +953,25 @@ void DsqlBatch::DataCache::remained(ULONG size, ULONG alignment)
}
if (!size)
m_cache->clear();
m_cache.clear();
else
m_cache->removeCount(0, m_cache->getCount() - size);
m_cache.removeCount(0, m_cache.getCount() - size);
m_shift = alignment;
}
ULONG DsqlBatch::DataCache::getSize() const
{
if(!m_cache)
if (!m_cacheCapacity)
return 0;
fb_assert((MAX_ULONG - 1) - m_used > m_cache->getCount());
return m_used + m_cache->getCount();
fb_assert((MAX_ULONG - 1) - m_used > m_cache.getCount());
return m_used + m_cache.getCount();
}
void DsqlBatch::DataCache::clear()
{
m_cache->clear();
m_cache.clear();
if (m_space && m_used)
m_space->releaseSpace(0, m_used);
m_used = m_got = m_shift = 0;

View File

@ -107,11 +107,11 @@ private:
{
public:
DataCache(MemoryPool& p)
: PermanentStorage(p),
m_used(0), m_got(0), m_limit(0), m_shift(0)
: PermanentStorage(p), m_cache(getPool()),
m_used(0), m_got(0), m_limit(0), m_shift(0), m_cacheCapacity(0)
{ }
void setBuf(ULONG size);
void setBuf(ULONG size, ULONG cacheCapacity);
void put(const void* data, ULONG dataSize);
void put3(const void* data, ULONG dataSize, ULONG offset);
@ -124,10 +124,10 @@ private:
void clear();
private:
typedef Firebird::Vector<UCHAR, DsqlBatch::RAM_BATCH, SINT64> Cache;
Firebird::AutoPtr<Cache> m_cache;
typedef Firebird::Array<UCHAR> Cache;
Cache m_cache;
Firebird::AutoPtr<TempSpace> m_space;
ULONG m_used, m_got, m_limit, m_shift;
ULONG m_used, m_got, m_limit, m_shift, m_cacheCapacity;
};
struct BlobMeta

View File

@ -1397,18 +1397,6 @@ void ArithmeticNode::getDescDialect1(thread_db* /*tdbb*/, dsc* desc, dsc& desc1,
break;
case blr_divide:
/***
if (desc1.isDecOrInt() && desc2.isDecOrInt())
{
desc->dsc_dtype = dtype_dec128;
desc->dsc_length = sizeof(Decimal128);
desc->dsc_scale = 0;
desc->dsc_sub_type = 0;
desc->dsc_flags = 0;
return;
}
***/
// for compatibility with older versions of the product, we accept
// text types for division in blr_version4 (dialect <= 1) only
if (!(DTYPE_IS_NUMERIC(desc1.dsc_dtype) || DTYPE_IS_TEXT(desc1.dsc_dtype)))
@ -7342,7 +7330,15 @@ bool LiteralNode::sameAs(CompilerScratch* csb, const ExprNode* other, bool ignor
fb_assert(otherNode);
thread_db* tdbb = JRD_get_thread_data();
return !MOV_compare(tdbb, &litDesc, &otherNode->litDesc);
try
{
return MOV_compare(tdbb, &litDesc, &otherNode->litDesc) == 0;
}
catch (const status_exception&)
{
fb_utils::init_status(tdbb->tdbb_status_vector);
return false;
}
}
ValueExprNode* LiteralNode::pass2(thread_db* tdbb, CompilerScratch* csb)

View File

@ -329,17 +329,12 @@ bool Parser::yylexSkipSpaces()
if (lex.ptr >= lex.end)
return false;
c = *lex.ptr++;
if (yylexSkipEol())
continue;
// Process comments
if (c == '\n')
{
lex.lines++;
lex.line_start = lex.ptr;
continue;
}
c = *lex.ptr++;
if (c == '-' && lex.ptr < lex.end && *lex.ptr == '-')
{
// single-line
@ -347,12 +342,9 @@ bool Parser::yylexSkipSpaces()
lex.ptr++;
while (lex.ptr < lex.end)
{
if ((c = *lex.ptr++) == '\n')
{
lex.lines++;
lex.line_start = lex.ptr; // + 1; // CVC: +1 left out.
if (yylexSkipEol())
break;
}
lex.ptr++;
}
if (lex.ptr >= lex.end)
return false;
@ -367,17 +359,14 @@ bool Parser::yylexSkipSpaces()
lex.ptr++;
while (lex.ptr < lex.end)
{
if (yylexSkipEol())
continue;
if ((c = *lex.ptr++) == '*')
{
if (*lex.ptr == '/')
break;
}
if (c == '\n')
{
lex.lines++;
lex.line_start = lex.ptr; // + 1; // CVC: +1 left out.
}
}
if (lex.ptr >= lex.end)
{
@ -401,6 +390,35 @@ bool Parser::yylexSkipSpaces()
}
bool Parser::yylexSkipEol()
{
bool eol = false;
const TEXT c = *lex.ptr;
if (c == '\r')
{
lex.ptr++;
if (lex.ptr < lex.end && *lex.ptr == '\n')
lex.ptr++;
eol = true;
}
else if (c == '\n')
{
lex.ptr++;
eol = true;
}
if (eol)
{
lex.lines++;
lex.line_start = lex.ptr; // + 1; // CVC: +1 left out.
}
return eol;
}
int Parser::yylexAux()
{
thread_db* tdbb = JRD_get_thread_data();

View File

@ -241,6 +241,7 @@ private:
int yylex();
bool yylexSkipSpaces();
bool yylexSkipEol(); // returns true if EOL is detected and skipped
int yylexAux();
void yyerror(const TEXT* error_string);
@ -271,7 +272,7 @@ private:
clause = value;
}
template <typename T, typename Delete>
template <typename T, template <typename C> class Delete>
void setClause(Firebird::AutoPtr<T, Delete>& clause, const char* duplicateMsg, T* value)
{
checkDuplicateClause(clause, duplicateMsg);

View File

@ -1241,10 +1241,14 @@ const StmtNode* CursorStmtNode::execute(thread_db* tdbb, jrd_req* request, ExeSt
static RegisterNode<DeclareCursorNode> regDeclareCursorNode(blr_dcl_cursor);
DmlNode* DeclareCursorNode::parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb, const UCHAR /*blrOp*/)
DmlNode* DeclareCursorNode::parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb, const UCHAR blrOp)
{
DeclareCursorNode* node = FB_NEW_POOL(pool) DeclareCursorNode(pool);
fb_assert(blrOp == blr_dcl_cursor);
if (blrOp == blr_dcl_cursor)
node->dsqlCursorType = CUR_TYPE_EXPLICIT;
node->cursorNumber = csb->csb_blr_reader.getWord();
node->rse = PAR_rse(tdbb, csb);
@ -1349,11 +1353,14 @@ DeclareCursorNode* DeclareCursorNode::pass2(thread_db* tdbb, CompilerScratch* cs
// Activate cursor streams to allow index usage for <cursor>.<field> references, see CORE-4675.
// It's also useful for correlated sub-queries in the select list, see CORE-4379.
// Mark cursor streams as unstable, see CORE-5773.
for (StreamList::const_iterator i = cursorStreams.begin(); i != cursorStreams.end(); ++i)
{
csb->csb_rpt[*i].csb_cursor_number = cursorNumber;
csb->csb_rpt[*i].activate();
if (dsqlCursorType == CUR_TYPE_EXPLICIT)
csb->csb_rpt[*i].csb_flags |= csb_unstable;
}
return this;
@ -8087,6 +8094,17 @@ void SetTransactionNode::genTableLock(DsqlCompilerScratch* dsqlScratch,
//--------------------
void SessionResetNode::execute(thread_db* tdbb, dsql_req* request) const
{
SET_TDBB(tdbb);
Attachment* const attachment = tdbb->getAttachment();
attachment->resetSession(tdbb);
}
//--------------------
void SetRoleNode::execute(thread_db* tdbb, dsql_req* request) const
{
SET_TDBB(tdbb);

View File

@ -1569,6 +1569,26 @@ public:
};
class SessionResetNode : public SessionManagementNode
{
public:
explicit SessionResetNode(MemoryPool& pool)
: SessionManagementNode(pool)
{
}
public:
virtual Firebird::string internalPrint(NodePrinter& printer) const
{
SessionManagementNode::internalPrint(printer);
return "SessionResetNode";
}
virtual void execute(thread_db* tdbb, dsql_req* request) const;
};
class SetRoleNode : public SessionManagementNode
{
public:

View File

@ -1142,7 +1142,7 @@ void dsql_req::mapInOut(thread_db* tdbb, bool toExternal, const dsql_msg* messag
desc.dsc_address = dsql_msg_buf + (IPTR) desc.dsc_address;
if (notNull)
MOVD_move(tdbb, &parDesc, &desc);
MOVD_move(tdbb, &parDesc, &desc, toExternal);
else
memset(desc.dsc_address, 0, desc.dsc_length);
}
@ -1150,7 +1150,7 @@ void dsql_req::mapInOut(thread_db* tdbb, bool toExternal, const dsql_msg* messag
{
// Safe cast because desc is used as source only.
desc.dsc_address = const_cast<UCHAR*>(in_dsql_msg_buf) + (IPTR) desc.dsc_address;
MOVD_move(tdbb, &desc, &parDesc);
MOVD_move(tdbb, &desc, &parDesc, toExternal);
}
else
memset(parDesc.dsc_address, 0, parDesc.dsc_length);
@ -1185,7 +1185,7 @@ void dsql_req::mapInOut(thread_db* tdbb, bool toExternal, const dsql_msg* messag
dsc desc = parameter->par_desc;
desc.dsc_address = msgBuffer + (IPTR) desc.dsc_address;
MOVD_move(tdbb, &parentDesc, &desc);
MOVD_move(tdbb, &parentDesc, &desc, false);
dsql_par* null_ind = parameter->par_null;
if (null_ind != NULL)
@ -1215,7 +1215,7 @@ void dsql_req::mapInOut(thread_db* tdbb, bool toExternal, const dsql_msg* messag
dsc desc = parameter->par_desc;
desc.dsc_address = msgBuffer + (IPTR) desc.dsc_address;
MOVD_move(tdbb, &parentDesc, &desc);
MOVD_move(tdbb, &parentDesc, &desc, false);
dsql_par* null_ind = parameter->par_null;
if (null_ind != NULL)

View File

@ -33,11 +33,11 @@ using namespace Firebird;
// Move (and possible convert) something to something else.
void MOVD_move(thread_db* tdbb, dsc* from, dsc* to)
void MOVD_move(thread_db* tdbb, dsc* from, dsc* to, bool toExternal)
{
try
{
MOV_move(tdbb, from, to);
MOV_move_ext(tdbb, from, to, toExternal);
}
catch (const status_exception& ex)
{

View File

@ -24,6 +24,6 @@
#ifndef DSQL_MOVD_PROTO_H
#define DSQL_MOVD_PROTO_H
void MOVD_move(Jrd::thread_db* tdbb, dsc*, dsc*);
void MOVD_move(Jrd::thread_db* tdbb, dsc*, dsc*, bool toExternal);
#endif // DSQL_MOVD_PROTO_H

View File

@ -618,6 +618,7 @@ using namespace Firebird;
%token <metaNamePtr> RDB_ERROR
%token <metaNamePtr> RDB_ROLE_IN_USE
%token <metaNamePtr> RDB_SYSTEM_PRIVILEGE
%token <metaNamePtr> RESET
%token <metaNamePtr> SECURITY
%token <metaNamePtr> SESSION
%token <metaNamePtr> SQL
@ -784,6 +785,7 @@ using namespace Firebird;
Jrd::SetRoundNode* setRoundNode;
Jrd::SetTrapsNode* setTrapsNode;
Jrd::SetBindNode* setBindNode;
Jrd::SessionResetNode* sessionResetNode;
}
%include types.y
@ -846,6 +848,7 @@ mng_statement
| set_bind { $$ = $1; }
| session_statement { $$ = $1; }
| set_role { $$ = $1; }
| session_reset { $$ = $1; }
;
@ -4166,7 +4169,8 @@ keyword_or_column
| UPDATING
| VAR_SAMP
| VAR_POP
| UNBOUNDED // added in FB 4.0
| DECFLOAT // added in FB 4.0
| UNBOUNDED
| WINDOW
;
@ -4830,15 +4834,17 @@ varbinary_character_keyword
%type <legacyField> decfloat_type
decfloat_type
: DECFLOAT '(' signed_long_integer ')'
: DECFLOAT precision_opt_nz
{
if ($3 != 16 && $3 != 34)
yyabandon(YYPOSNARG(3), -842, isc_decprecision_err); // DecFloat precision must be 16 or 34.
SLONG precision = $2;
if (precision != 0 && precision != 16 && precision != 34)
yyabandon(YYPOSNARG(2), -842, isc_decprecision_err); // DecFloat precision must be 16 or 34.
$$ = newNode<dsql_fld>();
$$->precision = $3;
$$->dtype = $3 == 16 ? dtype_dec64 : dtype_dec128;
$$->length = $3 == 16 ? sizeof(Decimal64) : sizeof(Decimal128);
$$->precision = precision == 0 ? 34 : (USHORT) precision;
$$->dtype = precision == 16 ? dtype_dec64 : dtype_dec128;
$$->length = precision == 16 ? sizeof(Decimal64) : sizeof(Decimal128);
}
;
@ -5040,6 +5046,12 @@ precision_opt
| '(' nonneg_short_integer ')' { $$ = $2; }
;
// alternative to precision_opt that does not allow zero
%type <int32Val> precision_opt_nz
precision_opt_nz
: /* nothing */ { $$ = 0; }
| '(' pos_short_integer ')' { $$ = $2; }
;
// transaction statements
@ -5130,6 +5142,12 @@ set_transaction
{ $$ = $3; }
;
%type <sessionResetNode> session_reset
session_reset
: ALTER SESSION RESET
{ $$ = newNode<SessionResetNode>(); }
;
%type <setRoleNode> set_role
set_role
: SET ROLE valid_symbol_name
@ -8513,7 +8531,6 @@ non_reserved_word
| BIND // added in FB 4.0
| COMPARE_DECFLOAT
| CUME_DIST
| DECFLOAT
| DEFINER
| EXCLUDE
| FIRST_DAY
@ -8532,6 +8549,7 @@ non_reserved_word
| PRIVILEGE
| QUANTIZE
| RANGE
| RESET
| SECURITY
| SESSION
| SQL

View File

@ -1075,10 +1075,9 @@ static void gen_blob_open( const act* action, USHORT column)
endp(column);
if (gpreGlob.sw_auto)
column -= INDENT;
set_sqlcode(action, column);
if (action->act_type == ACT_blob_create)
{
printa(column, "if (!SQLCODE)");
printa(column, "if (!(%s->getErrors() & Firebird::IStatus::STATE_ERRORS))", global_status_name);
align(column + INDENT);
fprintf(gpreGlob.out_file, "%s = %s;", reference->ref_value, s);
}
@ -2235,6 +2234,8 @@ static void gen_finish( const act* action, int column)
db = ready->rdy_database;
printa(column, "%s->detach(%s);",
db->dbb_name->sym_string, status_vector(action));
success(column, true, status_vector(action));
printa(column + INDENT, "%s = 0;", db->dbb_name->sym_string);
}
// no hanbdles, so we finish all known databases
@ -2250,6 +2251,8 @@ static void gen_finish( const act* action, int column)
printa(column, "if (%s)", db->dbb_name->sym_string);
printa(column + INDENT, "%s->detach(%s);",
db->dbb_name->sym_string, status_vector(action));
success(column, true, status_vector(action));
printa(column + INDENT, "%s = 0;", db->dbb_name->sym_string);
}
}
@ -3357,8 +3360,6 @@ static void gen_t_start( const act* action, int column)
printa(column, "}\t\t// end fbComponents scope\n");
}
set_sqlcode(action, column);
}
@ -3435,9 +3436,10 @@ static void gen_trans( const act* action, int column)
(action->act_type == ACT_commit) ?
"commit" : (action->act_type == ACT_rollback) ? "rollback" : "prepare",
status_vector(action));
success(column, true, status_vector(action));
printa(column + INDENT, "%s = 0;", tranText);
break;
}
set_sqlcode(action, column);
}

View File

@ -347,7 +347,7 @@
#define isc_info_svc_capabilities 57 /* Retrieves a bitmask representing the server's capabilities */
#define isc_info_svc_user_dbpath 58 /* Retrieves the path to the security database in use by the server */
#define isc_info_svc_get_env 59 /* Retrieves the setting of $FIREBIRD */
#define isc_info_svc_get_env_lock 60 /* Retrieves the setting of $FIREBIRD_LCK */
#define isc_info_svc_get_env_lock 60 /* Retrieves the setting of $FIREBIRD_LOCK */
#define isc_info_svc_get_env_msg 61 /* Retrieves the setting of $FIREBIRD_MSG */
#define isc_info_svc_line 62 /* Retrieves 1 line of service output per call */
#define isc_info_svc_to_eof 63 /* Retrieves as much of the server output as will fit in the supplied buffer */
@ -393,6 +393,9 @@
#define isc_spb_bkp_length 7
#define isc_spb_bkp_skip_data 8
#define isc_spb_bkp_stat 15
#define isc_spb_bkp_keyholder 16
#define isc_spb_bkp_keyname 17
#define isc_spb_bkp_crypt 18
#define isc_spb_bkp_ignore_checksums 0x01
#define isc_spb_bkp_ignore_limbo 0x02
#define isc_spb_bkp_metadata_only 0x04
@ -402,6 +405,7 @@
#define isc_spb_bkp_convert 0x40
#define isc_spb_bkp_expand 0x80
#define isc_spb_bkp_no_triggers 0x8000
#define isc_spb_bkp_zip 0x010000
/********************************************
* Parameters for isc_action_svc_properties *
@ -505,6 +509,9 @@
#define isc_spb_res_access_mode 12
#define isc_spb_res_fix_fss_data 13
#define isc_spb_res_fix_fss_metadata 14
#define isc_spb_res_keyholder isc_spb_bkp_keyholder
#define isc_spb_res_keyname isc_spb_bkp_keyname
#define isc_spb_res_crypt isc_spb_bkp_crypt
#define isc_spb_res_stat isc_spb_bkp_stat
#define isc_spb_res_metadata_only isc_spb_bkp_metadata_only
#define isc_spb_res_deactivate_idx 0x0100

View File

@ -206,6 +206,9 @@
/* Define to 1 if you have the `gmtime_r' function. */
#define HAVE_GMTIME_R 1
/* Define to 1 if you have the `ctime_r' function. */
#define HAVE_CTIME_R 1
/* Define to 1 if you have the <grp.h> header file. */
#define HAVE_GRP_H 1

View File

@ -212,6 +212,9 @@
/* Define to 1 if you have the `gmtime_r' function. */
#define HAVE_GMTIME_R 1
/* Define to 1 if you have the `ctime_r' function. */
#define HAVE_CTIME_R 1
/* Define to 1 if you have the <grp.h> header file. */
#define HAVE_GRP_H 1

View File

@ -206,6 +206,9 @@
/* Define to 1 if you have the `gmtime_r' function. */
#define HAVE_GMTIME_R 1
/* Define to 1 if you have the `ctime_r' function. */
#define HAVE_CTIME_R 1
/* Define to 1 if you have the <grp.h> header file. */
#define HAVE_GRP_H 1

View File

@ -206,6 +206,9 @@
/* Define to 1 if you have the `gmtime_r' function. */
#define HAVE_GMTIME_R 1
/* Define to 1 if you have the `ctime_r' function. */
#define HAVE_CTIME_R 1
/* Define to 1 if you have the <grp.h> header file. */
#define HAVE_GRP_H 1

View File

@ -125,6 +125,7 @@ typedef void (*ErrorFunction) (const Firebird::Arg::StatusVector& v);
typedef void (*FPTR_ERROR) (ISC_STATUS, ...);
typedef ULONG RCRD_OFFSET;
typedef ULONG RCRD_LENGTH;
typedef USHORT FLD_LENGTH;
/* CVC: internal usage. I suspect the only reason to return int is that
vmslock.cpp:LOCK_convert() calls VMS' sys$enq that may require this signature,

View File

@ -31,7 +31,6 @@ typedef ISC_QUAD;
typedef ISC_TIME;
typedef FB_DEC16;
typedef FB_DEC34;
typedef FB_DEC_FIXED;
// Versioned interface - base for all FB interfaces
interface Versioned
@ -214,6 +213,10 @@ interface PluginFactory : Versioned
interface PluginModule : Versioned
{
void doClean();
version: // 3.0.3 => 3.0.4
// Used to release resources allocated per-thread
void threadDetach();
}
// Interface to deal with plugins here and there, returned by master interface
@ -514,15 +517,15 @@ interface Pipe : ReferenceCounted
interface Request : ReferenceCounted
{
void receive(Status status, int level, uint msgType,
uint length, uchar* message);
uint length, void* message);
void send(Status status, int level, uint msgType,
uint length, const uchar* message);
uint length, const void* message);
void getInfo(Status status, int level,
uint itemsLength, const uchar* items,
uint bufferLength, uchar* buffer);
void start(Status status, Transaction tra, int level);
void startAndSend(Status status, Transaction tra, int level, uint msgType,
uint length, const uchar* message);
uint length, const void* message);
void unwind(Status status, int level);
void free(Status status);
}
@ -599,6 +602,7 @@ version: // 3.0 => 4.0
// Batch API
Batch createBatch(Status status, Transaction transaction, uint stmtLength, const string sqlStmt,
uint dialect, MessageMetadata inMetadata, uint parLength, const uchar* par);
/*
Pipe createPipe(Status status, uint stmtLength, const string sqlStmt, uint dialect,
Transaction transaction, MessageMetadata inMetadata, void* inBuffer,
@ -1061,7 +1065,6 @@ version: // 3.0 => 4.0
EventBlock createEventBlock(Status status, const string* events);
DecFloat16 getDecFloat16(Status status);
DecFloat34 getDecFloat34(Status status);
DecFixed getDecFixed(Status status);
}
interface OffsetsCallback : Versioned
@ -1467,13 +1470,3 @@ interface DecFloat34 : Versioned
void fromBcd(int sign, const uchar* bcd, int exp, FB_DEC34* to);
void fromString(Status status, const string from, FB_DEC34* to);
}
interface DecFixed : Versioned
{
const uint BCD_SIZE = 34;
const uint STRING_SIZE = 41; // may include exponent not more than 3 digits
void toBcd(const FB_DEC_FIXED* from, int* sign, uchar* bcd);
void toString(Status status, const FB_DEC_FIXED* from, int scale, uint bufferLength, string buffer);
void fromBcd(int sign, const uchar* bcd, FB_DEC_FIXED* to);
void fromString(Status status, const string from, int scale, FB_DEC_FIXED* to);
}

View File

@ -115,7 +115,6 @@ namespace Firebird
class IUdrPlugin;
class IDecFloat16;
class IDecFloat34;
class IDecFixed;
// Interfaces declarations
@ -737,6 +736,7 @@ namespace Firebird
struct VTable : public IVersioned::VTable
{
void (CLOOP_CARG *doClean)(IPluginModule* self) throw();
void (CLOOP_CARG *threadDetach)(IPluginModule* self) throw();
};
protected:
@ -750,12 +750,21 @@ namespace Firebird
}
public:
static const unsigned VERSION = 2;
static const unsigned VERSION = 3;
void doClean()
{
static_cast<VTable*>(this->cloopVTable)->doClean(this);
}
void threadDetach()
{
if (cloopVTable->version < 3)
{
return;
}
static_cast<VTable*>(this->cloopVTable)->threadDetach(this);
}
};
class IPluginManager : public IVersioned
@ -1931,11 +1940,11 @@ namespace Firebird
public:
struct VTable : public IReferenceCounted::VTable
{
void (CLOOP_CARG *receive)(IRequest* self, IStatus* status, int level, unsigned msgType, unsigned length, unsigned char* message) throw();
void (CLOOP_CARG *send)(IRequest* self, IStatus* status, int level, unsigned msgType, unsigned length, const unsigned char* message) throw();
void (CLOOP_CARG *receive)(IRequest* self, IStatus* status, int level, unsigned msgType, unsigned length, void* message) throw();
void (CLOOP_CARG *send)(IRequest* self, IStatus* status, int level, unsigned msgType, unsigned length, const void* message) throw();
void (CLOOP_CARG *getInfo)(IRequest* self, IStatus* status, int level, unsigned itemsLength, const unsigned char* items, unsigned bufferLength, unsigned char* buffer) throw();
void (CLOOP_CARG *start)(IRequest* self, IStatus* status, ITransaction* tra, int level) throw();
void (CLOOP_CARG *startAndSend)(IRequest* self, IStatus* status, ITransaction* tra, int level, unsigned msgType, unsigned length, const unsigned char* message) throw();
void (CLOOP_CARG *startAndSend)(IRequest* self, IStatus* status, ITransaction* tra, int level, unsigned msgType, unsigned length, const void* message) throw();
void (CLOOP_CARG *unwind)(IRequest* self, IStatus* status, int level) throw();
void (CLOOP_CARG *free)(IRequest* self, IStatus* status) throw();
};
@ -1953,14 +1962,14 @@ namespace Firebird
public:
static const unsigned VERSION = 3;
template <typename StatusType> void receive(StatusType* status, int level, unsigned msgType, unsigned length, unsigned char* message)
template <typename StatusType> void receive(StatusType* status, int level, unsigned msgType, unsigned length, void* message)
{
StatusType::clearException(status);
static_cast<VTable*>(this->cloopVTable)->receive(this, status, level, msgType, length, message);
StatusType::checkException(status);
}
template <typename StatusType> void send(StatusType* status, int level, unsigned msgType, unsigned length, const unsigned char* message)
template <typename StatusType> void send(StatusType* status, int level, unsigned msgType, unsigned length, const void* message)
{
StatusType::clearException(status);
static_cast<VTable*>(this->cloopVTable)->send(this, status, level, msgType, length, message);
@ -1981,7 +1990,7 @@ namespace Firebird
StatusType::checkException(status);
}
template <typename StatusType> void startAndSend(StatusType* status, ITransaction* tra, int level, unsigned msgType, unsigned length, const unsigned char* message)
template <typename StatusType> void startAndSend(StatusType* status, ITransaction* tra, int level, unsigned msgType, unsigned length, const void* message)
{
StatusType::clearException(status);
static_cast<VTable*>(this->cloopVTable)->startAndSend(this, status, tra, level, msgType, length, message);
@ -3938,7 +3947,6 @@ namespace Firebird
IEventBlock* (CLOOP_CARG *createEventBlock)(IUtil* self, IStatus* status, const char** events) throw();
IDecFloat16* (CLOOP_CARG *getDecFloat16)(IUtil* self, IStatus* status) throw();
IDecFloat34* (CLOOP_CARG *getDecFloat34)(IUtil* self, IStatus* status) throw();
IDecFixed* (CLOOP_CARG *getDecFixed)(IUtil* self, IStatus* status) throw();
};
protected:
@ -4081,20 +4089,6 @@ namespace Firebird
StatusType::checkException(status);
return ret;
}
template <typename StatusType> IDecFixed* getDecFixed(StatusType* status)
{
if (cloopVTable->version < 3)
{
StatusType::setVersionError(status, "IUtil", cloopVTable->version, 3);
StatusType::checkException(status);
return 0;
}
StatusType::clearException(status);
IDecFixed* ret = static_cast<VTable*>(this->cloopVTable)->getDecFixed(this, status);
StatusType::checkException(status);
return ret;
}
};
class IOffsetsCallback : public IVersioned
@ -5676,58 +5670,6 @@ namespace Firebird
}
};
class IDecFixed : public IVersioned
{
public:
struct VTable : public IVersioned::VTable
{
void (CLOOP_CARG *toBcd)(IDecFixed* self, const FB_DEC_FIXED* from, int* sign, unsigned char* bcd) throw();
void (CLOOP_CARG *toString)(IDecFixed* self, IStatus* status, const FB_DEC_FIXED* from, int scale, unsigned bufferLength, char* buffer) throw();
void (CLOOP_CARG *fromBcd)(IDecFixed* self, int sign, const unsigned char* bcd, FB_DEC_FIXED* to) throw();
void (CLOOP_CARG *fromString)(IDecFixed* self, IStatus* status, const char* from, int scale, FB_DEC_FIXED* to) throw();
};
protected:
IDecFixed(DoNotInherit)
: IVersioned(DoNotInherit())
{
}
~IDecFixed()
{
}
public:
static const unsigned VERSION = 2;
static const unsigned BCD_SIZE = 34;
static const unsigned STRING_SIZE = 41;
void toBcd(const FB_DEC_FIXED* from, int* sign, unsigned char* bcd)
{
static_cast<VTable*>(this->cloopVTable)->toBcd(this, from, sign, bcd);
}
template <typename StatusType> void toString(StatusType* status, const FB_DEC_FIXED* from, int scale, unsigned bufferLength, char* buffer)
{
StatusType::clearException(status);
static_cast<VTable*>(this->cloopVTable)->toString(this, status, from, scale, bufferLength, buffer);
StatusType::checkException(status);
}
void fromBcd(int sign, const unsigned char* bcd, FB_DEC_FIXED* to)
{
static_cast<VTable*>(this->cloopVTable)->fromBcd(this, sign, bcd, to);
}
template <typename StatusType> void fromString(StatusType* status, const char* from, int scale, FB_DEC_FIXED* to)
{
StatusType::clearException(status);
static_cast<VTable*>(this->cloopVTable)->fromString(this, status, from, scale, to);
StatusType::checkException(status);
}
};
// Interfaces implementations
template <typename Name, typename StatusType, typename Base>
@ -7072,6 +7014,7 @@ namespace Firebird
{
this->version = Base::VERSION;
this->doClean = &Name::cloopdoCleanDispatcher;
this->threadDetach = &Name::cloopthreadDetachDispatcher;
}
} vTable;
@ -7089,6 +7032,18 @@ namespace Firebird
StatusType::catchException(0);
}
}
static void CLOOP_CARG cloopthreadDetachDispatcher(IPluginModule* self) throw()
{
try
{
static_cast<Name*>(self)->Name::threadDetach();
}
catch (...)
{
StatusType::catchException(0);
}
}
};
template <typename Name, typename StatusType, typename Base = IVersionedImpl<Name, StatusType, Inherit<IPluginModule> > >
@ -7105,6 +7060,7 @@ namespace Firebird
}
virtual void doClean() = 0;
virtual void threadDetach() = 0;
};
template <typename Name, typename StatusType, typename Base>
@ -9401,7 +9357,7 @@ namespace Firebird
this->cloopVTable = &vTable;
}
static void CLOOP_CARG cloopreceiveDispatcher(IRequest* self, IStatus* status, int level, unsigned msgType, unsigned length, unsigned char* message) throw()
static void CLOOP_CARG cloopreceiveDispatcher(IRequest* self, IStatus* status, int level, unsigned msgType, unsigned length, void* message) throw()
{
StatusType status2(status);
@ -9415,7 +9371,7 @@ namespace Firebird
}
}
static void CLOOP_CARG cloopsendDispatcher(IRequest* self, IStatus* status, int level, unsigned msgType, unsigned length, const unsigned char* message) throw()
static void CLOOP_CARG cloopsendDispatcher(IRequest* self, IStatus* status, int level, unsigned msgType, unsigned length, const void* message) throw()
{
StatusType status2(status);
@ -9457,7 +9413,7 @@ namespace Firebird
}
}
static void CLOOP_CARG cloopstartAndSendDispatcher(IRequest* self, IStatus* status, ITransaction* tra, int level, unsigned msgType, unsigned length, const unsigned char* message) throw()
static void CLOOP_CARG cloopstartAndSendDispatcher(IRequest* self, IStatus* status, ITransaction* tra, int level, unsigned msgType, unsigned length, const void* message) throw()
{
StatusType status2(status);
@ -9538,11 +9494,11 @@ namespace Firebird
{
}
virtual void receive(StatusType* status, int level, unsigned msgType, unsigned length, unsigned char* message) = 0;
virtual void send(StatusType* status, int level, unsigned msgType, unsigned length, const unsigned char* message) = 0;
virtual void receive(StatusType* status, int level, unsigned msgType, unsigned length, void* message) = 0;
virtual void send(StatusType* status, int level, unsigned msgType, unsigned length, const void* message) = 0;
virtual void getInfo(StatusType* status, int level, unsigned itemsLength, const unsigned char* items, unsigned bufferLength, unsigned char* buffer) = 0;
virtual void start(StatusType* status, ITransaction* tra, int level) = 0;
virtual void startAndSend(StatusType* status, ITransaction* tra, int level, unsigned msgType, unsigned length, const unsigned char* message) = 0;
virtual void startAndSend(StatusType* status, ITransaction* tra, int level, unsigned msgType, unsigned length, const void* message) = 0;
virtual void unwind(StatusType* status, int level) = 0;
virtual void free(StatusType* status) = 0;
};
@ -13809,7 +13765,6 @@ namespace Firebird
this->createEventBlock = &Name::cloopcreateEventBlockDispatcher;
this->getDecFloat16 = &Name::cloopgetDecFloat16Dispatcher;
this->getDecFloat34 = &Name::cloopgetDecFloat34Dispatcher;
this->getDecFixed = &Name::cloopgetDecFixedDispatcher;
}
} vTable;
@ -14037,21 +13992,6 @@ namespace Firebird
return static_cast<IDecFloat34*>(0);
}
}
static IDecFixed* CLOOP_CARG cloopgetDecFixedDispatcher(IUtil* self, IStatus* status) throw()
{
StatusType status2(status);
try
{
return static_cast<Name*>(self)->Name::getDecFixed(&status2);
}
catch (...)
{
StatusType::catchException(&status2);
return static_cast<IDecFixed*>(0);
}
}
};
template <typename Name, typename StatusType, typename Base = IVersionedImpl<Name, StatusType, Inherit<IUtil> > >
@ -14083,7 +14023,6 @@ namespace Firebird
virtual IEventBlock* createEventBlock(StatusType* status, const char** events) = 0;
virtual IDecFloat16* getDecFloat16(StatusType* status) = 0;
virtual IDecFloat34* getDecFloat34(StatusType* status) = 0;
virtual IDecFixed* getDecFixed(StatusType* status) = 0;
};
template <typename Name, typename StatusType, typename Base>
@ -17481,101 +17420,6 @@ namespace Firebird
virtual void fromBcd(int sign, const unsigned char* bcd, int exp, FB_DEC34* to) = 0;
virtual void fromString(StatusType* status, const char* from, FB_DEC34* to) = 0;
};
template <typename Name, typename StatusType, typename Base>
class IDecFixedBaseImpl : public Base
{
public:
typedef IDecFixed Declaration;
IDecFixedBaseImpl(DoNotInherit = DoNotInherit())
{
static struct VTableImpl : Base::VTable
{
VTableImpl()
{
this->version = Base::VERSION;
this->toBcd = &Name::clooptoBcdDispatcher;
this->toString = &Name::clooptoStringDispatcher;
this->fromBcd = &Name::cloopfromBcdDispatcher;
this->fromString = &Name::cloopfromStringDispatcher;
}
} vTable;
this->cloopVTable = &vTable;
}
static void CLOOP_CARG clooptoBcdDispatcher(IDecFixed* self, const FB_DEC_FIXED* from, int* sign, unsigned char* bcd) throw()
{
try
{
static_cast<Name*>(self)->Name::toBcd(from, sign, bcd);
}
catch (...)
{
StatusType::catchException(0);
}
}
static void CLOOP_CARG clooptoStringDispatcher(IDecFixed* self, IStatus* status, const FB_DEC_FIXED* from, int scale, unsigned bufferLength, char* buffer) throw()
{
StatusType status2(status);
try
{
static_cast<Name*>(self)->Name::toString(&status2, from, scale, bufferLength, buffer);
}
catch (...)
{
StatusType::catchException(&status2);
}
}
static void CLOOP_CARG cloopfromBcdDispatcher(IDecFixed* self, int sign, const unsigned char* bcd, FB_DEC_FIXED* to) throw()
{
try
{
static_cast<Name*>(self)->Name::fromBcd(sign, bcd, to);
}
catch (...)
{
StatusType::catchException(0);
}
}
static void CLOOP_CARG cloopfromStringDispatcher(IDecFixed* self, IStatus* status, const char* from, int scale, FB_DEC_FIXED* to) throw()
{
StatusType status2(status);
try
{
static_cast<Name*>(self)->Name::fromString(&status2, from, scale, to);
}
catch (...)
{
StatusType::catchException(&status2);
}
}
};
template <typename Name, typename StatusType, typename Base = IVersionedImpl<Name, StatusType, Inherit<IDecFixed> > >
class IDecFixedImpl : public IDecFixedBaseImpl<Name, StatusType, Base>
{
protected:
IDecFixedImpl(DoNotInherit = DoNotInherit())
{
}
public:
virtual ~IDecFixedImpl()
{
}
virtual void toBcd(const FB_DEC_FIXED* from, int* sign, unsigned char* bcd) = 0;
virtual void toString(StatusType* status, const FB_DEC_FIXED* from, int scale, unsigned bufferLength, char* buffer) = 0;
virtual void fromBcd(int sign, const unsigned char* bcd, FB_DEC_FIXED* to) = 0;
virtual void fromString(StatusType* status, const char* from, int scale, FB_DEC_FIXED* to) = 0;
};
};

View File

@ -141,11 +141,6 @@
builder->setType(status, index, SQL_DEC34); \
builder->setLength(status, index, sizeof(FB_DEC34));
#define FB__META_FB_DEC_FIXED(scale) \
builder->setType(status, index, SQL_DEC_FIXED); \
builder->setLength(status, index, sizeof(FB_DEC_FIXED)); \
builder->setScale(status, index, scale);
#define FB__META_FB_BLOB \
builder->setType(status, index, SQL_BLOB); \
builder->setLength(status, index, sizeof(ISC_QUAD));
@ -200,7 +195,6 @@
#define FB__TYPE_FB_DOUBLE double
#define FB__TYPE_FB_DECFLOAT16 FB_DEC16
#define FB__TYPE_FB_DECFLOAT34 FB_DEC34
#define FB__TYPE_FB_DEC_FIXED FB_DEC_FIXED
#define FB__TYPE_FB_BLOB ISC_QUAD
#define FB__TYPE_FB_BOOLEAN ISC_UCHAR
#define FB__TYPE_FB_DATE ::Firebird::FbDate

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