From 425a98aa12bf42833d3bdce780bafe0040e74709 Mon Sep 17 00:00:00 2001 From: Dmitry Yemanov Date: Mon, 5 Feb 2018 19:40:54 +0300 Subject: [PATCH 001/171] Fixed ISQL after changes in gds__vax_integer(). If we insist on passing unsigned integers, then don't allow implicit sign extension --- src/isql/isql.epp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/isql/isql.epp b/src/isql/isql.epp index 6a93461246..5c1b555351 100644 --- a/src/isql/isql.epp +++ b/src/isql/isql.epp @@ -7991,7 +7991,7 @@ static void process_plan() case isc_info_sql_get_plan: case isc_info_sql_explain_plan: { - const ULONG len = gds__vax_integer(ptr, sizeof(USHORT)); + const USHORT len = (USHORT) gds__vax_integer(ptr, sizeof(USHORT)); ptr += sizeof(USHORT); planString.assign((const char*) ptr, len); ptr += len; From b3f157fc2141ddfad7c7049a50caa3800d85bdb7 Mon Sep 17 00:00:00 2001 From: AlexPeshkoff Date: Mon, 5 Feb 2018 19:47:46 +0300 Subject: [PATCH 002/171] Fixed docs after CORE-5700 --- doc/sql.extensions/README.data_types | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/sql.extensions/README.data_types b/doc/sql.extensions/README.data_types index fbe4a9f3b0..a3119f4827 100644 --- a/doc/sql.extensions/README.data_types +++ b/doc/sql.extensions/README.data_types @@ -166,7 +166,7 @@ DECFLOAT (FB 4.0) SET DECFLOAT TRAPS TO - 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 - controls how are DECFLOAT values represented in outer world (i.e. in messages or in XSQLDA). Valid binding types are: NATIVE (use IEEE754 From 67e625677a70244206cd1f3d285834a3023f3ed3 Mon Sep 17 00:00:00 2001 From: AlexPeshkoff Date: Mon, 5 Feb 2018 21:41:32 +0300 Subject: [PATCH 003/171] Implemented CORE-5741: Word "fixing" in gbak output is too scary --- src/msgs/messages2.sql | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/msgs/messages2.sql b/src/msgs/messages2.sql index fd7585794a..a87f11373d 100644 --- a/src/msgs/messages2.sql +++ b/src/msgs/messages2.sql @@ -2406,7 +2406,7 @@ ERROR: Backup incomplete', NULL, NULL); (NULL, 'get_exception', 'restore.epp', NULL, 12, 313, NULL, 'Trying to recover from unexpected attribute @1 due to wrong message length for exception @2', NULL, NULL); (NULL, 'put_exception', 'backup.epp', NULL, 12, 314, NULL, 'Attribute not specified for storing text bigger than 255 bytes', NULL, NULL); (NULL, 'put_exception', 'backup.epp', NULL, 12, 315, NULL, 'Unable to store text bigger than 65536 bytes', NULL, NULL); -(NULL, 'fix_security_class_name', 'restore.epp', NULL, 12, 316, NULL, 'Failed while fixing the security class name', NULL, NULL); +(NULL, 'fix_security_class_name', 'restore.epp', NULL, 12, 316, NULL, 'Failed while adjusting the security class name', NULL, NULL); (NULL, 'burp_usage', 'burp.cpp', NULL, 12, 317, NULL, 'Usage:', NULL, NULL); (NULL, 'burp_usage', 'burp.cpp', NULL, 12, 318, NULL, ' gbak -b [backup options] [general options]', NULL, NULL); (NULL, 'burp_usage', 'burp.cpp', NULL, 12, 319, NULL, ' gbak -c [restore options] [general options]', NULL, NULL); @@ -2440,14 +2440,14 @@ ERROR: Backup incomplete', NULL, NULL); (NULL, 'write_secclasses', 'backup.epp', NULL, 12, 347, NULL, 'writing security classes', NULL, NULL); ('gbak_db_format_too_old2', 'BACKUP_backup', 'backup.epp', NULL, 12, 348, NULL, 'database format @1 is too old to backup', NULL, NULL); (NULL, 'restore', 'restore.epp', NULL, 12, 349, NULL, 'backup version is @1', NULL, NULL); -(NULL, 'fix_system_generators', 'restore.epp', NULL, 12, 350, NULL, 'fixing system generators', NULL, NULL); +(NULL, 'fix_system_generators', 'restore.epp', NULL, 12, 350, NULL, 'adjusting system generators', NULL, NULL); (NULL, 'BURP_abort', 'burp.cpp', NULL, 12, 351, NULL, 'Error closing database, but backup file is OK', NULL, NULL); (NULL, NULL, 'restore.epp', NULL, 12, 352, NULL, 'database', NULL, NULL); (NULL, 'get_mapping', 'restore.epp', NULL, 12, 353, NULL, 'required mapping attributes are missing in backup file', NULL, NULL); (NULL, NULL, 'burp.cpp', NULL, 12, 354, NULL, 'missing regular expression to skip tables', NULL, NULL); (NULL, 'burp_usage', 'burp.c', NULL, 12, 355, NULL, ' @1SKIP_D(ATA) skip data for table', NULL, NULL); (NULL, NULL, 'burp.cpp', NULL, 12, 356, NULL, 'regular expression to skip tables was already set', NULL, NULL); -(NULL, 'update_view_dbkey_lengths', 'restore.epp', NULL, 12, 357, NULL, 'fixing views dbkey length', NULL, NULL); +(NULL, 'update_view_dbkey_lengths', 'restore.epp', NULL, 12, 357, NULL, 'adjusting views dbkey length', NULL, NULL); (NULL, 'update_ownership', 'restore.epp', NULL, 12, 358, NULL, 'updating ownership of packages, procedures and tables', NULL, NULL); (NULL, 'fix_missing_privileges', 'restore.epp', NULL, 12, 359, NULL, 'adding missing privileges', NULL, NULL); (NULL, 'RESTORE_restore', 'restore.epp', NULL, 12, 360, NULL, 'adjusting the ONLINE and FORCED WRITES flags', NULL, NULL); From 7666ee281f6dcb11dba88635810525abda4ce118 Mon Sep 17 00:00:00 2001 From: firebirds <> Date: Tue, 6 Feb 2018 00:04:14 +0000 Subject: [PATCH 004/171] increment build number --- src/jrd/build_no.h | 12 ++++++------ src/misc/writeBuildNum.sh | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/jrd/build_no.h b/src/jrd/build_no.h index 75b9bd5166..67738c89c0 100644 --- a/src/jrd/build_no.h +++ b/src/jrd/build_no.h @@ -3,16 +3,16 @@ *** DO NOT EDIT *** TO CHANGE ANY INFORMATION IN HERE PLEASE EDIT src/misc/writeBuildNum.sh - FORMAL BUILD NUMBER:875 + FORMAL BUILD NUMBER:878 */ -#define PRODUCT_VER_STRING "4.0.0.875" -#define FILE_VER_STRING "WI-T4.0.0.875" -#define LICENSE_VER_STRING "WI-T4.0.0.875" -#define FILE_VER_NUMBER 4, 0, 0, 875 +#define PRODUCT_VER_STRING "4.0.0.878" +#define FILE_VER_STRING "WI-T4.0.0.878" +#define LICENSE_VER_STRING "WI-T4.0.0.878" +#define FILE_VER_NUMBER 4, 0, 0, 878 #define FB_MAJOR_VER "4" #define FB_MINOR_VER "0" #define FB_REV_NO "0" -#define FB_BUILD_NO "875" +#define FB_BUILD_NO "878" #define FB_BUILD_TYPE "T" #define FB_BUILD_SUFFIX "Firebird 4.0 Alpha 1" diff --git a/src/misc/writeBuildNum.sh b/src/misc/writeBuildNum.sh index 926578ab79..dac3bf2699 100755 --- a/src/misc/writeBuildNum.sh +++ b/src/misc/writeBuildNum.sh @@ -9,7 +9,7 @@ BuildType=T MajorVer=4 MinorVer=0 RevNo=0 -BuildNum=875 +BuildNum=878 NowAt=`pwd` cd `dirname $0` From 7a4a6067d1386293590b75e988ecdb646e18c93d Mon Sep 17 00:00:00 2001 From: Paul Reeves Date: Tue, 6 Feb 2018 11:34:45 +0100 Subject: [PATCH 005/171] Correct spelling of env var in comment. --- src/include/consts_pub.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/include/consts_pub.h b/src/include/consts_pub.h index 1fb604230c..ef478c54de 100644 --- a/src/include/consts_pub.h +++ b/src/include/consts_pub.h @@ -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 */ From cf7fd050706363899cd83bb82587b065a140b4c4 Mon Sep 17 00:00:00 2001 From: Paul Reeves Date: Tue, 6 Feb 2018 11:45:45 +0100 Subject: [PATCH 006/171] Correct spelling of env var is FIREBIRD_LOCK. --- src/utilities/ntrace/TracePluginImpl.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/utilities/ntrace/TracePluginImpl.cpp b/src/utilities/ntrace/TracePluginImpl.cpp index eb60445e52..fea5061580 100644 --- a/src/utilities/ntrace/TracePluginImpl.cpp +++ b/src/utilities/ntrace/TracePluginImpl.cpp @@ -1026,7 +1026,7 @@ void TracePluginImpl::appendServiceQueryParams(size_t send_item_length, break; case isc_info_svc_get_env_lock: - recv_query.printf(NEWLINE "\t\t retrieve the setting of $FIREBIRD_LCK"); + recv_query.printf(NEWLINE "\t\t retrieve the setting of $FIREBIRD_LOCK"); break; case isc_info_svc_get_env_msg: From cec4be840e7bcc510a3139bb237fe22828e3e93e Mon Sep 17 00:00:00 2001 From: firebirds <> Date: Wed, 7 Feb 2018 00:04:26 +0000 Subject: [PATCH 007/171] increment build number --- src/jrd/build_no.h | 12 ++++++------ src/misc/writeBuildNum.sh | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/jrd/build_no.h b/src/jrd/build_no.h index 67738c89c0..323dbe3b9c 100644 --- a/src/jrd/build_no.h +++ b/src/jrd/build_no.h @@ -3,16 +3,16 @@ *** DO NOT EDIT *** TO CHANGE ANY INFORMATION IN HERE PLEASE EDIT src/misc/writeBuildNum.sh - FORMAL BUILD NUMBER:878 + FORMAL BUILD NUMBER:880 */ -#define PRODUCT_VER_STRING "4.0.0.878" -#define FILE_VER_STRING "WI-T4.0.0.878" -#define LICENSE_VER_STRING "WI-T4.0.0.878" -#define FILE_VER_NUMBER 4, 0, 0, 878 +#define PRODUCT_VER_STRING "4.0.0.880" +#define FILE_VER_STRING "WI-T4.0.0.880" +#define LICENSE_VER_STRING "WI-T4.0.0.880" +#define FILE_VER_NUMBER 4, 0, 0, 880 #define FB_MAJOR_VER "4" #define FB_MINOR_VER "0" #define FB_REV_NO "0" -#define FB_BUILD_NO "878" +#define FB_BUILD_NO "880" #define FB_BUILD_TYPE "T" #define FB_BUILD_SUFFIX "Firebird 4.0 Alpha 1" diff --git a/src/misc/writeBuildNum.sh b/src/misc/writeBuildNum.sh index dac3bf2699..910bd4330b 100755 --- a/src/misc/writeBuildNum.sh +++ b/src/misc/writeBuildNum.sh @@ -9,7 +9,7 @@ BuildType=T MajorVer=4 MinorVer=0 RevNo=0 -BuildNum=878 +BuildNum=880 NowAt=`pwd` cd `dirname $0` From a686559fba7f55d98d9a2e6f7e22bdca1dc2f66e Mon Sep 17 00:00:00 2001 From: AlexPeshkoff Date: Wed, 7 Feb 2018 19:11:42 +0300 Subject: [PATCH 008/171] Fresh tools version --- builds/make.new/config/install-sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/builds/make.new/config/install-sh b/builds/make.new/config/install-sh index 0b0fdcbba6..0360b79e7d 100755 --- a/builds/make.new/config/install-sh +++ b/builds/make.new/config/install-sh @@ -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: From 5289997053f806f082da47eb2abd834551468f6b Mon Sep 17 00:00:00 2001 From: AlexPeshkoff Date: Wed, 7 Feb 2018 19:13:48 +0300 Subject: [PATCH 009/171] Misc --- extern/libtommath/.gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/extern/libtommath/.gitignore b/extern/libtommath/.gitignore index 86cbfa9b3b..3ce71e6d90 100644 --- a/extern/libtommath/.gitignore +++ b/extern/libtommath/.gitignore @@ -1,5 +1,6 @@ lib/ temp/ *.o +*.d *.l* .libs/ From c70cc39b62c824608fbb0da0c987f237afdd409a Mon Sep 17 00:00:00 2001 From: AlexPeshkoff Date: Wed, 7 Feb 2018 19:14:42 +0300 Subject: [PATCH 010/171] Front-ported android-related fix from FB3 --- src/include/cross/android.arm64 | 3 +++ src/include/cross/android.arme | 3 +++ src/include/cross/android.x86 | 3 +++ src/include/cross/android.x86_64 | 3 +++ 4 files changed, 12 insertions(+) diff --git a/src/include/cross/android.arm64 b/src/include/cross/android.arm64 index 7dde0fa2fe..c3b6b0f9dc 100644 --- a/src/include/cross/android.arm64 +++ b/src/include/cross/android.arm64 @@ -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 header file. */ #define HAVE_GRP_H 1 diff --git a/src/include/cross/android.arme b/src/include/cross/android.arme index d2f13768f9..67970f7074 100644 --- a/src/include/cross/android.arme +++ b/src/include/cross/android.arme @@ -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 header file. */ #define HAVE_GRP_H 1 diff --git a/src/include/cross/android.x86 b/src/include/cross/android.x86 index b1e43b4293..faae1b973e 100644 --- a/src/include/cross/android.x86 +++ b/src/include/cross/android.x86 @@ -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 header file. */ #define HAVE_GRP_H 1 diff --git a/src/include/cross/android.x86_64 b/src/include/cross/android.x86_64 index d461a6e375..e4ebdfb628 100644 --- a/src/include/cross/android.x86_64 +++ b/src/include/cross/android.x86_64 @@ -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 header file. */ #define HAVE_GRP_H 1 From 854e1f5208bc8e4bee85b9cda81260d794faa650 Mon Sep 17 00:00:00 2001 From: AlexPeshkoff Date: Wed, 7 Feb 2018 20:16:57 +0300 Subject: [PATCH 011/171] Android build - work in progress --- builds/posix/Makefile.in | 14 +++++++++++++- builds/posix/make.android.arme | 25 ++++++++++++++++++------- builds/posix/make.defaults | 2 +- extern/decNumber/Makefile | 6 +++--- 4 files changed, 35 insertions(+), 12 deletions(-) diff --git a/builds/posix/Makefile.in b/builds/posix/Makefile.in index bb9b43bc8c..d681deadd6 100644 --- a/builds/posix/Makefile.in +++ b/builds/posix/Makefile.in @@ -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=$(addprefix ../extern/libtomcrypt/,$(call doObjects,$(TOM_Src))) tomcrypt: $(TOMCRYPT_LIB) @@ -264,6 +274,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 diff --git a/builds/posix/make.android.arme b/builds/posix/make.android.arme index 4547bb7590..41170ff098 100644 --- a/builds/posix/make.android.arme +++ b/builds/posix/make.android.arme @@ -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,7 @@ 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) LINK_LIBS = $(DroidLibs) SO_LINK_LIBS = $(DroidLibs) diff --git a/builds/posix/make.defaults b/builds/posix/make.defaults index d0a8bf46f3..cbec7a476e 100755 --- a/builds/posix/make.defaults +++ b/builds/posix/make.defaults @@ -133,7 +133,7 @@ CAS_OPTIONS=@CAS_OPTIONS@ # multiple-precision integer library MATHLIB=@MATHLIB@ -DECLIB=-ldecFloat +DECLIB=-ldecFloat$(CROSS) # crypt library CRYPTLIB=@CRYPTLIB@ diff --git a/extern/decNumber/Makefile b/extern/decNumber/Makefile index 7aa18ad805..253e34c180 100644 --- a/extern/decNumber/Makefile +++ b/extern/decNumber/Makefile @@ -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 From 3d412da26c91e0cb5c7666ca562d90a62d7b8030 Mon Sep 17 00:00:00 2001 From: firebirds <> Date: Thu, 8 Feb 2018 00:04:29 +0000 Subject: [PATCH 012/171] increment build number --- src/jrd/build_no.h | 12 ++++++------ src/misc/writeBuildNum.sh | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/jrd/build_no.h b/src/jrd/build_no.h index 323dbe3b9c..b9db31135c 100644 --- a/src/jrd/build_no.h +++ b/src/jrd/build_no.h @@ -3,16 +3,16 @@ *** DO NOT EDIT *** TO CHANGE ANY INFORMATION IN HERE PLEASE EDIT src/misc/writeBuildNum.sh - FORMAL BUILD NUMBER:880 + FORMAL BUILD NUMBER:884 */ -#define PRODUCT_VER_STRING "4.0.0.880" -#define FILE_VER_STRING "WI-T4.0.0.880" -#define LICENSE_VER_STRING "WI-T4.0.0.880" -#define FILE_VER_NUMBER 4, 0, 0, 880 +#define PRODUCT_VER_STRING "4.0.0.884" +#define FILE_VER_STRING "WI-T4.0.0.884" +#define LICENSE_VER_STRING "WI-T4.0.0.884" +#define FILE_VER_NUMBER 4, 0, 0, 884 #define FB_MAJOR_VER "4" #define FB_MINOR_VER "0" #define FB_REV_NO "0" -#define FB_BUILD_NO "880" +#define FB_BUILD_NO "884" #define FB_BUILD_TYPE "T" #define FB_BUILD_SUFFIX "Firebird 4.0 Alpha 1" diff --git a/src/misc/writeBuildNum.sh b/src/misc/writeBuildNum.sh index 910bd4330b..4f3e61cb6b 100755 --- a/src/misc/writeBuildNum.sh +++ b/src/misc/writeBuildNum.sh @@ -9,7 +9,7 @@ BuildType=T MajorVer=4 MinorVer=0 RevNo=0 -BuildNum=880 +BuildNum=884 NowAt=`pwd` cd `dirname $0` From 2c30ddfab002ee0bea113d39d6627adfc17ac4b2 Mon Sep 17 00:00:00 2001 From: AlexPeshkoff Date: Thu, 8 Feb 2018 13:21:02 +0300 Subject: [PATCH 013/171] Cleanup hand-made isinf() --- src/common/classes/FpeControl.h | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/common/classes/FpeControl.h b/src/common/classes/FpeControl.h index b3f0b66d4f..7f50fc4aa6 100644 --- a/src/common/classes/FpeControl.h +++ b/src/common/classes/FpeControl.h @@ -222,14 +222,6 @@ inline bool isinf(double x) { return (!_finite (x) && !isnan(x)); } -#else -#ifndef isinf -template -inline bool isinf(F x) -{ - return !isnan(x) && isnan(x - x); -} -#endif // isinf #endif // WIN_NT namespace Firebird { From 9bb4ce764b014386429211e8cfd077583f60cf32 Mon Sep 17 00:00:00 2001 From: AlexPeshkoff Date: Thu, 8 Feb 2018 20:21:48 +0300 Subject: [PATCH 014/171] Fixed cross build for android/arm 32-bit --- builds/posix/Makefile.in | 8 ++++---- builds/posix/make.android.arme | 1 + builds/posix/make.defaults | 1 + 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/builds/posix/Makefile.in b/builds/posix/Makefile.in index d681deadd6..8f724d3cf3 100644 --- a/builds/posix/Makefile.in +++ b/builds/posix/Makefile.in @@ -192,10 +192,10 @@ $(TOMMATH_LIB): $(TOM_Objs) .PHONY: tomcrypt TOMCRYPT_LIB=$(LIB)/libtomcrypt.a -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_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=$(addprefix ../extern/libtomcrypt/,$(call doObjects,$(TOM_Src))) +TOM_Objs=$(call doObjects,$(TOM_Src)) tomcrypt: $(TOMCRYPT_LIB) @@ -547,7 +547,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 $^ $@ diff --git a/builds/posix/make.android.arme b/builds/posix/make.android.arme index 41170ff098..e49c2c5e89 100644 --- a/builds/posix/make.android.arme +++ b/builds/posix/make.android.arme @@ -65,6 +65,7 @@ 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++ $(DECLIB) +UDR_SUPPORT_LIBS := -lgnustl_shared LINK_LIBS = $(DroidLibs) SO_LINK_LIBS = $(DroidLibs) diff --git a/builds/posix/make.defaults b/builds/posix/make.defaults index cbec7a476e..2a274bb337 100755 --- a/builds/posix/make.defaults +++ b/builds/posix/make.defaults @@ -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) From d4d40c367fef2aa87d3566d6e500a59a07d19379 Mon Sep 17 00:00:00 2001 From: AlexPeshkoff Date: Thu, 8 Feb 2018 20:23:26 +0300 Subject: [PATCH 015/171] Misc --- .gitignore | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 57aaf99cc6..a91a3e069b 100644 --- a/.gitignore +++ b/.gitignore @@ -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 From 7c8a46cf413f14d6a4b79b2ecb9586c1d41ea8a5 Mon Sep 17 00:00:00 2001 From: firebirds <> Date: Fri, 9 Feb 2018 00:04:17 +0000 Subject: [PATCH 016/171] increment build number --- src/jrd/build_no.h | 12 ++++++------ src/misc/writeBuildNum.sh | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/jrd/build_no.h b/src/jrd/build_no.h index b9db31135c..3707fe3119 100644 --- a/src/jrd/build_no.h +++ b/src/jrd/build_no.h @@ -3,16 +3,16 @@ *** DO NOT EDIT *** TO CHANGE ANY INFORMATION IN HERE PLEASE EDIT src/misc/writeBuildNum.sh - FORMAL BUILD NUMBER:884 + FORMAL BUILD NUMBER:887 */ -#define PRODUCT_VER_STRING "4.0.0.884" -#define FILE_VER_STRING "WI-T4.0.0.884" -#define LICENSE_VER_STRING "WI-T4.0.0.884" -#define FILE_VER_NUMBER 4, 0, 0, 884 +#define PRODUCT_VER_STRING "4.0.0.887" +#define FILE_VER_STRING "WI-T4.0.0.887" +#define LICENSE_VER_STRING "WI-T4.0.0.887" +#define FILE_VER_NUMBER 4, 0, 0, 887 #define FB_MAJOR_VER "4" #define FB_MINOR_VER "0" #define FB_REV_NO "0" -#define FB_BUILD_NO "884" +#define FB_BUILD_NO "887" #define FB_BUILD_TYPE "T" #define FB_BUILD_SUFFIX "Firebird 4.0 Alpha 1" diff --git a/src/misc/writeBuildNum.sh b/src/misc/writeBuildNum.sh index 4f3e61cb6b..fd75a4e794 100755 --- a/src/misc/writeBuildNum.sh +++ b/src/misc/writeBuildNum.sh @@ -9,7 +9,7 @@ BuildType=T MajorVer=4 MinorVer=0 RevNo=0 -BuildNum=884 +BuildNum=887 NowAt=`pwd` cd `dirname $0` From 90c072f3e4abc13449f2d85b50cf3ad455ff9402 Mon Sep 17 00:00:00 2001 From: Adriano dos Santos Fernandes Date: Fri, 9 Feb 2018 12:57:25 -0200 Subject: [PATCH 017/171] Fixed CORE-5743 - Query parsing failed. --- src/dsql/ExprNodes.cpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/dsql/ExprNodes.cpp b/src/dsql/ExprNodes.cpp index 406f9ca4ad..41b343521a 100644 --- a/src/dsql/ExprNodes.cpp +++ b/src/dsql/ExprNodes.cpp @@ -7342,7 +7342,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) From 35dff679f281e7494fcfcffc0250f2354cb1a4dd Mon Sep 17 00:00:00 2001 From: firebirds <> Date: Sat, 10 Feb 2018 00:04:09 +0000 Subject: [PATCH 018/171] increment build number --- src/jrd/build_no.h | 12 ++++++------ src/misc/writeBuildNum.sh | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/jrd/build_no.h b/src/jrd/build_no.h index 3707fe3119..e01c64bcae 100644 --- a/src/jrd/build_no.h +++ b/src/jrd/build_no.h @@ -3,16 +3,16 @@ *** DO NOT EDIT *** TO CHANGE ANY INFORMATION IN HERE PLEASE EDIT src/misc/writeBuildNum.sh - FORMAL BUILD NUMBER:887 + FORMAL BUILD NUMBER:888 */ -#define PRODUCT_VER_STRING "4.0.0.887" -#define FILE_VER_STRING "WI-T4.0.0.887" -#define LICENSE_VER_STRING "WI-T4.0.0.887" -#define FILE_VER_NUMBER 4, 0, 0, 887 +#define PRODUCT_VER_STRING "4.0.0.888" +#define FILE_VER_STRING "WI-T4.0.0.888" +#define LICENSE_VER_STRING "WI-T4.0.0.888" +#define FILE_VER_NUMBER 4, 0, 0, 888 #define FB_MAJOR_VER "4" #define FB_MINOR_VER "0" #define FB_REV_NO "0" -#define FB_BUILD_NO "887" +#define FB_BUILD_NO "888" #define FB_BUILD_TYPE "T" #define FB_BUILD_SUFFIX "Firebird 4.0 Alpha 1" diff --git a/src/misc/writeBuildNum.sh b/src/misc/writeBuildNum.sh index fd75a4e794..36ae30b44a 100755 --- a/src/misc/writeBuildNum.sh +++ b/src/misc/writeBuildNum.sh @@ -9,7 +9,7 @@ BuildType=T MajorVer=4 MinorVer=0 RevNo=0 -BuildNum=887 +BuildNum=888 NowAt=`pwd` cd `dirname $0` From 7d942c0607961260affae6424c107e3ef54019d2 Mon Sep 17 00:00:00 2001 From: Dmitry Yemanov Date: Mon, 12 Feb 2018 19:17:48 +0300 Subject: [PATCH 019/171] Avoid reading the page buffer after it was released --- src/jrd/btr.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/jrd/btr.cpp b/src/jrd/btr.cpp index 66cf44b88b..6a19d7457f 100644 --- a/src/jrd/btr.cpp +++ b/src/jrd/btr.cpp @@ -2046,6 +2046,9 @@ void BTR_selectivity(thread_db* tdbb, jrd_rel* relation, USHORT id, SelectivityL return; } + const bool descending = (root->irt_rpt[id].irt_flags & irt_descending); + const ULONG segments = root->irt_rpt[id].irt_keys; + window.win_flags = WIN_large_scan; window.win_scans = 1; btree_page* bucket = (btree_page*) CCH_HANDOFF(tdbb, &window, page, LCK_read, pag_index); @@ -2068,8 +2071,6 @@ void BTR_selectivity(thread_db* tdbb, jrd_rel* relation, USHORT id, SelectivityL key.key_length = 0; SSHORT l; bool firstNode = true; - const bool descending = (root->irt_rpt[id].irt_flags & irt_descending); - const ULONG segments = root->irt_rpt[id].irt_keys; // SSHORT count, stuff_count, pos, i; HalfStaticArray duplicatesList; From 1a6bb8c34272ee02450686c94bbc397a2c74d9a7 Mon Sep 17 00:00:00 2001 From: firebirds <> Date: Tue, 13 Feb 2018 00:04:15 +0000 Subject: [PATCH 020/171] increment build number --- src/jrd/build_no.h | 12 ++++++------ src/misc/writeBuildNum.sh | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/jrd/build_no.h b/src/jrd/build_no.h index e01c64bcae..c1d71942f9 100644 --- a/src/jrd/build_no.h +++ b/src/jrd/build_no.h @@ -3,16 +3,16 @@ *** DO NOT EDIT *** TO CHANGE ANY INFORMATION IN HERE PLEASE EDIT src/misc/writeBuildNum.sh - FORMAL BUILD NUMBER:888 + FORMAL BUILD NUMBER:889 */ -#define PRODUCT_VER_STRING "4.0.0.888" -#define FILE_VER_STRING "WI-T4.0.0.888" -#define LICENSE_VER_STRING "WI-T4.0.0.888" -#define FILE_VER_NUMBER 4, 0, 0, 888 +#define PRODUCT_VER_STRING "4.0.0.889" +#define FILE_VER_STRING "WI-T4.0.0.889" +#define LICENSE_VER_STRING "WI-T4.0.0.889" +#define FILE_VER_NUMBER 4, 0, 0, 889 #define FB_MAJOR_VER "4" #define FB_MINOR_VER "0" #define FB_REV_NO "0" -#define FB_BUILD_NO "888" +#define FB_BUILD_NO "889" #define FB_BUILD_TYPE "T" #define FB_BUILD_SUFFIX "Firebird 4.0 Alpha 1" diff --git a/src/misc/writeBuildNum.sh b/src/misc/writeBuildNum.sh index 36ae30b44a..f3b79a70e0 100755 --- a/src/misc/writeBuildNum.sh +++ b/src/misc/writeBuildNum.sh @@ -9,7 +9,7 @@ BuildType=T MajorVer=4 MinorVer=0 RevNo=0 -BuildNum=888 +BuildNum=889 NowAt=`pwd` cd `dirname $0` From 6c65ccfc8b95d16395d6972069437ccf31bf8095 Mon Sep 17 00:00:00 2001 From: "Maciej S. Szmigiero" Date: Thu, 15 Feb 2018 13:26:21 +0100 Subject: [PATCH 021/171] ARM needs MSG_NOSIGNAL in FB_SEND_FLAGS, too (#140) We need to add MSG_NOSIGNAL to FB_SEND_FLAGS for ARM, too, otherwise clients get killed with SIGPIPE when server connection breaks, just like commit 37bcd38740a187dad79a14a47241945fcd193b82 did for other platforms. Use this opportunity to also split out common build flags to COMMON_FLAGS variable, as the above commit did. Signed-off-by: Maciej S. Szmigiero --- builds/posix/prefix.linux_arm | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/builds/posix/prefix.linux_arm b/builds/posix/prefix.linux_arm index 9f844e2d77..6ac7745f8b 100644 --- a/builds/posix/prefix.linux_arm +++ b/builds/posix/prefix.linux_arm @@ -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 From e4a78ce3fe8002ff7bb98f4bd74a8c95b6457866 Mon Sep 17 00:00:00 2001 From: firebirds <> Date: Fri, 16 Feb 2018 00:04:26 +0000 Subject: [PATCH 022/171] increment build number --- src/jrd/build_no.h | 12 ++++++------ src/misc/writeBuildNum.sh | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/jrd/build_no.h b/src/jrd/build_no.h index c1d71942f9..8e0541d1c3 100644 --- a/src/jrd/build_no.h +++ b/src/jrd/build_no.h @@ -3,16 +3,16 @@ *** DO NOT EDIT *** TO CHANGE ANY INFORMATION IN HERE PLEASE EDIT src/misc/writeBuildNum.sh - FORMAL BUILD NUMBER:889 + FORMAL BUILD NUMBER:890 */ -#define PRODUCT_VER_STRING "4.0.0.889" -#define FILE_VER_STRING "WI-T4.0.0.889" -#define LICENSE_VER_STRING "WI-T4.0.0.889" -#define FILE_VER_NUMBER 4, 0, 0, 889 +#define PRODUCT_VER_STRING "4.0.0.890" +#define FILE_VER_STRING "WI-T4.0.0.890" +#define LICENSE_VER_STRING "WI-T4.0.0.890" +#define FILE_VER_NUMBER 4, 0, 0, 890 #define FB_MAJOR_VER "4" #define FB_MINOR_VER "0" #define FB_REV_NO "0" -#define FB_BUILD_NO "889" +#define FB_BUILD_NO "890" #define FB_BUILD_TYPE "T" #define FB_BUILD_SUFFIX "Firebird 4.0 Alpha 1" diff --git a/src/misc/writeBuildNum.sh b/src/misc/writeBuildNum.sh index f3b79a70e0..08120fe167 100755 --- a/src/misc/writeBuildNum.sh +++ b/src/misc/writeBuildNum.sh @@ -9,7 +9,7 @@ BuildType=T MajorVer=4 MinorVer=0 RevNo=0 -BuildNum=889 +BuildNum=890 NowAt=`pwd` cd `dirname $0` From 5e6f90fbedc7c3865850e356ca3045a359a2a4af Mon Sep 17 00:00:00 2001 From: AlexPeshkoff Date: Fri, 16 Feb 2018 13:09:04 +0300 Subject: [PATCH 023/171] deprecated UDF cleanup --- configure.ac | 6 ------ 1 file changed, 6 deletions(-) diff --git a/configure.ac b/configure.ac index 9c040c2a0b..ee114415b6 100644 --- a/configure.ac +++ b/configure.ac @@ -1211,7 +1211,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 +1237,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 From 27034707490babf9c515387df88c3d294b8a95a8 Mon Sep 17 00:00:00 2001 From: AlexPeshkoff Date: Fri, 16 Feb 2018 13:13:20 +0300 Subject: [PATCH 024/171] Added check for presence of ICU when installing --- builds/install/posix-common/posixLibrary.sh.in | 2 ++ 1 file changed, 2 insertions(+) diff --git a/builds/install/posix-common/posixLibrary.sh.in b/builds/install/posix-common/posixLibrary.sh.in index c28b3849bc..19ba601f8f 100644 --- a/builds/install/posix-common/posixLibrary.sh.in +++ b/builds/install/posix-common/posixLibrary.sh.in @@ -228,6 +228,8 @@ checkLibraries() { then checkLibrary tomcrypt fi + + checkLibrary icu } From 54607bbce47a97894182936550fec312f2f6b2d7 Mon Sep 17 00:00:00 2001 From: AlexPeshkoff Date: Wed, 6 Dec 2017 20:33:42 +0300 Subject: [PATCH 025/171] Build gbak using OO API --- builds/posix/make.rules | 7 +- src/burp/OdsDetection.epp | 11 +- src/burp/backup.epp | 323 ++++++----------- src/burp/burp.cpp | 229 ++++++------ src/burp/burp.h | 166 ++++++--- src/burp/burp_proto.h | 6 +- src/burp/misc.cpp | 6 +- src/burp/misc_proto.h | 2 +- src/burp/restore.epp | 401 +++++++++++---------- src/common/classes/BlobWrapper.cpp | 263 ++++++++++++++ src/common/classes/BlobWrapper.h | 95 +++++ src/common/status.h | 116 ++++++ src/dsql/DsqlBatch.cpp | 88 ++--- src/dsql/DsqlBatch.h | 10 +- src/gpre/obj_cxx.cpp | 14 +- src/include/firebird/FirebirdInterface.idl | 6 +- src/include/firebird/IdlFbInterfaces.h | 24 +- src/jrd/EngineInterface.h | 6 +- src/jrd/exe.cpp | 6 +- src/jrd/exe_proto.h | 4 +- src/jrd/jrd.cpp | 12 +- src/jrd/jrd_proto.h | 6 +- src/jrd/status.h | 83 +---- src/msgs/messages2.sql | 2 +- src/remote/client/interface.cpp | 16 +- src/yvalve/YObjects.h | 6 +- src/yvalve/why.cpp | 6 +- 27 files changed, 1143 insertions(+), 771 deletions(-) create mode 100644 src/common/classes/BlobWrapper.cpp create mode 100644 src/common/classes/BlobWrapper.h create mode 100644 src/common/status.h diff --git a/builds/posix/make.rules b/builds/posix/make.rules index 6745d0f0ea..5fb7f97a54 100644 --- a/builds/posix/make.rules +++ b/builds/posix/make.rules @@ -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 $<) $@ diff --git a/src/burp/OdsDetection.epp b/src/burp/OdsDetection.epp index f0a66545c4..cbe4e2032a 100644 --- a/src/burp/OdsDetection.epp +++ b/src/burp/OdsDetection.epp @@ -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) diff --git a/src/burp/backup.epp b/src/burp/backup.epp index 3d1f68d2e6..246110a2d0 100644 --- a/src/burp/backup.epp +++ b/src/burp/backup.epp @@ -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 { @@ -173,7 +177,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 +188,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,7 +215,7 @@ 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(); @@ -229,23 +233,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; } @@ -827,125 +831,32 @@ 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); + Firebird::string nm, sql; + nm.assign(name, name_len); + sql = "select first(1) gen_id(" + nm + ", 0) from rdb$database"; + + BurpGlobals* tdgbl = BurpGlobals::getSpecific(); + 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 +1018,15 @@ 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 @@ -1244,31 +1154,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 +1252,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 +1268,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 +1289,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 +1339,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 +1348,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 +1381,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,9 +1404,6 @@ 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, @@ -1509,6 +1412,7 @@ void put_data(burp_rel* relation) // However, SSHORT is the limit for request_length in isc_compile_request. SSHORT field_count = 1; + burp_fld* field; for (field = relation->rel_fields; field; field = field->fld_next) { if (!(field->fld_flags & FLD_computed)) @@ -1728,10 +1632,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 +1646,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 +1672,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) @@ -1825,8 +1732,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 +2163,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 +2176,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 +2222,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 +2233,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 +2268,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 +2328,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 +2426,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 +2460,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 +2560,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 +2590,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 +2618,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 +2696,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 +2760,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 +2795,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 +2837,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 +3091,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 +3200,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 +3431,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 +3498,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 +3688,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 +3724,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 +3768,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 +3898,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 +3934,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 +3975,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 +4044,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 +4127,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 +4244,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 +4283,7 @@ void write_types() * each type. * **************************************/ - isc_req_handle req_handle1 = 0; + Firebird::IRequest* req_handle1 = nullptr; BurpGlobals* tdgbl = BurpGlobals::getSpecific(); @@ -4414,7 +4323,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(); diff --git a/src/burp/burp.cpp b/src/burp/burp.cpp index 80b64161c8..39a0d475e3 100644 --- a/src/burp/burp.cpp +++ b/src/burp/burp.cpp @@ -65,6 +65,7 @@ #include #endif #include "../common/utils_proto.h" +#include "../common/status.h" #ifdef HAVE_UNISTD_H #include @@ -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(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(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, + svc_handle->query(&status, 0, NULL, sizeof(sendbuf), sendbuf, - sizeof(respbuf), respbuf)) + 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; } @@ -1285,10 +1288,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 @@ -1319,9 +1320,10 @@ int gbak(Firebird::UtilSvc* uSvc) { close_out_transaction(action, &tdgbl->tr_handle); close_out_transaction(action, &tdgbl->global_trans); - if (isc_detach_database(tdgbl->status_vector, &tdgbl->db_handle)) + tdgbl->db_handle->detach(&tdgbl->status_vector); + if (tdgbl->status_vector->getState() & Firebird::IStatus::STATE_ERRORS) { - BURP_print_status(true, tdgbl->status_vector); + BURP_print_status(true, &tdgbl->status_vector); } } @@ -1428,7 +1430,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 +1518,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(arg1), arg2); + burp_output(false, format, text); } - void BURP_print(bool err, USHORT number, const SafeArg& arg) { /************************************** @@ -1577,7 +1577,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 +1592,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 +1622,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 +1635,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 +1712,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 +1727,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,38 +1813,37 @@ static gbak_action open_files(const TEXT* file1, * **************************************/ BurpGlobals* tdgbl = BurpGlobals::getSpecific(); - ISC_STATUS_ARRAY temp_status; - ISC_STATUS* status_vector = temp_status; + FbLocalStatus temp_status; + Firebird::CheckStatusWrapper* status_vector = &temp_status; // 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(dpb.getBuffer()))) + tdgbl->db_handle = Firebird::DispatcherPtr()->attachDatabase(status_vector, file1, + dpb.getBufferLength(), dpb.getBuffer()); + if (!status_vector->hasData()) { 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)) { + tdgbl->db_handle->detach(status_vector); + if (status_vector->hasData()) BURP_print_status(true, status_vector); - } 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 } 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); return QUIT; @@ -1965,10 +1967,9 @@ 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->hasData()) + BURP_print_status(true, status_vector); } return flag; @@ -2139,49 +2140,45 @@ 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(dpb.getBuffer()))) + if (sw_replace == IN_SW_BURP_C || sw_replace == IN_SW_BURP_R) { - if (sw_replace == IN_SW_BURP_C) + tdgbl->db_handle = Firebird::DispatcherPtr()->attachDatabase(status_vector, *file2, + dpb.getBufferLength(), dpb.getBuffer()); + if (status_vector->isEmpty()) { - 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) + if (sw_replace == IN_SW_BURP_C) { - ISC_STATUS_ARRAY status_vector2; - if (isc_detach_database(status_vector2, &tdgbl->db_handle)) { - BURP_print_status(false, status_vector2); - } + tdgbl->db_handle->detach(status_vector); + if (status_vector->hasData()) + 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 + { + tdgbl->db_handle->dropDatabase(status_vector); + if (status_vector->hasData()) + { + Firebird::FbLocalStatus status2; + tdgbl->db_handle->detach(&status2); + if (!status2.isSuccess()) + BURP_print_status(true, &status2); - // 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 + // msg 233 Cannot drop database %s, might be in use + } } } - } - 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 + 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. + 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 +2455,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 +2487,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; } diff --git a/src/burp/burp.h b/src/burp/burp.h index a1dbf97d9a..270c7a5554 100644 --- a/src/burp/burp.h +++ b/src/burp/burp.h @@ -31,6 +31,8 @@ #include #include "../jrd/ibase.h" +#include "firebird/Interface.h" +#include "firebird/Message.h" #include "../common/dsc.h" #include "../burp/misc_proto.h" #include "../yvalve/gds_proto.h" @@ -40,6 +42,8 @@ #include "../common/classes/fb_pair.h" #include "../common/classes/MetaName.h" #include "../../jrd/SimilarToMatcher.h" +#include "../common/status.h" +#include "../common/classes/ImplementHelper.h" #ifdef HAVE_UNISTD_H #include @@ -928,7 +932,6 @@ public: // this is VERY dirty hack to keep current behaviour memset (&gbl_database_file_name, 0, &veryEnd - reinterpret_cast(&gbl_database_file_name)); - memset(status_vector, 0, sizeof(status_vector)); gbl_stat_flags = 0; gbl_stat_header = false; @@ -1001,11 +1004,10 @@ 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; + 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 +1017,59 @@ 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 +1091,9 @@ public: char veryEnd; //starting after this members must be initialized in constructor explicitly + Firebird::FbLocalStatus status_vector; + Firebird::ThrowLocalStatus throwStatus; + Firebird::Array > > defaultCollations; Firebird::UtilSvc* uSvc; @@ -1162,4 +1167,51 @@ enum burp_messages_vals { // BLOB buffer typedef Firebird::HalfStaticArray 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 + void singleSelect(Firebird::ITransaction* trans, M* msg) + { + stmt->execute(&tdgbl->throwStatus, tdgbl->tr_handle, nullptr, nullptr, msg->getMetadata(), msg->getData()); + } + + template + 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 +{ +public: + OutputVersion(const char* printFormat) + : format(printFormat) + { } + + void callback(Firebird::CheckStatusWrapper* status, const char* text); + +private: + const char* format; +}; + + + #endif // BURP_BURP_H diff --git a/src/burp/burp_proto.h b/src/burp/burp_proto.h index b8487b86ae..e9302a365d 100644 --- a/src/burp/burp_proto.h +++ b/src/burp/burp_proto.h @@ -34,7 +34,7 @@ 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_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 +42,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); diff --git a/src/burp/misc.cpp b/src/burp/misc.cpp index a25b8e1262..b4fa133edc 100644 --- a/src/burp/misc.cpp +++ b/src/burp/misc.cpp @@ -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; } } diff --git a/src/burp/misc_proto.h b/src/burp/misc_proto.h index c015cb4516..971309e8e1 100644 --- a/src/burp/misc_proto.h +++ b/src/burp/misc_proto.h @@ -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); diff --git a/src/burp/restore.epp b/src/burp/restore.epp index 99609475a5..5af331f183 100644 --- a/src/burp/restore.epp +++ b/src/burp/restore.epp @@ -49,7 +49,7 @@ #include "../common/prett_proto.h" #endif #include "../common/classes/ClumpletWriter.h" -#include "../common/classes/UserBlob.h" +#include "../common/classes/BlobWrapper.h" #include "../common/classes/SafeArg.h" #include "../common/utils_proto.h" #include "memory_routines.h" @@ -57,6 +57,7 @@ #include "../auth/trusted/AuthSspi.h" using MsgFormat::SafeArg; +using Firebird::FbLocalStatus; // For service APIs the follow DB handle is a value stored @@ -67,8 +68,11 @@ using MsgFormat::SafeArg; 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) namespace // unnamed, private @@ -267,7 +271,9 @@ int RESTORE_restore (const TEXT* file_name, const TEXT* database_name) * Recreate a database from a backup. * **************************************/ - isc_req_handle req_handle1 = 0, req_handle3 = 0, req_handle5 = 0; + Firebird::IRequest* req_handle1 = nullptr; + Firebird::IRequest* req_handle3 = nullptr; + Firebird::IRequest* req_handle5 = nullptr; BASED_ON RDB$INDICES.RDB$INDEX_NAME index_name; BurpGlobals* tdgbl = BurpGlobals::getSpecific(); @@ -304,7 +310,7 @@ int RESTORE_restore (const TEXT* file_name, const TEXT* database_name) case isc_sort_mem_err: case isc_no_dup: strcpy(index_name, (TEXT *)tdgbl->status_vector[3]); - BURP_print_status(false, tdgbl->status_vector); + BURP_print_status(false, &tdgbl->status_vector); FOR (REQUEST_HANDLE req_handle3) IDX IN RDB$INDICES WITH IDX.RDB$INDEX_NAME EQ index_name @@ -353,7 +359,7 @@ int RESTORE_restore (const TEXT* file_name, const TEXT* database_name) // Always try to activate deferred indices - it helps for some broken backups, // and in normal cases doesn't take much time to look for such indices. AP-2008. EXEC SQL SET TRANSACTION ISOLATION LEVEL READ COMMITTED NO_AUTO_UNDO; - if (gds_status[1]) + if (gds_status->hasData()) EXEC SQL SET TRANSACTION; // Activate first indexes that are not foreign keys @@ -397,7 +403,7 @@ int RESTORE_restore (const TEXT* file_name, const TEXT* database_name) END_ERROR; EXEC SQL SET TRANSACTION ISOLATION LEVEL READ COMMITTED NO_AUTO_UNDO; - if (gds_status[1]) + if (gds_status->hasData()) EXEC SQL SET TRANSACTION; // Only activate Foreign keys that have been marked for deferred @@ -423,9 +429,8 @@ int RESTORE_restore (const TEXT* file_name, const TEXT* database_name) // activating and creating deferred index %s bool fError = false; - isc_tr_handle activateIndexTran = 0; - ISC_STATUS_ARRAY local_status_vector; - ISC_STATUS* local_status = local_status_vector; + Firebird::ITransaction* activateIndexTran = nullptr; + FbLocalStatus local_status_vector; START_TRANSACTION activateIndexTran; FOR (TRANSACTION_HANDLE activateIndexTran REQUEST_HANDLE req_handle5) @@ -436,7 +441,7 @@ int RESTORE_restore (const TEXT* file_name, const TEXT* database_name) END_FOR; ON_ERROR fError = true; - memcpy(local_status, isc_status, sizeof (ISC_STATUS_ARRAY)); + fb_utils::copyStatus(&local_status_vector, isc_status); END_ERROR; MISC_release_request_silent(req_handle5); @@ -445,7 +450,7 @@ int RESTORE_restore (const TEXT* file_name, const TEXT* database_name) COMMIT activateIndexTran; ON_ERROR fError = true; - memcpy(local_status, isc_status, sizeof (ISC_STATUS_ARRAY)); + fb_utils::copyStatus(&local_status_vector, isc_status); END_ERROR; } if (fError) @@ -455,7 +460,7 @@ int RESTORE_restore (const TEXT* file_name, const TEXT* database_name) general_on_error (); END_ERROR; BURP_print (false, 173, index_name); - BURP_print_status(false, local_status); + BURP_print_status(false, &local_status_vector); tdgbl->flag_on_line = false; } END_FOR; @@ -474,17 +479,17 @@ int RESTORE_restore (const TEXT* file_name, const TEXT* database_name) BURP_verbose (68); // msg 68 committing meta data EXEC SQL COMMIT TRANSACTION tdgbl->global_trans; - if (gds_status[1]) + if (gds_status->hasData()) general_on_error (); // Check to see if there is a warning - if (gds_status[0] == isc_arg_gds && gds_status[1] == 0 && gds_status[2] != isc_arg_end) + if (gds_status->getState() && Firebird::IStatus::STATE_WARNINGS) { BURP_print_warning(gds_status); } } EXEC SQL SET TRANSACTION ISOLATION LEVEL READ COMMITTED NO_AUTO_UNDO; - if (gds_status[1]) + if (gds_status->hasData()) EXEC SQL SET TRANSACTION; // AB: Recalculate RDB$DBKEY_LENGTH for VIEWS @@ -532,7 +537,7 @@ int RESTORE_restore (const TEXT* file_name, const TEXT* database_name) END_ERROR; // Check to see if there is a warning - if (gds_status[0] == isc_arg_gds && gds_status[1] == 0 && gds_status[2] != isc_arg_end) + if (gds_status->getState() && Firebird::IStatus::STATE_WARNINGS) { BURP_print_warning(gds_status); } @@ -568,13 +573,12 @@ int RESTORE_restore (const TEXT* file_name, const TEXT* database_name) // set forced writes to the value which was in the header dpb.insertByte(isc_dpb_force_write, tdgbl->hdr_forced_writes ? 1 : 0); - FB_API_HANDLE db_handle = 0; - if (isc_attach_database(tdgbl->status_vector, 0, database_name, &db_handle, - dpb.getBufferLength(), reinterpret_cast(dpb.getBuffer()))) - { + Firebird::IAttachment* db_handle = Firebird::DispatcherPtr()->attachDatabase(&tdgbl->status_vector, database_name, + dpb.getBufferLength(), dpb.getBuffer()); + if (tdgbl->status_vector->hasData()) general_on_error(); - } - if (isc_detach_database (tdgbl->status_vector, &db_handle)) + db_handle->detach(&tdgbl->status_vector); + if (tdgbl->status_vector->hasData()) general_on_error(); if (!tdgbl->flag_on_line) @@ -597,12 +601,12 @@ int RESTORE_restore (const TEXT* file_name, const TEXT* database_name) dpb.insertByte(isc_dpb_set_db_readonly, 1); - if (isc_attach_database(tdgbl->status_vector, 0, database_name, &db_handle, - dpb.getBufferLength(), reinterpret_cast(dpb.getBuffer()))) - { + db_handle = Firebird::DispatcherPtr()->attachDatabase(&tdgbl->status_vector, database_name, + dpb.getBufferLength(), dpb.getBuffer()); + if (tdgbl->status_vector->hasData()) general_on_error(); - } - if (isc_detach_database (tdgbl->status_vector, &db_handle)) + db_handle->detach(&tdgbl->status_vector); + if (tdgbl->status_vector->hasData()) general_on_error(); } @@ -652,7 +656,7 @@ void add_files(BurpGlobals* tdgbl, const char* file_name) * addresses & commit this much. * **************************************/ - isc_req_handle req_handle1 = 0; + Firebird::IRequest* req_handle1 = nullptr; // store the RDB$FILES records @@ -703,7 +707,7 @@ void add_files(BurpGlobals* tdgbl, const char* file_name) ON_ERROR BURP_print (false, 174); // msg 174 cannot commit files - BURP_print_status (false, tdgbl->status_vector); + BURP_print_status (false, &tdgbl->status_vector); ROLLBACK; ON_ERROR general_on_error (); @@ -711,7 +715,7 @@ void add_files(BurpGlobals* tdgbl, const char* file_name) END_ERROR; EXEC SQL SET TRANSACTION NO_AUTO_UNDO; - if (gds_status[1]) + if (gds_status->hasData()) EXEC SQL SET TRANSACTION; } } @@ -844,7 +848,7 @@ void create_database(BurpGlobals* tdgbl, const TEXT* file_name) } if (record != rec_database) - BURP_error_redirect (NULL, 32); + BURP_error_redirect(NULL, 32); // msg 32 Expected database description record if (tdgbl->gbl_sw_page_size) @@ -936,7 +940,7 @@ void create_database(BurpGlobals* tdgbl, const TEXT* file_name) dpb.insertByte(isc_dpb_no_db_triggers, 1); - ISC_STATUS_ARRAY status_vector; + FbLocalStatus status_vector; if (tdgbl->gbl_sw_fix_fss_metadata) { @@ -944,11 +948,11 @@ void create_database(BurpGlobals* tdgbl, const TEXT* file_name) fb_strlen(tdgbl->gbl_sw_fix_fss_metadata)); } - if (isc_create_database(status_vector, 0, file_name, &DB, - dpb.getBufferLength(), reinterpret_cast(dpb.getBuffer()), - 0)) + DB = Firebird::DispatcherPtr()->createDatabase(&status_vector, file_name, + dpb.getBufferLength(), dpb.getBuffer()); + if (status_vector->hasData()) { - BURP_error_redirect (status_vector, 33, SafeArg() << file_name); + BURP_error_redirect(&status_vector, 33, SafeArg() << file_name); // msg 33 failed to create database %s } @@ -956,7 +960,8 @@ void create_database(BurpGlobals* tdgbl, const TEXT* file_name) { BURP_print(false, 139, file_name); // msg 139 Version(s) for database "%s" - isc_version(&DB, BURP_output_version, (void*)"\t%s\n"); + OutputVersion outputVersion("\t%s\n"); + Firebird::UtilInterfacePtr()->getFbVersion(&status_vector, DB, &outputVersion); } BURP_verbose (74, SafeArg() << file_name << page_size); @@ -1010,7 +1015,7 @@ void decompress(BurpGlobals* tdgbl, UCHAR* buffer, USHORT length) } if (p > end) { - BURP_error_redirect (NULL, 34); // msg 34 RESTORE: decompression length error + BURP_error_redirect(NULL, 34); // msg 34 RESTORE: decompression length error } } @@ -1080,7 +1085,7 @@ burp_rel* find_relation(BurpGlobals* tdgbl, const TEXT* name) } } - BURP_error_redirect (NULL, 35, SafeArg() << name); + BURP_error_redirect(NULL, 35, SafeArg() << name); // msg 35 can't find relation %s return NULL; @@ -1109,9 +1114,9 @@ void fix_security_class_name(BurpGlobals* tdgbl, TEXT* sec_class, bool is_field) if (tdgbl->runtimeODS < DB_VERSION_DDL11_2) return; - ISC_STATUS_ARRAY status_vector; + FbLocalStatus status_vector; - isc_req_handle& handle = tdgbl->handles_fix_security_class_name_req_handle1; + Firebird::IRequest*& handle = tdgbl->handles_fix_security_class_name_req_handle1; if (!handle) { @@ -1153,25 +1158,27 @@ void fix_security_class_name(BurpGlobals* tdgbl, TEXT* sec_class, bool is_field) const USHORT blr_length = blr - blr_buffer; fb_assert(blr_length <= sizeof(blr_buffer)); - if (isc_compile_request(status_vector, &DB, &handle, - blr_length, (const SCHAR*) blr_buffer)) + handle = DB->compileRequest(&status_vector, blr_length, blr_buffer); + if (status_vector->hasData()) { - BURP_error_redirect(status_vector, 316); + BURP_error_redirect(&status_vector, 316); // msg 316 Failed while fixing the security class name } } - if (isc_start_request(status_vector, &handle, &gds_trans, 0)) + handle->start(&status_vector, gds_trans, 0); + if (status_vector->hasData()) { - BURP_error_redirect(status_vector, 316); + BURP_error_redirect(&status_vector, 316); // msg 316 Failed while fixing the security class name } SINT64 id = 0; - if (isc_receive(status_vector, &handle, 0, sizeof(SINT64), &id, 0)) + handle->receive(&status_vector, 0, 0, sizeof(SINT64), &id); + if (status_vector->hasData()) { - BURP_error_redirect(status_vector, 316); + BURP_error_redirect(&status_vector, 316); // msg 316 Failed while fixing the security class name } @@ -1194,7 +1201,7 @@ void general_on_error() **************************************/ BurpGlobals* tdgbl = BurpGlobals::getSpecific(); - if (isc_status[1] == isc_malformed_string) + if (isc_status->getErrors()[1] == isc_malformed_string) { Firebird::Arg::StatusVector oldVector(isc_status); Firebird::Arg::Gds newVector(isc_gbak_invalid_metadata); @@ -1239,20 +1246,20 @@ bool get_acl(BurpGlobals* tdgbl, const TEXT* owner_nm, ISC_QUAD* blob_id, ISC_QU // Open the blob and get it's vital statistics - ISC_STATUS_ARRAY status_vector; - UserBlob blob(status_vector); + FbLocalStatus status_vector; + BlobWrapper blob(&status_vector); if (! blob.open(DB, gds_trans, *blob_id)) { // msg 24 isc_open_blob failed - BURP_error_redirect (status_vector, 24); + BURP_error_redirect(&status_vector, 24); } UCHAR blob_info[32]; if (!blob.getInfo(sizeof(blr_items), blr_items, sizeof(blob_info), blob_info)) { // msg 20 isc_blob_info failed - BURP_error_redirect (status_vector, 20); + BURP_error_redirect(&status_vector, 20); } ULONG length = 0; @@ -1296,7 +1303,7 @@ bool get_acl(BurpGlobals* tdgbl, const TEXT* owner_nm, ISC_QUAD* blob_id, ISC_QU // CVC: do you return, without closing the blob, dear function??? if (!blob.close()) { - BURP_error_redirect (status_vector, 23); + BURP_error_redirect(&status_vector, 23); // msg 23 isc_close_blob failed } return false; @@ -1307,7 +1314,7 @@ bool get_acl(BurpGlobals* tdgbl, const TEXT* owner_nm, ISC_QUAD* blob_id, ISC_QU { if (!blob.close()) { - BURP_error_redirect (status_vector, 23); + BURP_error_redirect(&status_vector, 23); // msg 23 isc_close_blob failed } return false; @@ -1329,7 +1336,7 @@ bool get_acl(BurpGlobals* tdgbl, const TEXT* owner_nm, ISC_QUAD* blob_id, ISC_QU if (!blob.getData(length, buffer, return_length)) { // msg 22 gds_$get_segment failed - BURP_error_redirect (status_vector, 22); + BURP_error_redirect(&status_vector, 22); } // protect ourselves length = return_length; @@ -1337,7 +1344,7 @@ bool get_acl(BurpGlobals* tdgbl, const TEXT* owner_nm, ISC_QUAD* blob_id, ISC_QU if (!blob.close()) { // msg 23 isc_close_blob failed - BURP_error_redirect (status_vector, 23); + BURP_error_redirect(&status_vector, 23); } const UCHAR* from = buffer + 3; // skip ACL_version, ACL_id_list, and id_person @@ -1378,19 +1385,19 @@ bool get_acl(BurpGlobals* tdgbl, const TEXT* owner_nm, ISC_QUAD* blob_id, ISC_QU if (!blob.create(DB, gds_trans, *new_blob_id)) { // msg 37 isc_create_blob failed - BURP_error_redirect (status_vector, 37); + BURP_error_redirect(&status_vector, 37); } if (!blob.putData(new_len, new_buffer)) { // msg 38 isc_put_segment failed - BURP_error_redirect (status_vector, 38); + BURP_error_redirect(&status_vector, 38); } if (!blob.close()) { // msg 23 isc_close_blob failed - BURP_error_redirect (status_vector, 23); + BURP_error_redirect(&status_vector, 23); } return true; @@ -1410,7 +1417,7 @@ void get_array(BurpGlobals* tdgbl, burp_rel* relation, UCHAR* record_buffer) * **************************************/ burp_fld* field = NULL; - ISC_STATUS_ARRAY status_vector; + FbLocalStatus status_vector; USHORT count, field_number, field_length = 0; UCHAR* buffer = NULL; UCHAR* p = NULL; @@ -1442,7 +1449,7 @@ void get_array(BurpGlobals* tdgbl, burp_rel* relation, UCHAR* record_buffer) break; } if (!field) { - BURP_error_redirect (NULL, 36); // msg 36 Can't find field for blob + BURP_error_redirect(NULL, 36); // msg 36 Can't find field for blob } field_length = field->fld_length; @@ -1727,7 +1734,7 @@ void get_array(BurpGlobals* tdgbl, burp_rel* relation, UCHAR* record_buffer) if (get_attribute(&attribute, tdgbl) != att_xdr_array) { // msg 55 Expected XDR record length - BURP_error_redirect (NULL, 55); + BURP_error_redirect(NULL, 55); } else { @@ -1755,15 +1762,14 @@ void get_array(BurpGlobals* tdgbl, burp_rel* relation, UCHAR* record_buffer) CAN_slice (&xdr_buffer, &xdr_slice, FALSE, /*blr_length,*/ blr_buffer); } - if (isc_put_slice(status_vector, &DB, &gds_trans, - blob_id, blr_length, reinterpret_cast(blr_buffer), - 0, // param length for subset of an array handling - NULL, // param for subset of an array handling - elements_written * field->fld_length, buffer + data_at)) + DB->putSlice(&status_vector, gds_trans, blob_id, blr_length, blr_buffer, + 0, NULL, // parameters for subset of an array handling + elements_written * field->fld_length, buffer + data_at); + if (status_vector->hasData()) { BURP_print (false, 81, field->fld_name); // msg 81 error accessing blob field %s -- continuing - BURP_print_status (true, status_vector); + BURP_print_status (true, &status_vector); #ifdef DEBUG PRETTY_print_sdl (blr_buffer, NULL, NULL, 0); #endif @@ -1853,7 +1859,7 @@ void get_array(BurpGlobals* tdgbl, burp_rel* relation, UCHAR* record_buffer) { if (get_attribute(&attribute, tdgbl) != att_xdr_array) { - BURP_error_redirect (NULL, 55); + BURP_error_redirect(NULL, 55); // msg 55 Expected XDR record length } else @@ -1882,16 +1888,14 @@ void get_array(BurpGlobals* tdgbl, burp_rel* relation, UCHAR* record_buffer) CAN_slice (&xdr_buffer, &xdr_slice, FALSE, /*blr_length,*/ blr_buffer); - if (isc_put_slice(status_vector, &DB, &gds_trans, - blob_id, blr_length, - reinterpret_cast(blr_buffer), - 0, // param length for subset of an array handling - NULL, // param for subset of an array handling - return_length, buffer)) + DB->putSlice(&status_vector, gds_trans, blob_id, blr_length, blr_buffer, + 0, NULL, // parameters for subset of an array handling + return_length, buffer); + if (status_vector->hasData()) { 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 @@ -1965,20 +1969,20 @@ void get_blob(BurpGlobals* tdgbl, const burp_fld* fields, UCHAR* record_buffer) if (!field) { - BURP_error_redirect (NULL, 36); + BURP_error_redirect(NULL, 36); // msg 36 Can't find field for blob } // Create new blob ISC_QUAD* blob_id = (ISC_QUAD*) ((UCHAR*) record_buffer + field->fld_offset); - ISC_STATUS_ARRAY status_vector; - UserBlob blob(status_vector); + FbLocalStatus status_vector; + BlobWrapper blob(&status_vector); const UCHAR blob_desc[] = {isc_bpb_version1, isc_bpb_type, 1, blob_type}; if (!blob.create(DB, gds_trans, *blob_id, sizeof(blob_desc), blob_desc)) { - BURP_error_redirect (status_vector, 37); + BURP_error_redirect(&status_vector, 37); // msg 37 isc_create_blob failed } @@ -1998,13 +2002,13 @@ void get_blob(BurpGlobals* tdgbl, const burp_fld* fields, UCHAR* record_buffer) } if (!blob.putSegment(length, buffer)) { - BURP_error_redirect (status_vector, 38); + BURP_error_redirect(&status_vector, 38); // msg 38 isc_put_segment failed } } if (!blob.close()) - BURP_error_redirect (status_vector, 23); + BURP_error_redirect(&status_vector, 23); // msg 23 isc_close_blob failed } @@ -2027,17 +2031,13 @@ void get_blr_blob(BurpGlobals* tdgbl, ISC_QUAD& blob_id, bool glb_trans) // Create new blob - isc_tr_handle local_trans; - if (glb_trans && tdgbl->global_trans) - local_trans = tdgbl->global_trans; - else - local_trans = gds_trans; + Firebird::ITransaction* local_trans = (glb_trans && tdgbl->global_trans) ? tdgbl->global_trans : gds_trans; - ISC_STATUS_ARRAY status_vector; - UserBlob blob(status_vector); + FbLocalStatus status_vector; + BlobWrapper blob(&status_vector); if (!blob.create(DB, local_trans, blob_id)) { - BURP_error_redirect (status_vector, 37); + BURP_error_redirect(&status_vector, 37); // msg 37 isc_create_blob failed } @@ -2057,12 +2057,12 @@ void get_blr_blob(BurpGlobals* tdgbl, ISC_QUAD& blob_id, bool glb_trans) if (!blob.putData(length, buffer)) { - BURP_error_redirect (status_vector, 38); + BURP_error_redirect(&status_vector, 38); // msg 38 isc_put_segment failed } if (!blob.close()) - BURP_error_redirect (status_vector, 23); + BURP_error_redirect(&status_vector, 23); // msg 23 isc_close_blob failed } @@ -2710,7 +2710,7 @@ rec_type get_data(BurpGlobals* tdgbl, burp_rel* relation, bool skip_relation) * Write data records for a relation. * **************************************/ - isc_req_handle req_handle = 0; + Firebird::IRequest* req_handle = 0; BASED_ON RDB$INDICES.RDB$INDEX_NAME index_name; // If we're only doing meta-data, ignore data records @@ -2908,18 +2908,18 @@ rec_type get_data(BurpGlobals* tdgbl, burp_rel* relation, bool skip_relation) fb_print_blr(blr_buffer, blr_length, NULL, NULL, 0); #endif - FB_API_HANDLE request = 0; - ISC_STATUS_ARRAY status_vector; + Firebird::IRequest* request = nullptr; + FbLocalStatus status_vector; - if (isc_compile_request (status_vector, &DB, &request, - blr_length, reinterpret_cast(blr_buffer))) + request = DB->compileRequest(&status_vector, blr_length, blr_buffer); + if (status_vector->hasData()) { fb_print_blr(blr_buffer, blr_length, NULL, NULL, 0); if (!tdgbl->gbl_sw_incremental) - BURP_error_redirect (status_vector, 27); // msg 27 isc_compile_request failed + BURP_error_redirect(&status_vector, 27); // msg 27 isc_compile_request failed else { - BURP_print_status (false, status_vector); + BURP_print_status (false, &status_vector); BURP_free (blr_buffer); return ignore_data(tdgbl, relation); } @@ -2942,7 +2942,7 @@ rec_type get_data(BurpGlobals* tdgbl, burp_rel* relation, bool skip_relation) while (true) { if (get(tdgbl) != att_data_length) - BURP_error_redirect (NULL, 39); // msg 39 expected record length + BURP_error_redirect(NULL, 39); // msg 39 expected record length USHORT len = (USHORT) get_int32(tdgbl); if (!tdgbl->gbl_sw_transportable && len != length) { @@ -2964,7 +2964,7 @@ rec_type get_data(BurpGlobals* tdgbl, burp_rel* relation, bool skip_relation) if (tdgbl->gbl_sw_transportable) { if (get(tdgbl) != att_xdr_length) - BURP_error_redirect (NULL, 55); + BURP_error_redirect(NULL, 55); // msg 55 Expected XDR record length else { @@ -2982,7 +2982,7 @@ rec_type get_data(BurpGlobals* tdgbl, burp_rel* relation, bool skip_relation) else p = reinterpret_cast(buffer); if (get(tdgbl) != att_data_data) - BURP_error_redirect (NULL, 41); // msg 41 expected data attribute + BURP_error_redirect(NULL, 41); // msg 41 expected data attribute if (tdgbl->gbl_sw_compress) decompress (tdgbl, p, len); @@ -3025,43 +3025,43 @@ rec_type get_data(BurpGlobals* tdgbl, burp_rel* relation, bool skip_relation) get_record(&record, tdgbl); } - ISC_STATUS s; - // ASF: Preferable we should call isc_start_and_send only when records == 1, but this leaks // memory when there are blobs and arrays fields - CORE-3802. if (resync || records % 1000 == 1) - s = isc_start_and_send(status_vector, &request, &gds_trans, 0, (USHORT) length, buffer, 0); + request->startAndSend(&status_vector, gds_trans, 0, 0, length, buffer); else - s = isc_send(status_vector, &request, 0, (USHORT) length, buffer, 0); + request->send(&status_vector, 0, 0, length, buffer); - resync = (s != 0); + resync = false; - if (s) + if (status_vector->hasData()) { - if (status_vector[1] == isc_not_valid) + resync = true; + ISC_STATUS code = status_vector->getErrors()[1]; + if (code == isc_not_valid) { if (tdgbl->gbl_sw_incremental) { BURP_print (false, 138, relation->rel_name); // msg 138 validation error on field in relation %s - BURP_print_status (false, status_vector); + BURP_print_status (false, &status_vector); } else - BURP_error_redirect (status_vector, 47); + BURP_error_redirect(&status_vector, 47); // msg 47 warning -- record could not be restored } - else if (status_vector[1] == isc_malformed_string) + else if (code == isc_malformed_string) { if (tdgbl->gbl_sw_incremental) { // msg 114 restore failed for record in relation %s BURP_print(false, 114, relation->rel_name); - BURP_print_status(false, status_vector); + BURP_print_status(false, &status_vector); BURP_print(false, 342); // isc_gbak_invalid_data } else - BURP_error_redirect(status_vector, 342); // isc_gbak_invalid_data + BURP_error_redirect(&status_vector, 342); // isc_gbak_invalid_data } else { @@ -3069,10 +3069,10 @@ rec_type get_data(BurpGlobals* tdgbl, burp_rel* relation, bool skip_relation) { BURP_print (false, 114, relation->rel_name); // msg 114 restore failed for record in relation %s - BURP_print_status (false, status_vector); + BURP_print_status (false, &status_vector); } else - BURP_error_redirect (status_vector, 48); + BURP_error_redirect(&status_vector, 48); // msg 48 isc_send failed } @@ -3087,7 +3087,7 @@ rec_type get_data(BurpGlobals* tdgbl, burp_rel* relation, bool skip_relation) if (data.lstr_address) BURP_free (data.lstr_address); - isc_release_request(status_vector, &request); + request->release(); if (tdgbl->gbl_sw_incremental) { BURP_verbose (72, relation->rel_name); @@ -3110,7 +3110,7 @@ rec_type get_data(BurpGlobals* tdgbl, burp_rel* relation, bool skip_relation) case isc_sort_mem_err: case isc_no_dup: strcpy(index_name, (TEXT *)tdgbl->status_vector[3]); - BURP_print_status(false, tdgbl->status_vector); + BURP_print_status(false, &tdgbl->status_vector); FOR (REQUEST_HANDLE req_handle) IDX IN RDB$INDICES WITH IDX.RDB$INDEX_NAME EQ index_name MODIFY IDX USING @@ -3144,7 +3144,7 @@ rec_type get_data(BurpGlobals* tdgbl, burp_rel* relation, bool skip_relation) default: BURP_print (false, 69, relation->rel_name); // msg 69 commit failed on relation %s - BURP_print_status (false, tdgbl->status_vector); + BURP_print_status (false, &tdgbl->status_vector); ROLLBACK; ON_ERROR general_on_error (); @@ -3155,7 +3155,7 @@ rec_type get_data(BurpGlobals* tdgbl, burp_rel* relation, bool skip_relation) END_ERROR; EXEC SQL SET TRANSACTION NO_AUTO_UNDO; - if (gds_status[1]) + if (gds_status->hasData()) EXEC SQL SET TRANSACTION; } BURP_verbose (107, SafeArg() << records); @@ -3545,7 +3545,7 @@ burp_fld* get_field(BurpGlobals* tdgbl, burp_rel* relation) // If it is a view and there is a global transaction then use it bool global_tr = false; - isc_tr_handle local_trans; + Firebird::ITransaction* local_trans; if ((relation->rel_flags & REL_view) && tdgbl->global_trans) { local_trans = tdgbl->global_trans; @@ -4386,7 +4386,7 @@ bool get_function(BurpGlobals* tdgbl) strcpy(function_name, X.RDB$FUNCTION_NAME); END_STORE; ON_ERROR - if (gds_status[1] != isc_no_dup) + if (gds_status->getErrors()[1] != isc_no_dup) general_on_error (); else existFlag = true; @@ -4513,7 +4513,7 @@ bool get_function(BurpGlobals* tdgbl) END_STORE; ON_ERROR - if (gds_status[1] != isc_no_dup) + if (gds_status->getErrors()[1] != isc_no_dup) general_on_error (); else existFlag = true; @@ -6462,22 +6462,22 @@ void get_misc_blob(BurpGlobals* tdgbl, ISC_QUAD& blob_id, bool glb_trans) * shiney, new blob. * **************************************/ - ISC_STATUS_ARRAY status_vector; + FbLocalStatus status_vector; const FB_SIZE_T length = get_int32(tdgbl); // Create new blob - isc_tr_handle local_trans; + Firebird::ITransaction* local_trans; if (glb_trans && tdgbl->global_trans) local_trans = tdgbl->global_trans; else local_trans = gds_trans; - UserBlob blob(status_vector); + BlobWrapper blob(&status_vector); if (!blob.create(DB, local_trans, blob_id)) { - BURP_error_redirect (status_vector, 37); + BURP_error_redirect(&status_vector, 37); // msg 37 isc_create_blob failed } @@ -6492,12 +6492,12 @@ void get_misc_blob(BurpGlobals* tdgbl, ISC_QUAD& blob_id, bool glb_trans) if (!blob.putData(length, buffer)) { - BURP_error_redirect (status_vector, 38); + BURP_error_redirect(&status_vector, 38); // msg 38 isc_put_segment failed } if (!blob.close()) - BURP_error_redirect (status_vector, 23); + BURP_error_redirect(&status_vector, 23); // msg 23 isc_close_blob failed } @@ -6567,7 +6567,7 @@ bool get_package(BurpGlobals* tdgbl) if (tdgbl->RESTORE_format < 10) return false; - isc_tr_handle local_trans = tdgbl->global_trans ? tdgbl->global_trans : gds_trans; + Firebird::ITransaction* local_trans = tdgbl->global_trans ? tdgbl->global_trans : gds_trans; burp_pkg* package = (burp_pkg*) BURP_alloc_zero(sizeof(burp_pkg)); package->pkg_next = tdgbl->packages; @@ -6674,7 +6674,7 @@ bool get_procedure(BurpGlobals* tdgbl) SSHORT l; scan_attr_t scan_next_attr; - isc_tr_handle local_trans = tdgbl->global_trans ? tdgbl->global_trans : gds_trans; + Firebird::ITransaction* local_trans = tdgbl->global_trans ? tdgbl->global_trans : gds_trans; burp_prc* procedure = (burp_prc*) BURP_alloc_zero (sizeof(burp_prc)); procedure->prc_next = tdgbl->procedures; @@ -7018,7 +7018,7 @@ bool get_procedure_prm (BurpGlobals* tdgbl, GDS_NAME package_name, GDS_NAME proc TEXT temp[GDS_NAME_LEN]; scan_attr_t scan_next_attr; - isc_tr_handle local_trans = tdgbl->global_trans ? tdgbl->global_trans : gds_trans; + Firebird::ITransaction* local_trans = tdgbl->global_trans ? tdgbl->global_trans : gds_trans; if (tdgbl->runtimeODS >= DB_VERSION_DDL11_1) { @@ -7338,8 +7338,8 @@ bool get_relation(BurpGlobals* tdgbl) **************************************/ SLONG rel_flags = 0, sys_flag = fb_sysflag_user, type = rel_persistent; bool rel_flags_null = true; - ISC_QUAD view_blr = isc_blob_null, view_src = isc_blob_null, - rel_desc = isc_blob_null, ext_desc = isc_blob_null; + ISC_QUAD view_blr = fbBlobNull, view_src = fbBlobNull, + rel_desc = fbBlobNull, ext_desc = fbBlobNull; bool view_blr_null = true, view_src_null = true, rel_desc_null = true, ext_desc_null = true; FB_BOOLEAN sql_security = FB_FALSE; @@ -7367,7 +7367,7 @@ bool get_relation(BurpGlobals* tdgbl) END_ERROR; EXEC SQL SET TRANSACTION NO_AUTO_UNDO; - if (gds_status[1]) + if (gds_status->hasData()) EXEC SQL SET TRANSACTION; } @@ -7491,7 +7491,7 @@ bool get_relation(BurpGlobals* tdgbl) } // If this is a view and there is a global transaction then use it - isc_tr_handle local_trans; + Firebird::ITransaction* local_trans; if (view_blr_null || !tdgbl->global_trans) local_trans = gds_trans; else @@ -7586,14 +7586,14 @@ bool get_relation(BurpGlobals* tdgbl) ON_ERROR BURP_print (false, 171, relation->rel_name); // msg 171: error committing metadata for relation %s - BURP_print_status (false, tdgbl->status_vector); + BURP_print_status (false, &tdgbl->status_vector); ROLLBACK; ON_ERROR general_on_error (); END_ERROR; END_ERROR; EXEC SQL SET TRANSACTION NO_AUTO_UNDO; - if (gds_status[1]) + if (gds_status->hasData()) EXEC SQL SET TRANSACTION; } return true; @@ -7630,7 +7630,7 @@ bool get_relation(BurpGlobals* tdgbl) END_ERROR; EXEC SQL SET TRANSACTION NO_AUTO_UNDO; - if (gds_status[1]) + if (gds_status->hasData()) EXEC SQL SET TRANSACTION; get_data(tdgbl, relation, tdgbl->skipRelation(rel_name)); @@ -7749,7 +7749,7 @@ bool get_relation_data(BurpGlobals* tdgbl) } if (!relation) - BURP_error_redirect (NULL, 49); + BURP_error_redirect(NULL, 49); // msg 49 no relation name for data // Eat up misc. records @@ -8148,10 +8148,14 @@ bool get_mapping(BurpGlobals* tdgbl) "UPDATE OR INSERT INTO RDB$ROLES(RDB$ROLE_NAME, RDB$SYSTEM_FLAG) VALUES", ADMIN_ROLE, 6, // constant 6 turns on auto admin mapping in FB 2.5 "MATCHING (RDB$ROLE_NAME)"); - isc_dsql_execute_immediate(tdgbl->status_vector, &tdgbl->db_handle, &tdgbl->tr_handle, - sql.length(), sql.c_str(), 1, NULL); - if (tdgbl->status_vector[1]) + try { + BurpSql mapRole(tdgbl, sql.c_str()); + mapRole.execute(tdgbl->tr_handle); + } + catch (const Firebird::FbException& ex) + { + fb_utils::copyStatus(&tdgbl->status_vector, ex.getStatus()); general_on_error (); } } @@ -8281,14 +8285,14 @@ void get_source_blob(BurpGlobals* tdgbl, ISC_QUAD& blob_id, bool glb_trans) * input file to nice, shiney, new blob. * **************************************/ - ISC_STATUS_ARRAY status_vector; + FbLocalStatus status_vector; SLONG length = get_int32(tdgbl); // Create new blob - UserBlob blob(status_vector); - isc_tr_handle local_trans; + BlobWrapper blob(&status_vector); + Firebird::ITransaction* local_trans; if (glb_trans && tdgbl->global_trans) local_trans = tdgbl->global_trans; else @@ -8326,7 +8330,7 @@ void get_source_blob(BurpGlobals* tdgbl, ISC_QUAD& blob_id, bool glb_trans) if (!ok) { - BURP_error_redirect (status_vector, 37); + BURP_error_redirect(&status_vector, 37); // msg 37 isc_create_blob failed } @@ -8345,13 +8349,13 @@ void get_source_blob(BurpGlobals* tdgbl, ISC_QUAD& blob_id, bool glb_trans) if (!blob.putSegment(seg_len, buffer)) { - BURP_error_redirect (status_vector, 38); + BURP_error_redirect(&status_vector, 38); // msg 38 isc_put_segment failed } } if (!blob.close()) - BURP_error_redirect (status_vector, 23); + BURP_error_redirect(&status_vector, 23); // msg 23 isc_close_blob failed } @@ -8370,7 +8374,7 @@ USHORT get_text(BurpGlobals* tdgbl, TEXT* text, ULONG length) const ULONG l = get(tdgbl); if (length <= l) - BURP_error_redirect (NULL, 46); + BURP_error_redirect(NULL, 46); // msg 46 string truncated if (l) @@ -8399,7 +8403,7 @@ USHORT get_text2(BurpGlobals* tdgbl, TEXT* text, ULONG length) if (length <= len) { - BURP_error_redirect (NULL, 46); + BURP_error_redirect(NULL, 46); // msg 46 string truncated } @@ -8519,14 +8523,14 @@ bool get_trigger_old (BurpGlobals* tdgbl, burp_rel* relation) ON_ERROR BURP_print (false, 94, name); // msg 94 trigger %s is invalid - BURP_print_status (false, tdgbl->status_vector); + BURP_print_status (false, &tdgbl->status_vector); ROLLBACK; ON_ERROR general_on_error (); END_ERROR; END_ERROR; EXEC SQL SET TRANSACTION NO_AUTO_UNDO; - if (gds_status[1]) + if (gds_status->hasData()) EXEC SQL SET TRANSACTION; } @@ -8549,7 +8553,7 @@ bool get_trigger(BurpGlobals* tdgbl) BASED_ON RDB$TRIGGERS.RDB$TRIGGER_NAME name; scan_attr_t scan_next_attr; - isc_tr_handle local_trans = tdgbl->global_trans ? tdgbl->global_trans : gds_trans; + Firebird::ITransaction* local_trans = tdgbl->global_trans ? tdgbl->global_trans : gds_trans; if (tdgbl->runtimeODS >= DB_VERSION_DDL11_1) { @@ -8835,14 +8839,14 @@ bool get_trigger(BurpGlobals* tdgbl) ON_ERROR BURP_print (false, 94, name); // msg 94 trigger %s is invalid - BURP_print_status (false, tdgbl->status_vector); + BURP_print_status (false, &tdgbl->status_vector); ROLLBACK; ON_ERROR general_on_error (); END_ERROR; END_ERROR; EXEC SQL SET TRANSACTION NO_AUTO_UNDO; - if (gds_status[1]) + if (gds_status->hasData()) EXEC SQL SET TRANSACTION; } @@ -8911,7 +8915,7 @@ bool get_trigger_message(BurpGlobals* tdgbl) if (tdgbl->runtimeODS < DB_VERSION_DDL11) message[78] = 0; - isc_tr_handle local_trans = tdgbl->global_trans ? tdgbl->global_trans : gds_trans; + Firebird::ITransaction* local_trans = tdgbl->global_trans ? tdgbl->global_trans : gds_trans; STORE (TRANSACTION_HANDLE local_trans REQUEST_HANDLE tdgbl->handles_get_trigger_message_req_handle2) @@ -8931,14 +8935,14 @@ bool get_trigger_message(BurpGlobals* tdgbl) ON_ERROR BURP_print (false, 94, name); // msg 94 trigger %s is invalid - BURP_print_status (false, tdgbl->status_vector); + BURP_print_status (false, &tdgbl->status_vector); ROLLBACK; ON_ERROR general_on_error (); END_ERROR; END_ERROR; EXEC SQL SET TRANSACTION NO_AUTO_UNDO; - if (gds_status[1]) + if (gds_status->hasData()) EXEC SQL SET TRANSACTION; } @@ -9107,7 +9111,7 @@ bool get_user_privilege(BurpGlobals* tdgbl) } // Check if object exists - isc_tr_handle local_trans = 0; + Firebird::ITransaction* local_trans = nullptr; bool exists = false; // if grantor is not set than it's system privilege which should not be restored if (grantor[0]) @@ -9287,7 +9291,7 @@ bool get_view(BurpGlobals* tdgbl, burp_rel* relation) // If there is a global transaction then use it - isc_tr_handle local_trans = tdgbl->global_trans ? tdgbl->global_trans : gds_trans; + Firebird::ITransaction* local_trans = tdgbl->global_trans ? tdgbl->global_trans : gds_trans; if (tdgbl->runtimeODS >= DB_VERSION_DDL12) { @@ -9446,7 +9450,7 @@ void ignore_array(BurpGlobals* tdgbl, burp_rel* relation) break; } if (!field) - BURP_error_redirect (NULL, 36); + BURP_error_redirect(NULL, 36); // msg 36 Can't find field for blob break; @@ -9484,7 +9488,7 @@ void ignore_array(BurpGlobals* tdgbl, burp_rel* relation) if (tdgbl->gbl_sw_transportable) { if (get_attribute(&attribute, tdgbl) != att_xdr_array) - BURP_error_redirect (NULL, 55); + BURP_error_redirect(NULL, 55); // msg 55 Expected XDR record length else { @@ -9579,19 +9583,19 @@ rec_type ignore_data(BurpGlobals* tdgbl, burp_rel* relation) while (true) { if (get(tdgbl) != att_data_length) - BURP_error_redirect (NULL, 39); + BURP_error_redirect(NULL, 39); // msg 39 expected record length USHORT len = (USHORT) get_int32(tdgbl); if (tdgbl->gbl_sw_transportable) { if (get(tdgbl) != att_xdr_length) - BURP_error_redirect (NULL, 55); + BURP_error_redirect(NULL, 55); // msg 55 Expected XDR record length else len = (USHORT) get_int32(tdgbl); } if (get(tdgbl) != att_data_data) - BURP_error_redirect (NULL, 41); + BURP_error_redirect(NULL, 41); // msg 41 expected data attribute if (len) { @@ -9784,7 +9788,7 @@ bool restore(BurpGlobals* tdgbl, const TEXT* file_name, const TEXT* database_nam create_database(tdgbl, database_name); EXEC SQL SET TRANSACTION NO_AUTO_UNDO; - if (gds_status[1]) + if (gds_status->hasData()) EXEC SQL SET TRANSACTION; // For V4.0, start a read commited transaction. This will be used @@ -9804,7 +9808,10 @@ bool restore(BurpGlobals* tdgbl, const TEXT* file_name, const TEXT* database_nam // msg 129 started transaction att_type attribute; - isc_req_handle req_handle2 = 0, req_handle3 = 0, req_handle4 = 0, req_handle5 = 0; + Firebird::IRequest* req_handle2 =nullptr; + Firebird::IRequest* req_handle3 = nullptr; + Firebird::IRequest* req_handle4 = nullptr; + Firebird::IRequest* req_handle5 = nullptr; while (get_attribute(&attribute, tdgbl) != att_end) { @@ -10093,7 +10100,7 @@ bool restore(BurpGlobals* tdgbl, const TEXT* file_name, const TEXT* database_nam general_on_error (); END_ERROR; EXEC SQL SET TRANSACTION NO_AUTO_UNDO; - if (gds_status[1]) + if (gds_status->hasData()) EXEC SQL SET TRANSACTION; flag = false; } @@ -10152,7 +10159,7 @@ bool restore(BurpGlobals* tdgbl, const TEXT* file_name, const TEXT* database_nam if (tdgbl->defaultCollations.getCount() > 0) { - isc_req_handle req_handle5 = 0; + Firebird::IRequest* req_handle5 = nullptr; FOR (REQUEST_HANDLE req_handle5) CS IN RDB$CHARACTER_SETS @@ -10196,7 +10203,7 @@ bool restore(BurpGlobals* tdgbl, const TEXT* file_name, const TEXT* database_nam general_on_error (); END_ERROR; EXEC SQL SET TRANSACTION NO_AUTO_UNDO; - if (gds_status[1]) + if (gds_status->hasData()) EXEC SQL SET TRANSACTION; } @@ -10208,7 +10215,7 @@ bool restore(BurpGlobals* tdgbl, const TEXT* file_name, const TEXT* database_nam if (tdgbl->gbl_sw_kill) { - isc_req_handle req_handle5 = 0; + Firebird::IRequest* req_handle5 = nullptr; FOR (REQUEST_HANDLE req_handle5) FIL IN RDB$FILES WITH FIL.RDB$SHADOW_NUMBER NOT MISSING @@ -10226,7 +10233,7 @@ bool restore(BurpGlobals* tdgbl, const TEXT* file_name, const TEXT* database_nam } // update statistics for system indices - isc_req_handle req_handle6 = 0; + Firebird::IRequest* req_handle6 = nullptr; FOR (REQUEST_HANDLE req_handle6) IND IN RDB$INDICES WITH IND.RDB$SYSTEM_FLAG EQ 1 @@ -10259,7 +10266,7 @@ void restore_security_class(BurpGlobals* tdgbl, const TEXT* owner_nm, const TEXT * restore the ownership of the relation in the ACL list * **************************************/ - isc_req_handle req_handle2 = 0; + Firebird::IRequest* req_handle2 = nullptr; //isc_tr_handle local_trans = gds_trans; @@ -10316,7 +10323,7 @@ USHORT get_view_base_relation_count(BurpGlobals* tdgbl, return 0; } - isc_req_handle req_handle1 = 0; + Firebird::IRequest* req_handle1 = nullptr; USHORT result = 0; @@ -10443,7 +10450,7 @@ void store_blr_gen_id(BurpGlobals* tdgbl, const TEXT* gen_name, SINT64 value, SI } - FB_API_HANDLE gen_id_reqh = 0; + Firebird::IRequest* gen_id_reqh = nullptr; UCHAR blr_buffer[100]; // enough to fit blr UCHAR* blr = blr_buffer; @@ -10499,26 +10506,25 @@ void store_blr_gen_id(BurpGlobals* tdgbl, const TEXT* gen_name, SINT64 value, SI const USHORT blr_length = blr - blr_buffer; fb_assert(blr_length <= sizeof(blr_buffer)); - ISC_STATUS_ARRAY status_vector; - if (isc_compile_request (status_vector, &DB, &gen_id_reqh, - blr_length, (const SCHAR*) blr_buffer)) + FbLocalStatus status_vector; + gen_id_reqh = DB->compileRequest(&status_vector, blr_length, blr_buffer); + if (status_vector->hasData()) { fb_print_blr(blr_buffer, blr_length, NULL, NULL, 0); - BURP_error_redirect (status_vector, 42); // msg 42 Failed in store_blr_gen_id + BURP_error_redirect(&status_vector, 42); // msg 42 Failed in store_blr_gen_id } - if (isc_start_request (status_vector, &gen_id_reqh, - &gds_trans, // use the same one generated by gpre - 0)) + gen_id_reqh->start(&status_vector, gds_trans, 0); + if (status_vector->hasData()) { fb_print_blr(blr_buffer, blr_length, NULL, NULL, 0); - BURP_error_redirect (status_vector, 42); // msg 42 Failed in store_blr_gen_id + BURP_error_redirect(&status_vector, 42); // msg 42 Failed in store_blr_gen_id } BURP_verbose (185, SafeArg() << gen_name << value); // msg 185 restoring generator %s value: %ld - isc_release_request (status_vector, &gen_id_reqh); + gen_id_reqh->release(); } @@ -10535,7 +10541,7 @@ void update_global_field(BurpGlobals* tdgbl) * The blobs have been created already. * **************************************/ - isc_req_handle req_handle1 = 0; + Firebird::IRequest* req_handle1 = nullptr; for (gfld* gfield = tdgbl->gbl_global_fields; gfield; ) { @@ -10600,7 +10606,9 @@ void update_global_field(BurpGlobals* tdgbl) void update_ownership(BurpGlobals* tdgbl) { - isc_req_handle req_handle2 = 0, req_handle4 = 0, req_handle6 = 0; + Firebird::IRequest* req_handle2 = nullptr; + Firebird::IRequest* req_handle4 = nullptr; + Firebird::IRequest* req_handle6 = nullptr; BURP_verbose(358); // Change ownership of any packages @@ -10740,7 +10748,7 @@ void update_view_dbkey_lengths(BurpGlobals* tdgbl) * numeric overflow, or string truncation" error. * **************************************/ - isc_req_handle req_handle2 = 0; + Firebird::IRequest* req_handle2 = nullptr; BURP_verbose(357); @@ -10784,7 +10792,8 @@ void fix_missing_privileges(BurpGlobals* tdgbl) BURP_verbose(359); GDS_NAME owner_name; - isc_req_handle req_handle1 = 0, req_handle2 = 0; + Firebird::IRequest* req_handle1 = nullptr; + Firebird::IRequest* req_handle2 = nullptr; FOR (REQUEST_HANDLE req_handle1) REL IN RDB$RELATIONS @@ -10886,8 +10895,16 @@ void fix_generator(BurpGlobals* tdgbl, const FixGenerator* g) /* SELECT 2 */ g->name, /* SET GEN */ g->name); - if (isc_execute_immediate(isc_status, &DB, &gds_trans, 0, sql.c_str()) != 0) - general_on_error(); + try + { + BurpSql fixGen(tdgbl, sql.c_str()); + fixGen.execute(gds_trans); + } + catch (const Firebird::FbException& ex) + { + fb_utils::copyStatus(&tdgbl->status_vector, ex.getStatus()); + general_on_error (); + } } static const FixGenerator genToFix[] = diff --git a/src/common/classes/BlobWrapper.cpp b/src/common/classes/BlobWrapper.cpp new file mode 100644 index 0000000000..bb5b75d7ef --- /dev/null +++ b/src/common/classes/BlobWrapper.cpp @@ -0,0 +1,263 @@ +/* + * 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(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(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(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(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; +} diff --git a/src/common/classes/BlobWrapper.h b/src/common/classes/BlobWrapper.h new file mode 100644 index 0000000000..4c52de59d2 --- /dev/null +++ b/src/common/classes/BlobWrapper.h @@ -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 +#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 + diff --git a/src/common/status.h b/src/common/status.h new file mode 100644 index 0000000000..51717b384d --- /dev/null +++ b/src/common/status.h @@ -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 + * 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 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 FbLocalStatus; + typedef LocalStatusWrapper ThrowLocalStatus; +} + +#endif // COMMON_STATUS_H diff --git a/src/dsql/DsqlBatch.cpp b/src/dsql/DsqlBatch.cpp index cf47aceaab..2773c7d16e 100644 --- a/src/dsql/DsqlBatch.cpp +++ b/src/dsql/DsqlBatch.cpp @@ -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(); @@ -160,9 +154,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); @@ -779,13 +773,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 +791,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 +805,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_used + m_cache.getCount() + dataSize > m_limit) { ERRD_post(Arg::Gds(isc_sqlerr) << Arg::Num(-104) << Arg::Gds(isc_batch_too_big)); @@ -823,17 +817,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 +836,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 +851,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 +867,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 +883,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 +918,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 +941,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; diff --git a/src/dsql/DsqlBatch.h b/src/dsql/DsqlBatch.h index 0816386008..5e244253f2 100644 --- a/src/dsql/DsqlBatch.h +++ b/src/dsql/DsqlBatch.h @@ -108,10 +108,10 @@ private: public: DataCache(MemoryPool& p) : PermanentStorage(p), - m_used(0), m_got(0), m_limit(0), m_shift(0) + 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 Cache; - Firebird::AutoPtr m_cache; + typedef Firebird::Array Cache; + Cache m_cache; Firebird::AutoPtr m_space; - ULONG m_used, m_got, m_limit, m_shift; + ULONG m_used, m_got, m_limit, m_shift, m_cacheCapacity; }; struct BlobMeta diff --git a/src/gpre/obj_cxx.cpp b/src/gpre/obj_cxx.cpp index b083241c55..a5811cf427 100644 --- a/src/gpre/obj_cxx.cpp +++ b/src/gpre/obj_cxx.cpp @@ -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); } diff --git a/src/include/firebird/FirebirdInterface.idl b/src/include/firebird/FirebirdInterface.idl index 511e5fbf8d..5340104067 100644 --- a/src/include/firebird/FirebirdInterface.idl +++ b/src/include/firebird/FirebirdInterface.idl @@ -514,15 +514,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); } diff --git a/src/include/firebird/IdlFbInterfaces.h b/src/include/firebird/IdlFbInterfaces.h index 85b1d2d22e..9c6fda1081 100644 --- a/src/include/firebird/IdlFbInterfaces.h +++ b/src/include/firebird/IdlFbInterfaces.h @@ -1931,11 +1931,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 +1953,14 @@ namespace Firebird public: static const unsigned VERSION = 3; - template void receive(StatusType* status, int level, unsigned msgType, unsigned length, unsigned char* message) + template void receive(StatusType* status, int level, unsigned msgType, unsigned length, void* message) { StatusType::clearException(status); static_cast(this->cloopVTable)->receive(this, status, level, msgType, length, message); StatusType::checkException(status); } - template void send(StatusType* status, int level, unsigned msgType, unsigned length, const unsigned char* message) + template void send(StatusType* status, int level, unsigned msgType, unsigned length, const void* message) { StatusType::clearException(status); static_cast(this->cloopVTable)->send(this, status, level, msgType, length, message); @@ -1981,7 +1981,7 @@ namespace Firebird StatusType::checkException(status); } - template void startAndSend(StatusType* status, ITransaction* tra, int level, unsigned msgType, unsigned length, const unsigned char* message) + template void startAndSend(StatusType* status, ITransaction* tra, int level, unsigned msgType, unsigned length, const void* message) { StatusType::clearException(status); static_cast(this->cloopVTable)->startAndSend(this, status, tra, level, msgType, length, message); @@ -9401,7 +9401,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 +9415,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 +9457,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 +9538,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; }; diff --git a/src/jrd/EngineInterface.h b/src/jrd/EngineInterface.h index 3576bae22d..a31ccabe35 100644 --- a/src/jrd/EngineInterface.h +++ b/src/jrd/EngineInterface.h @@ -277,15 +277,15 @@ public: // IRequest implementation int release(); void receive(Firebird::CheckStatusWrapper* status, int level, unsigned int msg_type, - unsigned int length, unsigned char* message); + unsigned int length, void* message); void send(Firebird::CheckStatusWrapper* status, int level, unsigned int msg_type, - unsigned int length, const unsigned char* message); + unsigned int length, const void* message); void getInfo(Firebird::CheckStatusWrapper* status, int level, unsigned int itemsLength, const unsigned char* items, unsigned int bufferLength, unsigned char* buffer); void start(Firebird::CheckStatusWrapper* status, Firebird::ITransaction* tra, int level); void startAndSend(Firebird::CheckStatusWrapper* status, Firebird::ITransaction* tra, int level, - unsigned int msg_type, unsigned int length, const unsigned char* message); + unsigned int msg_type, unsigned int length, const void* message); void unwind(Firebird::CheckStatusWrapper* status, int level); void free(Firebird::CheckStatusWrapper* status); diff --git a/src/jrd/exe.cpp b/src/jrd/exe.cpp index 1862cf3893..b944376d74 100644 --- a/src/jrd/exe.cpp +++ b/src/jrd/exe.cpp @@ -614,7 +614,7 @@ void EXE_receive(thread_db* tdbb, jrd_req* request, USHORT msg, ULONG length, - UCHAR* buffer, + void* buffer, bool top_level) { /************************************** @@ -692,7 +692,7 @@ void EXE_receive(thread_db* tdbb, if (desc->isBlob()) { - const bid* id = (bid*) (buffer + (ULONG)(IPTR)desc->dsc_address); + const bid* id = (bid*) (reinterpret_cast(buffer) + (ULONG)(IPTR)desc->dsc_address); if (transaction->tra_blobs->locate(id->bid_temp_id())) { @@ -766,7 +766,7 @@ void EXE_release(thread_db* tdbb, jrd_req* request) } -void EXE_send(thread_db* tdbb, jrd_req* request, USHORT msg, ULONG length, const UCHAR* buffer) +void EXE_send(thread_db* tdbb, jrd_req* request, USHORT msg, ULONG length, const void* buffer) { /************************************** * diff --git a/src/jrd/exe_proto.h b/src/jrd/exe_proto.h index 2bc4ae301e..ea3dedcc2e 100644 --- a/src/jrd/exe_proto.h +++ b/src/jrd/exe_proto.h @@ -46,9 +46,9 @@ const Jrd::StmtNode* EXE_looper(Jrd::thread_db* tdbb, Jrd::jrd_req* request, void EXE_execute_triggers(Jrd::thread_db*, Jrd::TrigVector**, Jrd::record_param*, Jrd::record_param*, enum TriggerAction, Jrd::StmtNode::WhichTrigger); -void EXE_receive(Jrd::thread_db*, Jrd::jrd_req*, USHORT, ULONG, UCHAR*, bool = false); +void EXE_receive(Jrd::thread_db*, Jrd::jrd_req*, USHORT, ULONG, void*, bool = false); void EXE_release(Jrd::thread_db*, Jrd::jrd_req*); -void EXE_send(Jrd::thread_db*, Jrd::jrd_req*, USHORT, ULONG, const UCHAR*); +void EXE_send(Jrd::thread_db*, Jrd::jrd_req*, USHORT, ULONG, const void*); void EXE_start(Jrd::thread_db*, Jrd::jrd_req*, Jrd::jrd_tra*); void EXE_unwind(Jrd::thread_db*, Jrd::jrd_req*); diff --git a/src/jrd/jrd.cpp b/src/jrd/jrd.cpp index 908d278396..27d335ba12 100644 --- a/src/jrd/jrd.cpp +++ b/src/jrd/jrd.cpp @@ -3490,7 +3490,7 @@ JEvents* JAttachment::queEvents(CheckStatusWrapper* user_status, IEventCallback* void JRequest::receive(CheckStatusWrapper* user_status, int level, unsigned int msg_type, - unsigned int msg_length, unsigned char* msg) + unsigned int msg_length, void* msg) { /************************************** * @@ -3803,7 +3803,7 @@ int JBlob::seek(CheckStatusWrapper* user_status, int mode, int offset) void JRequest::send(CheckStatusWrapper* user_status, int level, unsigned int msg_type, - unsigned int msg_length, const unsigned char* msg) + unsigned int msg_length, const void* msg) { /************************************** * @@ -4028,7 +4028,7 @@ void JService::start(CheckStatusWrapper* user_status, unsigned int spbLength, co void JRequest::startAndSend(CheckStatusWrapper* user_status, ITransaction* tra, int level, - unsigned int msg_type, unsigned int msg_length, const unsigned char* msg) + unsigned int msg_type, unsigned int msg_length, const void* msg) { /************************************** * @@ -8400,7 +8400,7 @@ void JRD_autocommit_ddl(thread_db* tdbb, jrd_tra* transaction) } -void JRD_receive(thread_db* tdbb, jrd_req* request, USHORT msg_type, ULONG msg_length, UCHAR* msg) +void JRD_receive(thread_db* tdbb, jrd_req* request, USHORT msg_type, ULONG msg_length, void* msg) { /************************************** * @@ -8424,7 +8424,7 @@ void JRD_receive(thread_db* tdbb, jrd_req* request, USHORT msg_type, ULONG msg_l } -void JRD_send(thread_db* tdbb, jrd_req* request, USHORT msg_type, ULONG msg_length, const UCHAR* msg) +void JRD_send(thread_db* tdbb, jrd_req* request, USHORT msg_type, ULONG msg_length, const void* msg) { /************************************** * @@ -8538,7 +8538,7 @@ void JRD_rollback_retaining(thread_db* tdbb, jrd_tra* transaction) void JRD_start_and_send(thread_db* tdbb, jrd_req* request, jrd_tra* transaction, - USHORT msg_type, ULONG msg_length, const UCHAR* msg) + USHORT msg_type, ULONG msg_length, const void* msg) { /************************************** * diff --git a/src/jrd/jrd_proto.h b/src/jrd/jrd_proto.h index 7f303a2544..4c096b7996 100644 --- a/src/jrd/jrd_proto.h +++ b/src/jrd/jrd_proto.h @@ -59,7 +59,7 @@ void JRD_print_procedure_info(Jrd::thread_db*, const char*); void JRD_autocommit_ddl(Jrd::thread_db* tdbb, Jrd::jrd_tra* transaction); void JRD_receive(Jrd::thread_db* tdbb, Jrd::jrd_req* request, USHORT msg_type, ULONG msg_length, - UCHAR* msg); + void* msg); void JRD_start(Jrd::thread_db* tdbb, Jrd::jrd_req* request, Jrd::jrd_tra* transaction); void JRD_commit_transaction(Jrd::thread_db* tdbb, Jrd::jrd_tra* transaction); @@ -67,9 +67,9 @@ void JRD_commit_retaining(Jrd::thread_db* tdbb, Jrd::jrd_tra* transaction); void JRD_rollback_transaction(Jrd::thread_db* tdbb, Jrd::jrd_tra* transaction); void JRD_rollback_retaining(Jrd::thread_db* tdbb, Jrd::jrd_tra* transaction); void JRD_send(Jrd::thread_db* tdbb, Jrd::jrd_req* request, USHORT msg_type, ULONG msg_length, - const UCHAR* msg); + const void* msg); void JRD_start_and_send(Jrd::thread_db* tdbb, Jrd::jrd_req* request, Jrd::jrd_tra* transaction, - USHORT msg_type, ULONG msg_length, const UCHAR* msg); + USHORT msg_type, ULONG msg_length, const void* msg); void JRD_start_transaction(Jrd::thread_db* tdbb, Jrd::jrd_tra** transaction, Jrd::Attachment* attachment, unsigned int tpb_length, const UCHAR* tpb); void JRD_unwind_request(Jrd::thread_db* tdbb, Jrd::jrd_req* request); diff --git a/src/jrd/status.h b/src/jrd/status.h index dfb07c823a..adbe1ca9b0 100644 --- a/src/jrd/status.h +++ b/src/jrd/status.h @@ -29,90 +29,13 @@ #ifndef JRD_STATUS_H #define JRD_STATUS_H -#include "../common/StatusHolder.h" -#include "../common/utils_proto.h" - -const int MAX_ERRMSG_LEN = 128; -const int MAX_ERRSTR_LEN = 1024; +#include "../common/status.h" namespace Jrd { typedef Firebird::CheckStatusWrapper FbStatusVector; - - template - 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 FbLocalStatus; - typedef LocalStatusWrapper ThrowLocalStatus; + typedef Firebird::FbLocalStatus FbLocalStatus; + typedef Firebird::ThrowLocalStatus ThrowLocalStatus; } #endif // JRD_STATUS_H diff --git a/src/msgs/messages2.sql b/src/msgs/messages2.sql index a87f11373d..8e95cdad66 100644 --- a/src/msgs/messages2.sql +++ b/src/msgs/messages2.sql @@ -970,7 +970,7 @@ Data source : @4', NULL, NULL) ('non_plugin_protocol', NULL, 'server.cpp', NULL, 0, 860, NULL, 'Plugin not supported by network protocol', NULL, NULL); ('message_format', NULL, 'server.cpp', NULL, 0, 861, NULL, 'Error parsing message format', NULL, NULL); ('batch_param_version', NULL, NULL, NULL, 0, 862, NULL, 'Wrong version of batch parameters block @1, should be @2', NULL, NULL); -('batch_msg_long', NULL, 'DsqlBatch.cpp', NULL, 0, 863, NULL, 'Message size (@1) in batch exceeds internal buffer size (@2)', NULL, NULL); +('batch_msg_long', NULL, '** Unused **', NULL, 0, 863, NULL, 'Message size (@1) in batch exceeds internal buffer size (@2)', NULL, NULL); ('batch_open', NULL, 'DsqlBatch.cpp', NULL, 0, 864, NULL, 'Batch already opened for this statement', NULL, NULL); ('batch_type', NULL, 'DsqlBatch.cpp', NULL, 0, 865, NULL, 'Invalid type of statement used in batch', NULL, NULL); ('batch_param', NULL, 'DsqlBatch.cpp', NULL, 0, 866, NULL, 'Statement used in batch must have parameters', NULL, NULL); diff --git a/src/remote/client/interface.cpp b/src/remote/client/interface.cpp index 3b2125206c..a6291d8088 100644 --- a/src/remote/client/interface.cpp +++ b/src/remote/client/interface.cpp @@ -621,15 +621,15 @@ public: // IRequest implementation int release(); void receive(CheckStatusWrapper* status, int level, unsigned int msg_type, - unsigned int length, unsigned char* message); + unsigned int length, void* message); void send(CheckStatusWrapper* status, int level, unsigned int msg_type, - unsigned int length, const unsigned char* message); + unsigned int length, const void* message); void getInfo(CheckStatusWrapper* status, int level, unsigned int itemsLength, const unsigned char* items, unsigned int bufferLength, unsigned char* buffer); void start(CheckStatusWrapper* status, Firebird::ITransaction* tra, int level); void startAndSend(CheckStatusWrapper* status, Firebird::ITransaction* tra, int level, unsigned int msg_type, - unsigned int length, const unsigned char* message); + unsigned int length, const void* message); void unwind(CheckStatusWrapper* status, int level); void free(CheckStatusWrapper* status); @@ -5057,7 +5057,7 @@ Firebird::IEvents* Attachment::queEvents(CheckStatusWrapper* status, Firebird::I void Request::receive(CheckStatusWrapper* status, int level, unsigned int msg_type, - unsigned int msg_length, unsigned char* msg) + unsigned int msg_length, void* msg) { /************************************** * @@ -5570,7 +5570,7 @@ int Blob::seek(CheckStatusWrapper* status, int mode, int offset) void Request::send(CheckStatusWrapper* status, int level, unsigned int msg_type, - unsigned int /*length*/, const unsigned char* msg) + unsigned int /*length*/, const void* msg) { /************************************** * @@ -5601,7 +5601,7 @@ void Request::send(CheckStatusWrapper* status, int level, unsigned int msg_type, RMessage* message = request->rrq_rpt[msg_type].rrq_message; // We are lying here, but the interface shows for years this param as const - message->msg_address = const_cast(msg); + message->msg_address = const_cast(reinterpret_cast(msg)); PACKET* packet = &rdb->rdb_packet; packet->p_operation = op_send; @@ -5852,7 +5852,7 @@ void Service::start(CheckStatusWrapper* status, void Request::startAndSend(CheckStatusWrapper* status, Firebird::ITransaction* apiTra, int level, - unsigned int msg_type, unsigned int /*length*/, const unsigned char* msg) + unsigned int msg_type, unsigned int /*length*/, const void* msg) { /************************************** * @@ -5894,7 +5894,7 @@ void Request::startAndSend(CheckStatusWrapper* status, Firebird::ITransaction* a REMOTE_reset_request(request, 0); RMessage* message = request->rrq_rpt[msg_type].rrq_message; - message->msg_address = const_cast(msg); + message->msg_address = const_cast(reinterpret_cast(msg)); PACKET* packet = &rdb->rdb_packet; packet->p_operation = op_start_send_and_receive; diff --git a/src/yvalve/YObjects.h b/src/yvalve/YObjects.h index bf3c5de056..ba10480527 100644 --- a/src/yvalve/YObjects.h +++ b/src/yvalve/YObjects.h @@ -210,14 +210,14 @@ public: // IRequest implementation void receive(Firebird::CheckStatusWrapper* status, int level, unsigned int msgType, - unsigned int length, unsigned char* message); + unsigned int length, void* message); void send(Firebird::CheckStatusWrapper* status, int level, unsigned int msgType, - unsigned int length, const unsigned char* message); + unsigned int length, const void* message); void getInfo(Firebird::CheckStatusWrapper* status, int level, unsigned int itemsLength, const unsigned char* items, unsigned int bufferLength, unsigned char* buffer); void start(Firebird::CheckStatusWrapper* status, Firebird::ITransaction* transaction, int level); void startAndSend(Firebird::CheckStatusWrapper* status, Firebird::ITransaction* transaction, int level, - unsigned int msgType, unsigned int length, const unsigned char* message); + unsigned int msgType, unsigned int length, const void* message); void unwind(Firebird::CheckStatusWrapper* status, int level); void free(Firebird::CheckStatusWrapper* status); diff --git a/src/yvalve/why.cpp b/src/yvalve/why.cpp index afe4e53050..8f77e5ccb1 100644 --- a/src/yvalve/why.cpp +++ b/src/yvalve/why.cpp @@ -3922,7 +3922,7 @@ void YRequest::destroy(unsigned dstrFlags) } void YRequest::receive(CheckStatusWrapper* status, int level, unsigned int msgType, - unsigned int length, unsigned char* message) + unsigned int length, void* message) { try { @@ -3936,7 +3936,7 @@ void YRequest::receive(CheckStatusWrapper* status, int level, unsigned int msgTy } void YRequest::send(CheckStatusWrapper* status, int level, unsigned int msgType, - unsigned int length, const unsigned char* message) + unsigned int length, const void* message) { try { @@ -3980,7 +3980,7 @@ void YRequest::start(CheckStatusWrapper* status, ITransaction* transaction, int } void YRequest::startAndSend(CheckStatusWrapper* status, ITransaction* transaction, int level, - unsigned int msgType, unsigned int length, const unsigned char* message) + unsigned int msgType, unsigned int length, const void* message) { try { From 763f96a40957e5fd279ae9650f8f914949770da6 Mon Sep 17 00:00:00 2001 From: Dmitry Yemanov Date: Thu, 7 Dec 2017 19:20:01 +0300 Subject: [PATCH 026/171] Raised max record size (to test new gbak implementation) --- src/jrd/val.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/jrd/val.h b/src/jrd/val.h index eb2c042cdd..926dc6eb0c 100644 --- a/src/jrd/val.h +++ b/src/jrd/val.h @@ -50,7 +50,8 @@ public: }; const UCHAR DEFAULT_DOUBLE = dtype_double; -const ULONG MAX_RECORD_SIZE = 65535; + +const ULONG MAX_RECORD_SIZE = 1024 * 1024; // 1MB namespace Jrd { From dd45e49f4bb0731f28682148ac1ed9bcfac81c2f Mon Sep 17 00:00:00 2001 From: AlexPeshkoff Date: Fri, 8 Dec 2017 20:29:26 +0300 Subject: [PATCH 027/171] Backup/restore of wide records works using transportable format --- src/burp/backup.epp | 14 ++++---------- src/burp/restore.epp | 4 ++-- src/include/fb_types.h | 1 + 3 files changed, 7 insertions(+), 12 deletions(-) diff --git a/src/burp/backup.epp b/src/burp/backup.epp index 246110a2d0..7848735075 100644 --- a/src/burp/backup.epp +++ b/src/burp/backup.epp @@ -1405,13 +1405,7 @@ void put_data(burp_rel* relation) * **************************************/ 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) { @@ -1433,7 +1427,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) { @@ -1569,7 +1563,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 @@ -1623,7 +1617,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) diff --git a/src/burp/restore.epp b/src/burp/restore.epp index 5af331f183..ca9584445b 100644 --- a/src/burp/restore.epp +++ b/src/burp/restore.epp @@ -2721,7 +2721,7 @@ rec_type get_data(BurpGlobals* tdgbl, burp_rel* relation, bool skip_relation) // Start by counting the interesting fields RCRD_OFFSET offset = 0; - ULONG length = 0; + RCRD_LENGTH length = 0; USHORT count = 0; burp_fld* field; @@ -2943,7 +2943,7 @@ rec_type get_data(BurpGlobals* tdgbl, burp_rel* relation, bool skip_relation) { if (get(tdgbl) != att_data_length) BURP_error_redirect(NULL, 39); // msg 39 expected record length - USHORT len = (USHORT) get_int32(tdgbl); + RCRD_LENGTH len = get_int32(tdgbl); if (!tdgbl->gbl_sw_transportable && len != length) { #ifdef sparc diff --git a/src/include/fb_types.h b/src/include/fb_types.h index cf691ca91b..7030f4b792 100644 --- a/src/include/fb_types.h +++ b/src/include/fb_types.h @@ -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, From 0a1b23004e6cd9a1a64ba0d00b05ca0cf39c5eda Mon Sep 17 00:00:00 2001 From: AlexPeshkoff Date: Tue, 12 Dec 2017 16:46:23 +0300 Subject: [PATCH 028/171] Make gbak correctly work with wide records when -nt and -e flags are used --- src/burp/backup.epp | 2 +- src/burp/restore.epp | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/burp/backup.epp b/src/burp/backup.epp index 7848735075..43a66b8277 100644 --- a/src/burp/backup.epp +++ b/src/burp/backup.epp @@ -469,7 +469,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) diff --git a/src/burp/restore.epp b/src/burp/restore.epp index ca9584445b..8ee3936b63 100644 --- a/src/burp/restore.epp +++ b/src/burp/restore.epp @@ -100,7 +100,7 @@ void add_access_dpb(BurpGlobals* tdgbl, Firebird::ClumpletWriter& dpb); void add_files(BurpGlobals* tdgbl, const char*); void bad_attribute(scan_attr_t, att_type, USHORT); void create_database(BurpGlobals* tdgbl, const TEXT*); -void decompress(BurpGlobals* tdgbl, UCHAR*, USHORT); +void decompress(BurpGlobals* tdgbl, UCHAR*, ULONG); void eat_blob(BurpGlobals* tdgbl); void eat_text(BurpGlobals* tdgbl); void eat_text2(BurpGlobals* tdgbl); @@ -968,7 +968,7 @@ void create_database(BurpGlobals* tdgbl, const TEXT* file_name) // msg 74 created database %s, page_size %ld bytes } -void decompress(BurpGlobals* tdgbl, UCHAR* buffer, USHORT length) +void decompress(BurpGlobals* tdgbl, UCHAR* buffer, ULONG length) { /************************************** * @@ -2902,7 +2902,7 @@ rec_type get_data(BurpGlobals* tdgbl, burp_rel* relation, bool skip_relation) // Compile request - USHORT blr_length = blr - blr_buffer; + ULONG blr_length = blr - blr_buffer; #ifdef DEBUG fb_print_blr(blr_buffer, blr_length, NULL, NULL, 0); @@ -2968,7 +2968,7 @@ rec_type get_data(BurpGlobals* tdgbl, burp_rel* relation, bool skip_relation) // msg 55 Expected XDR record length else { - data.lstr_length = len = (USHORT) get_int32(tdgbl); + data.lstr_length = len = get_int32(tdgbl); if (len > data.lstr_allocated) { data.lstr_allocated = len; From 520a28fc19e14a519893a39d2736bb7b56702fea Mon Sep 17 00:00:00 2001 From: AlexPeshkoff Date: Wed, 27 Dec 2017 16:18:20 +0300 Subject: [PATCH 029/171] Improve gbak performance over network using batch interface --- src/burp/backup.epp | 4 +- src/burp/burp.h | 6 + src/burp/canon_proto.h | 4 +- src/burp/canonical.cpp | 14 +- src/burp/restore.epp | 756 ++++++++++++++++++--- src/common/classes/BlobWrapper.cpp | 2 +- src/common/classes/auto.h | 10 + src/dsql/DsqlBatch.cpp | 39 +- src/dsql/DsqlBatch.h | 2 +- src/include/firebird/FirebirdInterface.idl | 2 + src/include/firebird/IdlFbInterfaces.h | 32 + src/jrd/EngineInterface.h | 1 + src/jrd/btr.cpp | 2 +- src/jrd/inf_pub.h | 1 + src/jrd/jrd.cpp | 6 + src/remote/client/interface.cpp | 15 + src/remote/merge.cpp | 1 - src/remote/protocol.cpp | 16 +- src/remote/remote.h | 2 +- src/yvalve/YObjects.h | 1 + src/yvalve/why.cpp | 16 + 21 files changed, 792 insertions(+), 140 deletions(-) diff --git a/src/burp/backup.epp b/src/burp/backup.epp index 43a66b8277..c21bfc4f5a 100644 --- a/src/burp/backup.epp +++ b/src/burp/backup.epp @@ -1089,7 +1089,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)); @@ -1684,7 +1684,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; } diff --git a/src/burp/burp.h b/src/burp/burp.h index 270c7a5554..ff074dffc4 100644 --- a/src/burp/burp.h +++ b/src/burp/burp.h @@ -664,12 +664,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; @@ -698,6 +700,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 { @@ -958,6 +962,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; @@ -976,6 +981,7 @@ public: burp_fil* gbl_sw_files; burp_fil* gbl_sw_backup_files; gfld* gbl_global_fields; + unsigned gbl_network_protocol; burp_act* action; ULONG io_buffer_size; redirect_vals sw_redirect; diff --git a/src/burp/canon_proto.h b/src/burp/canon_proto.h index a377c8a508..f41e68ccbc 100644 --- a/src/burp/canon_proto.h +++ b/src/burp/canon_proto.h @@ -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 diff --git a/src/burp/canonical.cpp b/src/burp/canonical.cpp index 308add7663..365409929a 100644 --- a/src/burp/canonical.cpp +++ b/src/burp/canonical.cpp @@ -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) { /************************************** * diff --git a/src/burp/restore.epp b/src/burp/restore.epp index 8ee3936b63..40a9a9f50c 100644 --- a/src/burp/restore.epp +++ b/src/burp/restore.epp @@ -30,6 +30,10 @@ #include #include #include +#ifdef HAVE_CTYPE_H +#include +#endif + #include "../burp/burp.h" #include "../jrd/align.h" #include "../jrd/flags.h" @@ -55,6 +59,7 @@ #include "memory_routines.h" #include "../burp/OdsDetection.h" #include "../auth/trusted/AuthSspi.h" +#include "../common/dsc_proto.h" using MsgFormat::SafeArg; using Firebird::FbLocalStatus; @@ -111,12 +116,14 @@ void fix_security_class_name(BurpGlobals* tdgbl, TEXT* sec_class, bool is_field) // returned value is not checked by the caller! bool get_acl(BurpGlobals* tdgbl, const TEXT*, ISC_QUAD*, ISC_QUAD*); void get_array(BurpGlobals* tdgbl, burp_rel*, UCHAR*); -void get_blob(BurpGlobals* tdgbl, const burp_fld*, UCHAR*); +void get_blob(BurpGlobals* tdgbl, Firebird::IBatch* batch, const burp_fld*, UCHAR*); +void get_blob_old(BurpGlobals* tdgbl, const burp_fld*, UCHAR*); void get_blr_blob(BurpGlobals* tdgbl, ISC_QUAD&, bool); bool get_character_set(BurpGlobals* tdgbl); bool get_chk_constraint(BurpGlobals* tdgbl); bool get_collation(BurpGlobals* tdgbl); rec_type get_data(BurpGlobals* tdgbl, burp_rel*, bool); +rec_type get_data_old(BurpGlobals* tdgbl, burp_rel*); bool get_exception(BurpGlobals* tdgbl); burp_fld* get_field(BurpGlobals* tdgbl, burp_rel*); bool get_field_dimensions(BurpGlobals* tdgbl); @@ -930,7 +937,8 @@ void create_database(BurpGlobals* tdgbl, const TEXT* file_name) // When we restore backup files that came from prior // to V6, we force the SQL database dialect to 1 - dpb.insertByte(isc_dpb_sql_dialect, SQL_dialect_flag ? SQL_dialect : SQL_DIALECT_V5); + tdgbl->gbl_dialect = SQL_dialect_flag ? SQL_dialect : SQL_DIALECT_V5; + dpb.insertByte(isc_dpb_sql_dialect, tdgbl->gbl_dialect); // start database up shut down, // use single-user mode to avoid conflicts during restore process @@ -956,6 +964,14 @@ void create_database(BurpGlobals* tdgbl, const TEXT* file_name) // msg 33 failed to create database %s } + tdgbl->gbl_network_protocol = DB->getRemoteProtocolVersion(&status_vector); + // treat errors as old provider missing new calls + if (status_vector->hasData()) + { + status_vector->init(); + tdgbl->gbl_network_protocol = 1; + } + if (tdgbl->gbl_sw_version && !tdgbl->uSvc->isService()) { BURP_print(false, 139, file_name); @@ -1759,7 +1775,7 @@ void get_array(BurpGlobals* tdgbl, burp_rel* relation, UCHAR* record_buffer) get_block(tdgbl, p, lcount); if (tdgbl->gbl_sw_transportable) - CAN_slice (&xdr_buffer, &xdr_slice, FALSE, /*blr_length,*/ blr_buffer); + CAN_slice (&xdr_buffer, &xdr_slice, false, blr_buffer); } DB->putSlice(&status_vector, gds_trans, blob_id, blr_length, blr_buffer, @@ -1885,7 +1901,7 @@ void get_array(BurpGlobals* tdgbl, burp_rel* relation, UCHAR* record_buffer) get_block(tdgbl, p, lcount); if (tdgbl->gbl_sw_transportable) - CAN_slice (&xdr_buffer, &xdr_slice, FALSE, /*blr_length,*/ blr_buffer); + CAN_slice (&xdr_buffer, &xdr_slice, false, blr_buffer); DB->putSlice(&status_vector, gds_trans, blob_id, blr_length, blr_buffer, @@ -1908,7 +1924,108 @@ void get_array(BurpGlobals* tdgbl, burp_rel* relation, UCHAR* record_buffer) BURP_free (xdr_buffer.lstr_address); } -void get_blob(BurpGlobals* tdgbl, const burp_fld* fields, UCHAR* record_buffer) +void get_blob(BurpGlobals* tdgbl, Firebird::IBatch* batch, const burp_fld* fields, UCHAR* record_buffer) +{ +/************************************** + * + * g e t _ b l o b + * + ************************************** + * + * Functional description + * Read blob attributes and copy data from input file to nice, + * shiny, new blob. + * + **************************************/ + + // Pick up attributes + + ULONG segments = 0; + USHORT field_number = MAX_USHORT; + USHORT max_segment = 0; + UCHAR blob_type = 0; + + att_type attribute; + scan_attr_t scan_next_attr; + skip_init(&scan_next_attr); + while (skip_scan(&scan_next_attr), get_attribute(&attribute, tdgbl) != att_blob_data) + { + switch (attribute) + { + case att_blob_field_number: + field_number = (USHORT) get_int32(tdgbl); + break; + + case att_blob_max_segment: + max_segment = (USHORT) get_int32(tdgbl); + break; + + case att_blob_number_segments: + segments = get_int32(tdgbl); + break; + + case att_blob_type: + blob_type = (UCHAR) get_int32(tdgbl); + break; + + default: + bad_attribute(scan_next_attr, attribute, 64); + // msg 64 blob + break; + } + } + + // Find the field associated with the blob + const burp_fld* field; + for (field = fields; field; field = field->fld_next) + { + if (field->fld_number == field_number) + break; + } + + if (!field) + { + BURP_error_redirect(NULL, 36); + // msg 36 Can't find field for blob + } + + // Create new blob + + ISC_QUAD* blob_id = (ISC_QUAD*) ((UCHAR*) record_buffer + field->fld_offset); + const UCHAR blob_desc[] = {isc_bpb_version1, isc_bpb_type, 1, blob_type}; + + BlobBuffer local_buffer; + UCHAR* const buffer = local_buffer.getBuffer(max_segment); + + FbLocalStatus status_vector; + bool first = true; + + // Eat up blob segments + + for (; segments > 0; --segments ) + { + USHORT length = get(tdgbl); + length |= get(tdgbl) << 8; + if (length) + { + get_block(tdgbl, buffer, length); + } + + if (first) + batch->addBlob(&status_vector, length, buffer, blob_id, sizeof(blob_desc), blob_desc); + else + batch->appendBlobData(&status_vector, length, buffer); + if (status_vector->hasData()) + { + BURP_error_redirect(&status_vector, 38); // !!!!!!!!! new message + // msg 38 isc_put_segment failed + } + first = false; + } +} + + +void get_blob_old(BurpGlobals* tdgbl, const burp_fld* fields, UCHAR* record_buffer) { /************************************** * @@ -2710,14 +2827,507 @@ rec_type get_data(BurpGlobals* tdgbl, burp_rel* relation, bool skip_relation) * Write data records for a relation. * **************************************/ - Firebird::IRequest* req_handle = 0; - BASED_ON RDB$INDICES.RDB$INDEX_NAME index_name; + ULONG records = 0; + rec_type record; + burp_fld* field; // If we're only doing meta-data, ignore data records if (tdgbl->gbl_sw_meta || skip_relation) return ignore_data(tdgbl, relation); + // For old versions and embedded connections switch to old style method + // Avoid if possible switch to old style when system domains are used in a table + + if (tdgbl->gbl_network_protocol == 0) + { + bool sysDomFlag = false; + for (field = relation->rel_fields; field && (!sysDomFlag); field = field->fld_next) + { + if (field->fld_flags & FLD_computed) + continue; + + const char* dom = field->fld_source; + if (strncmp(dom, "RDB$", 4) != 0) + continue; + + for (dom += 4; *dom; ++dom) + { +#ifdef HAVE_CTYPE_H + if (!isdigit(*dom)) +#else + if (*dom < '0' || *dom > '9') +#endif + { + sysDomFlag = true; + break; + } + } + } + + if (!sysDomFlag) + return get_data_old(tdgbl, relation); + } + else if (tdgbl->gbl_network_protocol < 16) + return get_data_old(tdgbl, relation); + + // Number of fields in a message + + unsigned count = 0; + for (field = relation->rel_fields; field; field = field->fld_next) + { + if (!(field->fld_flags & FLD_computed)) + ++count; + } + + // Time to generate SQL and message metadata to store data. Whoppee. + + try + { + Firebird::string sqlStatement; + sqlStatement.printf("insert into %s(", relation->rel_name); + + Firebird::RefPtr builder(Firebird::REF_NO_INCR, + Firebird::MasterInterfacePtr()->getMetadataBuilder(fbStatus, count)); + if (fbStatus->hasData()) + general_on_error(); + + RCRD_OFFSET offset = 0; + count = 0; + for (field = relation->rel_fields; field; field = field->fld_next) + { + if (field->fld_flags & FLD_computed) + continue; + + USHORT dtype = field->fld_type; + + // arrays are of various fld_types but are really blobs + + if (field->fld_flags & FLD_array) + dtype = blr_blob; + + DSC desc; + if (!DSC_make_descriptor(&desc, dtype, field->fld_scale, field->fld_length, + field->fld_sub_type, field->fld_character_set_id, field->fld_collation_id)) + { + BURP_error(26, true, SafeArg() << dtype); + // msg 26 datatype %ld not understood + } + + SSHORT alignment = type_alignments[desc.dsc_dtype]; + if (alignment) + offset = FB_ALIGN(offset, alignment); + field->fld_offset = offset; + offset += field->fld_total_len = desc.dsc_length; + + SLONG sqlLength, sqlSubType, sqlScale, sqlType; + desc.getSqlInfo(&sqlLength, &sqlSubType, &sqlScale, &sqlType); + SLONG characterSetId = field->fld_character_set_id; + + if (tdgbl->gbl_sw_fix_fss_data && field->fld_character_set_id == CS_UNICODE_FSS && + ((sqlType == SQL_BLOB && field->fld_sub_type == isc_blob_text && !(field->fld_flags & FLD_array)) || + sqlType == SQL_TEXT || sqlType == SQL_VARYING)) + { + characterSetId = tdgbl->gbl_sw_fix_fss_data_id; + } + else if (field->fld_flags & FLD_array) + { + sqlType = SQL_QUAD; + sqlScale = 0; + } + + builder->setType(&tdgbl->throwStatus, count, sqlType); + builder->setSubType(&tdgbl->throwStatus, count, sqlSubType); + builder->setLength(&tdgbl->throwStatus, count, sqlLength); + builder->setScale(&tdgbl->throwStatus, count, sqlScale); + builder->setCharSet(&tdgbl->throwStatus, count, characterSetId); + + sqlStatement += field->fld_name; + sqlStatement += ", "; + + field->fld_parameter = count++; + } + + fb_assert(sqlStatement.end()[-2] == ','); + sqlStatement.end()[-2] = ')'; + + Firebird::RefPtr meta(Firebird::REF_NO_INCR, + builder->getMetadata(&tdgbl->throwStatus)); + builder = nullptr; + + sqlStatement += "values ("; + + count = 0; + for (field = relation->rel_fields; field; field = field->fld_next) + { + if (field->fld_flags & FLD_computed) + continue; + + offset = FB_ALIGN(offset, sizeof(SSHORT)); + field->fld_missing_parameter = count; + field->fld_missing_offset = offset; + offset += sizeof(SSHORT); + + field->fld_sql = meta->getOffset(&tdgbl->throwStatus, count); + field->fld_null = meta->getNullOffset(&tdgbl->throwStatus, count); + + if (tdgbl->gbl_sw_transportable) + { + field->fld_offset = field->fld_sql; + field->fld_missing_offset = field->fld_null; + } + + sqlStatement += "?, "; + ++count; + } + + fb_assert(sqlStatement.end()[-2] == ','); + sqlStatement.end()[-2] = ')'; + + RCRD_LENGTH length = offset; + + // Create batch + + const int GBAK_BATCH_STEP = 1000; + Firebird::AutoDispose pb(Firebird::UtilInterfacePtr()-> + getXpbBuilder(&tdgbl->throwStatus, Firebird::IXpbBuilder::BATCH, NULL, 0)); + pb->insertInt(&tdgbl->throwStatus, Firebird::IBatch::TAG_MULTIERROR, 1); + pb->insertInt(&tdgbl->throwStatus, Firebird::IBatch::TAG_BLOB_POLICY, Firebird::IBatch::BLOB_ID_ENGINE); + pb->insertInt(&tdgbl->throwStatus, Firebird::IBatch::TAG_DETAILED_ERRORS, GBAK_BATCH_STEP); + pb->insertInt(&tdgbl->throwStatus, Firebird::IBatch::TAG_BUFFER_BYTES_SIZE, 0); + + Firebird::RefPtr batch(DB-> + createBatch(fbStatus, gds_trans, sqlStatement.length(), sqlStatement.c_str(), tdgbl->gbl_dialect, + meta, pb->getBufferLength(&tdgbl->throwStatus), pb->getBuffer(&tdgbl->throwStatus))); + if (fbStatus->hasData()) + { + // Possible reason of fail - use of keywords as fields in old backup + // Try to roll back to use of old version (fieldnames independent) + BURP_print(false, 27/*, sqlStatement.c_str()*/); // msg 27 isc_compile_request failed !!!!!!!! new WARNING + BURP_print_warning(fbStatus); + return get_data_old(tdgbl, relation); + } + + UCHAR* buffer = NULL; + Firebird::Array requestBuffer; + + BURP_verbose (124, relation->rel_name); // msg 124 restoring data for relation %s + + lstring data; + data.lstr_allocated = 0; + data.lstr_address = NULL; + Firebird::Array dataBuffer; + RCRD_LENGTH old_length = 0; + + Firebird::Array sqlBuffer; + UCHAR* sql = sqlBuffer.getBuffer(meta->getMessageLength(&tdgbl->throwStatus)); + + while (true) + { + if (get(tdgbl) != att_data_length) + BURP_error_redirect(NULL, 39); // msg 39 expected record length + RCRD_LENGTH len = get_int32(tdgbl); + + if (!tdgbl->gbl_sw_transportable && len != length) + { +#ifdef sparc + if (!old_length) + old_length = recompute_length(tdgbl, relation); +#endif + if (len != old_length) + { + BURP_error(40, true, SafeArg() << length << len); + // msg 40 wrong length record, expected %ld encountered %ld + } + } + + if (!buffer) + buffer = requestBuffer.getBuffer(MAX (length, len)); + + UCHAR* p; + if (tdgbl->gbl_sw_transportable) + { + if (get(tdgbl) != att_xdr_length) + { + BURP_error_redirect(NULL, 55); + // msg 55 Expected XDR record length + } + else + { + data.lstr_length = len = get_int32(tdgbl); + if (len > data.lstr_allocated) + { + data.lstr_allocated = len; + data.lstr_address = dataBuffer.getBuffer(data.lstr_allocated); + } + p = data.lstr_address; + } + } + else + p = buffer; + + if (get(tdgbl) != att_data_data) + BURP_error_redirect(NULL, 41); // msg 41 expected data attribute + + if (tdgbl->gbl_sw_compress) + decompress (tdgbl, p, len); + else + { + get_block(tdgbl, p, len); + } + + if (old_length) + realign (tdgbl, buffer, relation); + + if (tdgbl->gbl_sw_transportable) + { + buffer = sql; + CAN_encode_decode (relation, &data, buffer, false, true); + } + + if ((++records % tdgbl->verboseInterval) == 0) + BURP_verbose(107, SafeArg() << records); + + for (field = relation->rel_fields; field; field = field->fld_next) + { + if (!(field->fld_flags & FLD_computed)) + { + if (field->fld_type == blr_blob || (field->fld_flags & FLD_array)) + { + ISC_QUAD* blob_id = (ISC_QUAD*) &buffer[field->fld_offset]; + blob_id->gds_quad_high = 0; + blob_id->gds_quad_low = 0; + } + } + } + + get_record(&record, tdgbl); + while (record == rec_blob || record == rec_array) + { + if (record == rec_blob) + get_blob (tdgbl, batch, relation->rel_fields, buffer); + else if (record == rec_array) + get_array (tdgbl, relation, buffer); + get_record(&record, tdgbl); + } + + if (!tdgbl->gbl_sw_transportable) + { + for (field = relation->rel_fields; field; field = field->fld_next) + { + if (field->fld_flags & FLD_computed) + continue; + + // convert record to SQL format + + memcpy(&sql[field->fld_sql], &buffer[field->fld_offset], field->fld_total_len); + memcpy(&sql[field->fld_null], &buffer[field->fld_missing_offset], sizeof(SSHORT)); + } + } + + batch->add(&tdgbl->throwStatus, 1, sql); + if ((records % 1000 != 0) && (record == rec_data)) + continue; + + Firebird::AutoDispose cs(batch->execute(&tdgbl->throwStatus, gds_trans)); + if (tdgbl->throwStatus->getState() && Firebird::IStatus::STATE_WARNINGS) + BURP_print_warning(&tdgbl->throwStatus); + + for (unsigned pos = 0; pos = cs->findError(&tdgbl->throwStatus, pos), + pos != Firebird::IBatchCompletionState::NO_MORE_ERRORS; ++pos) + { + Firebird::LocalStatus status_vector; + cs->getStatus(&tdgbl->throwStatus, &status_vector, pos); + ISC_STATUS code = status_vector.getErrors()[1]; + + if (code == isc_not_valid) + { + if (tdgbl->gbl_sw_incremental) + { + BURP_print (false, 138, relation->rel_name); + // msg 138 validation error on field in relation %s + BURP_print_status (false, &status_vector); + } + else + BURP_error_redirect(&status_vector, 47); + // msg 47 warning -- record could not be restored + } + else if (code == isc_malformed_string) + { + if (tdgbl->gbl_sw_incremental) + { + // msg 114 restore failed for record in relation %s + BURP_print(false, 114, relation->rel_name); + + BURP_print_status(false, &status_vector); + BURP_print(false, 342); // isc_gbak_invalid_data + } + else + BURP_error_redirect(&status_vector, 342); // isc_gbak_invalid_data + } + else + { + if (tdgbl->gbl_sw_incremental) + { + BURP_print (false, 114, relation->rel_name); + // msg 114 restore failed for record in relation %s + BURP_print_status (false, &status_vector); + } + else + BURP_error_redirect(&status_vector, 48); + // msg 48 isc_send failed + } + + records--; + } + + if (record != rec_data) + break; + } // while (true) + } + catch(const Firebird::FbException& ex) + { + BURP_print_status (true, ex.getStatus()); + BURP_abort(); + } + + if (tdgbl->gbl_sw_incremental) + { + BURP_verbose (72, relation->rel_name); + // msg 72 committing data for relation %s + COMMIT + // existing ON_ERROR continues past error, beck + ON_ERROR + + // Fix for bug_no 8055: + // don't throw away the database just because an index + // could not be made + + // don't bring the database on-line + tdgbl->flag_on_line = false; + ISC_STATUS error_code; + while (error_code = tdgbl->status_vector[1]) + { + BASED_ON RDB$INDICES.RDB$INDEX_NAME index_name; + Firebird::IRequest* req_handle = 0; + + switch (error_code) + { + case isc_sort_mem_err: + case isc_no_dup: + strcpy(index_name, (TEXT *)tdgbl->status_vector[3]); + BURP_print_status(false, &tdgbl->status_vector); + FOR (REQUEST_HANDLE req_handle) + IDX IN RDB$INDICES WITH IDX.RDB$INDEX_NAME EQ index_name + MODIFY IDX USING + IDX.RDB$INDEX_INACTIVE = TRUE; + BURP_print(false, 240, index_name); + // msg 240 Index \"%s\" failed to activate because: + if ( error_code == isc_no_dup ) + { + BURP_print(false, 241); + // msg 241 The unique index has duplicate values or NULLs + BURP_print(false, 242); + // msg 242 Delete or Update duplicate values or NULLs, and activate index with + } + else + { + BURP_print(false, 244); + // msg 244 Not enough disk space to create the sort file for an index + BURP_print(false, 245); + // msg 245 Set the TMP environment variable to a directory on a filesystem that does have enough space, and activate index with + } + BURP_print(false, 243, index_name); + // msg 243 ALTER INDEX \"%s\" ACTIVE + END_MODIFY; + END_FOR; + // commit one more time + COMMIT + ON_ERROR + continue; + END_ERROR + break; + default: + BURP_print (false, 69, relation->rel_name); + // msg 69 commit failed on relation %s + BURP_print_status (false, &tdgbl->status_vector); + ROLLBACK; + ON_ERROR + general_on_error (); + END_ERROR; + break; + } // end of switch + } // end of while + END_ERROR; + + EXEC SQL SET TRANSACTION NO_AUTO_UNDO; + if (gds_status->hasData()) + EXEC SQL SET TRANSACTION; + } + BURP_verbose (107, SafeArg() << records); + // msg 107 %ld records restored + + return record; +} + +// We have a corrupt backup, save the restore process from becoming useless. +void fix_exception(BurpGlobals* tdgbl, const char* exc_name, scan_attr_t& scan_next_attr, + const att_type attribute, att_type& failed_attrib, UCHAR*& msg_ptr, ULONG& l2, bool& msg_seen) +{ + if (msg_seen && (tdgbl->RESTORE_format == 7 || tdgbl->RESTORE_format == 8)) + { + if (!failed_attrib) + { + failed_attrib = attribute; + BURP_print(false, 313, SafeArg() << failed_attrib << exc_name); + } + + // Notice we use 1021 instead of 1023 because this is the maximum length + // for this field in v2.0 and v2.1 and they produce the corrupt backups. + const unsigned int FIELD_LIMIT = 1021; + + if (FIELD_LIMIT < l2 + 1) // not enough space + { + bad_attribute(scan_next_attr, failed_attrib, 287); + return; + } + const unsigned int remaining = FIELD_LIMIT - l2; + + *msg_ptr++ = char(attribute); // (1) + + UCHAR* rc_ptr = get_block(tdgbl, msg_ptr, MIN(remaining - 1, 255)); + if (remaining > 1 && rc_ptr == msg_ptr) // we couldn't read anything + { + bad_attribute(scan_next_attr, failed_attrib, 287); + return; + } + + l2 += rc_ptr - msg_ptr + 1; // + 1 because (1) + msg_ptr = rc_ptr; + *msg_ptr = 0; + + if (l2 == FIELD_LIMIT) + msg_seen = false; + } + else + bad_attribute(scan_next_attr, attribute, 287); // msg 287 exception +} + +rec_type get_data_old(BurpGlobals* tdgbl, burp_rel* relation) +{ +/************************************** + * + * g e t _ d a t a + * + ************************************** + * + * Functional description + * Write data records for a relation. + * + **************************************/ + Firebird::IRequest* req_handle = 0; + BASED_ON RDB$INDICES.RDB$INDEX_NAME index_name; + // Start by counting the interesting fields RCRD_OFFSET offset = 0; @@ -2734,8 +3344,7 @@ rec_type get_data(BurpGlobals* tdgbl, burp_rel* relation, bool skip_relation) } } - if (tdgbl->RESTORE_format >= 2) - count += count; + count += count; // Time to generate blr to store data. Whoppee. @@ -2846,19 +3455,16 @@ rec_type get_data(BurpGlobals* tdgbl, burp_rel* relation, bool skip_relation) offset += length; } - // If this is format version 2, build fields for null flags - - if (tdgbl->RESTORE_format >= 2) - for (field = relation->rel_fields; field; field = field->fld_next) - { - if (field->fld_flags & FLD_computed) - continue; - add_byte(blr, blr_short); - add_byte(blr, 0); - offset = FB_ALIGN(offset, sizeof(SSHORT)); - field->fld_missing_parameter = count++; - offset += sizeof(SSHORT); - } + for (field = relation->rel_fields; field; field = field->fld_next) + { + if (field->fld_flags & FLD_computed) + continue; + add_byte(blr, blr_short); + add_byte(blr, 0); + offset = FB_ALIGN(offset, sizeof(SSHORT)); + field->fld_missing_parameter = count++; + offset += sizeof(SSHORT); + } length = offset; @@ -2878,19 +3484,12 @@ rec_type get_data(BurpGlobals* tdgbl, burp_rel* relation, bool skip_relation) if (field->fld_flags & FLD_computed) continue; add_byte(blr, blr_assignment); - if (tdgbl->RESTORE_format >= 2) - { - add_byte(blr, blr_parameter2); - add_byte(blr, 0); - add_word(blr, field->fld_parameter); - add_word(blr, field->fld_missing_parameter); - } - else - { - add_byte(blr, blr_parameter); - add_byte(blr, 0); - add_word(blr, field->fld_parameter); - } + + add_byte(blr, blr_parameter2); + add_byte(blr, 0); + add_word(blr, field->fld_parameter); + add_word(blr, field->fld_missing_parameter); + add_byte(blr, blr_field); add_byte(blr, 0); add_string(blr, field->fld_name); @@ -2995,7 +3594,7 @@ rec_type get_data(BurpGlobals* tdgbl, burp_rel* relation, bool skip_relation) realign (tdgbl, (UCHAR*) buffer, relation); if (tdgbl->gbl_sw_transportable) - CAN_encode_decode (relation, &data, (UCHAR *)buffer, FALSE); + CAN_encode_decode (relation, &data, (UCHAR *)buffer, false); records++; @@ -3019,7 +3618,7 @@ rec_type get_data(BurpGlobals* tdgbl, burp_rel* relation, bool skip_relation) while (record == rec_blob || record == rec_array) { if (record == rec_blob) - get_blob (tdgbl, relation->rel_fields, (UCHAR *) buffer); + get_blob_old (tdgbl, relation->rel_fields, (UCHAR *) buffer); else if (record == rec_array) get_array (tdgbl, relation, (UCHAR *) buffer); get_record(&record, tdgbl); @@ -3164,49 +3763,6 @@ rec_type get_data(BurpGlobals* tdgbl, burp_rel* relation, bool skip_relation) return record; } -// We have a corrupt backup, save the restore process from becoming useless. -void fix_exception(BurpGlobals* tdgbl, const char* exc_name, scan_attr_t& scan_next_attr, - const att_type attribute, att_type& failed_attrib, UCHAR*& msg_ptr, ULONG& l2, bool& msg_seen) -{ - if (msg_seen && (tdgbl->RESTORE_format == 7 || tdgbl->RESTORE_format == 8)) - { - if (!failed_attrib) - { - failed_attrib = attribute; - BURP_print(false, 313, SafeArg() << failed_attrib << exc_name); - } - - // Notice we use 1021 instead of 1023 because this is the maximum length - // for this field in v2.0 and v2.1 and they produce the corrupt backups. - const unsigned int FIELD_LIMIT = 1021; - - if (FIELD_LIMIT < l2 + 1) // not enough space - { - bad_attribute(scan_next_attr, failed_attrib, 287); - return; - } - const unsigned int remaining = FIELD_LIMIT - l2; - - *msg_ptr++ = char(attribute); // (1) - - UCHAR* rc_ptr = get_block(tdgbl, msg_ptr, MIN(remaining - 1, 255)); - if (remaining > 1 && rc_ptr == msg_ptr) // we couldn't read anything - { - bad_attribute(scan_next_attr, failed_attrib, 287); - return; - } - - l2 += rc_ptr - msg_ptr + 1; // + 1 because (1) - msg_ptr = rc_ptr; - *msg_ptr = 0; - - if (l2 == FIELD_LIMIT) - msg_seen = false; - } - else - bad_attribute(scan_next_attr, attribute, 287); // msg 287 exception -} - bool get_exception(BurpGlobals* tdgbl) { /************************************** @@ -3597,6 +4153,7 @@ burp_fld* get_field(BurpGlobals* tdgbl, burp_rel* relation) case att_field_source: GET_TEXT(X.RDB$FIELD_SOURCE); + strcpy(field->fld_source, X.RDB$FIELD_SOURCE); break; case att_field_security_class: @@ -3799,6 +4356,7 @@ burp_fld* get_field(BurpGlobals* tdgbl, burp_rel* relation) case att_field_source: GET_TEXT(X.RDB$FIELD_SOURCE); + strcpy(field->fld_source, X.RDB$FIELD_SOURCE); break; case att_field_security_class: @@ -9671,19 +10229,14 @@ void realign(BurpGlobals* tdgbl, UCHAR* buffer, const burp_rel* relation) } } - // If this is format version 2 or greater, build fields for null flags - - if (tdgbl->RESTORE_format >= 2) + for (const burp_fld* field = relation->rel_fields; field; field = field->fld_next) { - for (const burp_fld* field = relation->rel_fields; field; field = field->fld_next) - { - if (field->fld_flags & FLD_computed) - continue; - p = FB_ALIGN(p, sizeof(SSHORT)); - q = FB_ALIGN(q, sizeof(SSHORT)); - *p++ = *q++; - *p++ = *q++; - } + if (field->fld_flags & FLD_computed) + continue; + p = FB_ALIGN(p, sizeof(SSHORT)); + q = FB_ALIGN(q, sizeof(SSHORT)); + *p++ = *q++; + *p++ = *q++; } } @@ -9733,17 +10286,12 @@ USHORT recompute_length(BurpGlobals* tdgbl, burp_rel* relation) offset += length; } - // If this is format version 2, build fields for null flags - - if (tdgbl->RESTORE_format >= 2) + for (const burp_fld* field = relation->rel_fields; field; field = field->fld_next) { - for (const burp_fld* field = relation->rel_fields; field; field = field->fld_next) - { - if (field->fld_flags & FLD_computed) - continue; - offset = FB_ALIGN(offset, sizeof(SSHORT)); - offset += sizeof(SSHORT); - } + if (field->fld_flags & FLD_computed) + continue; + offset = FB_ALIGN(offset, sizeof(SSHORT)); + offset += sizeof(SSHORT); } return offset; @@ -9777,9 +10325,9 @@ bool restore(BurpGlobals* tdgbl, const TEXT* file_name, const TEXT* database_nam // restore only from those backup files created by current or previous GBAK - if (tdgbl->RESTORE_format < 1 || tdgbl->RESTORE_format > ATT_BACKUP_FORMAT) + if (tdgbl->RESTORE_format < 2 || tdgbl->RESTORE_format > ATT_BACKUP_FORMAT) { - BURP_error(344, true, SafeArg() << tdgbl->RESTORE_format << 1 << ATT_BACKUP_FORMAT); + BURP_error(344, true, SafeArg() << tdgbl->RESTORE_format << 2 << ATT_BACKUP_FORMAT); // msg 44 Expected backup version @2..@3. Found @1 } diff --git a/src/common/classes/BlobWrapper.cpp b/src/common/classes/BlobWrapper.cpp index bb5b75d7ef..0549ba0e86 100644 --- a/src/common/classes/BlobWrapper.cpp +++ b/src/common/classes/BlobWrapper.cpp @@ -89,7 +89,7 @@ bool BlobWrapper::getSegment(FB_SIZE_T len, void* buffer, FB_SIZE_T& real_len) if (!m_blob || m_direction != dir_read) return false; - if (!len || !buffer) + if (len && !buffer) return false; unsigned ilen = len > SEGMENT_LIMIT ? SEGMENT_LIMIT : static_cast(len); diff --git a/src/common/classes/auto.h b/src/common/classes/auto.h index a6c1ed719b..cb53880161 100644 --- a/src/common/classes/auto.h +++ b/src/common/classes/auto.h @@ -168,6 +168,16 @@ private: }; +template +class AutoDispose : public AutoPtr > +{ +public: + AutoDispose(ID* v = nullptr) + : AutoPtr >(v) + { } +}; + + template class AutoSetRestore { diff --git a/src/dsql/DsqlBatch.cpp b/src/dsql/DsqlBatch.cpp index 2773c7d16e..bf57b088fc 100644 --- a/src/dsql/DsqlBatch.cpp +++ b/src/dsql/DsqlBatch.cpp @@ -140,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); @@ -264,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() @@ -413,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); } @@ -533,13 +534,13 @@ private: // parse blob header fb_assert(intptr_t(flow.data) % BLOB_STREAM_ALIGN == 0); - ISC_QUAD* batchBlobId = reinterpret_cast(flow.data); + ISC_QUAD batchBlobId = *reinterpret_cast(flow.data); ULONG* blobSize = reinterpret_cast(flow.data + sizeof(ISC_QUAD)); ULONG* bpbSize = reinterpret_cast(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) @@ -585,7 +586,8 @@ private: bid engineBlobId; blob = blb::create2(tdbb, transaction, &engineBlobId, bpb->getCount(), bpb->begin(), true); - registerBlob(reinterpret_cast(&engineBlobId), batchBlobId); + //DEB_BATCH(fprintf(stderr, "B-ID: (%x,%x)\n", batchBlobId.gds_quad_high, batchBlobId.gds_quad_low)); + registerBlob(reinterpret_cast(&engineBlobId), &batchBlobId); } } @@ -696,6 +698,9 @@ private: continue; ISC_QUAD* id = reinterpret_cast(&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)) { @@ -713,9 +718,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); @@ -747,6 +752,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); @@ -756,14 +770,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) @@ -805,7 +816,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.getCount() + 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)); diff --git a/src/dsql/DsqlBatch.h b/src/dsql/DsqlBatch.h index 5e244253f2..6d55e40aa0 100644 --- a/src/dsql/DsqlBatch.h +++ b/src/dsql/DsqlBatch.h @@ -107,7 +107,7 @@ private: { public: DataCache(MemoryPool& p) - : PermanentStorage(p), + : PermanentStorage(p), m_cache(getPool()), m_used(0), m_got(0), m_limit(0), m_shift(0), m_cacheCapacity(0) { } diff --git a/src/include/firebird/FirebirdInterface.idl b/src/include/firebird/FirebirdInterface.idl index 5340104067..fddf4aa6a7 100644 --- a/src/include/firebird/FirebirdInterface.idl +++ b/src/include/firebird/FirebirdInterface.idl @@ -599,6 +599,8 @@ 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); + + uint getRemoteProtocolVersion(Status status); /* Pipe createPipe(Status status, uint stmtLength, const string sqlStmt, uint dialect, Transaction transaction, MessageMetadata inMetadata, void* inBuffer, diff --git a/src/include/firebird/IdlFbInterfaces.h b/src/include/firebird/IdlFbInterfaces.h index 9c6fda1081..0905b41089 100644 --- a/src/include/firebird/IdlFbInterfaces.h +++ b/src/include/firebird/IdlFbInterfaces.h @@ -2122,6 +2122,7 @@ namespace Firebird unsigned (CLOOP_CARG *getStatementTimeout)(IAttachment* self, IStatus* status) throw(); void (CLOOP_CARG *setStatementTimeout)(IAttachment* self, IStatus* status, unsigned timeOut) throw(); IBatch* (CLOOP_CARG *createBatch)(IAttachment* self, IStatus* status, ITransaction* transaction, unsigned stmtLength, const char* sqlStmt, unsigned dialect, IMessageMetadata* inMetadata, unsigned parLength, const unsigned char* par) throw(); + unsigned (CLOOP_CARG *getRemoteProtocolVersion)(IAttachment* self, IStatus* status) throw(); }; protected: @@ -2340,6 +2341,20 @@ namespace Firebird StatusType::checkException(status); return ret; } + + template unsigned getRemoteProtocolVersion(StatusType* status) + { + if (cloopVTable->version < 4) + { + StatusType::setVersionError(status, "IAttachment", cloopVTable->version, 4); + StatusType::checkException(status); + return 0; + } + StatusType::clearException(status); + unsigned ret = static_cast(this->cloopVTable)->getRemoteProtocolVersion(this, status); + StatusType::checkException(status); + return ret; + } }; class IService : public IReferenceCounted @@ -9800,6 +9815,7 @@ namespace Firebird this->getStatementTimeout = &Name::cloopgetStatementTimeoutDispatcher; this->setStatementTimeout = &Name::cloopsetStatementTimeoutDispatcher; this->createBatch = &Name::cloopcreateBatchDispatcher; + this->getRemoteProtocolVersion = &Name::cloopgetRemoteProtocolVersionDispatcher; } } vTable; @@ -10141,6 +10157,21 @@ namespace Firebird } } + static unsigned CLOOP_CARG cloopgetRemoteProtocolVersionDispatcher(IAttachment* self, IStatus* status) throw() + { + StatusType status2(status); + + try + { + return static_cast(self)->Name::getRemoteProtocolVersion(&status2); + } + catch (...) + { + StatusType::catchException(&status2); + return static_cast(0); + } + } + static void CLOOP_CARG cloopaddRefDispatcher(IReferenceCounted* self) throw() { try @@ -10203,6 +10234,7 @@ namespace Firebird virtual unsigned getStatementTimeout(StatusType* status) = 0; virtual void setStatementTimeout(StatusType* status, unsigned timeOut) = 0; virtual IBatch* createBatch(StatusType* status, ITransaction* transaction, unsigned stmtLength, const char* sqlStmt, unsigned dialect, IMessageMetadata* inMetadata, unsigned parLength, const unsigned char* par) = 0; + virtual unsigned getRemoteProtocolVersion(StatusType* status) = 0; }; template diff --git a/src/jrd/EngineInterface.h b/src/jrd/EngineInterface.h index a31ccabe35..75e6f834fb 100644 --- a/src/jrd/EngineInterface.h +++ b/src/jrd/EngineInterface.h @@ -396,6 +396,7 @@ public: Firebird::IBatch* createBatch(Firebird::CheckStatusWrapper* status, Firebird::ITransaction* transaction, unsigned stmtLength, const char* sqlStmt, unsigned dialect, Firebird::IMessageMetadata* inMetadata, unsigned parLength, const unsigned char* par); + unsigned int getRemoteProtocolVersion(Firebird::CheckStatusWrapper* status); public: explicit JAttachment(StableAttachmentPart* js); diff --git a/src/jrd/btr.cpp b/src/jrd/btr.cpp index 6a19d7457f..fd0733b2bc 100644 --- a/src/jrd/btr.cpp +++ b/src/jrd/btr.cpp @@ -2250,7 +2250,7 @@ bool BTR_types_comparable(const dsc& target, const dsc& source) return (source.dsc_dtype <= dtype_long || source.dsc_dtype == dtype_int64); if (DTYPE_IS_NUMERIC(target.dsc_dtype)) - return (source.dsc_dtype <= dtype_double || source.dsc_dtype == dtype_int64); //!!!!!!!! + return (source.dsc_dtype <= dtype_double || source.dsc_dtype == dtype_int64); if (target.dsc_dtype == dtype_sql_date) return (source.dsc_dtype <= dtype_sql_date || source.dsc_dtype == dtype_timestamp); diff --git a/src/jrd/inf_pub.h b/src/jrd/inf_pub.h index 77527aa6b0..da36ce0b54 100644 --- a/src/jrd/inf_pub.h +++ b/src/jrd/inf_pub.h @@ -148,6 +148,7 @@ enum db_info_types fb_info_ses_idle_timeout_run = 131, fb_info_conn_flags = 132, + fb_info_protocol_version = 133, fb_info_crypt_key = 133, fb_info_crypt_state = 134, diff --git a/src/jrd/jrd.cpp b/src/jrd/jrd.cpp index 27d335ba12..630f4d080d 100644 --- a/src/jrd/jrd.cpp +++ b/src/jrd/jrd.cpp @@ -4827,6 +4827,12 @@ IBatch* JAttachment::createBatch(CheckStatusWrapper* status, ITransaction* trans } +unsigned int JAttachment::getRemoteProtocolVersion(Firebird::CheckStatusWrapper* status) +{ + return 0; // protocol == 0, i.e. no network, i.e. embedded connection +} + + int JResultSet::fetchNext(CheckStatusWrapper* user_status, void* buffer) { try diff --git a/src/remote/client/interface.cpp b/src/remote/client/interface.cpp index a6291d8088..77ddfc071b 100644 --- a/src/remote/client/interface.cpp +++ b/src/remote/client/interface.cpp @@ -371,6 +371,7 @@ private: // working with blob stream buffer void newBlob() { + setBlobAlignment(); alignBlobBuffer(blobAlign); fb_assert(blobStream - blobStreamBuffer <= blobBufferSize); @@ -384,6 +385,8 @@ private: void alignBlobBuffer(unsigned alignment, ULONG* bs = NULL) { + fb_assert(alignment); + FB_UINT64 zeroFill = 0; UCHAR* newPointer = FB_ALIGN(blobStream, alignment); ULONG align = FB_ALIGN(blobStream, alignment) - blobStream; @@ -464,6 +467,7 @@ private: void flashBatch() { + setBlobAlignment(); alignBlobBuffer(blobAlign); ULONG size = blobStream - blobStreamBuffer; if (size) @@ -472,6 +476,12 @@ private: blobStream = blobStreamBuffer; } + if (messageStream) + { + sendMessagePacket(messageStream, messageStreamBuffer); + messageStream = 0; + } + batchActive = false; } @@ -760,6 +770,11 @@ public: unsigned stmtLength, const char* sqlStmt, unsigned dialect, IMessageMetadata* inMetadata, unsigned parLength, const unsigned char* par); + unsigned getRemoteProtocolVersion(CheckStatusWrapper* status) + { + return rdb->rdb_port->port_protocol & FB_PROTOCOL_MASK; + } + public: Attachment(Rdb* handle, const PathName& path) : rdb(handle), dbPath(getPool(), path) diff --git a/src/remote/merge.cpp b/src/remote/merge.cpp index c4563d7b8d..8dc424a41a 100644 --- a/src/remote/merge.cpp +++ b/src/remote/merge.cpp @@ -48,7 +48,6 @@ USHORT MERGE_database_info(const UCHAR* in, USHORT base_level, const UCHAR* version, const UCHAR* id) - //ULONG mask Was always zero { /************************************** * diff --git a/src/remote/protocol.cpp b/src/remote/protocol.cpp index 9332a790a2..75fa9e8e73 100644 --- a/src/remote/protocol.cpp +++ b/src/remote/protocol.cpp @@ -893,7 +893,7 @@ bool_t xdr_protocol(XDR* xdrs, PACKET* p) while (count--) { - DEB_BATCH(fprintf(stderr, "BatRem: xdr packed msg\n")); + DEB_RBATCH(fprintf(stderr, "BatRem: xdr packed msg\n")); if (!xdr_packed_message(xdrs, message, statement->rsr_format)) return P_FALSE(xdrs, p); message->msg_address += statement->rsr_batch_size; @@ -912,7 +912,7 @@ bool_t xdr_protocol(XDR* xdrs, PACKET* p) MAP(xdr_short, reinterpret_cast(b->p_batch_transaction)); if (xdrs->x_op != XDR_FREE) - DEB_BATCH(fprintf(stderr, "BatRem: xdr execute\n")); + DEB_RBATCH(fprintf(stderr, "BatRem: xdr execute\n")); return P_TRUE(xdrs, p); } @@ -931,7 +931,7 @@ bool_t xdr_protocol(XDR* xdrs, PACKET* p) rem_port* port = (rem_port*) xdrs->x_public; SSHORT statement_id = b->p_batch_statement; - DEB_BATCH(fprintf(stderr, "BatRem: xdr CS %d\n", statement_id)); + DEB_RBATCH(fprintf(stderr, "BatRem: xdr CS %d\n", statement_id)); Rsr* statement; if (statement_id >= 0) @@ -961,12 +961,12 @@ bool_t xdr_protocol(XDR* xdrs, PACKET* p) if ((xdrs->x_op == XDR_DECODE) && (!b->p_batch_updates)) { - DEB_BATCH(fprintf(stderr, "BatRem: xdr reccount=%d\n", b->p_batch_reccount)); + DEB_RBATCH(fprintf(stderr, "BatRem: xdr reccount=%d\n", b->p_batch_reccount)); statement->rsr_batch_cs->regSize(b->p_batch_reccount); } // Process update counters - DEB_BATCH(fprintf(stderr, "BatRem: xdr up %d\n", b->p_batch_updates)); + DEB_RBATCH(fprintf(stderr, "BatRem: xdr up %d\n", b->p_batch_updates)); for (unsigned i = 0; i < b->p_batch_updates; ++i) { SLONG v; @@ -988,7 +988,7 @@ bool_t xdr_protocol(XDR* xdrs, PACKET* p) // Process status vectors ULONG pos = 0u; LocalStatus to; - DEB_BATCH(fprintf(stderr, "BatRem: xdr sv %d\n", b->p_batch_vectors)); + DEB_RBATCH(fprintf(stderr, "BatRem: xdr sv %d\n", b->p_batch_vectors)); for (unsigned i = 0; i < b->p_batch_vectors; ++i, ++pos) { @@ -1026,7 +1026,7 @@ bool_t xdr_protocol(XDR* xdrs, PACKET* p) // Process status-less errors pos = 0u; - DEB_BATCH(fprintf(stderr, "BatRem: xdr err %d\n", b->p_batch_errors)); + DEB_RBATCH(fprintf(stderr, "BatRem: xdr err %d\n", b->p_batch_errors)); for (unsigned i = 0; i < b->p_batch_errors; ++i, ++pos) { @@ -1059,7 +1059,7 @@ bool_t xdr_protocol(XDR* xdrs, PACKET* p) MAP(xdr_short, reinterpret_cast(b->p_batch_statement)); if (xdrs->x_op != XDR_FREE) - DEB_BATCH(fprintf(stderr, "BatRem: xdr release\n")); + DEB_RBATCH(fprintf(stderr, "BatRem: xdr release\n")); return P_TRUE(xdrs, p); } diff --git a/src/remote/remote.h b/src/remote/remote.h index 26c1404d3d..93e238c503 100644 --- a/src/remote/remote.h +++ b/src/remote/remote.h @@ -64,7 +64,7 @@ //#define COMPRESS_DEBUG 1 #endif // WIRE_COMPRESS_SUPPORT -#define DEB_BATCH(x) +#define DEB_RBATCH(x) #define REM_SEND_OFFSET(bs) (0) #define REM_RECV_OFFSET(bs) (bs) diff --git a/src/yvalve/YObjects.h b/src/yvalve/YObjects.h index ba10480527..ae7bf8ede7 100644 --- a/src/yvalve/YObjects.h +++ b/src/yvalve/YObjects.h @@ -510,6 +510,7 @@ public: YBatch* createBatch(Firebird::CheckStatusWrapper* status, Firebird::ITransaction* transaction, unsigned stmtLength, const char* sqlStmt, unsigned dialect, Firebird::IMessageMetadata* inMetadata, unsigned parLength, const unsigned char* par); + unsigned int getRemoteProtocolVersion(Firebird::CheckStatusWrapper* status); public: Firebird::IProvider* provider; diff --git a/src/yvalve/why.cpp b/src/yvalve/why.cpp index 8f77e5ccb1..7e10029762 100644 --- a/src/yvalve/why.cpp +++ b/src/yvalve/why.cpp @@ -5931,6 +5931,22 @@ YBatch* YAttachment::createBatch(CheckStatusWrapper* status, ITransaction* trans return NULL; } +unsigned int YAttachment::getRemoteProtocolVersion(CheckStatusWrapper* status) +{ + try + { + YEntry entry(status, this); + + return entry.next()->getRemoteProtocolVersion(status); + } + catch (const Exception& e) + { + e.stuffException(status); + } + + return 0; +} + //------------------------------------- From a8f30581db7ca04b367eedb7b6c6c129020702f0 Mon Sep 17 00:00:00 2001 From: Adriano dos Santos Fernandes Date: Mon, 1 Jan 2018 20:19:29 -0200 Subject: [PATCH 030/171] Corrections. --- src/burp/restore.epp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/burp/restore.epp b/src/burp/restore.epp index 40a9a9f50c..5af648a75b 100644 --- a/src/burp/restore.epp +++ b/src/burp/restore.epp @@ -489,7 +489,7 @@ int RESTORE_restore (const TEXT* file_name, const TEXT* database_name) if (gds_status->hasData()) general_on_error (); // Check to see if there is a warning - if (gds_status->getState() && Firebird::IStatus::STATE_WARNINGS) + if (gds_status->getState() & Firebird::IStatus::STATE_WARNINGS) { BURP_print_warning(gds_status); } @@ -544,7 +544,7 @@ int RESTORE_restore (const TEXT* file_name, const TEXT* database_name) END_ERROR; // Check to see if there is a warning - if (gds_status->getState() && Firebird::IStatus::STATE_WARNINGS) + if (gds_status->getState() & Firebird::IStatus::STATE_WARNINGS) { BURP_print_warning(gds_status); } @@ -3130,7 +3130,7 @@ rec_type get_data(BurpGlobals* tdgbl, burp_rel* relation, bool skip_relation) continue; Firebird::AutoDispose cs(batch->execute(&tdgbl->throwStatus, gds_trans)); - if (tdgbl->throwStatus->getState() && Firebird::IStatus::STATE_WARNINGS) + if (tdgbl->throwStatus->getState() & Firebird::IStatus::STATE_WARNINGS) BURP_print_warning(&tdgbl->throwStatus); for (unsigned pos = 0; pos = cs->findError(&tdgbl->throwStatus, pos), From 988f13dcd746015a2d398a63041777e480e88cb6 Mon Sep 17 00:00:00 2001 From: Adriano dos Santos Fernandes Date: Mon, 1 Jan 2018 21:58:26 -0200 Subject: [PATCH 031/171] Misc --- src/burp/backup.epp | 3 +- src/burp/burp.cpp | 4 +- src/burp/burp.h | 4 +- src/burp/restore.epp | 75 +++++++++++++++++------------- src/common/classes/BlobWrapper.cpp | 8 ++++ src/dsql/DsqlBatch.cpp | 1 + src/jrd/exe.cpp | 2 +- 7 files changed, 59 insertions(+), 38 deletions(-) diff --git a/src/burp/backup.epp b/src/burp/backup.epp index c21bfc4f5a..7b63369303 100644 --- a/src/burp/backup.epp +++ b/src/burp/backup.epp @@ -845,7 +845,7 @@ SINT64 get_gen_id( const TEXT* name, SSHORT name_len) getGenerator.singleSelect(tdgbl->tr_handle, &getGen); return getGen->id; } - catch(const Firebird::FbException& ex) + catch (const Firebird::FbException& ex) { Firebird::IStatus* st = ex.getStatus(); @@ -1022,6 +1022,7 @@ void put_array( burp_fld* field, burp_rel* relation, ISC_QUAD* blob_id) 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); diff --git a/src/burp/burp.cpp b/src/burp/burp.cpp index 39a0d475e3..70f88da919 100644 --- a/src/burp/burp.cpp +++ b/src/burp/burp.cpp @@ -368,8 +368,8 @@ static int svc_api_gbak(Firebird::UtilSvc* uSvc, const Switches& switches) const UCHAR* sl; do { svc_handle->query(&status, 0, NULL, - sizeof(sendbuf), sendbuf, - sizeof(respbuf), respbuf); + sizeof(sendbuf), sendbuf, + sizeof(respbuf), respbuf); if (!status.isSuccess()) { BURP_print_status(true, &status); diff --git a/src/burp/burp.h b/src/burp/burp.h index ff074dffc4..c5fbd85ed6 100644 --- a/src/burp/burp.h +++ b/src/burp/burp.h @@ -1061,6 +1061,7 @@ public: 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. Firebird::IRequest* handles_put_index_req_handle1; Firebird::IRequest* handles_put_index_req_handle2; @@ -1076,6 +1077,7 @@ public: 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 @@ -1218,6 +1220,4 @@ private: const char* format; }; - - #endif // BURP_BURP_H diff --git a/src/burp/restore.epp b/src/burp/restore.epp index 5af648a75b..49a7234426 100644 --- a/src/burp/restore.epp +++ b/src/burp/restore.epp @@ -2002,24 +2002,24 @@ void get_blob(BurpGlobals* tdgbl, Firebird::IBatch* batch, const burp_fld* field // Eat up blob segments - for (; segments > 0; --segments ) + for (; segments > 0; --segments) { USHORT length = get(tdgbl); length |= get(tdgbl) << 8; if (length) - { get_block(tdgbl, buffer, length); - } if (first) batch->addBlob(&status_vector, length, buffer, blob_id, sizeof(blob_desc), blob_desc); else batch->appendBlobData(&status_vector, length, buffer); + if (status_vector->hasData()) { BURP_error_redirect(&status_vector, 38); // !!!!!!!!! new message // msg 38 isc_put_segment failed } + first = false; } } @@ -2049,6 +2049,7 @@ void get_blob_old(BurpGlobals* tdgbl, const burp_fld* fields, UCHAR* record_buff att_type attribute; scan_attr_t scan_next_attr; skip_init(&scan_next_attr); + while (skip_scan(&scan_next_attr), get_attribute(&attribute, tdgbl) != att_blob_data) { switch (attribute) @@ -2842,7 +2843,8 @@ rec_type get_data(BurpGlobals* tdgbl, burp_rel* relation, bool skip_relation) if (tdgbl->gbl_network_protocol == 0) { bool sysDomFlag = false; - for (field = relation->rel_fields; field && (!sysDomFlag); field = field->fld_next) + + for (field = relation->rel_fields; field && !sysDomFlag; field = field->fld_next) { if (field->fld_flags & FLD_computed) continue; @@ -3011,7 +3013,7 @@ rec_type get_data(BurpGlobals* tdgbl, burp_rel* relation, bool skip_relation) UCHAR* buffer = NULL; Firebird::Array requestBuffer; - BURP_verbose (124, relation->rel_name); // msg 124 restoring data for relation %s + BURP_verbose(124, relation->rel_name); // msg 124 restoring data for relation %s lstring data; data.lstr_allocated = 0; @@ -3072,9 +3074,7 @@ rec_type get_data(BurpGlobals* tdgbl, burp_rel* relation, bool skip_relation) if (tdgbl->gbl_sw_compress) decompress (tdgbl, p, len); else - { get_block(tdgbl, p, len); - } if (old_length) realign (tdgbl, buffer, relation); @@ -3082,7 +3082,7 @@ rec_type get_data(BurpGlobals* tdgbl, burp_rel* relation, bool skip_relation) if (tdgbl->gbl_sw_transportable) { buffer = sql; - CAN_encode_decode (relation, &data, buffer, false, true); + CAN_encode_decode(relation, &data, buffer, false, true); } if ((++records % tdgbl->verboseInterval) == 0) @@ -3133,8 +3133,10 @@ rec_type get_data(BurpGlobals* tdgbl, burp_rel* relation, bool skip_relation) if (tdgbl->throwStatus->getState() & Firebird::IStatus::STATE_WARNINGS) BURP_print_warning(&tdgbl->throwStatus); - for (unsigned pos = 0; pos = cs->findError(&tdgbl->throwStatus, pos), - pos != Firebird::IBatchCompletionState::NO_MORE_ERRORS; ++pos) + for (unsigned pos = 0; + pos = cs->findError(&tdgbl->throwStatus, pos), + pos != Firebird::IBatchCompletionState::NO_MORE_ERRORS; + ++pos) { Firebird::LocalStatus status_vector; cs->getStatus(&tdgbl->throwStatus, &status_vector, pos); @@ -3185,7 +3187,7 @@ rec_type get_data(BurpGlobals* tdgbl, burp_rel* relation, bool skip_relation) break; } // while (true) } - catch(const Firebird::FbException& ex) + catch (const Firebird::FbException& ex) { BURP_print_status (true, ex.getStatus()); BURP_abort(); @@ -3193,7 +3195,7 @@ rec_type get_data(BurpGlobals* tdgbl, burp_rel* relation, bool skip_relation) if (tdgbl->gbl_sw_incremental) { - BURP_verbose (72, relation->rel_name); + BURP_verbose(72, relation->rel_name); // msg 72 committing data for relation %s COMMIT // existing ON_ERROR continues past error, beck @@ -3215,10 +3217,13 @@ rec_type get_data(BurpGlobals* tdgbl, burp_rel* relation, bool skip_relation) { case isc_sort_mem_err: case isc_no_dup: - strcpy(index_name, (TEXT *)tdgbl->status_vector[3]); + strcpy(index_name, (TEXT*) tdgbl->status_vector[3]); BURP_print_status(false, &tdgbl->status_vector); + FOR (REQUEST_HANDLE req_handle) - IDX IN RDB$INDICES WITH IDX.RDB$INDEX_NAME EQ index_name + IDX IN RDB$INDICES + WITH IDX.RDB$INDEX_NAME EQ index_name + { MODIFY IDX USING IDX.RDB$INDEX_INACTIVE = TRUE; BURP_print(false, 240, index_name); @@ -3240,6 +3245,7 @@ rec_type get_data(BurpGlobals* tdgbl, burp_rel* relation, bool skip_relation) BURP_print(false, 243, index_name); // msg 243 ALTER INDEX \"%s\" ACTIVE END_MODIFY; + } END_FOR; // commit one more time COMMIT @@ -3248,12 +3254,12 @@ rec_type get_data(BurpGlobals* tdgbl, burp_rel* relation, bool skip_relation) END_ERROR break; default: - BURP_print (false, 69, relation->rel_name); + BURP_print(false, 69, relation->rel_name); // msg 69 commit failed on relation %s BURP_print_status (false, &tdgbl->status_vector); ROLLBACK; ON_ERROR - general_on_error (); + general_on_error(); END_ERROR; break; } // end of switch @@ -3264,7 +3270,8 @@ rec_type get_data(BurpGlobals* tdgbl, burp_rel* relation, bool skip_relation) if (gds_status->hasData()) EXEC SQL SET TRANSACTION; } - BURP_verbose (107, SafeArg() << records); + + BURP_verbose(107, SafeArg() << records); // msg 107 %ld records restored return record; @@ -3291,6 +3298,7 @@ void fix_exception(BurpGlobals* tdgbl, const char* exc_name, scan_attr_t& scan_n bad_attribute(scan_next_attr, failed_attrib, 287); return; } + const unsigned int remaining = FIELD_LIMIT - l2; *msg_ptr++ = char(attribute); // (1) @@ -3317,7 +3325,7 @@ rec_type get_data_old(BurpGlobals* tdgbl, burp_rel* relation) { /************************************** * - * g e t _ d a t a + * g e t _ d a t a _ o l d * ************************************** * @@ -3542,7 +3550,9 @@ rec_type get_data_old(BurpGlobals* tdgbl, burp_rel* relation) { if (get(tdgbl) != att_data_length) BURP_error_redirect(NULL, 39); // msg 39 expected record length + RCRD_LENGTH len = get_int32(tdgbl); + if (!tdgbl->gbl_sw_transportable && len != length) { #ifdef sparc @@ -3555,9 +3565,9 @@ rec_type get_data_old(BurpGlobals* tdgbl, burp_rel* relation) // msg 40 wrong length record, expected %ld encountered %ld } } - if (!buffer) { + + if (!buffer) buffer = (SSHORT *) BURP_alloc (MAX (length, len)); - } UCHAR* p; if (tdgbl->gbl_sw_transportable) @@ -3575,26 +3585,26 @@ rec_type get_data_old(BurpGlobals* tdgbl, burp_rel* relation) BURP_free (data.lstr_address); data.lstr_address = BURP_alloc(data.lstr_allocated); } + p = data.lstr_address; } } else p = reinterpret_cast(buffer); + if (get(tdgbl) != att_data_data) BURP_error_redirect(NULL, 41); // msg 41 expected data attribute if (tdgbl->gbl_sw_compress) decompress (tdgbl, p, len); else - { get_block(tdgbl, p, len); - } if (old_length) realign (tdgbl, (UCHAR*) buffer, relation); if (tdgbl->gbl_sw_transportable) - CAN_encode_decode (relation, &data, (UCHAR *)buffer, false); + CAN_encode_decode(relation, &data, (UCHAR *)buffer, false); records++; @@ -3618,9 +3628,9 @@ rec_type get_data_old(BurpGlobals* tdgbl, burp_rel* relation) while (record == rec_blob || record == rec_array) { if (record == rec_blob) - get_blob_old (tdgbl, relation->rel_fields, (UCHAR *) buffer); + get_blob_old(tdgbl, relation->rel_fields, (UCHAR *) buffer); else if (record == rec_array) - get_array (tdgbl, relation, (UCHAR *) buffer); + get_array(tdgbl, relation, (UCHAR *) buffer); get_record(&record, tdgbl); } @@ -3637,6 +3647,7 @@ rec_type get_data_old(BurpGlobals* tdgbl, burp_rel* relation) { resync = true; ISC_STATUS code = status_vector->getErrors()[1]; + if (code == isc_not_valid) { if (tdgbl->gbl_sw_incremental) @@ -3671,8 +3682,7 @@ rec_type get_data_old(BurpGlobals* tdgbl, burp_rel* relation) BURP_print_status (false, &status_vector); } else - BURP_error_redirect(&status_vector, 48); - // msg 48 isc_send failed + BURP_error_redirect(&status_vector, 48); // msg 48 isc_send failed } records--; @@ -3687,6 +3697,7 @@ rec_type get_data_old(BurpGlobals* tdgbl, burp_rel* relation) BURP_free (data.lstr_address); request->release(); + if (tdgbl->gbl_sw_incremental) { BURP_verbose (72, relation->rel_name); @@ -3743,7 +3754,7 @@ rec_type get_data_old(BurpGlobals* tdgbl, burp_rel* relation) default: BURP_print (false, 69, relation->rel_name); // msg 69 commit failed on relation %s - BURP_print_status (false, &tdgbl->status_vector); + BURP_print_status(false, &tdgbl->status_vector); ROLLBACK; ON_ERROR general_on_error (); @@ -9081,7 +9092,7 @@ bool get_trigger_old (BurpGlobals* tdgbl, burp_rel* relation) ON_ERROR BURP_print (false, 94, name); // msg 94 trigger %s is invalid - BURP_print_status (false, &tdgbl->status_vector); + BURP_print_status(false, &tdgbl->status_vector); ROLLBACK; ON_ERROR general_on_error (); @@ -9397,7 +9408,7 @@ bool get_trigger(BurpGlobals* tdgbl) ON_ERROR BURP_print (false, 94, name); // msg 94 trigger %s is invalid - BURP_print_status (false, &tdgbl->status_vector); + BURP_print_status(false, &tdgbl->status_vector); ROLLBACK; ON_ERROR general_on_error (); @@ -9493,7 +9504,7 @@ bool get_trigger_message(BurpGlobals* tdgbl) ON_ERROR BURP_print (false, 94, name); // msg 94 trigger %s is invalid - BURP_print_status (false, &tdgbl->status_vector); + BURP_print_status(false, &tdgbl->status_vector); ROLLBACK; ON_ERROR general_on_error (); @@ -10356,7 +10367,7 @@ bool restore(BurpGlobals* tdgbl, const TEXT* file_name, const TEXT* database_nam // msg 129 started transaction att_type attribute; - Firebird::IRequest* req_handle2 =nullptr; + Firebird::IRequest* req_handle2 = nullptr; Firebird::IRequest* req_handle3 = nullptr; Firebird::IRequest* req_handle4 = nullptr; Firebird::IRequest* req_handle5 = nullptr; diff --git a/src/common/classes/BlobWrapper.cpp b/src/common/classes/BlobWrapper.cpp index 0549ba0e86..6ae3d58164 100644 --- a/src/common/classes/BlobWrapper.cpp +++ b/src/common/classes/BlobWrapper.cpp @@ -126,17 +126,20 @@ bool BlobWrapper::getData(FB_SIZE_T len, void* buffer, FB_SIZE_T& real_len, 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; } @@ -168,6 +171,7 @@ bool BlobWrapper::putSegment(FB_SIZE_T len, const void* buffer, FB_SIZE_T& real_ real_len = 0; unsigned ilen = len > SEGMENT_LIMIT ? SEGMENT_LIMIT : static_cast(len); m_blob->putSegment(m_status, ilen, buffer); + if (!m_status->isEmpty()) return false; @@ -185,6 +189,7 @@ bool BlobWrapper::putData(FB_SIZE_T len, const void* buffer, FB_SIZE_T& real_len real_len = 0; m_blob->putSegment(m_status, len, buffer); + if (!m_status->isEmpty()) return false; @@ -199,6 +204,7 @@ bool BlobWrapper::getInfo(FB_SIZE_T items_size, const UCHAR* items, return false; m_blob->getInfo(m_status, items_size, items, info_size, blob_info); + return m_status->isEmpty(); } @@ -231,12 +237,14 @@ bool BlobWrapper::getSize(SLONG* size, SLONG* seg_count, SLONG* max_seg) const 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: diff --git a/src/dsql/DsqlBatch.cpp b/src/dsql/DsqlBatch.cpp index bf57b088fc..4c82ed2e3e 100644 --- a/src/dsql/DsqlBatch.cpp +++ b/src/dsql/DsqlBatch.cpp @@ -586,6 +586,7 @@ private: bid engineBlobId; blob = blb::create2(tdbb, transaction, &engineBlobId, bpb->getCount(), bpb->begin(), true); + //DEB_BATCH(fprintf(stderr, "B-ID: (%x,%x)\n", batchBlobId.gds_quad_high, batchBlobId.gds_quad_low)); registerBlob(reinterpret_cast(&engineBlobId), &batchBlobId); } diff --git a/src/jrd/exe.cpp b/src/jrd/exe.cpp index b944376d74..5c3b46d029 100644 --- a/src/jrd/exe.cpp +++ b/src/jrd/exe.cpp @@ -692,7 +692,7 @@ void EXE_receive(thread_db* tdbb, if (desc->isBlob()) { - const bid* id = (bid*) (reinterpret_cast(buffer) + (ULONG)(IPTR)desc->dsc_address); + const bid* id = (bid*) (reinterpret_cast(buffer) + (ULONG)(IPTR) desc->dsc_address); if (transaction->tra_blobs->locate(id->bid_temp_id())) { From bee3105b475bdaaf11ecdb26c0dc0738114e359c Mon Sep 17 00:00:00 2001 From: Adriano dos Santos Fernandes Date: Fri, 16 Feb 2018 15:42:41 -0200 Subject: [PATCH 032/171] Revert wrong push (branch gbak) to master. --- builds/posix/make.rules | 7 +- src/burp/OdsDetection.epp | 11 +- src/burp/backup.epp | 344 ++++-- src/burp/burp.cpp | 231 ++-- src/burp/burp.h | 172 +-- src/burp/burp_proto.h | 6 +- src/burp/canon_proto.h | 4 +- src/burp/canonical.cpp | 14 +- src/burp/misc.cpp | 6 +- src/burp/misc_proto.h | 2 +- src/burp/restore.epp | 1190 +++++--------------- src/common/classes/BlobWrapper.cpp | 271 ----- src/common/classes/BlobWrapper.h | 95 -- src/common/classes/auto.h | 10 - src/common/status.h | 116 -- src/dsql/DsqlBatch.cpp | 126 +-- src/dsql/DsqlBatch.h | 12 +- src/gpre/obj_cxx.cpp | 14 +- src/include/fb_types.h | 1 - src/include/firebird/FirebirdInterface.idl | 8 +- src/include/firebird/IdlFbInterfaces.h | 56 +- src/jrd/EngineInterface.h | 7 +- src/jrd/btr.cpp | 2 +- src/jrd/exe.cpp | 6 +- src/jrd/exe_proto.h | 4 +- src/jrd/inf_pub.h | 1 - src/jrd/jrd.cpp | 18 +- src/jrd/jrd_proto.h | 6 +- src/jrd/status.h | 83 +- src/jrd/val.h | 3 +- src/msgs/messages2.sql | 2 +- src/remote/client/interface.cpp | 31 +- src/remote/merge.cpp | 1 + src/remote/protocol.cpp | 16 +- src/remote/remote.h | 2 +- src/yvalve/YObjects.h | 7 +- src/yvalve/why.cpp | 22 +- 37 files changed, 933 insertions(+), 1974 deletions(-) delete mode 100644 src/common/classes/BlobWrapper.cpp delete mode 100644 src/common/classes/BlobWrapper.h delete mode 100644 src/common/status.h diff --git a/builds/posix/make.rules b/builds/posix/make.rules index 5fb7f97a54..6745d0f0ea 100644 --- a/builds/posix/make.rules +++ b/builds/posix/make.rules @@ -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 -OBJECT_GPRE_FLAGS = -m -z -n -ocxx +ISQL_GPRE_FLAGS = -m -z -n -ocxx .SUFFIXES: .c .e .epp .cpp @@ -87,10 +87,7 @@ $(OBJ)/jrd/%.cpp: $(SRC_ROOT)/jrd/%.epp $(GPRE_CURRENT) $(JRD_GPRE_FLAGS) $(firstword $<) $@ $(OBJ)/isql/%.cpp: $(SRC_ROOT)/isql/%.epp - $(GPRE_CURRENT) $(OBJECT_GPRE_FLAGS) $< $@ - -$(OBJ)/burp/%.cpp: $(SRC_ROOT)/burp/%.epp - $(GPRE_CURRENT) $(OBJECT_GPRE_FLAGS) $< $@ + $(GPRE_CURRENT) $(ISQL_GPRE_FLAGS) $< $@ $(OBJ)/%.cpp: $(SRC_ROOT)/%.epp $(GPRE_CURRENT) $(GPRE_FLAGS) $(firstword $<) $@ diff --git a/src/burp/OdsDetection.epp b/src/burp/OdsDetection.epp index cbe4e2032a..f0a66545c4 100644 --- a/src/burp/OdsDetection.epp +++ b/src/burp/OdsDetection.epp @@ -64,11 +64,8 @@ namespace DATABASE DB = STATIC FILENAME "yachts.lnk"; #define DB tdgbl->db_handle -#define fbTrans tdgbl->tr_handle #define gds_trans tdgbl->tr_handle -#define fbStatus (&tdgbl->status_vector) -#define isc_status (&tdgbl->status_vector) -#define gds_status (&tdgbl->status_vector) +#define isc_status tdgbl->status_vector void detectRuntimeODS() @@ -94,7 +91,7 @@ void detectRuntimeODS() // and rdb$field_name = 'RDB$SYSTEM_FLAG'; int count = 0; - Firebird::IRequest* req_handle = nullptr; + isc_req_handle req_handle = 0; 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') @@ -109,7 +106,7 @@ void detectRuntimeODS() if (count != 2) return; - Firebird::IRequest* req_handle2 = nullptr; + isc_req_handle req_handle2 = 0; for (const rel_field_t* rel = relations; rel->relation; ++rel) { FOR (REQUEST_HANDLE req_handle2) @@ -128,7 +125,7 @@ void detectRuntimeODS() if (tdgbl->runtimeODS < DB_VERSION_DDL8) return; - Firebird::IRequest* req_handle3 = nullptr; + isc_req_handle req_handle3 = 0; for (const rel_field_t* rf = rel_fields; rf->relation; ++rf) { FOR (REQUEST_HANDLE req_handle3) diff --git a/src/burp/backup.epp b/src/burp/backup.epp index 7b63369303..3d1f68d2e6 100644 --- a/src/burp/backup.epp +++ b/src/burp/backup.epp @@ -57,12 +57,11 @@ #include "../common/prett_proto.h" #endif -#include "../common/classes/BlobWrapper.h" +#include "../common/classes/UserBlob.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 @@ -73,11 +72,8 @@ using Firebird::FbLocalStatus; 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 fbStatus (&tdgbl->status_vector) -#define isc_status (&tdgbl->status_vector) -#define gds_status (&tdgbl->status_vector) +#define isc_status tdgbl->status_vector namespace // unnamed, private { @@ -177,7 +173,7 @@ const UCHAR source_items[] = isc_info_blob_total_length, isc_info_blob_num_segments }; -const UCHAR db_info_items[] = +const SCHAR db_info_items[] = { isc_info_db_sql_dialect, isc_info_page_size, @@ -188,12 +184,12 @@ const UCHAR db_info_items[] = isc_info_db_read_only, isc_info_end }; -const UCHAR limbo_tpb[] = +const SCHAR limbo_tpb[] = { isc_tpb_version1, isc_tpb_ignore_limbo }; -const UCHAR limbo_nau_tpb[] = +const SCHAR limbo_nau_tpb[] = { isc_tpb_version1, isc_tpb_ignore_limbo, @@ -215,7 +211,7 @@ int BACKUP_backup(const TEXT* dbb_file, const TEXT* file_name) * Backup a database. * **************************************/ - FbLocalStatus status_vector; + ISC_STATUS_ARRAY status_vector; BurpGlobals* tdgbl = BurpGlobals::getSpecific(); @@ -233,23 +229,23 @@ int BACKUP_backup(const TEXT* dbb_file, const TEXT* file_name) if (tdgbl->gbl_sw_ignore_limbo) { - gds_trans = DB->startTransaction(&status_vector, sizeof(limbo_nau_tpb), limbo_nau_tpb); - if (status_vector->getState() & Firebird::IStatus::STATE_ERRORS) + 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_tpb), limbo_tpb); + isc_start_transaction(status_vector, &gds_trans, 1, &DB, sizeof(limbo_tpb), limbo_tpb); } } else { EXEC SQL SET TRANSACTION NO_AUTO_UNDO; - if (isc_status->getState() & Firebird::IStatus::STATE_ERRORS) + if (isc_status[1]) EXEC SQL SET TRANSACTION; } if (!gds_trans) { EXEC SQL SET TRANSACTION NAME gds_trans NO_AUTO_UNDO; - if (isc_status->getState() & Firebird::IStatus::STATE_ERRORS) + if (isc_status[1]) EXEC SQL SET TRANSACTION NAME gds_trans; } @@ -469,7 +465,7 @@ void compress(const UCHAR* data, ULONG length) { for (q = p + 2; q < end && (q[-2] != q[-1] || q[-1] != q[0]); q++) ; - ULONG run = (q < end) ? q - p - 2 : end - p; + USHORT run = (q < end) ? q - p - 2 : end - p; if (run) { for (; run > 127; run -= 127) @@ -831,32 +827,125 @@ SINT64 get_gen_id( const TEXT* name, SSHORT name_len) * Read id for a generator; * **************************************/ - try + 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) { - Firebird::string nm, sql; - nm.assign(name, name_len); - sql = "select first(1) gen_id(" + nm + ", 0) from rdb$database"; - - BurpGlobals* tdgbl = BurpGlobals::getSpecific(); - 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; + // 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); } - catch (const Firebird::FbException& ex) + else { - Firebird::IStatus* st = ex.getStatus(); + // 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); + } + 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 ... - if (st->getErrors()[1] == isc_dsql_error) - return 0; + return 0; + } - BURP_error_redirect(st, 25); + // 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); // msg 25 Failed in put_blr_gen_id } - return 0; // warning silencer + + + 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; } @@ -1018,16 +1107,16 @@ void put_array( burp_fld* field, burp_rel* relation, ISC_QUAD* blob_id) xdr_buffer.lstr_allocated = xdr_buffer.lstr_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()) + 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)) { 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 @@ -1090,7 +1179,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_buffer); + return_length = CAN_slice(&xdr_buffer, &xdr_slice, TRUE, /*blr_length,*/ blr_buffer); put(tdgbl, att_xdr_array); put(tdgbl, (UCHAR) (return_length)); put(tdgbl, (UCHAR) (return_length >> 8)); @@ -1155,31 +1244,31 @@ void put_blob( burp_fld* field, ISC_QUAD& blob_id) * This is for user data blobs. * **************************************/ - FbLocalStatus status_vector; + ISC_STATUS_ARRAY status_vector; BurpGlobals* tdgbl = BurpGlobals::getSpecific(); // If the blob is null, don't store it. It will be restored as null. - if (BlobWrapper::blobIsNull(blob_id)) + if (UserBlob::blobIsNull(blob_id)) return; // Open the blob and get it's vital statistics - BlobWrapper blob(&status_vector); + UserBlob 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 } @@ -1253,9 +1342,13 @@ void put_blob( burp_fld* field, ISC_QUAD& blob_id) while (segments > 0) { FB_SIZE_T segment_length; - if (!blob.getSegment(max_segment, buffer, 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)) { - BURP_error_redirect(&status_vector, 22); + BURP_error_redirect(status_vector, 22); // msg 22 isc_get_segment failed } @@ -1269,7 +1362,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) @@ -1290,28 +1383,28 @@ bool put_blr_blob( att_type attribute, ISC_QUAD& blob_id) * Return true if the blob was present, false otherwise. * **************************************/ - FbLocalStatus status_vector; + ISC_STATUS_ARRAY status_vector; BurpGlobals* tdgbl = BurpGlobals::getSpecific(); // If the blob is null, don't store it. It will be restored as null. - if (BlobWrapper::blobIsNull(blob_id)) + if (UserBlob::blobIsNull(blob_id)) return false; // Open the blob and get it's vital statistics - BlobWrapper blob(&status_vector); + UserBlob 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 } @@ -1340,7 +1433,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; } @@ -1349,7 +1442,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; } @@ -1382,7 +1475,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 } @@ -1405,9 +1498,17 @@ void put_data(burp_rel* relation) * Write relation meta-data and data. * **************************************/ - BurpGlobals* tdgbl = BurpGlobals::getSpecific(); - USHORT field_count = 1; // eof field 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; + for (field = relation->rel_fields; field; field = field->fld_next) { if (!(field->fld_flags & FLD_computed)) @@ -1428,7 +1529,7 @@ void put_data(burp_rel* relation) add_word(blr, field_count); // Number of fields, counting eof RCRD_OFFSET offset = 0; - USHORT count = 0; // This is param count. + SSHORT count = 0; // This is param count. for (field = relation->rel_fields; field; field = field->fld_next) { @@ -1564,7 +1665,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 RCRD_LENGTH length = (RCRD_LENGTH) (eof_offset + sizeof(SSHORT)); + const FLD_LENGTH length = (USHORT) (eof_offset + sizeof(SSHORT)); // Build FOR loop, body, and eof handler @@ -1618,7 +1719,7 @@ void put_data(burp_rel* relation) add_byte(blr, blr_end); add_byte(blr, blr_eoc); - unsigned blr_length = blr - blr_buffer; + SSHORT blr_length = blr - blr_buffer; #ifdef DEBUG if (debug_on) @@ -1627,11 +1728,10 @@ void put_data(burp_rel* relation) // Compile request - FbLocalStatus status_vector; - Firebird::IRequest* request = DB->compileRequest(&status_vector, blr_length, blr_buffer); - if (!status_vector.isSuccess()) + FB_API_HANDLE request = 0; + if (isc_compile_request(status_vector, &DB, &request, blr_length, (const SCHAR*) blr_buffer)) { - 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); } @@ -1641,10 +1741,9 @@ void put_data(burp_rel* relation) BURP_verbose(142, relation->rel_name); // msg 142 writing data for relation %s - request->start(&status_vector, gds_trans, 0); - if (!status_vector.isSuccess()) + if (isc_start_request(status_vector, &request, &gds_trans, 0)) { - BURP_error_redirect(&status_vector, 28); + BURP_error_redirect(status_vector, 28); // msg 28 isc_start_request failed } @@ -1667,10 +1766,9 @@ void put_data(burp_rel* relation) ULONG records = 0; while (true) { - request->receive(&status_vector, 0, 0, length, buffer); - if (!status_vector.isSuccess()) + if (isc_receive(status_vector, &request, 0, length, buffer, 0)) { - BURP_error_redirect(&status_vector, 29); + BURP_error_redirect(status_vector, 29); // msg 29 isc_receive failed } if (!*eof) @@ -1685,7 +1783,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; } @@ -1727,9 +1825,8 @@ void put_data(burp_rel* relation) BURP_verbose(108, SafeArg() << records); // msg 108 %ld records written - request->free(&status_vector); - if (!status_vector.isSuccess()) - BURP_error_redirect(&status_vector, 30); + if (isc_release_request(status_vector, &request)) + BURP_error_redirect(status_vector, 30); // msg 30 isc_release_request failed } @@ -2158,12 +2255,12 @@ bool put_source_blob(att_type attribute, att_type old_attribute, ISC_QUAD& blob_ * Include the NULL character to separate each segment. * **************************************/ - FbLocalStatus status_vector; + ISC_STATUS_ARRAY status_vector; BurpGlobals* tdgbl = BurpGlobals::getSpecific(); // If the blob is null, don't store it. It will be restored as null. - if (BlobWrapper::blobIsNull(blob_id)) + if (UserBlob::blobIsNull(blob_id)) return false; if (tdgbl->gbl_sw_old_descriptions && attribute != att_field_query_header) @@ -2171,18 +2268,18 @@ bool put_source_blob(att_type attribute, att_type old_attribute, ISC_QUAD& blob_ // Open the blob and get it's vital statistics - BlobWrapper blob(&status_vector); + UserBlob 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 } @@ -2217,7 +2314,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; @@ -2228,7 +2325,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; @@ -2263,7 +2360,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) @@ -2323,7 +2420,7 @@ void write_character_sets() * each user defined character set. * **************************************/ - Firebird::IRequest* req_handle1 = nullptr; + isc_req_handle req_handle1 = 0; BurpGlobals* tdgbl = BurpGlobals::getSpecific(); @@ -2421,7 +2518,7 @@ void write_check_constraints() * each check constraint. * **************************************/ - Firebird::IRequest* req_handle1 = nullptr; + isc_req_handle req_handle1 = 0; BurpGlobals* tdgbl = BurpGlobals::getSpecific(); @@ -2455,7 +2552,7 @@ void write_collations() * each user defined collation * **************************************/ - Firebird::IRequest* req_handle1 = nullptr; + isc_req_handle req_handle1 = 0; BurpGlobals* tdgbl = BurpGlobals::getSpecific(); @@ -2555,29 +2652,28 @@ void write_database( const TEXT* dbb_file) * the database itself. * **************************************/ - FbLocalStatus status_vector; - UCHAR buffer[256]; - Firebird::IRequest* req_handle1 = nullptr; + ISC_STATUS_ARRAY status_vector; + SCHAR buffer[256]; + isc_req_handle req_handle1 = 0; BurpGlobals* tdgbl = BurpGlobals::getSpecific(); put(tdgbl, (UCHAR) rec_physical_db); - DB->getInfo(&status_vector, sizeof(db_info_items), db_info_items, - sizeof(buffer), buffer); - if (!status_vector.isSuccess()) + if (isc_database_info(status_vector, &DB, sizeof(db_info_items), db_info_items, + sizeof(buffer), buffer)) { - 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 UCHAR* d = buffer; *d != isc_info_end; d += length) + for (const SCHAR* d = buffer; *d != isc_info_end; d += length) { const UCHAR item = *d++; - length = (USHORT) gds__vax_integer(d, 2); + length = (USHORT) isc_vax_integer(d, 2); d += 2; switch (item) { @@ -2585,27 +2681,27 @@ void write_database( const TEXT* dbb_file) break; case isc_info_page_size: - page_size = (USHORT) gds__vax_integer(d, length); + page_size = (USHORT) isc_vax_integer(d, length); put_int32(att_page_size, page_size); break; case isc_info_sweep_interval: - sweep_interval = gds__vax_integer(d, length); + sweep_interval = isc_vax_integer(d, length); put_int32(att_sweep_interval, sweep_interval); break; case isc_info_forced_writes: - forced_writes = (USHORT) gds__vax_integer(d, length); + forced_writes = (USHORT) isc_vax_integer(d, length); put_int32(att_forced_writes, forced_writes); break; case isc_info_no_reserve: - if (no_reserve = (USHORT) gds__vax_integer(d, length)) + if (no_reserve = (USHORT) isc_vax_integer(d, length)) put_int32(att_no_reserve, no_reserve); break; case isc_info_set_page_buffers: - if (page_buffers = gds__vax_integer(d, length)) + if (page_buffers = isc_vax_integer(d, length)) put_int32(att_page_buffers, page_buffers); break; @@ -2613,17 +2709,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) gds__vax_integer(d, length); + SQL_dialect = (USHORT) isc_vax_integer(d, length); put_int32(att_SQL_dialect, SQL_dialect); break; case isc_info_db_read_only: - if (db_read_only = (USHORT) gds__vax_integer(d, length)) + if (db_read_only = (USHORT) isc_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; } @@ -2691,7 +2787,7 @@ void write_exceptions() * **************************************/ TEXT temp[GDS_NAME_LEN]; - Firebird::IRequest* req_handle1 = nullptr; + isc_req_handle req_handle1 = 0; BurpGlobals* tdgbl = BurpGlobals::getSpecific(); @@ -2755,7 +2851,7 @@ void write_field_dimensions() * each array field dimension. * **************************************/ - Firebird::IRequest* req_handle1 = nullptr; + isc_req_handle req_handle1 = 0; BurpGlobals* tdgbl = BurpGlobals::getSpecific(); @@ -2790,7 +2886,7 @@ void write_filters() * **************************************/ TEXT temp[GDS_NAME_LEN]; - Firebird::IRequest* req_handle1 = nullptr; + isc_req_handle req_handle1 = 0; BurpGlobals* tdgbl = BurpGlobals::getSpecific(); @@ -2832,7 +2928,7 @@ void write_functions() **************************************/ GDS_NAME func; TEXT temp[GDS_NAME_LEN * 2]; - Firebird::IRequest* req_handle1 = nullptr; + isc_req_handle req_handle1 = 0; BurpGlobals* tdgbl = BurpGlobals::getSpecific(); @@ -3086,7 +3182,7 @@ void write_generators() * Write any defined generators. * **************************************/ - Firebird::IRequest* req_handle1 = nullptr; + isc_req_handle req_handle1 = 0; TEXT temp[GDS_NAME_LEN]; BurpGlobals* tdgbl = BurpGlobals::getSpecific(); @@ -3195,7 +3291,7 @@ void write_global_fields() * **************************************/ TEXT temp[GDS_NAME_LEN]; - Firebird::IRequest* req_handle1 = nullptr; + isc_req_handle req_handle1 = 0; BurpGlobals* tdgbl = BurpGlobals::getSpecific(); @@ -3426,7 +3522,7 @@ void write_packages() * **************************************/ TEXT temp[GDS_NAME_LEN]; - Firebird::IRequest* req_handle1 = nullptr; + isc_req_handle req_handle1 = 0; BurpGlobals* tdgbl = BurpGlobals::getSpecific(); @@ -3493,7 +3589,7 @@ void write_procedures() **************************************/ GDS_NAME proc; TEXT temp[GDS_NAME_LEN * 2]; - Firebird::IRequest* req_handle1 = nullptr; + isc_req_handle req_handle1 = 0; BurpGlobals* tdgbl = BurpGlobals::getSpecific(); @@ -3683,7 +3779,7 @@ void write_ref_constraints() * each referential constraint. * **************************************/ - Firebird::IRequest* req_handle1 = nullptr; + isc_req_handle req_handle1 = 0; BurpGlobals* tdgbl = BurpGlobals::getSpecific(); @@ -3719,7 +3815,7 @@ void write_rel_constraints() * **************************************/ TEXT temp[GDS_NAME_LEN]; - Firebird::IRequest* req_handle1 = nullptr; + isc_req_handle req_handle1 = 0; BurpGlobals* tdgbl = BurpGlobals::getSpecific(); @@ -3763,7 +3859,7 @@ void write_relations() * **************************************/ TEXT temp[GDS_NAME_LEN]; - Firebird::IRequest* req_handle1 = nullptr; + isc_req_handle req_handle1 = 0; BurpGlobals* tdgbl = BurpGlobals::getSpecific(); @@ -3893,7 +3989,7 @@ void write_relations() void write_secclasses() { TEXT temp[GDS_NAME_LEN]; - Firebird::IRequest* req_handle1 = nullptr; + isc_req_handle req_handle1 = 0; BurpGlobals* tdgbl = BurpGlobals::getSpecific(); @@ -3929,7 +4025,7 @@ void write_shadow_files() * **************************************/ BASED ON RDB$FILES.RDB$FILE_NAME temp; - Firebird::IRequest* req_handle1 = nullptr; + isc_req_handle req_handle1 = 0; BurpGlobals* tdgbl = BurpGlobals::getSpecific(); @@ -3970,7 +4066,7 @@ void write_sql_roles() * each SQL roles. * **************************************/ - Firebird::IRequest* req_handle1 = nullptr; + isc_req_handle req_handle1 = 0; TEXT temp[GDS_NAME_LEN]; BurpGlobals* tdgbl = BurpGlobals::getSpecific(); @@ -4039,7 +4135,7 @@ void write_mapping() * each names mapping. * **************************************/ - Firebird::IRequest* req_handle = nullptr; + isc_req_handle req_handle = 0; TEXT temp[GDS_NAME_LEN]; BurpGlobals* tdgbl = BurpGlobals::getSpecific(); @@ -4122,7 +4218,7 @@ void write_triggers() * **************************************/ TEXT temp[GDS_NAME_LEN]; - Firebird::IRequest* req_handle1 = nullptr; + isc_req_handle req_handle1 = 0; BurpGlobals* tdgbl = BurpGlobals::getSpecific(); @@ -4239,7 +4335,7 @@ void write_trigger_messages() * **************************************/ TEXT temp[GDS_NAME_LEN]; - Firebird::IRequest* req_handle1 = nullptr; + isc_req_handle req_handle1 = 0; BurpGlobals* tdgbl = BurpGlobals::getSpecific(); @@ -4278,7 +4374,7 @@ void write_types() * each type. * **************************************/ - Firebird::IRequest* req_handle1 = nullptr; + isc_req_handle req_handle1 = 0; BurpGlobals* tdgbl = BurpGlobals::getSpecific(); @@ -4318,7 +4414,7 @@ void write_user_privileges() * **************************************/ TEXT temp[GDS_NAME_LEN]; - Firebird::IRequest* req_handle1 = nullptr; + isc_req_handle req_handle1 = 0; BurpGlobals* tdgbl = BurpGlobals::getSpecific(); diff --git a/src/burp/burp.cpp b/src/burp/burp.cpp index 70f88da919..80b64161c8 100644 --- a/src/burp/burp.cpp +++ b/src/burp/burp.cpp @@ -65,7 +65,6 @@ #include #endif #include "../common/utils_proto.h" -#include "../common/status.h" #ifdef HAVE_UNISTD_H #include @@ -83,7 +82,6 @@ #endif using MsgFormat::SafeArg; -using Firebird::FbLocalStatus; const char* fopen_write_type = "w"; const char* fopen_read_type = "r"; @@ -104,7 +102,7 @@ enum gbak_action //FDESC = 3 // CVC: Unused }; -static void close_out_transaction(gbak_action, Firebird::ITransaction**); +static void close_out_transaction(gbak_action, isc_tr_handle*); //static void enable_signals(); //static void excp_handler(); static SLONG get_number(const SCHAR*); @@ -274,8 +272,8 @@ static int svc_api_gbak(Firebird::UtilSvc* uSvc, const Switches& switches) const Firebird::string* dbName = flag_restore ? &files[1] : &files[0]; - FbLocalStatus status; - Firebird::IService* svc_handle = nullptr; + ISC_STATUS_ARRAY status; + FB_API_HANDLE svc_handle = 0; try { @@ -319,22 +317,21 @@ static int svc_api_gbak(Firebird::UtilSvc* uSvc, const Switches& switches) spb.insertString(isc_spb_command_line, options); - svc_handle = Firebird::DispatcherPtr()->attachServiceManager(&status, service.c_str(), - spb.getBufferLength(), spb.getBuffer()); - if (!status.isSuccess()) + if (isc_service_attach(status, 0, service.c_str(), &svc_handle, + spb.getBufferLength(), reinterpret_cast(spb.getBuffer()))) { - 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; } - UCHAR thd[10]; + char thd[10]; // 'isc_action_svc_restore/isc_action_svc_backup' // 'isc_spb_verbose' // 'isc_spb_verbint' - UCHAR* thd_ptr = thd; + char* thd_ptr = thd; if (flag_restore) *thd_ptr++ = isc_action_svc_restore; else @@ -347,43 +344,41 @@ 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(thd_ptr, verbint_val); + put_vax_long(reinterpret_cast(thd_ptr), verbint_val); thd_ptr += sizeof(SLONG); } const USHORT thdlen = thd_ptr - thd; fb_assert(thdlen <= sizeof(thd)); - svc_handle->start(&status, thdlen, thd); - if (!status.isSuccess()) + if (isc_service_start(status, &svc_handle, NULL, thdlen, thd)) { - BURP_print_status(true, &status); - svc_handle->release(); + BURP_print_status(true, status); + isc_service_detach(status, &svc_handle); BURP_print(true, 83); // msg 83 Exiting before completion due to errors return FINI_ERROR; } - const UCHAR sendbuf[] = { isc_info_svc_line }; - UCHAR respbuf[1024]; - const UCHAR* sl; + const char sendbuf[] = { isc_info_svc_line }; + char respbuf[1024]; + const char* sl; do { - svc_handle->query(&status, 0, NULL, - sizeof(sendbuf), sendbuf, - sizeof(respbuf), respbuf); - if (!status.isSuccess()) + if (isc_service_query(status, &svc_handle, NULL, 0, NULL, + sizeof(sendbuf), sendbuf, + sizeof(respbuf), respbuf)) { - BURP_print_status(true, &status); - svc_handle->release(); + BURP_print_status(true, status); + isc_service_detach(status, &svc_handle); BURP_print(true, 83); // msg 83 Exiting before completion due to errors return FINI_ERROR; } - UCHAR* p = respbuf; + char* p = respbuf; sl = p; if (*p++ == isc_info_svc_line) { - const ISC_USHORT len = (ISC_USHORT) gds__vax_integer(p, sizeof(ISC_USHORT)); + const ISC_USHORT len = (ISC_USHORT) isc_vax_integer(p, sizeof(ISC_USHORT)); p += sizeof(ISC_USHORT); if (!len) { @@ -400,16 +395,18 @@ static int svc_api_gbak(Firebird::UtilSvc* uSvc, const Switches& switches) } } while (*sl == isc_info_svc_line); - svc_handle->release(); + isc_service_detach(status, &svc_handle); return FINI_OK; } catch (const Firebird::Exception& e) { - FbLocalStatus s; - e.stuffException(&s); - BURP_print_status(true, &s); + Firebird::StaticStatusVector s; + e.stuffException(s); + BURP_print_status(true, s.begin()); if (svc_handle) - svc_handle->release(); + { + isc_service_detach(status, &svc_handle); + } BURP_print(true, 83); // msg 83 Exiting before completion due to errors return FINI_ERROR; } @@ -1288,8 +1285,10 @@ int gbak(Firebird::UtilSvc* uSvc) { // Non-burp exception was caught tdgbl->burp_throw = false; - e.stuffException(&tdgbl->status_vector); - BURP_print_status(true, &tdgbl->status_vector); + 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); if (! tdgbl->uSvc->isService()) { BURP_print(true, 83); // msg 83 Exiting before completion due to errors @@ -1320,10 +1319,9 @@ int gbak(Firebird::UtilSvc* uSvc) { close_out_transaction(action, &tdgbl->tr_handle); close_out_transaction(action, &tdgbl->global_trans); - tdgbl->db_handle->detach(&tdgbl->status_vector); - if (tdgbl->status_vector->getState() & Firebird::IStatus::STATE_ERRORS) + if (isc_detach_database(tdgbl->status_vector, &tdgbl->db_handle)) { - BURP_print_status(true, &tdgbl->status_vector); + BURP_print_status(true, tdgbl->status_vector); } } @@ -1430,7 +1428,7 @@ void BURP_error(USHORT errcode, bool abort, const char* str) } -void BURP_error_redirect(Firebird::IStatus* status_vector, USHORT errcode, const SafeArg& arg) +void BURP_error_redirect(const ISC_STATUS* status_vector, USHORT errcode, const SafeArg& arg) { /************************************** * @@ -1518,24 +1516,26 @@ void BURP_msg_get(USHORT number, TEXT* output_msg, const SafeArg& arg) strcpy(output_msg, buffer); } -void OutputVersion::callback(Firebird::CheckStatusWrapper* status, const char* text) + +void BURP_output_version(void* arg1, const TEXT* arg2) { /************************************** * - * O u t p u t V e r s i o n :: c a l l b a c k + * B U R P _ o u t p u t _ v e r s i o n * ************************************** * * Functional description * Callback routine for access method - * printing (specifically show version) + * printing (specifically show version); * will accept. * **************************************/ - burp_output(false, format, text); + burp_output(false, static_cast(arg1), arg2); } + void BURP_print(bool err, USHORT number, const SafeArg& arg) { /************************************** @@ -1577,7 +1577,7 @@ void BURP_print(bool err, USHORT number, const char* str) } -void BURP_print_status(bool err, Firebird::IStatus* status_vector) +void BURP_print_status(bool err, const ISC_STATUS* status_vector) { /************************************** * @@ -1592,7 +1592,7 @@ void BURP_print_status(bool err, Firebird::IStatus* status_vector) **************************************/ if (status_vector) { - const ISC_STATUS* vector = status_vector->getErrors(); + const ISC_STATUS* vector = status_vector; if (err) { @@ -1622,7 +1622,7 @@ void BURP_print_status(bool err, Firebird::IStatus* status_vector) } -void BURP_print_warning(Firebird::IStatus* status) +void BURP_print_warning(const ISC_STATUS* status_vector) { /************************************** * @@ -1635,10 +1635,14 @@ void BURP_print_warning(Firebird::IStatus* status) * to allow redirecting output. * **************************************/ - if (status && (status->getState() & Firebird::IStatus::STATE_WARNINGS)) + if (status_vector) { + // 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->getWarnings(); + const ISC_STATUS* vector = &status_vector[2]; SCHAR s[1024]; if (fb_interpret(s, sizeof(s), &vector)) @@ -1712,7 +1716,7 @@ void BURP_verbose(USHORT number, const char* str) } -static void close_out_transaction(gbak_action action, Firebird::ITransaction** tPtr) +static void close_out_transaction(gbak_action action, isc_tr_handle* handle) { /************************************** * @@ -1727,38 +1731,31 @@ static void close_out_transaction(gbak_action action, Firebird::ITransaction** t * returned to the system. * **************************************/ - if (*tPtr) + if (*handle != 0) { - FbLocalStatus status_vector; + ISC_STATUS_ARRAY status_vector; if (action == RESTORE) { // Even if the restore failed, commit the transaction so that // a partial database is at least recovered. - (*tPtr)->commit(&status_vector); - if (!status_vector.isSuccess()) + isc_commit_transaction(status_vector, handle); + if (status_vector[1]) { // 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. - (*tPtr)->rollback(&status_vector); - if (!status_vector.isSuccess()) - BURP_print_status(false, &status_vector); - else - *tPtr = nullptr; + isc_rollback_transaction(status_vector, handle); + if (status_vector[1]) + BURP_print_status(false, status_vector); } - 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 - (*tPtr)->rollback(&status_vector); - if (!status_vector.isSuccess()) - BURP_print_status(false, &status_vector); - else - *tPtr = nullptr; + if (isc_rollback_transaction(status_vector, handle)) + BURP_print_status(false, status_vector); } } } @@ -1813,37 +1810,38 @@ static gbak_action open_files(const TEXT* file1, * **************************************/ BurpGlobals* tdgbl = BurpGlobals::getSpecific(); - FbLocalStatus temp_status; - Firebird::CheckStatusWrapper* status_vector = &temp_status; + ISC_STATUS_ARRAY temp_status; + ISC_STATUS* status_vector = temp_status; // try to attach the database using the first file_name if (sw_replace != IN_SW_BURP_C && sw_replace != IN_SW_BURP_R) { - tdgbl->db_handle = Firebird::DispatcherPtr()->attachDatabase(status_vector, file1, - dpb.getBufferLength(), dpb.getBuffer()); - if (!status_vector->hasData()) + if (!isc_attach_database(status_vector, + (SSHORT) 0, file1, + &tdgbl->db_handle, + dpb.getBufferLength(), + reinterpret_cast(dpb.getBuffer()))) { if (sw_replace != IN_SW_BURP_B) { // msg 13 REPLACE specified, but the first file %s is a database BURP_error(13, true, file1); - tdgbl->db_handle->detach(status_vector); - if (status_vector->hasData()) + if (isc_detach_database(status_vector, &tdgbl->db_handle)) { BURP_print_status(true, status_vector); + } return QUIT; } if (tdgbl->gbl_sw_version) { // msg 139 Version(s) for database "%s" BURP_print(false, 139, file1); - OutputVersion outputVersion("\t%s\n"); - Firebird::UtilInterfacePtr()->getFbVersion(status_vector, tdgbl->db_handle, &outputVersion); + isc_version(&tdgbl->db_handle, BURP_output_version, (void*) "\t%s\n"); } BURP_verbose(166, file1); // msg 166: readied database %s for backup } else if (sw_replace == IN_SW_BURP_B || - (status_vector->getErrors()[1] != isc_io_error && status_vector->getErrors()[1] != isc_bad_db_format)) + (status_vector[1] != isc_io_error && status_vector[1] != isc_bad_db_format)) { BURP_print_status(true, status_vector); return QUIT; @@ -1967,9 +1965,10 @@ static gbak_action open_files(const TEXT* file1, } else { - tdgbl->db_handle->detach(status_vector); - if (status_vector->hasData()) - BURP_print_status(true, status_vector); + if (isc_detach_database(status_vector, &tdgbl->db_handle)) + { + BURP_print_status(false, status_vector); + } } return flag; @@ -2140,45 +2139,49 @@ 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) + 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(dpb.getBuffer()))) { - tdgbl->db_handle = Firebird::DispatcherPtr()->attachDatabase(status_vector, *file2, - dpb.getBufferLength(), dpb.getBuffer()); - if (status_vector->isEmpty()) + if (sw_replace == IN_SW_BURP_C) { - if (sw_replace == IN_SW_BURP_C) - { - tdgbl->db_handle->detach(status_vector); - if (status_vector->hasData()) - BURP_print_status(true, status_vector); - BURP_error(14, true, *file2); - // msg 14 database %s already exists. To replace it, use the -R switch + if (isc_detach_database(status_vector, &tdgbl->db_handle)) { + BURP_print_status(true, status_vector); } - else + 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->db_handle->dropDatabase(status_vector); - if (status_vector->hasData()) - { - Firebird::FbLocalStatus status2; - tdgbl->db_handle->detach(&status2); - if (!status2.isSuccess()) - BURP_print_status(true, &status2); - - BURP_error(233, true, *file2); - // msg 233 Cannot drop database %s, might be in use + 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 } } - 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 + } + 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. - } + 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 @@ -2455,18 +2458,18 @@ void BurpGlobals::read_stats(SINT64* stats) if (!db_handle) return; - const UCHAR info[] = + const char info[] = { isc_info_reads, isc_info_writes }; - FbLocalStatus status; - UCHAR buffer[sizeof(info) * (1 + 2 + 8) + 2]; + ISC_STATUS_ARRAY status = {0}; + char buffer[sizeof(info) * (1 + 2 + 8) + 2]; - db_handle->getInfo(&status, sizeof(info), info, sizeof(buffer), buffer); + isc_database_info(status, &db_handle, sizeof(info), info, sizeof(buffer), buffer); - UCHAR* p = buffer, *const e = buffer + sizeof(buffer); + char* p = buffer, *const e = buffer + sizeof(buffer); while (p < e) { int flag = -1; @@ -2487,7 +2490,7 @@ void BurpGlobals::read_stats(SINT64* stats) if (flag != -1) { - const int len = gds__vax_integer(p + 1, 2); + const int len = isc_vax_integer(p + 1, 2); stats[flag] = isc_portable_integer((ISC_UCHAR*) p + 1 + 2, len); p += len + 3; } diff --git a/src/burp/burp.h b/src/burp/burp.h index c5fbd85ed6..a1dbf97d9a 100644 --- a/src/burp/burp.h +++ b/src/burp/burp.h @@ -31,8 +31,6 @@ #include #include "../jrd/ibase.h" -#include "firebird/Interface.h" -#include "firebird/Message.h" #include "../common/dsc.h" #include "../burp/misc_proto.h" #include "../yvalve/gds_proto.h" @@ -42,8 +40,6 @@ #include "../common/classes/fb_pair.h" #include "../common/classes/MetaName.h" #include "../../jrd/SimilarToMatcher.h" -#include "../common/status.h" -#include "../common/classes/ImplementHelper.h" #ifdef HAVE_UNISTD_H #include @@ -664,14 +660,12 @@ 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; @@ -700,8 +694,6 @@ 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 { @@ -936,6 +928,7 @@ public: // this is VERY dirty hack to keep current behaviour memset (&gbl_database_file_name, 0, &veryEnd - reinterpret_cast(&gbl_database_file_name)); + memset(status_vector, 0, sizeof(status_vector)); gbl_stat_flags = 0; gbl_stat_header = false; @@ -962,7 +955,6 @@ 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; @@ -981,7 +973,6 @@ public: burp_fil* gbl_sw_files; burp_fil* gbl_sw_backup_files; gfld* gbl_global_fields; - unsigned gbl_network_protocol; burp_act* action; ULONG io_buffer_size; redirect_vals sw_redirect; @@ -1010,10 +1001,11 @@ public: SCHAR mvol_old_file [MAX_FILE_NAME_SIZE]; int mvol_volume_count; bool mvol_empty_file; - Firebird::IAttachment* db_handle; - Firebird::ITransaction* tr_handle; - Firebird::ITransaction* global_trans; + isc_db_handle db_handle; + isc_tr_handle tr_handle; + isc_tr_handle global_trans; DESC file_desc; + ISC_STATUS_ARRAY status_vector; int exit_code; UCHAR* head_of_mem_list; FILE* output_file; @@ -1023,61 +1015,59 @@ public: // burp_fld* v3_cvt_fld_list; // The handles_get... are for restore. - 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; - + 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; // The handles_put.. are for backup. - 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; - + 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; bool hdr_forced_writes; TEXT database_security_class[GDS_NAME_LEN]; // To save database security class for deferred update @@ -1099,9 +1089,6 @@ public: char veryEnd; //starting after this members must be initialized in constructor explicitly - Firebird::FbLocalStatus status_vector; - Firebird::ThrowLocalStatus throwStatus; - Firebird::Array > > defaultCollations; Firebird::UtilSvc* uSvc; @@ -1175,49 +1162,4 @@ enum burp_messages_vals { // BLOB buffer typedef Firebird::HalfStaticArray 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 - void singleSelect(Firebird::ITransaction* trans, M* msg) - { - stmt->execute(&tdgbl->throwStatus, tdgbl->tr_handle, nullptr, nullptr, msg->getMetadata(), msg->getData()); - } - - template - 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 -{ -public: - OutputVersion(const char* printFormat) - : format(printFormat) - { } - - void callback(Firebird::CheckStatusWrapper* status, const char* text); - -private: - const char* format; -}; - #endif // BURP_BURP_H diff --git a/src/burp/burp_proto.h b/src/burp/burp_proto.h index e9302a365d..b8487b86ae 100644 --- a/src/burp/burp_proto.h +++ b/src/burp/burp_proto.h @@ -34,7 +34,7 @@ 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(Firebird::IStatus*, USHORT, const MsgFormat::SafeArg& arg = MsgFormat::SafeArg()); +void BURP_error_redirect(const ISC_STATUS*, USHORT, const MsgFormat::SafeArg& arg = MsgFormat::SafeArg()); 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 +42,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, Firebird::IStatus* status); -void BURP_print_warning(Firebird::IStatus* status); +void BURP_print_status(bool err, const ISC_STATUS* status); +void BURP_print_warning(const ISC_STATUS*); void BURP_verbose(USHORT, const MsgFormat::SafeArg& arg = MsgFormat::SafeArg()); void BURP_verbose(USHORT, const char* str); diff --git a/src/burp/canon_proto.h b/src/burp/canon_proto.h index f41e68ccbc..a377c8a508 100644 --- a/src/burp/canon_proto.h +++ b/src/burp/canon_proto.h @@ -24,8 +24,8 @@ #ifndef BURP_CANON_PROTO_H #define BURP_CANON_PROTO_H -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); +ULONG CAN_encode_decode (burp_rel*, lstring*, UCHAR*, int); +ULONG CAN_slice (lstring*, lstring*, int, /*USHORT,*/ UCHAR*); #endif // BURP_CANON_PROTO_H diff --git a/src/burp/canonical.cpp b/src/burp/canonical.cpp index 365409929a..308add7663 100644 --- a/src/burp/canonical.cpp +++ b/src/burp/canonical.cpp @@ -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 direction, bool useMissingOffset) +ULONG CAN_encode_decode(burp_rel* relation, lstring* buffer, UCHAR* data, bool_t direction) { /************************************** * @@ -203,21 +203,17 @@ ULONG CAN_encode_decode(burp_rel* relation, lstring* buffer, UCHAR* data, bool d { if (field->fld_flags & FLD_computed) continue; - UCHAR* p = data + field->fld_missing_offset; - if (!useMissingOffset) - { - offset = FB_ALIGN(offset, sizeof(SSHORT)); - p = data + offset; - offset += sizeof(SSHORT); - } + offset = FB_ALIGN(offset, sizeof(SSHORT)); + UCHAR* p = data + offset; 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 direction, UCHAR* sdl) +ULONG CAN_slice(lstring* buffer, lstring* slice, bool_t direction, /*USHORT sdl_length,*/ UCHAR* sdl) { /************************************** * diff --git a/src/burp/misc.cpp b/src/burp/misc.cpp index b4fa133edc..a25b8e1262 100644 --- a/src/burp/misc.cpp +++ b/src/burp/misc.cpp @@ -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(Firebird::IRequest*& req_handle) +void MISC_release_request_silent(isc_req_handle& req_handle) { if (req_handle) { - req_handle->release(); - req_handle = nullptr; + ISC_STATUS_ARRAY req_status; + isc_release_request(req_status, &req_handle); } } diff --git a/src/burp/misc_proto.h b/src/burp/misc_proto.h index 971309e8e1..c015cb4516 100644 --- a/src/burp/misc_proto.h +++ b/src/burp/misc_proto.h @@ -26,7 +26,7 @@ UCHAR* MISC_alloc_burp(ULONG); void MISC_free_burp(void*); -void MISC_release_request_silent(Firebird::IRequest*& req_handle); +void MISC_release_request_silent(isc_req_handle& req_handle); int MISC_symbol_length(const TEXT*, ULONG); void MISC_terminate(const TEXT*, TEXT*, ULONG, ULONG); diff --git a/src/burp/restore.epp b/src/burp/restore.epp index 49a7234426..99609475a5 100644 --- a/src/burp/restore.epp +++ b/src/burp/restore.epp @@ -30,10 +30,6 @@ #include #include #include -#ifdef HAVE_CTYPE_H -#include -#endif - #include "../burp/burp.h" #include "../jrd/align.h" #include "../jrd/flags.h" @@ -53,16 +49,14 @@ #include "../common/prett_proto.h" #endif #include "../common/classes/ClumpletWriter.h" -#include "../common/classes/BlobWrapper.h" +#include "../common/classes/UserBlob.h" #include "../common/classes/SafeArg.h" #include "../common/utils_proto.h" #include "memory_routines.h" #include "../burp/OdsDetection.h" #include "../auth/trusted/AuthSspi.h" -#include "../common/dsc_proto.h" using MsgFormat::SafeArg; -using Firebird::FbLocalStatus; // For service APIs the follow DB handle is a value stored @@ -73,11 +67,8 @@ using Firebird::FbLocalStatus; DATABASE DB = STATIC FILENAME "yachts.lnk"; #define DB tdgbl->db_handle -#define fbTrans tdgbl->tr_handle #define gds_trans tdgbl->tr_handle -#define fbStatus (&tdgbl->status_vector) -#define isc_status (&tdgbl->status_vector) -#define gds_status (&tdgbl->status_vector) +#define isc_status tdgbl->status_vector namespace // unnamed, private @@ -105,7 +96,7 @@ void add_access_dpb(BurpGlobals* tdgbl, Firebird::ClumpletWriter& dpb); void add_files(BurpGlobals* tdgbl, const char*); void bad_attribute(scan_attr_t, att_type, USHORT); void create_database(BurpGlobals* tdgbl, const TEXT*); -void decompress(BurpGlobals* tdgbl, UCHAR*, ULONG); +void decompress(BurpGlobals* tdgbl, UCHAR*, USHORT); void eat_blob(BurpGlobals* tdgbl); void eat_text(BurpGlobals* tdgbl); void eat_text2(BurpGlobals* tdgbl); @@ -116,14 +107,12 @@ void fix_security_class_name(BurpGlobals* tdgbl, TEXT* sec_class, bool is_field) // returned value is not checked by the caller! bool get_acl(BurpGlobals* tdgbl, const TEXT*, ISC_QUAD*, ISC_QUAD*); void get_array(BurpGlobals* tdgbl, burp_rel*, UCHAR*); -void get_blob(BurpGlobals* tdgbl, Firebird::IBatch* batch, const burp_fld*, UCHAR*); -void get_blob_old(BurpGlobals* tdgbl, const burp_fld*, UCHAR*); +void get_blob(BurpGlobals* tdgbl, const burp_fld*, UCHAR*); void get_blr_blob(BurpGlobals* tdgbl, ISC_QUAD&, bool); bool get_character_set(BurpGlobals* tdgbl); bool get_chk_constraint(BurpGlobals* tdgbl); bool get_collation(BurpGlobals* tdgbl); rec_type get_data(BurpGlobals* tdgbl, burp_rel*, bool); -rec_type get_data_old(BurpGlobals* tdgbl, burp_rel*); bool get_exception(BurpGlobals* tdgbl); burp_fld* get_field(BurpGlobals* tdgbl, burp_rel*); bool get_field_dimensions(BurpGlobals* tdgbl); @@ -278,9 +267,7 @@ int RESTORE_restore (const TEXT* file_name, const TEXT* database_name) * Recreate a database from a backup. * **************************************/ - Firebird::IRequest* req_handle1 = nullptr; - Firebird::IRequest* req_handle3 = nullptr; - Firebird::IRequest* req_handle5 = nullptr; + isc_req_handle req_handle1 = 0, req_handle3 = 0, req_handle5 = 0; BASED_ON RDB$INDICES.RDB$INDEX_NAME index_name; BurpGlobals* tdgbl = BurpGlobals::getSpecific(); @@ -317,7 +304,7 @@ int RESTORE_restore (const TEXT* file_name, const TEXT* database_name) case isc_sort_mem_err: case isc_no_dup: strcpy(index_name, (TEXT *)tdgbl->status_vector[3]); - BURP_print_status(false, &tdgbl->status_vector); + BURP_print_status(false, tdgbl->status_vector); FOR (REQUEST_HANDLE req_handle3) IDX IN RDB$INDICES WITH IDX.RDB$INDEX_NAME EQ index_name @@ -366,7 +353,7 @@ int RESTORE_restore (const TEXT* file_name, const TEXT* database_name) // Always try to activate deferred indices - it helps for some broken backups, // and in normal cases doesn't take much time to look for such indices. AP-2008. EXEC SQL SET TRANSACTION ISOLATION LEVEL READ COMMITTED NO_AUTO_UNDO; - if (gds_status->hasData()) + if (gds_status[1]) EXEC SQL SET TRANSACTION; // Activate first indexes that are not foreign keys @@ -410,7 +397,7 @@ int RESTORE_restore (const TEXT* file_name, const TEXT* database_name) END_ERROR; EXEC SQL SET TRANSACTION ISOLATION LEVEL READ COMMITTED NO_AUTO_UNDO; - if (gds_status->hasData()) + if (gds_status[1]) EXEC SQL SET TRANSACTION; // Only activate Foreign keys that have been marked for deferred @@ -436,8 +423,9 @@ int RESTORE_restore (const TEXT* file_name, const TEXT* database_name) // activating and creating deferred index %s bool fError = false; - Firebird::ITransaction* activateIndexTran = nullptr; - FbLocalStatus local_status_vector; + isc_tr_handle activateIndexTran = 0; + ISC_STATUS_ARRAY local_status_vector; + ISC_STATUS* local_status = local_status_vector; START_TRANSACTION activateIndexTran; FOR (TRANSACTION_HANDLE activateIndexTran REQUEST_HANDLE req_handle5) @@ -448,7 +436,7 @@ int RESTORE_restore (const TEXT* file_name, const TEXT* database_name) END_FOR; ON_ERROR fError = true; - fb_utils::copyStatus(&local_status_vector, isc_status); + memcpy(local_status, isc_status, sizeof (ISC_STATUS_ARRAY)); END_ERROR; MISC_release_request_silent(req_handle5); @@ -457,7 +445,7 @@ int RESTORE_restore (const TEXT* file_name, const TEXT* database_name) COMMIT activateIndexTran; ON_ERROR fError = true; - fb_utils::copyStatus(&local_status_vector, isc_status); + memcpy(local_status, isc_status, sizeof (ISC_STATUS_ARRAY)); END_ERROR; } if (fError) @@ -467,7 +455,7 @@ int RESTORE_restore (const TEXT* file_name, const TEXT* database_name) general_on_error (); END_ERROR; BURP_print (false, 173, index_name); - BURP_print_status(false, &local_status_vector); + BURP_print_status(false, local_status); tdgbl->flag_on_line = false; } END_FOR; @@ -486,17 +474,17 @@ int RESTORE_restore (const TEXT* file_name, const TEXT* database_name) BURP_verbose (68); // msg 68 committing meta data EXEC SQL COMMIT TRANSACTION tdgbl->global_trans; - if (gds_status->hasData()) + if (gds_status[1]) general_on_error (); // Check to see if there is a warning - if (gds_status->getState() & Firebird::IStatus::STATE_WARNINGS) + if (gds_status[0] == isc_arg_gds && gds_status[1] == 0 && gds_status[2] != isc_arg_end) { BURP_print_warning(gds_status); } } EXEC SQL SET TRANSACTION ISOLATION LEVEL READ COMMITTED NO_AUTO_UNDO; - if (gds_status->hasData()) + if (gds_status[1]) EXEC SQL SET TRANSACTION; // AB: Recalculate RDB$DBKEY_LENGTH for VIEWS @@ -544,7 +532,7 @@ int RESTORE_restore (const TEXT* file_name, const TEXT* database_name) END_ERROR; // Check to see if there is a warning - if (gds_status->getState() & Firebird::IStatus::STATE_WARNINGS) + if (gds_status[0] == isc_arg_gds && gds_status[1] == 0 && gds_status[2] != isc_arg_end) { BURP_print_warning(gds_status); } @@ -580,12 +568,13 @@ int RESTORE_restore (const TEXT* file_name, const TEXT* database_name) // set forced writes to the value which was in the header dpb.insertByte(isc_dpb_force_write, tdgbl->hdr_forced_writes ? 1 : 0); - Firebird::IAttachment* db_handle = Firebird::DispatcherPtr()->attachDatabase(&tdgbl->status_vector, database_name, - dpb.getBufferLength(), dpb.getBuffer()); - if (tdgbl->status_vector->hasData()) + FB_API_HANDLE db_handle = 0; + if (isc_attach_database(tdgbl->status_vector, 0, database_name, &db_handle, + dpb.getBufferLength(), reinterpret_cast(dpb.getBuffer()))) + { general_on_error(); - db_handle->detach(&tdgbl->status_vector); - if (tdgbl->status_vector->hasData()) + } + if (isc_detach_database (tdgbl->status_vector, &db_handle)) general_on_error(); if (!tdgbl->flag_on_line) @@ -608,12 +597,12 @@ int RESTORE_restore (const TEXT* file_name, const TEXT* database_name) dpb.insertByte(isc_dpb_set_db_readonly, 1); - db_handle = Firebird::DispatcherPtr()->attachDatabase(&tdgbl->status_vector, database_name, - dpb.getBufferLength(), dpb.getBuffer()); - if (tdgbl->status_vector->hasData()) + if (isc_attach_database(tdgbl->status_vector, 0, database_name, &db_handle, + dpb.getBufferLength(), reinterpret_cast(dpb.getBuffer()))) + { general_on_error(); - db_handle->detach(&tdgbl->status_vector); - if (tdgbl->status_vector->hasData()) + } + if (isc_detach_database (tdgbl->status_vector, &db_handle)) general_on_error(); } @@ -663,7 +652,7 @@ void add_files(BurpGlobals* tdgbl, const char* file_name) * addresses & commit this much. * **************************************/ - Firebird::IRequest* req_handle1 = nullptr; + isc_req_handle req_handle1 = 0; // store the RDB$FILES records @@ -714,7 +703,7 @@ void add_files(BurpGlobals* tdgbl, const char* file_name) ON_ERROR BURP_print (false, 174); // msg 174 cannot commit files - BURP_print_status (false, &tdgbl->status_vector); + BURP_print_status (false, tdgbl->status_vector); ROLLBACK; ON_ERROR general_on_error (); @@ -722,7 +711,7 @@ void add_files(BurpGlobals* tdgbl, const char* file_name) END_ERROR; EXEC SQL SET TRANSACTION NO_AUTO_UNDO; - if (gds_status->hasData()) + if (gds_status[1]) EXEC SQL SET TRANSACTION; } } @@ -855,7 +844,7 @@ void create_database(BurpGlobals* tdgbl, const TEXT* file_name) } if (record != rec_database) - BURP_error_redirect(NULL, 32); + BURP_error_redirect (NULL, 32); // msg 32 Expected database description record if (tdgbl->gbl_sw_page_size) @@ -937,8 +926,7 @@ void create_database(BurpGlobals* tdgbl, const TEXT* file_name) // When we restore backup files that came from prior // to V6, we force the SQL database dialect to 1 - tdgbl->gbl_dialect = SQL_dialect_flag ? SQL_dialect : SQL_DIALECT_V5; - dpb.insertByte(isc_dpb_sql_dialect, tdgbl->gbl_dialect); + dpb.insertByte(isc_dpb_sql_dialect, SQL_dialect_flag ? SQL_dialect : SQL_DIALECT_V5); // start database up shut down, // use single-user mode to avoid conflicts during restore process @@ -948,7 +936,7 @@ void create_database(BurpGlobals* tdgbl, const TEXT* file_name) dpb.insertByte(isc_dpb_no_db_triggers, 1); - FbLocalStatus status_vector; + ISC_STATUS_ARRAY status_vector; if (tdgbl->gbl_sw_fix_fss_metadata) { @@ -956,35 +944,26 @@ void create_database(BurpGlobals* tdgbl, const TEXT* file_name) fb_strlen(tdgbl->gbl_sw_fix_fss_metadata)); } - DB = Firebird::DispatcherPtr()->createDatabase(&status_vector, file_name, - dpb.getBufferLength(), dpb.getBuffer()); - if (status_vector->hasData()) + if (isc_create_database(status_vector, 0, file_name, &DB, + dpb.getBufferLength(), reinterpret_cast(dpb.getBuffer()), + 0)) { - BURP_error_redirect(&status_vector, 33, SafeArg() << file_name); + BURP_error_redirect (status_vector, 33, SafeArg() << file_name); // msg 33 failed to create database %s } - tdgbl->gbl_network_protocol = DB->getRemoteProtocolVersion(&status_vector); - // treat errors as old provider missing new calls - if (status_vector->hasData()) - { - status_vector->init(); - tdgbl->gbl_network_protocol = 1; - } - if (tdgbl->gbl_sw_version && !tdgbl->uSvc->isService()) { BURP_print(false, 139, file_name); // msg 139 Version(s) for database "%s" - OutputVersion outputVersion("\t%s\n"); - Firebird::UtilInterfacePtr()->getFbVersion(&status_vector, DB, &outputVersion); + isc_version(&DB, BURP_output_version, (void*)"\t%s\n"); } BURP_verbose (74, SafeArg() << file_name << page_size); // msg 74 created database %s, page_size %ld bytes } -void decompress(BurpGlobals* tdgbl, UCHAR* buffer, ULONG length) +void decompress(BurpGlobals* tdgbl, UCHAR* buffer, USHORT length) { /************************************** * @@ -1031,7 +1010,7 @@ void decompress(BurpGlobals* tdgbl, UCHAR* buffer, ULONG length) } if (p > end) { - BURP_error_redirect(NULL, 34); // msg 34 RESTORE: decompression length error + BURP_error_redirect (NULL, 34); // msg 34 RESTORE: decompression length error } } @@ -1101,7 +1080,7 @@ burp_rel* find_relation(BurpGlobals* tdgbl, const TEXT* name) } } - BURP_error_redirect(NULL, 35, SafeArg() << name); + BURP_error_redirect (NULL, 35, SafeArg() << name); // msg 35 can't find relation %s return NULL; @@ -1130,9 +1109,9 @@ void fix_security_class_name(BurpGlobals* tdgbl, TEXT* sec_class, bool is_field) if (tdgbl->runtimeODS < DB_VERSION_DDL11_2) return; - FbLocalStatus status_vector; + ISC_STATUS_ARRAY status_vector; - Firebird::IRequest*& handle = tdgbl->handles_fix_security_class_name_req_handle1; + isc_req_handle& handle = tdgbl->handles_fix_security_class_name_req_handle1; if (!handle) { @@ -1174,27 +1153,25 @@ void fix_security_class_name(BurpGlobals* tdgbl, TEXT* sec_class, bool is_field) const USHORT blr_length = blr - blr_buffer; fb_assert(blr_length <= sizeof(blr_buffer)); - handle = DB->compileRequest(&status_vector, blr_length, blr_buffer); - if (status_vector->hasData()) + if (isc_compile_request(status_vector, &DB, &handle, + blr_length, (const SCHAR*) blr_buffer)) { - BURP_error_redirect(&status_vector, 316); + BURP_error_redirect(status_vector, 316); // msg 316 Failed while fixing the security class name } } - handle->start(&status_vector, gds_trans, 0); - if (status_vector->hasData()) + if (isc_start_request(status_vector, &handle, &gds_trans, 0)) { - BURP_error_redirect(&status_vector, 316); + BURP_error_redirect(status_vector, 316); // msg 316 Failed while fixing the security class name } SINT64 id = 0; - handle->receive(&status_vector, 0, 0, sizeof(SINT64), &id); - if (status_vector->hasData()) + if (isc_receive(status_vector, &handle, 0, sizeof(SINT64), &id, 0)) { - BURP_error_redirect(&status_vector, 316); + BURP_error_redirect(status_vector, 316); // msg 316 Failed while fixing the security class name } @@ -1217,7 +1194,7 @@ void general_on_error() **************************************/ BurpGlobals* tdgbl = BurpGlobals::getSpecific(); - if (isc_status->getErrors()[1] == isc_malformed_string) + if (isc_status[1] == isc_malformed_string) { Firebird::Arg::StatusVector oldVector(isc_status); Firebird::Arg::Gds newVector(isc_gbak_invalid_metadata); @@ -1262,20 +1239,20 @@ bool get_acl(BurpGlobals* tdgbl, const TEXT* owner_nm, ISC_QUAD* blob_id, ISC_QU // Open the blob and get it's vital statistics - FbLocalStatus status_vector; - BlobWrapper blob(&status_vector); + ISC_STATUS_ARRAY status_vector; + UserBlob blob(status_vector); if (! blob.open(DB, gds_trans, *blob_id)) { // msg 24 isc_open_blob failed - BURP_error_redirect(&status_vector, 24); + BURP_error_redirect (status_vector, 24); } UCHAR blob_info[32]; if (!blob.getInfo(sizeof(blr_items), blr_items, sizeof(blob_info), blob_info)) { // msg 20 isc_blob_info failed - BURP_error_redirect(&status_vector, 20); + BURP_error_redirect (status_vector, 20); } ULONG length = 0; @@ -1319,7 +1296,7 @@ bool get_acl(BurpGlobals* tdgbl, const TEXT* owner_nm, ISC_QUAD* blob_id, ISC_QU // CVC: do you return, without closing the blob, dear function??? if (!blob.close()) { - BURP_error_redirect(&status_vector, 23); + BURP_error_redirect (status_vector, 23); // msg 23 isc_close_blob failed } return false; @@ -1330,7 +1307,7 @@ bool get_acl(BurpGlobals* tdgbl, const TEXT* owner_nm, ISC_QUAD* blob_id, ISC_QU { if (!blob.close()) { - BURP_error_redirect(&status_vector, 23); + BURP_error_redirect (status_vector, 23); // msg 23 isc_close_blob failed } return false; @@ -1352,7 +1329,7 @@ bool get_acl(BurpGlobals* tdgbl, const TEXT* owner_nm, ISC_QUAD* blob_id, ISC_QU if (!blob.getData(length, buffer, return_length)) { // msg 22 gds_$get_segment failed - BURP_error_redirect(&status_vector, 22); + BURP_error_redirect (status_vector, 22); } // protect ourselves length = return_length; @@ -1360,7 +1337,7 @@ bool get_acl(BurpGlobals* tdgbl, const TEXT* owner_nm, ISC_QUAD* blob_id, ISC_QU if (!blob.close()) { // msg 23 isc_close_blob failed - BURP_error_redirect(&status_vector, 23); + BURP_error_redirect (status_vector, 23); } const UCHAR* from = buffer + 3; // skip ACL_version, ACL_id_list, and id_person @@ -1401,19 +1378,19 @@ bool get_acl(BurpGlobals* tdgbl, const TEXT* owner_nm, ISC_QUAD* blob_id, ISC_QU if (!blob.create(DB, gds_trans, *new_blob_id)) { // msg 37 isc_create_blob failed - BURP_error_redirect(&status_vector, 37); + BURP_error_redirect (status_vector, 37); } if (!blob.putData(new_len, new_buffer)) { // msg 38 isc_put_segment failed - BURP_error_redirect(&status_vector, 38); + BURP_error_redirect (status_vector, 38); } if (!blob.close()) { // msg 23 isc_close_blob failed - BURP_error_redirect(&status_vector, 23); + BURP_error_redirect (status_vector, 23); } return true; @@ -1433,7 +1410,7 @@ void get_array(BurpGlobals* tdgbl, burp_rel* relation, UCHAR* record_buffer) * **************************************/ burp_fld* field = NULL; - FbLocalStatus status_vector; + ISC_STATUS_ARRAY status_vector; USHORT count, field_number, field_length = 0; UCHAR* buffer = NULL; UCHAR* p = NULL; @@ -1465,7 +1442,7 @@ void get_array(BurpGlobals* tdgbl, burp_rel* relation, UCHAR* record_buffer) break; } if (!field) { - BURP_error_redirect(NULL, 36); // msg 36 Can't find field for blob + BURP_error_redirect (NULL, 36); // msg 36 Can't find field for blob } field_length = field->fld_length; @@ -1750,7 +1727,7 @@ void get_array(BurpGlobals* tdgbl, burp_rel* relation, UCHAR* record_buffer) if (get_attribute(&attribute, tdgbl) != att_xdr_array) { // msg 55 Expected XDR record length - BURP_error_redirect(NULL, 55); + BURP_error_redirect (NULL, 55); } else { @@ -1775,17 +1752,18 @@ void get_array(BurpGlobals* tdgbl, burp_rel* relation, UCHAR* record_buffer) get_block(tdgbl, p, lcount); if (tdgbl->gbl_sw_transportable) - CAN_slice (&xdr_buffer, &xdr_slice, false, blr_buffer); + CAN_slice (&xdr_buffer, &xdr_slice, FALSE, /*blr_length,*/ blr_buffer); } - DB->putSlice(&status_vector, gds_trans, blob_id, blr_length, blr_buffer, - 0, NULL, // parameters for subset of an array handling - elements_written * field->fld_length, buffer + data_at); - if (status_vector->hasData()) + if (isc_put_slice(status_vector, &DB, &gds_trans, + blob_id, blr_length, reinterpret_cast(blr_buffer), + 0, // param length for subset of an array handling + NULL, // param for subset of an array handling + elements_written * field->fld_length, buffer + data_at)) { BURP_print (false, 81, field->fld_name); // msg 81 error accessing blob field %s -- continuing - BURP_print_status (true, &status_vector); + BURP_print_status (true, status_vector); #ifdef DEBUG PRETTY_print_sdl (blr_buffer, NULL, NULL, 0); #endif @@ -1875,7 +1853,7 @@ void get_array(BurpGlobals* tdgbl, burp_rel* relation, UCHAR* record_buffer) { if (get_attribute(&attribute, tdgbl) != att_xdr_array) { - BURP_error_redirect(NULL, 55); + BURP_error_redirect (NULL, 55); // msg 55 Expected XDR record length } else @@ -1901,17 +1879,19 @@ void get_array(BurpGlobals* tdgbl, burp_rel* relation, UCHAR* record_buffer) get_block(tdgbl, p, lcount); if (tdgbl->gbl_sw_transportable) - CAN_slice (&xdr_buffer, &xdr_slice, false, blr_buffer); + CAN_slice (&xdr_buffer, &xdr_slice, FALSE, /*blr_length,*/ blr_buffer); - DB->putSlice(&status_vector, gds_trans, blob_id, blr_length, blr_buffer, - 0, NULL, // parameters for subset of an array handling - return_length, buffer); - if (status_vector->hasData()) + if (isc_put_slice(status_vector, &DB, &gds_trans, + blob_id, blr_length, + reinterpret_cast(blr_buffer), + 0, // param length for subset of an array handling + NULL, // param for subset of an array handling + return_length, buffer)) { 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 @@ -1924,7 +1904,7 @@ void get_array(BurpGlobals* tdgbl, burp_rel* relation, UCHAR* record_buffer) BURP_free (xdr_buffer.lstr_address); } -void get_blob(BurpGlobals* tdgbl, Firebird::IBatch* batch, const burp_fld* fields, UCHAR* record_buffer) +void get_blob(BurpGlobals* tdgbl, const burp_fld* fields, UCHAR* record_buffer) { /************************************** * @@ -1985,122 +1965,20 @@ void get_blob(BurpGlobals* tdgbl, Firebird::IBatch* batch, const burp_fld* field if (!field) { - BURP_error_redirect(NULL, 36); + BURP_error_redirect (NULL, 36); // msg 36 Can't find field for blob } // Create new blob ISC_QUAD* blob_id = (ISC_QUAD*) ((UCHAR*) record_buffer + field->fld_offset); - const UCHAR blob_desc[] = {isc_bpb_version1, isc_bpb_type, 1, blob_type}; - - BlobBuffer local_buffer; - UCHAR* const buffer = local_buffer.getBuffer(max_segment); - - FbLocalStatus status_vector; - bool first = true; - - // Eat up blob segments - - for (; segments > 0; --segments) - { - USHORT length = get(tdgbl); - length |= get(tdgbl) << 8; - if (length) - get_block(tdgbl, buffer, length); - - if (first) - batch->addBlob(&status_vector, length, buffer, blob_id, sizeof(blob_desc), blob_desc); - else - batch->appendBlobData(&status_vector, length, buffer); - - if (status_vector->hasData()) - { - BURP_error_redirect(&status_vector, 38); // !!!!!!!!! new message - // msg 38 isc_put_segment failed - } - - first = false; - } -} - - -void get_blob_old(BurpGlobals* tdgbl, const burp_fld* fields, UCHAR* record_buffer) -{ -/************************************** - * - * g e t _ b l o b - * - ************************************** - * - * Functional description - * Read blob attributes and copy data from input file to nice, - * shiny, new blob. - * - **************************************/ - - // Pick up attributes - - ULONG segments = 0; - USHORT field_number = MAX_USHORT; - USHORT max_segment = 0; - UCHAR blob_type = 0; - - att_type attribute; - scan_attr_t scan_next_attr; - skip_init(&scan_next_attr); - - while (skip_scan(&scan_next_attr), get_attribute(&attribute, tdgbl) != att_blob_data) - { - switch (attribute) - { - case att_blob_field_number: - field_number = (USHORT) get_int32(tdgbl); - break; - - case att_blob_max_segment: - max_segment = (USHORT) get_int32(tdgbl); - break; - - case att_blob_number_segments: - segments = get_int32(tdgbl); - break; - - case att_blob_type: - blob_type = (UCHAR) get_int32(tdgbl); - break; - - default: - bad_attribute(scan_next_attr, attribute, 64); - // msg 64 blob - break; - } - } - - // Find the field associated with the blob - const burp_fld* field; - for (field = fields; field; field = field->fld_next) - { - if (field->fld_number == field_number) - break; - } - - if (!field) - { - BURP_error_redirect(NULL, 36); - // msg 36 Can't find field for blob - } - - // Create new blob - - ISC_QUAD* blob_id = (ISC_QUAD*) ((UCHAR*) record_buffer + field->fld_offset); - FbLocalStatus status_vector; - BlobWrapper blob(&status_vector); + ISC_STATUS_ARRAY status_vector; + UserBlob blob(status_vector); const UCHAR blob_desc[] = {isc_bpb_version1, isc_bpb_type, 1, blob_type}; if (!blob.create(DB, gds_trans, *blob_id, sizeof(blob_desc), blob_desc)) { - BURP_error_redirect(&status_vector, 37); + BURP_error_redirect (status_vector, 37); // msg 37 isc_create_blob failed } @@ -2120,13 +1998,13 @@ void get_blob_old(BurpGlobals* tdgbl, const burp_fld* fields, UCHAR* record_buff } if (!blob.putSegment(length, buffer)) { - BURP_error_redirect(&status_vector, 38); + BURP_error_redirect (status_vector, 38); // msg 38 isc_put_segment failed } } if (!blob.close()) - BURP_error_redirect(&status_vector, 23); + BURP_error_redirect (status_vector, 23); // msg 23 isc_close_blob failed } @@ -2149,13 +2027,17 @@ void get_blr_blob(BurpGlobals* tdgbl, ISC_QUAD& blob_id, bool glb_trans) // Create new blob - Firebird::ITransaction* local_trans = (glb_trans && tdgbl->global_trans) ? tdgbl->global_trans : gds_trans; + isc_tr_handle local_trans; + if (glb_trans && tdgbl->global_trans) + local_trans = tdgbl->global_trans; + else + local_trans = gds_trans; - FbLocalStatus status_vector; - BlobWrapper blob(&status_vector); + ISC_STATUS_ARRAY status_vector; + UserBlob blob(status_vector); if (!blob.create(DB, local_trans, blob_id)) { - BURP_error_redirect(&status_vector, 37); + BURP_error_redirect (status_vector, 37); // msg 37 isc_create_blob failed } @@ -2175,12 +2057,12 @@ void get_blr_blob(BurpGlobals* tdgbl, ISC_QUAD& blob_id, bool glb_trans) if (!blob.putData(length, buffer)) { - BURP_error_redirect(&status_vector, 38); + BURP_error_redirect (status_vector, 38); // msg 38 isc_put_segment failed } if (!blob.close()) - BURP_error_redirect(&status_vector, 23); + BURP_error_redirect (status_vector, 23); // msg 23 isc_close_blob failed } @@ -2828,518 +2710,18 @@ rec_type get_data(BurpGlobals* tdgbl, burp_rel* relation, bool skip_relation) * Write data records for a relation. * **************************************/ - ULONG records = 0; - rec_type record; - burp_fld* field; + isc_req_handle req_handle = 0; + BASED_ON RDB$INDICES.RDB$INDEX_NAME index_name; // If we're only doing meta-data, ignore data records if (tdgbl->gbl_sw_meta || skip_relation) return ignore_data(tdgbl, relation); - // For old versions and embedded connections switch to old style method - // Avoid if possible switch to old style when system domains are used in a table - - if (tdgbl->gbl_network_protocol == 0) - { - bool sysDomFlag = false; - - for (field = relation->rel_fields; field && !sysDomFlag; field = field->fld_next) - { - if (field->fld_flags & FLD_computed) - continue; - - const char* dom = field->fld_source; - if (strncmp(dom, "RDB$", 4) != 0) - continue; - - for (dom += 4; *dom; ++dom) - { -#ifdef HAVE_CTYPE_H - if (!isdigit(*dom)) -#else - if (*dom < '0' || *dom > '9') -#endif - { - sysDomFlag = true; - break; - } - } - } - - if (!sysDomFlag) - return get_data_old(tdgbl, relation); - } - else if (tdgbl->gbl_network_protocol < 16) - return get_data_old(tdgbl, relation); - - // Number of fields in a message - - unsigned count = 0; - for (field = relation->rel_fields; field; field = field->fld_next) - { - if (!(field->fld_flags & FLD_computed)) - ++count; - } - - // Time to generate SQL and message metadata to store data. Whoppee. - - try - { - Firebird::string sqlStatement; - sqlStatement.printf("insert into %s(", relation->rel_name); - - Firebird::RefPtr builder(Firebird::REF_NO_INCR, - Firebird::MasterInterfacePtr()->getMetadataBuilder(fbStatus, count)); - if (fbStatus->hasData()) - general_on_error(); - - RCRD_OFFSET offset = 0; - count = 0; - for (field = relation->rel_fields; field; field = field->fld_next) - { - if (field->fld_flags & FLD_computed) - continue; - - USHORT dtype = field->fld_type; - - // arrays are of various fld_types but are really blobs - - if (field->fld_flags & FLD_array) - dtype = blr_blob; - - DSC desc; - if (!DSC_make_descriptor(&desc, dtype, field->fld_scale, field->fld_length, - field->fld_sub_type, field->fld_character_set_id, field->fld_collation_id)) - { - BURP_error(26, true, SafeArg() << dtype); - // msg 26 datatype %ld not understood - } - - SSHORT alignment = type_alignments[desc.dsc_dtype]; - if (alignment) - offset = FB_ALIGN(offset, alignment); - field->fld_offset = offset; - offset += field->fld_total_len = desc.dsc_length; - - SLONG sqlLength, sqlSubType, sqlScale, sqlType; - desc.getSqlInfo(&sqlLength, &sqlSubType, &sqlScale, &sqlType); - SLONG characterSetId = field->fld_character_set_id; - - if (tdgbl->gbl_sw_fix_fss_data && field->fld_character_set_id == CS_UNICODE_FSS && - ((sqlType == SQL_BLOB && field->fld_sub_type == isc_blob_text && !(field->fld_flags & FLD_array)) || - sqlType == SQL_TEXT || sqlType == SQL_VARYING)) - { - characterSetId = tdgbl->gbl_sw_fix_fss_data_id; - } - else if (field->fld_flags & FLD_array) - { - sqlType = SQL_QUAD; - sqlScale = 0; - } - - builder->setType(&tdgbl->throwStatus, count, sqlType); - builder->setSubType(&tdgbl->throwStatus, count, sqlSubType); - builder->setLength(&tdgbl->throwStatus, count, sqlLength); - builder->setScale(&tdgbl->throwStatus, count, sqlScale); - builder->setCharSet(&tdgbl->throwStatus, count, characterSetId); - - sqlStatement += field->fld_name; - sqlStatement += ", "; - - field->fld_parameter = count++; - } - - fb_assert(sqlStatement.end()[-2] == ','); - sqlStatement.end()[-2] = ')'; - - Firebird::RefPtr meta(Firebird::REF_NO_INCR, - builder->getMetadata(&tdgbl->throwStatus)); - builder = nullptr; - - sqlStatement += "values ("; - - count = 0; - for (field = relation->rel_fields; field; field = field->fld_next) - { - if (field->fld_flags & FLD_computed) - continue; - - offset = FB_ALIGN(offset, sizeof(SSHORT)); - field->fld_missing_parameter = count; - field->fld_missing_offset = offset; - offset += sizeof(SSHORT); - - field->fld_sql = meta->getOffset(&tdgbl->throwStatus, count); - field->fld_null = meta->getNullOffset(&tdgbl->throwStatus, count); - - if (tdgbl->gbl_sw_transportable) - { - field->fld_offset = field->fld_sql; - field->fld_missing_offset = field->fld_null; - } - - sqlStatement += "?, "; - ++count; - } - - fb_assert(sqlStatement.end()[-2] == ','); - sqlStatement.end()[-2] = ')'; - - RCRD_LENGTH length = offset; - - // Create batch - - const int GBAK_BATCH_STEP = 1000; - Firebird::AutoDispose pb(Firebird::UtilInterfacePtr()-> - getXpbBuilder(&tdgbl->throwStatus, Firebird::IXpbBuilder::BATCH, NULL, 0)); - pb->insertInt(&tdgbl->throwStatus, Firebird::IBatch::TAG_MULTIERROR, 1); - pb->insertInt(&tdgbl->throwStatus, Firebird::IBatch::TAG_BLOB_POLICY, Firebird::IBatch::BLOB_ID_ENGINE); - pb->insertInt(&tdgbl->throwStatus, Firebird::IBatch::TAG_DETAILED_ERRORS, GBAK_BATCH_STEP); - pb->insertInt(&tdgbl->throwStatus, Firebird::IBatch::TAG_BUFFER_BYTES_SIZE, 0); - - Firebird::RefPtr batch(DB-> - createBatch(fbStatus, gds_trans, sqlStatement.length(), sqlStatement.c_str(), tdgbl->gbl_dialect, - meta, pb->getBufferLength(&tdgbl->throwStatus), pb->getBuffer(&tdgbl->throwStatus))); - if (fbStatus->hasData()) - { - // Possible reason of fail - use of keywords as fields in old backup - // Try to roll back to use of old version (fieldnames independent) - BURP_print(false, 27/*, sqlStatement.c_str()*/); // msg 27 isc_compile_request failed !!!!!!!! new WARNING - BURP_print_warning(fbStatus); - return get_data_old(tdgbl, relation); - } - - UCHAR* buffer = NULL; - Firebird::Array requestBuffer; - - BURP_verbose(124, relation->rel_name); // msg 124 restoring data for relation %s - - lstring data; - data.lstr_allocated = 0; - data.lstr_address = NULL; - Firebird::Array dataBuffer; - RCRD_LENGTH old_length = 0; - - Firebird::Array sqlBuffer; - UCHAR* sql = sqlBuffer.getBuffer(meta->getMessageLength(&tdgbl->throwStatus)); - - while (true) - { - if (get(tdgbl) != att_data_length) - BURP_error_redirect(NULL, 39); // msg 39 expected record length - RCRD_LENGTH len = get_int32(tdgbl); - - if (!tdgbl->gbl_sw_transportable && len != length) - { -#ifdef sparc - if (!old_length) - old_length = recompute_length(tdgbl, relation); -#endif - if (len != old_length) - { - BURP_error(40, true, SafeArg() << length << len); - // msg 40 wrong length record, expected %ld encountered %ld - } - } - - if (!buffer) - buffer = requestBuffer.getBuffer(MAX (length, len)); - - UCHAR* p; - if (tdgbl->gbl_sw_transportable) - { - if (get(tdgbl) != att_xdr_length) - { - BURP_error_redirect(NULL, 55); - // msg 55 Expected XDR record length - } - else - { - data.lstr_length = len = get_int32(tdgbl); - if (len > data.lstr_allocated) - { - data.lstr_allocated = len; - data.lstr_address = dataBuffer.getBuffer(data.lstr_allocated); - } - p = data.lstr_address; - } - } - else - p = buffer; - - if (get(tdgbl) != att_data_data) - BURP_error_redirect(NULL, 41); // msg 41 expected data attribute - - if (tdgbl->gbl_sw_compress) - decompress (tdgbl, p, len); - else - get_block(tdgbl, p, len); - - if (old_length) - realign (tdgbl, buffer, relation); - - if (tdgbl->gbl_sw_transportable) - { - buffer = sql; - CAN_encode_decode(relation, &data, buffer, false, true); - } - - if ((++records % tdgbl->verboseInterval) == 0) - BURP_verbose(107, SafeArg() << records); - - for (field = relation->rel_fields; field; field = field->fld_next) - { - if (!(field->fld_flags & FLD_computed)) - { - if (field->fld_type == blr_blob || (field->fld_flags & FLD_array)) - { - ISC_QUAD* blob_id = (ISC_QUAD*) &buffer[field->fld_offset]; - blob_id->gds_quad_high = 0; - blob_id->gds_quad_low = 0; - } - } - } - - get_record(&record, tdgbl); - while (record == rec_blob || record == rec_array) - { - if (record == rec_blob) - get_blob (tdgbl, batch, relation->rel_fields, buffer); - else if (record == rec_array) - get_array (tdgbl, relation, buffer); - get_record(&record, tdgbl); - } - - if (!tdgbl->gbl_sw_transportable) - { - for (field = relation->rel_fields; field; field = field->fld_next) - { - if (field->fld_flags & FLD_computed) - continue; - - // convert record to SQL format - - memcpy(&sql[field->fld_sql], &buffer[field->fld_offset], field->fld_total_len); - memcpy(&sql[field->fld_null], &buffer[field->fld_missing_offset], sizeof(SSHORT)); - } - } - - batch->add(&tdgbl->throwStatus, 1, sql); - if ((records % 1000 != 0) && (record == rec_data)) - continue; - - Firebird::AutoDispose cs(batch->execute(&tdgbl->throwStatus, gds_trans)); - if (tdgbl->throwStatus->getState() & Firebird::IStatus::STATE_WARNINGS) - BURP_print_warning(&tdgbl->throwStatus); - - for (unsigned pos = 0; - pos = cs->findError(&tdgbl->throwStatus, pos), - pos != Firebird::IBatchCompletionState::NO_MORE_ERRORS; - ++pos) - { - Firebird::LocalStatus status_vector; - cs->getStatus(&tdgbl->throwStatus, &status_vector, pos); - ISC_STATUS code = status_vector.getErrors()[1]; - - if (code == isc_not_valid) - { - if (tdgbl->gbl_sw_incremental) - { - BURP_print (false, 138, relation->rel_name); - // msg 138 validation error on field in relation %s - BURP_print_status (false, &status_vector); - } - else - BURP_error_redirect(&status_vector, 47); - // msg 47 warning -- record could not be restored - } - else if (code == isc_malformed_string) - { - if (tdgbl->gbl_sw_incremental) - { - // msg 114 restore failed for record in relation %s - BURP_print(false, 114, relation->rel_name); - - BURP_print_status(false, &status_vector); - BURP_print(false, 342); // isc_gbak_invalid_data - } - else - BURP_error_redirect(&status_vector, 342); // isc_gbak_invalid_data - } - else - { - if (tdgbl->gbl_sw_incremental) - { - BURP_print (false, 114, relation->rel_name); - // msg 114 restore failed for record in relation %s - BURP_print_status (false, &status_vector); - } - else - BURP_error_redirect(&status_vector, 48); - // msg 48 isc_send failed - } - - records--; - } - - if (record != rec_data) - break; - } // while (true) - } - catch (const Firebird::FbException& ex) - { - BURP_print_status (true, ex.getStatus()); - BURP_abort(); - } - - if (tdgbl->gbl_sw_incremental) - { - BURP_verbose(72, relation->rel_name); - // msg 72 committing data for relation %s - COMMIT - // existing ON_ERROR continues past error, beck - ON_ERROR - - // Fix for bug_no 8055: - // don't throw away the database just because an index - // could not be made - - // don't bring the database on-line - tdgbl->flag_on_line = false; - ISC_STATUS error_code; - while (error_code = tdgbl->status_vector[1]) - { - BASED_ON RDB$INDICES.RDB$INDEX_NAME index_name; - Firebird::IRequest* req_handle = 0; - - switch (error_code) - { - case isc_sort_mem_err: - case isc_no_dup: - strcpy(index_name, (TEXT*) tdgbl->status_vector[3]); - BURP_print_status(false, &tdgbl->status_vector); - - FOR (REQUEST_HANDLE req_handle) - IDX IN RDB$INDICES - WITH IDX.RDB$INDEX_NAME EQ index_name - { - MODIFY IDX USING - IDX.RDB$INDEX_INACTIVE = TRUE; - BURP_print(false, 240, index_name); - // msg 240 Index \"%s\" failed to activate because: - if ( error_code == isc_no_dup ) - { - BURP_print(false, 241); - // msg 241 The unique index has duplicate values or NULLs - BURP_print(false, 242); - // msg 242 Delete or Update duplicate values or NULLs, and activate index with - } - else - { - BURP_print(false, 244); - // msg 244 Not enough disk space to create the sort file for an index - BURP_print(false, 245); - // msg 245 Set the TMP environment variable to a directory on a filesystem that does have enough space, and activate index with - } - BURP_print(false, 243, index_name); - // msg 243 ALTER INDEX \"%s\" ACTIVE - END_MODIFY; - } - END_FOR; - // commit one more time - COMMIT - ON_ERROR - continue; - END_ERROR - break; - default: - BURP_print(false, 69, relation->rel_name); - // msg 69 commit failed on relation %s - BURP_print_status (false, &tdgbl->status_vector); - ROLLBACK; - ON_ERROR - general_on_error(); - END_ERROR; - break; - } // end of switch - } // end of while - END_ERROR; - - EXEC SQL SET TRANSACTION NO_AUTO_UNDO; - if (gds_status->hasData()) - EXEC SQL SET TRANSACTION; - } - - BURP_verbose(107, SafeArg() << records); - // msg 107 %ld records restored - - return record; -} - -// We have a corrupt backup, save the restore process from becoming useless. -void fix_exception(BurpGlobals* tdgbl, const char* exc_name, scan_attr_t& scan_next_attr, - const att_type attribute, att_type& failed_attrib, UCHAR*& msg_ptr, ULONG& l2, bool& msg_seen) -{ - if (msg_seen && (tdgbl->RESTORE_format == 7 || tdgbl->RESTORE_format == 8)) - { - if (!failed_attrib) - { - failed_attrib = attribute; - BURP_print(false, 313, SafeArg() << failed_attrib << exc_name); - } - - // Notice we use 1021 instead of 1023 because this is the maximum length - // for this field in v2.0 and v2.1 and they produce the corrupt backups. - const unsigned int FIELD_LIMIT = 1021; - - if (FIELD_LIMIT < l2 + 1) // not enough space - { - bad_attribute(scan_next_attr, failed_attrib, 287); - return; - } - - const unsigned int remaining = FIELD_LIMIT - l2; - - *msg_ptr++ = char(attribute); // (1) - - UCHAR* rc_ptr = get_block(tdgbl, msg_ptr, MIN(remaining - 1, 255)); - if (remaining > 1 && rc_ptr == msg_ptr) // we couldn't read anything - { - bad_attribute(scan_next_attr, failed_attrib, 287); - return; - } - - l2 += rc_ptr - msg_ptr + 1; // + 1 because (1) - msg_ptr = rc_ptr; - *msg_ptr = 0; - - if (l2 == FIELD_LIMIT) - msg_seen = false; - } - else - bad_attribute(scan_next_attr, attribute, 287); // msg 287 exception -} - -rec_type get_data_old(BurpGlobals* tdgbl, burp_rel* relation) -{ -/************************************** - * - * g e t _ d a t a _ o l d - * - ************************************** - * - * Functional description - * Write data records for a relation. - * - **************************************/ - Firebird::IRequest* req_handle = 0; - BASED_ON RDB$INDICES.RDB$INDEX_NAME index_name; - // Start by counting the interesting fields RCRD_OFFSET offset = 0; - RCRD_LENGTH length = 0; + ULONG length = 0; USHORT count = 0; burp_fld* field; @@ -3352,7 +2734,8 @@ rec_type get_data_old(BurpGlobals* tdgbl, burp_rel* relation) } } - count += count; + if (tdgbl->RESTORE_format >= 2) + count += count; // Time to generate blr to store data. Whoppee. @@ -3463,16 +2846,19 @@ rec_type get_data_old(BurpGlobals* tdgbl, burp_rel* relation) offset += length; } - for (field = relation->rel_fields; field; field = field->fld_next) - { - if (field->fld_flags & FLD_computed) - continue; - add_byte(blr, blr_short); - add_byte(blr, 0); - offset = FB_ALIGN(offset, sizeof(SSHORT)); - field->fld_missing_parameter = count++; - offset += sizeof(SSHORT); - } + // If this is format version 2, build fields for null flags + + if (tdgbl->RESTORE_format >= 2) + for (field = relation->rel_fields; field; field = field->fld_next) + { + if (field->fld_flags & FLD_computed) + continue; + add_byte(blr, blr_short); + add_byte(blr, 0); + offset = FB_ALIGN(offset, sizeof(SSHORT)); + field->fld_missing_parameter = count++; + offset += sizeof(SSHORT); + } length = offset; @@ -3492,12 +2878,19 @@ rec_type get_data_old(BurpGlobals* tdgbl, burp_rel* relation) if (field->fld_flags & FLD_computed) continue; add_byte(blr, blr_assignment); - - add_byte(blr, blr_parameter2); - add_byte(blr, 0); - add_word(blr, field->fld_parameter); - add_word(blr, field->fld_missing_parameter); - + if (tdgbl->RESTORE_format >= 2) + { + add_byte(blr, blr_parameter2); + add_byte(blr, 0); + add_word(blr, field->fld_parameter); + add_word(blr, field->fld_missing_parameter); + } + else + { + add_byte(blr, blr_parameter); + add_byte(blr, 0); + add_word(blr, field->fld_parameter); + } add_byte(blr, blr_field); add_byte(blr, 0); add_string(blr, field->fld_name); @@ -3509,24 +2902,24 @@ rec_type get_data_old(BurpGlobals* tdgbl, burp_rel* relation) // Compile request - ULONG blr_length = blr - blr_buffer; + USHORT blr_length = blr - blr_buffer; #ifdef DEBUG fb_print_blr(blr_buffer, blr_length, NULL, NULL, 0); #endif - Firebird::IRequest* request = nullptr; - FbLocalStatus status_vector; + FB_API_HANDLE request = 0; + ISC_STATUS_ARRAY status_vector; - request = DB->compileRequest(&status_vector, blr_length, blr_buffer); - if (status_vector->hasData()) + if (isc_compile_request (status_vector, &DB, &request, + blr_length, reinterpret_cast(blr_buffer))) { fb_print_blr(blr_buffer, blr_length, NULL, NULL, 0); if (!tdgbl->gbl_sw_incremental) - BURP_error_redirect(&status_vector, 27); // msg 27 isc_compile_request failed + BURP_error_redirect (status_vector, 27); // msg 27 isc_compile_request failed else { - BURP_print_status (false, &status_vector); + BURP_print_status (false, status_vector); BURP_free (blr_buffer); return ignore_data(tdgbl, relation); } @@ -3549,10 +2942,8 @@ rec_type get_data_old(BurpGlobals* tdgbl, burp_rel* relation) while (true) { if (get(tdgbl) != att_data_length) - BURP_error_redirect(NULL, 39); // msg 39 expected record length - - RCRD_LENGTH len = get_int32(tdgbl); - + BURP_error_redirect (NULL, 39); // msg 39 expected record length + USHORT len = (USHORT) get_int32(tdgbl); if (!tdgbl->gbl_sw_transportable && len != length) { #ifdef sparc @@ -3565,19 +2956,19 @@ rec_type get_data_old(BurpGlobals* tdgbl, burp_rel* relation) // msg 40 wrong length record, expected %ld encountered %ld } } - - if (!buffer) + if (!buffer) { buffer = (SSHORT *) BURP_alloc (MAX (length, len)); + } UCHAR* p; if (tdgbl->gbl_sw_transportable) { if (get(tdgbl) != att_xdr_length) - BURP_error_redirect(NULL, 55); + BURP_error_redirect (NULL, 55); // msg 55 Expected XDR record length else { - data.lstr_length = len = get_int32(tdgbl); + data.lstr_length = len = (USHORT) get_int32(tdgbl); if (len > data.lstr_allocated) { data.lstr_allocated = len; @@ -3585,26 +2976,26 @@ rec_type get_data_old(BurpGlobals* tdgbl, burp_rel* relation) BURP_free (data.lstr_address); data.lstr_address = BURP_alloc(data.lstr_allocated); } - p = data.lstr_address; } } else p = reinterpret_cast(buffer); - if (get(tdgbl) != att_data_data) - BURP_error_redirect(NULL, 41); // msg 41 expected data attribute + BURP_error_redirect (NULL, 41); // msg 41 expected data attribute if (tdgbl->gbl_sw_compress) decompress (tdgbl, p, len); else + { get_block(tdgbl, p, len); + } if (old_length) realign (tdgbl, (UCHAR*) buffer, relation); if (tdgbl->gbl_sw_transportable) - CAN_encode_decode(relation, &data, (UCHAR *)buffer, false); + CAN_encode_decode (relation, &data, (UCHAR *)buffer, FALSE); records++; @@ -3628,50 +3019,49 @@ rec_type get_data_old(BurpGlobals* tdgbl, burp_rel* relation) while (record == rec_blob || record == rec_array) { if (record == rec_blob) - get_blob_old(tdgbl, relation->rel_fields, (UCHAR *) buffer); + get_blob (tdgbl, relation->rel_fields, (UCHAR *) buffer); else if (record == rec_array) - get_array(tdgbl, relation, (UCHAR *) buffer); + get_array (tdgbl, relation, (UCHAR *) buffer); get_record(&record, tdgbl); } + ISC_STATUS s; + // ASF: Preferable we should call isc_start_and_send only when records == 1, but this leaks // memory when there are blobs and arrays fields - CORE-3802. if (resync || records % 1000 == 1) - request->startAndSend(&status_vector, gds_trans, 0, 0, length, buffer); + s = isc_start_and_send(status_vector, &request, &gds_trans, 0, (USHORT) length, buffer, 0); else - request->send(&status_vector, 0, 0, length, buffer); + s = isc_send(status_vector, &request, 0, (USHORT) length, buffer, 0); - resync = false; + resync = (s != 0); - if (status_vector->hasData()) + if (s) { - resync = true; - ISC_STATUS code = status_vector->getErrors()[1]; - - if (code == isc_not_valid) + if (status_vector[1] == isc_not_valid) { if (tdgbl->gbl_sw_incremental) { BURP_print (false, 138, relation->rel_name); // msg 138 validation error on field in relation %s - BURP_print_status (false, &status_vector); + BURP_print_status (false, status_vector); } else - BURP_error_redirect(&status_vector, 47); + BURP_error_redirect (status_vector, 47); // msg 47 warning -- record could not be restored } - else if (code == isc_malformed_string) + else if (status_vector[1] == isc_malformed_string) { if (tdgbl->gbl_sw_incremental) { // msg 114 restore failed for record in relation %s BURP_print(false, 114, relation->rel_name); - BURP_print_status(false, &status_vector); + BURP_print_status(false, status_vector); BURP_print(false, 342); // isc_gbak_invalid_data } else - BURP_error_redirect(&status_vector, 342); // isc_gbak_invalid_data + BURP_error_redirect(status_vector, 342); // isc_gbak_invalid_data } else { @@ -3679,10 +3069,11 @@ rec_type get_data_old(BurpGlobals* tdgbl, burp_rel* relation) { BURP_print (false, 114, relation->rel_name); // msg 114 restore failed for record in relation %s - BURP_print_status (false, &status_vector); + BURP_print_status (false, status_vector); } else - BURP_error_redirect(&status_vector, 48); // msg 48 isc_send failed + BURP_error_redirect (status_vector, 48); + // msg 48 isc_send failed } records--; @@ -3696,8 +3087,7 @@ rec_type get_data_old(BurpGlobals* tdgbl, burp_rel* relation) if (data.lstr_address) BURP_free (data.lstr_address); - request->release(); - + isc_release_request(status_vector, &request); if (tdgbl->gbl_sw_incremental) { BURP_verbose (72, relation->rel_name); @@ -3720,7 +3110,7 @@ rec_type get_data_old(BurpGlobals* tdgbl, burp_rel* relation) case isc_sort_mem_err: case isc_no_dup: strcpy(index_name, (TEXT *)tdgbl->status_vector[3]); - BURP_print_status(false, &tdgbl->status_vector); + BURP_print_status(false, tdgbl->status_vector); FOR (REQUEST_HANDLE req_handle) IDX IN RDB$INDICES WITH IDX.RDB$INDEX_NAME EQ index_name MODIFY IDX USING @@ -3754,7 +3144,7 @@ rec_type get_data_old(BurpGlobals* tdgbl, burp_rel* relation) default: BURP_print (false, 69, relation->rel_name); // msg 69 commit failed on relation %s - BURP_print_status(false, &tdgbl->status_vector); + BURP_print_status (false, tdgbl->status_vector); ROLLBACK; ON_ERROR general_on_error (); @@ -3765,7 +3155,7 @@ rec_type get_data_old(BurpGlobals* tdgbl, burp_rel* relation) END_ERROR; EXEC SQL SET TRANSACTION NO_AUTO_UNDO; - if (gds_status->hasData()) + if (gds_status[1]) EXEC SQL SET TRANSACTION; } BURP_verbose (107, SafeArg() << records); @@ -3774,6 +3164,49 @@ rec_type get_data_old(BurpGlobals* tdgbl, burp_rel* relation) return record; } +// We have a corrupt backup, save the restore process from becoming useless. +void fix_exception(BurpGlobals* tdgbl, const char* exc_name, scan_attr_t& scan_next_attr, + const att_type attribute, att_type& failed_attrib, UCHAR*& msg_ptr, ULONG& l2, bool& msg_seen) +{ + if (msg_seen && (tdgbl->RESTORE_format == 7 || tdgbl->RESTORE_format == 8)) + { + if (!failed_attrib) + { + failed_attrib = attribute; + BURP_print(false, 313, SafeArg() << failed_attrib << exc_name); + } + + // Notice we use 1021 instead of 1023 because this is the maximum length + // for this field in v2.0 and v2.1 and they produce the corrupt backups. + const unsigned int FIELD_LIMIT = 1021; + + if (FIELD_LIMIT < l2 + 1) // not enough space + { + bad_attribute(scan_next_attr, failed_attrib, 287); + return; + } + const unsigned int remaining = FIELD_LIMIT - l2; + + *msg_ptr++ = char(attribute); // (1) + + UCHAR* rc_ptr = get_block(tdgbl, msg_ptr, MIN(remaining - 1, 255)); + if (remaining > 1 && rc_ptr == msg_ptr) // we couldn't read anything + { + bad_attribute(scan_next_attr, failed_attrib, 287); + return; + } + + l2 += rc_ptr - msg_ptr + 1; // + 1 because (1) + msg_ptr = rc_ptr; + *msg_ptr = 0; + + if (l2 == FIELD_LIMIT) + msg_seen = false; + } + else + bad_attribute(scan_next_attr, attribute, 287); // msg 287 exception +} + bool get_exception(BurpGlobals* tdgbl) { /************************************** @@ -4112,7 +3545,7 @@ burp_fld* get_field(BurpGlobals* tdgbl, burp_rel* relation) // If it is a view and there is a global transaction then use it bool global_tr = false; - Firebird::ITransaction* local_trans; + isc_tr_handle local_trans; if ((relation->rel_flags & REL_view) && tdgbl->global_trans) { local_trans = tdgbl->global_trans; @@ -4164,7 +3597,6 @@ burp_fld* get_field(BurpGlobals* tdgbl, burp_rel* relation) case att_field_source: GET_TEXT(X.RDB$FIELD_SOURCE); - strcpy(field->fld_source, X.RDB$FIELD_SOURCE); break; case att_field_security_class: @@ -4367,7 +3799,6 @@ burp_fld* get_field(BurpGlobals* tdgbl, burp_rel* relation) case att_field_source: GET_TEXT(X.RDB$FIELD_SOURCE); - strcpy(field->fld_source, X.RDB$FIELD_SOURCE); break; case att_field_security_class: @@ -4955,7 +4386,7 @@ bool get_function(BurpGlobals* tdgbl) strcpy(function_name, X.RDB$FUNCTION_NAME); END_STORE; ON_ERROR - if (gds_status->getErrors()[1] != isc_no_dup) + if (gds_status[1] != isc_no_dup) general_on_error (); else existFlag = true; @@ -5082,7 +4513,7 @@ bool get_function(BurpGlobals* tdgbl) END_STORE; ON_ERROR - if (gds_status->getErrors()[1] != isc_no_dup) + if (gds_status[1] != isc_no_dup) general_on_error (); else existFlag = true; @@ -7031,22 +6462,22 @@ void get_misc_blob(BurpGlobals* tdgbl, ISC_QUAD& blob_id, bool glb_trans) * shiney, new blob. * **************************************/ - FbLocalStatus status_vector; + ISC_STATUS_ARRAY status_vector; const FB_SIZE_T length = get_int32(tdgbl); // Create new blob - Firebird::ITransaction* local_trans; + isc_tr_handle local_trans; if (glb_trans && tdgbl->global_trans) local_trans = tdgbl->global_trans; else local_trans = gds_trans; - BlobWrapper blob(&status_vector); + UserBlob blob(status_vector); if (!blob.create(DB, local_trans, blob_id)) { - BURP_error_redirect(&status_vector, 37); + BURP_error_redirect (status_vector, 37); // msg 37 isc_create_blob failed } @@ -7061,12 +6492,12 @@ void get_misc_blob(BurpGlobals* tdgbl, ISC_QUAD& blob_id, bool glb_trans) if (!blob.putData(length, buffer)) { - BURP_error_redirect(&status_vector, 38); + BURP_error_redirect (status_vector, 38); // msg 38 isc_put_segment failed } if (!blob.close()) - BURP_error_redirect(&status_vector, 23); + BURP_error_redirect (status_vector, 23); // msg 23 isc_close_blob failed } @@ -7136,7 +6567,7 @@ bool get_package(BurpGlobals* tdgbl) if (tdgbl->RESTORE_format < 10) return false; - Firebird::ITransaction* local_trans = tdgbl->global_trans ? tdgbl->global_trans : gds_trans; + isc_tr_handle local_trans = tdgbl->global_trans ? tdgbl->global_trans : gds_trans; burp_pkg* package = (burp_pkg*) BURP_alloc_zero(sizeof(burp_pkg)); package->pkg_next = tdgbl->packages; @@ -7243,7 +6674,7 @@ bool get_procedure(BurpGlobals* tdgbl) SSHORT l; scan_attr_t scan_next_attr; - Firebird::ITransaction* local_trans = tdgbl->global_trans ? tdgbl->global_trans : gds_trans; + isc_tr_handle local_trans = tdgbl->global_trans ? tdgbl->global_trans : gds_trans; burp_prc* procedure = (burp_prc*) BURP_alloc_zero (sizeof(burp_prc)); procedure->prc_next = tdgbl->procedures; @@ -7587,7 +7018,7 @@ bool get_procedure_prm (BurpGlobals* tdgbl, GDS_NAME package_name, GDS_NAME proc TEXT temp[GDS_NAME_LEN]; scan_attr_t scan_next_attr; - Firebird::ITransaction* local_trans = tdgbl->global_trans ? tdgbl->global_trans : gds_trans; + isc_tr_handle local_trans = tdgbl->global_trans ? tdgbl->global_trans : gds_trans; if (tdgbl->runtimeODS >= DB_VERSION_DDL11_1) { @@ -7907,8 +7338,8 @@ bool get_relation(BurpGlobals* tdgbl) **************************************/ SLONG rel_flags = 0, sys_flag = fb_sysflag_user, type = rel_persistent; bool rel_flags_null = true; - ISC_QUAD view_blr = fbBlobNull, view_src = fbBlobNull, - rel_desc = fbBlobNull, ext_desc = fbBlobNull; + ISC_QUAD view_blr = isc_blob_null, view_src = isc_blob_null, + rel_desc = isc_blob_null, ext_desc = isc_blob_null; bool view_blr_null = true, view_src_null = true, rel_desc_null = true, ext_desc_null = true; FB_BOOLEAN sql_security = FB_FALSE; @@ -7936,7 +7367,7 @@ bool get_relation(BurpGlobals* tdgbl) END_ERROR; EXEC SQL SET TRANSACTION NO_AUTO_UNDO; - if (gds_status->hasData()) + if (gds_status[1]) EXEC SQL SET TRANSACTION; } @@ -8060,7 +7491,7 @@ bool get_relation(BurpGlobals* tdgbl) } // If this is a view and there is a global transaction then use it - Firebird::ITransaction* local_trans; + isc_tr_handle local_trans; if (view_blr_null || !tdgbl->global_trans) local_trans = gds_trans; else @@ -8155,14 +7586,14 @@ bool get_relation(BurpGlobals* tdgbl) ON_ERROR BURP_print (false, 171, relation->rel_name); // msg 171: error committing metadata for relation %s - BURP_print_status (false, &tdgbl->status_vector); + BURP_print_status (false, tdgbl->status_vector); ROLLBACK; ON_ERROR general_on_error (); END_ERROR; END_ERROR; EXEC SQL SET TRANSACTION NO_AUTO_UNDO; - if (gds_status->hasData()) + if (gds_status[1]) EXEC SQL SET TRANSACTION; } return true; @@ -8199,7 +7630,7 @@ bool get_relation(BurpGlobals* tdgbl) END_ERROR; EXEC SQL SET TRANSACTION NO_AUTO_UNDO; - if (gds_status->hasData()) + if (gds_status[1]) EXEC SQL SET TRANSACTION; get_data(tdgbl, relation, tdgbl->skipRelation(rel_name)); @@ -8318,7 +7749,7 @@ bool get_relation_data(BurpGlobals* tdgbl) } if (!relation) - BURP_error_redirect(NULL, 49); + BURP_error_redirect (NULL, 49); // msg 49 no relation name for data // Eat up misc. records @@ -8717,14 +8148,10 @@ bool get_mapping(BurpGlobals* tdgbl) "UPDATE OR INSERT INTO RDB$ROLES(RDB$ROLE_NAME, RDB$SYSTEM_FLAG) VALUES", ADMIN_ROLE, 6, // constant 6 turns on auto admin mapping in FB 2.5 "MATCHING (RDB$ROLE_NAME)"); - try + isc_dsql_execute_immediate(tdgbl->status_vector, &tdgbl->db_handle, &tdgbl->tr_handle, + sql.length(), sql.c_str(), 1, NULL); + if (tdgbl->status_vector[1]) { - BurpSql mapRole(tdgbl, sql.c_str()); - mapRole.execute(tdgbl->tr_handle); - } - catch (const Firebird::FbException& ex) - { - fb_utils::copyStatus(&tdgbl->status_vector, ex.getStatus()); general_on_error (); } } @@ -8854,14 +8281,14 @@ void get_source_blob(BurpGlobals* tdgbl, ISC_QUAD& blob_id, bool glb_trans) * input file to nice, shiney, new blob. * **************************************/ - FbLocalStatus status_vector; + ISC_STATUS_ARRAY status_vector; SLONG length = get_int32(tdgbl); // Create new blob - BlobWrapper blob(&status_vector); - Firebird::ITransaction* local_trans; + UserBlob blob(status_vector); + isc_tr_handle local_trans; if (glb_trans && tdgbl->global_trans) local_trans = tdgbl->global_trans; else @@ -8899,7 +8326,7 @@ void get_source_blob(BurpGlobals* tdgbl, ISC_QUAD& blob_id, bool glb_trans) if (!ok) { - BURP_error_redirect(&status_vector, 37); + BURP_error_redirect (status_vector, 37); // msg 37 isc_create_blob failed } @@ -8918,13 +8345,13 @@ void get_source_blob(BurpGlobals* tdgbl, ISC_QUAD& blob_id, bool glb_trans) if (!blob.putSegment(seg_len, buffer)) { - BURP_error_redirect(&status_vector, 38); + BURP_error_redirect (status_vector, 38); // msg 38 isc_put_segment failed } } if (!blob.close()) - BURP_error_redirect(&status_vector, 23); + BURP_error_redirect (status_vector, 23); // msg 23 isc_close_blob failed } @@ -8943,7 +8370,7 @@ USHORT get_text(BurpGlobals* tdgbl, TEXT* text, ULONG length) const ULONG l = get(tdgbl); if (length <= l) - BURP_error_redirect(NULL, 46); + BURP_error_redirect (NULL, 46); // msg 46 string truncated if (l) @@ -8972,7 +8399,7 @@ USHORT get_text2(BurpGlobals* tdgbl, TEXT* text, ULONG length) if (length <= len) { - BURP_error_redirect(NULL, 46); + BURP_error_redirect (NULL, 46); // msg 46 string truncated } @@ -9092,14 +8519,14 @@ bool get_trigger_old (BurpGlobals* tdgbl, burp_rel* relation) ON_ERROR BURP_print (false, 94, name); // msg 94 trigger %s is invalid - BURP_print_status(false, &tdgbl->status_vector); + BURP_print_status (false, tdgbl->status_vector); ROLLBACK; ON_ERROR general_on_error (); END_ERROR; END_ERROR; EXEC SQL SET TRANSACTION NO_AUTO_UNDO; - if (gds_status->hasData()) + if (gds_status[1]) EXEC SQL SET TRANSACTION; } @@ -9122,7 +8549,7 @@ bool get_trigger(BurpGlobals* tdgbl) BASED_ON RDB$TRIGGERS.RDB$TRIGGER_NAME name; scan_attr_t scan_next_attr; - Firebird::ITransaction* local_trans = tdgbl->global_trans ? tdgbl->global_trans : gds_trans; + isc_tr_handle local_trans = tdgbl->global_trans ? tdgbl->global_trans : gds_trans; if (tdgbl->runtimeODS >= DB_VERSION_DDL11_1) { @@ -9408,14 +8835,14 @@ bool get_trigger(BurpGlobals* tdgbl) ON_ERROR BURP_print (false, 94, name); // msg 94 trigger %s is invalid - BURP_print_status(false, &tdgbl->status_vector); + BURP_print_status (false, tdgbl->status_vector); ROLLBACK; ON_ERROR general_on_error (); END_ERROR; END_ERROR; EXEC SQL SET TRANSACTION NO_AUTO_UNDO; - if (gds_status->hasData()) + if (gds_status[1]) EXEC SQL SET TRANSACTION; } @@ -9484,7 +8911,7 @@ bool get_trigger_message(BurpGlobals* tdgbl) if (tdgbl->runtimeODS < DB_VERSION_DDL11) message[78] = 0; - Firebird::ITransaction* local_trans = tdgbl->global_trans ? tdgbl->global_trans : gds_trans; + isc_tr_handle local_trans = tdgbl->global_trans ? tdgbl->global_trans : gds_trans; STORE (TRANSACTION_HANDLE local_trans REQUEST_HANDLE tdgbl->handles_get_trigger_message_req_handle2) @@ -9504,14 +8931,14 @@ bool get_trigger_message(BurpGlobals* tdgbl) ON_ERROR BURP_print (false, 94, name); // msg 94 trigger %s is invalid - BURP_print_status(false, &tdgbl->status_vector); + BURP_print_status (false, tdgbl->status_vector); ROLLBACK; ON_ERROR general_on_error (); END_ERROR; END_ERROR; EXEC SQL SET TRANSACTION NO_AUTO_UNDO; - if (gds_status->hasData()) + if (gds_status[1]) EXEC SQL SET TRANSACTION; } @@ -9680,7 +9107,7 @@ bool get_user_privilege(BurpGlobals* tdgbl) } // Check if object exists - Firebird::ITransaction* local_trans = nullptr; + isc_tr_handle local_trans = 0; bool exists = false; // if grantor is not set than it's system privilege which should not be restored if (grantor[0]) @@ -9860,7 +9287,7 @@ bool get_view(BurpGlobals* tdgbl, burp_rel* relation) // If there is a global transaction then use it - Firebird::ITransaction* local_trans = tdgbl->global_trans ? tdgbl->global_trans : gds_trans; + isc_tr_handle local_trans = tdgbl->global_trans ? tdgbl->global_trans : gds_trans; if (tdgbl->runtimeODS >= DB_VERSION_DDL12) { @@ -10019,7 +9446,7 @@ void ignore_array(BurpGlobals* tdgbl, burp_rel* relation) break; } if (!field) - BURP_error_redirect(NULL, 36); + BURP_error_redirect (NULL, 36); // msg 36 Can't find field for blob break; @@ -10057,7 +9484,7 @@ void ignore_array(BurpGlobals* tdgbl, burp_rel* relation) if (tdgbl->gbl_sw_transportable) { if (get_attribute(&attribute, tdgbl) != att_xdr_array) - BURP_error_redirect(NULL, 55); + BURP_error_redirect (NULL, 55); // msg 55 Expected XDR record length else { @@ -10152,19 +9579,19 @@ rec_type ignore_data(BurpGlobals* tdgbl, burp_rel* relation) while (true) { if (get(tdgbl) != att_data_length) - BURP_error_redirect(NULL, 39); + BURP_error_redirect (NULL, 39); // msg 39 expected record length USHORT len = (USHORT) get_int32(tdgbl); if (tdgbl->gbl_sw_transportable) { if (get(tdgbl) != att_xdr_length) - BURP_error_redirect(NULL, 55); + BURP_error_redirect (NULL, 55); // msg 55 Expected XDR record length else len = (USHORT) get_int32(tdgbl); } if (get(tdgbl) != att_data_data) - BURP_error_redirect(NULL, 41); + BURP_error_redirect (NULL, 41); // msg 41 expected data attribute if (len) { @@ -10240,14 +9667,19 @@ void realign(BurpGlobals* tdgbl, UCHAR* buffer, const burp_rel* relation) } } - for (const burp_fld* field = relation->rel_fields; field; field = field->fld_next) + // If this is format version 2 or greater, build fields for null flags + + if (tdgbl->RESTORE_format >= 2) { - if (field->fld_flags & FLD_computed) - continue; - p = FB_ALIGN(p, sizeof(SSHORT)); - q = FB_ALIGN(q, sizeof(SSHORT)); - *p++ = *q++; - *p++ = *q++; + for (const burp_fld* field = relation->rel_fields; field; field = field->fld_next) + { + if (field->fld_flags & FLD_computed) + continue; + p = FB_ALIGN(p, sizeof(SSHORT)); + q = FB_ALIGN(q, sizeof(SSHORT)); + *p++ = *q++; + *p++ = *q++; + } } } @@ -10297,12 +9729,17 @@ USHORT recompute_length(BurpGlobals* tdgbl, burp_rel* relation) offset += length; } - for (const burp_fld* field = relation->rel_fields; field; field = field->fld_next) + // If this is format version 2, build fields for null flags + + if (tdgbl->RESTORE_format >= 2) { - if (field->fld_flags & FLD_computed) - continue; - offset = FB_ALIGN(offset, sizeof(SSHORT)); - offset += sizeof(SSHORT); + for (const burp_fld* field = relation->rel_fields; field; field = field->fld_next) + { + if (field->fld_flags & FLD_computed) + continue; + offset = FB_ALIGN(offset, sizeof(SSHORT)); + offset += sizeof(SSHORT); + } } return offset; @@ -10336,9 +9773,9 @@ bool restore(BurpGlobals* tdgbl, const TEXT* file_name, const TEXT* database_nam // restore only from those backup files created by current or previous GBAK - if (tdgbl->RESTORE_format < 2 || tdgbl->RESTORE_format > ATT_BACKUP_FORMAT) + if (tdgbl->RESTORE_format < 1 || tdgbl->RESTORE_format > ATT_BACKUP_FORMAT) { - BURP_error(344, true, SafeArg() << tdgbl->RESTORE_format << 2 << ATT_BACKUP_FORMAT); + BURP_error(344, true, SafeArg() << tdgbl->RESTORE_format << 1 << ATT_BACKUP_FORMAT); // msg 44 Expected backup version @2..@3. Found @1 } @@ -10347,7 +9784,7 @@ bool restore(BurpGlobals* tdgbl, const TEXT* file_name, const TEXT* database_nam create_database(tdgbl, database_name); EXEC SQL SET TRANSACTION NO_AUTO_UNDO; - if (gds_status->hasData()) + if (gds_status[1]) EXEC SQL SET TRANSACTION; // For V4.0, start a read commited transaction. This will be used @@ -10367,10 +9804,7 @@ bool restore(BurpGlobals* tdgbl, const TEXT* file_name, const TEXT* database_nam // msg 129 started transaction att_type attribute; - Firebird::IRequest* req_handle2 = nullptr; - Firebird::IRequest* req_handle3 = nullptr; - Firebird::IRequest* req_handle4 = nullptr; - Firebird::IRequest* req_handle5 = nullptr; + isc_req_handle req_handle2 = 0, req_handle3 = 0, req_handle4 = 0, req_handle5 = 0; while (get_attribute(&attribute, tdgbl) != att_end) { @@ -10659,7 +10093,7 @@ bool restore(BurpGlobals* tdgbl, const TEXT* file_name, const TEXT* database_nam general_on_error (); END_ERROR; EXEC SQL SET TRANSACTION NO_AUTO_UNDO; - if (gds_status->hasData()) + if (gds_status[1]) EXEC SQL SET TRANSACTION; flag = false; } @@ -10718,7 +10152,7 @@ bool restore(BurpGlobals* tdgbl, const TEXT* file_name, const TEXT* database_nam if (tdgbl->defaultCollations.getCount() > 0) { - Firebird::IRequest* req_handle5 = nullptr; + isc_req_handle req_handle5 = 0; FOR (REQUEST_HANDLE req_handle5) CS IN RDB$CHARACTER_SETS @@ -10762,7 +10196,7 @@ bool restore(BurpGlobals* tdgbl, const TEXT* file_name, const TEXT* database_nam general_on_error (); END_ERROR; EXEC SQL SET TRANSACTION NO_AUTO_UNDO; - if (gds_status->hasData()) + if (gds_status[1]) EXEC SQL SET TRANSACTION; } @@ -10774,7 +10208,7 @@ bool restore(BurpGlobals* tdgbl, const TEXT* file_name, const TEXT* database_nam if (tdgbl->gbl_sw_kill) { - Firebird::IRequest* req_handle5 = nullptr; + isc_req_handle req_handle5 = 0; FOR (REQUEST_HANDLE req_handle5) FIL IN RDB$FILES WITH FIL.RDB$SHADOW_NUMBER NOT MISSING @@ -10792,7 +10226,7 @@ bool restore(BurpGlobals* tdgbl, const TEXT* file_name, const TEXT* database_nam } // update statistics for system indices - Firebird::IRequest* req_handle6 = nullptr; + isc_req_handle req_handle6 = 0; FOR (REQUEST_HANDLE req_handle6) IND IN RDB$INDICES WITH IND.RDB$SYSTEM_FLAG EQ 1 @@ -10825,7 +10259,7 @@ void restore_security_class(BurpGlobals* tdgbl, const TEXT* owner_nm, const TEXT * restore the ownership of the relation in the ACL list * **************************************/ - Firebird::IRequest* req_handle2 = nullptr; + isc_req_handle req_handle2 = 0; //isc_tr_handle local_trans = gds_trans; @@ -10882,7 +10316,7 @@ USHORT get_view_base_relation_count(BurpGlobals* tdgbl, return 0; } - Firebird::IRequest* req_handle1 = nullptr; + isc_req_handle req_handle1 = 0; USHORT result = 0; @@ -11009,7 +10443,7 @@ void store_blr_gen_id(BurpGlobals* tdgbl, const TEXT* gen_name, SINT64 value, SI } - Firebird::IRequest* gen_id_reqh = nullptr; + FB_API_HANDLE gen_id_reqh = 0; UCHAR blr_buffer[100]; // enough to fit blr UCHAR* blr = blr_buffer; @@ -11065,25 +10499,26 @@ void store_blr_gen_id(BurpGlobals* tdgbl, const TEXT* gen_name, SINT64 value, SI const USHORT blr_length = blr - blr_buffer; fb_assert(blr_length <= sizeof(blr_buffer)); - FbLocalStatus status_vector; - gen_id_reqh = DB->compileRequest(&status_vector, blr_length, blr_buffer); - if (status_vector->hasData()) + ISC_STATUS_ARRAY status_vector; + if (isc_compile_request (status_vector, &DB, &gen_id_reqh, + blr_length, (const SCHAR*) blr_buffer)) { fb_print_blr(blr_buffer, blr_length, NULL, NULL, 0); - BURP_error_redirect(&status_vector, 42); // msg 42 Failed in store_blr_gen_id + BURP_error_redirect (status_vector, 42); // msg 42 Failed in store_blr_gen_id } - gen_id_reqh->start(&status_vector, gds_trans, 0); - if (status_vector->hasData()) + if (isc_start_request (status_vector, &gen_id_reqh, + &gds_trans, // use the same one generated by gpre + 0)) { fb_print_blr(blr_buffer, blr_length, NULL, NULL, 0); - BURP_error_redirect(&status_vector, 42); // msg 42 Failed in store_blr_gen_id + BURP_error_redirect (status_vector, 42); // msg 42 Failed in store_blr_gen_id } BURP_verbose (185, SafeArg() << gen_name << value); // msg 185 restoring generator %s value: %ld - gen_id_reqh->release(); + isc_release_request (status_vector, &gen_id_reqh); } @@ -11100,7 +10535,7 @@ void update_global_field(BurpGlobals* tdgbl) * The blobs have been created already. * **************************************/ - Firebird::IRequest* req_handle1 = nullptr; + isc_req_handle req_handle1 = 0; for (gfld* gfield = tdgbl->gbl_global_fields; gfield; ) { @@ -11165,9 +10600,7 @@ void update_global_field(BurpGlobals* tdgbl) void update_ownership(BurpGlobals* tdgbl) { - Firebird::IRequest* req_handle2 = nullptr; - Firebird::IRequest* req_handle4 = nullptr; - Firebird::IRequest* req_handle6 = nullptr; + isc_req_handle req_handle2 = 0, req_handle4 = 0, req_handle6 = 0; BURP_verbose(358); // Change ownership of any packages @@ -11307,7 +10740,7 @@ void update_view_dbkey_lengths(BurpGlobals* tdgbl) * numeric overflow, or string truncation" error. * **************************************/ - Firebird::IRequest* req_handle2 = nullptr; + isc_req_handle req_handle2 = 0; BURP_verbose(357); @@ -11351,8 +10784,7 @@ void fix_missing_privileges(BurpGlobals* tdgbl) BURP_verbose(359); GDS_NAME owner_name; - Firebird::IRequest* req_handle1 = nullptr; - Firebird::IRequest* req_handle2 = nullptr; + isc_req_handle req_handle1 = 0, req_handle2 = 0; FOR (REQUEST_HANDLE req_handle1) REL IN RDB$RELATIONS @@ -11454,16 +10886,8 @@ void fix_generator(BurpGlobals* tdgbl, const FixGenerator* g) /* SELECT 2 */ g->name, /* SET GEN */ g->name); - try - { - BurpSql fixGen(tdgbl, sql.c_str()); - fixGen.execute(gds_trans); - } - catch (const Firebird::FbException& ex) - { - fb_utils::copyStatus(&tdgbl->status_vector, ex.getStatus()); - general_on_error (); - } + if (isc_execute_immediate(isc_status, &DB, &gds_trans, 0, sql.c_str()) != 0) + general_on_error(); } static const FixGenerator genToFix[] = diff --git a/src/common/classes/BlobWrapper.cpp b/src/common/classes/BlobWrapper.cpp deleted file mode 100644 index 6ae3d58164..0000000000 --- a/src/common/classes/BlobWrapper.cpp +++ /dev/null @@ -1,271 +0,0 @@ -/* - * 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(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(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(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(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; -} diff --git a/src/common/classes/BlobWrapper.h b/src/common/classes/BlobWrapper.h deleted file mode 100644 index 4c52de59d2..0000000000 --- a/src/common/classes/BlobWrapper.h +++ /dev/null @@ -1,95 +0,0 @@ -/* - * 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 -#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 - diff --git a/src/common/classes/auto.h b/src/common/classes/auto.h index cb53880161..a6c1ed719b 100644 --- a/src/common/classes/auto.h +++ b/src/common/classes/auto.h @@ -168,16 +168,6 @@ private: }; -template -class AutoDispose : public AutoPtr > -{ -public: - AutoDispose(ID* v = nullptr) - : AutoPtr >(v) - { } -}; - - template class AutoSetRestore { diff --git a/src/common/status.h b/src/common/status.h deleted file mode 100644 index 51717b384d..0000000000 --- a/src/common/status.h +++ /dev/null @@ -1,116 +0,0 @@ -/* - * 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 - * 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 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 FbLocalStatus; - typedef LocalStatusWrapper ThrowLocalStatus; -} - -#endif // COMMON_STATUS_H diff --git a/src/dsql/DsqlBatch.cpp b/src/dsql/DsqlBatch.cpp index 4c82ed2e3e..cf47aceaab 100644 --- a/src/dsql/DsqlBatch.cpp +++ b/src/dsql/DsqlBatch.cpp @@ -87,6 +87,12 @@ 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(); @@ -140,6 +146,7 @@ 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); @@ -153,9 +160,9 @@ DsqlBatch::DsqlBatch(dsql_req* req, const dsql_msg* /*message*/, IMessageMetadat } // allocate data buffers - m_messages.setBuf(m_bufferSize, MAX(m_alignedMessage * 2, RAM_BATCH)); + m_messages.setBuf(m_bufferSize); if (m_blobMeta.hasData()) - m_blobs.setBuf(m_bufferSize, RAM_BATCH); + m_blobs.setBuf(m_bufferSize); // assign initial default BPB setDefBpb(FB_NELEM(initBlobParameters), initBlobParameters); @@ -263,7 +270,6 @@ 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() @@ -413,7 +419,6 @@ 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); } @@ -534,13 +539,13 @@ private: // parse blob header fb_assert(intptr_t(flow.data) % BLOB_STREAM_ALIGN == 0); - ISC_QUAD batchBlobId = *reinterpret_cast(flow.data); + ISC_QUAD* batchBlobId = reinterpret_cast(flow.data); ULONG* blobSize = reinterpret_cast(flow.data + sizeof(ISC_QUAD)); ULONG* bpbSize = reinterpret_cast(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) @@ -586,9 +591,7 @@ private: bid engineBlobId; blob = blb::create2(tdbb, transaction, &engineBlobId, bpb->getCount(), bpb->begin(), true); - - //DEB_BATCH(fprintf(stderr, "B-ID: (%x,%x)\n", batchBlobId.gds_quad_high, batchBlobId.gds_quad_low)); - registerBlob(reinterpret_cast(&engineBlobId), &batchBlobId); + registerBlob(reinterpret_cast(&engineBlobId), batchBlobId); } } @@ -699,9 +702,6 @@ private: continue; ISC_QUAD* id = reinterpret_cast(&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,15 +753,6 @@ 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); @@ -771,11 +762,14 @@ private: void DsqlBatch::cancel(thread_db* tdbb) { m_messages.clear(); - m_blobs.clear(); - m_setBlobSize = false; - m_lastBlob = MAX_ULONG; - memset(&m_genId, 0, sizeof(m_genId)); - m_blobMap.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(); + } } void DsqlBatch::genBlobId(ISC_QUAD* blobId) @@ -785,13 +779,13 @@ void DsqlBatch::genBlobId(ISC_QUAD* blobId) memcpy(blobId, &m_genId, sizeof(m_genId)); } -void DsqlBatch::DataCache::setBuf(ULONG size, ULONG cacheCapacity) +void DsqlBatch::DataCache::setBuf(ULONG size) { m_limit = size; - fb_assert(m_cacheCapacity == 0); - fb_assert(cacheCapacity >= RAM_BATCH); - m_cacheCapacity = cacheCapacity; + // create ram cache + fb_assert(!m_cache); + m_cache = FB_NEW_POOL(getPool()) Cache; } void DsqlBatch::DataCache::put3(const void* data, ULONG dataSize, ULONG offset) @@ -803,9 +797,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 @@ -817,7 +811,7 @@ void DsqlBatch::DataCache::put3(const void* data, ULONG dataSize, ULONG offset) void DsqlBatch::DataCache::put(const void* d, ULONG dataSize) { - if (m_limit && (m_used + m_cache.getCount() + dataSize > m_limit)) + if (m_used + (m_cache ? m_cache->getCount() : 0) + dataSize > m_limit) { ERRD_post(Arg::Gds(isc_sqlerr) << Arg::Num(-104) << Arg::Gds(isc_batch_too_big)); @@ -829,17 +823,17 @@ void DsqlBatch::DataCache::put(const void* d, ULONG dataSize) const ULONG K = 4; // ensure ram cache presence - fb_assert(m_cacheCapacity); + fb_assert(m_cache); // swap to secondary cache if needed - if (m_cache.getCount() + dataSize > m_cacheCapacity) + if (m_cache->getCount() + dataSize > m_cache->getCapacity()) { // store data in the end of ram cache if needed // avoid copy in case of huge buffer passed - ULONG delta = m_cacheCapacity - m_cache.getCount(); - if (dataSize - delta < m_cacheCapacity / K) + ULONG delta = m_cache->getCapacity() - m_cache->getCount(); + if (dataSize - delta < m_cache->getCapacity() / K) { - m_cache.append(data, delta); + m_cache->append(data, delta); data += delta; dataSize -= delta; } @@ -848,13 +842,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_cacheCapacity / K) + if (dataSize > m_cache->getCapacity() / K) { const FB_UINT64 writtenBytes = m_space->write(m_used, data, dataSize); fb_assert(writtenBytes == dataSize); @@ -863,7 +857,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) @@ -879,14 +873,16 @@ void DsqlBatch::DataCache::align(ULONG alignment) void DsqlBatch::DataCache::done() { - if (m_cache.getCount() && m_used) + fb_assert(m_cache); + + 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(); } } @@ -895,26 +891,26 @@ ULONG DsqlBatch::DataCache::get(UCHAR** buffer) if (m_used > m_got) { // get data from tempspace - ULONG dlen = m_cache.getCount(); - ULONG delta = m_cacheCapacity - dlen; + ULONG dlen = m_cache->getCount(); + ULONG delta = m_cache->getCapacity() - 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 @@ -930,9 +926,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; @@ -953,25 +949,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_cacheCapacity) + if(!m_cache) 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; diff --git a/src/dsql/DsqlBatch.h b/src/dsql/DsqlBatch.h index 6d55e40aa0..0816386008 100644 --- a/src/dsql/DsqlBatch.h +++ b/src/dsql/DsqlBatch.h @@ -107,11 +107,11 @@ private: { public: DataCache(MemoryPool& p) - : PermanentStorage(p), m_cache(getPool()), - m_used(0), m_got(0), m_limit(0), m_shift(0), m_cacheCapacity(0) + : PermanentStorage(p), + m_used(0), m_got(0), m_limit(0), m_shift(0) { } - void setBuf(ULONG size, ULONG cacheCapacity); + void setBuf(ULONG size); 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::Array Cache; - Cache m_cache; + typedef Firebird::Vector Cache; + Firebird::AutoPtr m_cache; Firebird::AutoPtr m_space; - ULONG m_used, m_got, m_limit, m_shift, m_cacheCapacity; + ULONG m_used, m_got, m_limit, m_shift; }; struct BlobMeta diff --git a/src/gpre/obj_cxx.cpp b/src/gpre/obj_cxx.cpp index a5811cf427..b083241c55 100644 --- a/src/gpre/obj_cxx.cpp +++ b/src/gpre/obj_cxx.cpp @@ -1075,9 +1075,10 @@ 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 (!(%s->getErrors() & Firebird::IStatus::STATE_ERRORS))", global_status_name); + printa(column, "if (!SQLCODE)"); align(column + INDENT); fprintf(gpreGlob.out_file, "%s = %s;", reference->ref_value, s); } @@ -2234,8 +2235,6 @@ 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 @@ -2251,8 +2250,6 @@ 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); } } @@ -3360,6 +3357,8 @@ static void gen_t_start( const act* action, int column) printa(column, "}\t\t// end fbComponents scope\n"); } + + set_sqlcode(action, column); } @@ -3436,10 +3435,9 @@ 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); } diff --git a/src/include/fb_types.h b/src/include/fb_types.h index 7030f4b792..cf691ca91b 100644 --- a/src/include/fb_types.h +++ b/src/include/fb_types.h @@ -125,7 +125,6 @@ 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, diff --git a/src/include/firebird/FirebirdInterface.idl b/src/include/firebird/FirebirdInterface.idl index fddf4aa6a7..511e5fbf8d 100644 --- a/src/include/firebird/FirebirdInterface.idl +++ b/src/include/firebird/FirebirdInterface.idl @@ -514,15 +514,15 @@ interface Pipe : ReferenceCounted interface Request : ReferenceCounted { void receive(Status status, int level, uint msgType, - uint length, void* message); + uint length, uchar* message); void send(Status status, int level, uint msgType, - uint length, const void* message); + uint length, const uchar* 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 void* message); + uint length, const uchar* message); void unwind(Status status, int level); void free(Status status); } @@ -599,8 +599,6 @@ 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); - - uint getRemoteProtocolVersion(Status status); /* Pipe createPipe(Status status, uint stmtLength, const string sqlStmt, uint dialect, Transaction transaction, MessageMetadata inMetadata, void* inBuffer, diff --git a/src/include/firebird/IdlFbInterfaces.h b/src/include/firebird/IdlFbInterfaces.h index 0905b41089..85b1d2d22e 100644 --- a/src/include/firebird/IdlFbInterfaces.h +++ b/src/include/firebird/IdlFbInterfaces.h @@ -1931,11 +1931,11 @@ namespace Firebird public: struct VTable : public IReferenceCounted::VTable { - 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 *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 *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 void* message) 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 *unwind)(IRequest* self, IStatus* status, int level) throw(); void (CLOOP_CARG *free)(IRequest* self, IStatus* status) throw(); }; @@ -1953,14 +1953,14 @@ namespace Firebird public: static const unsigned VERSION = 3; - template void receive(StatusType* status, int level, unsigned msgType, unsigned length, void* message) + template void receive(StatusType* status, int level, unsigned msgType, unsigned length, unsigned char* message) { StatusType::clearException(status); static_cast(this->cloopVTable)->receive(this, status, level, msgType, length, message); StatusType::checkException(status); } - template void send(StatusType* status, int level, unsigned msgType, unsigned length, const void* message) + template void send(StatusType* status, int level, unsigned msgType, unsigned length, const unsigned char* message) { StatusType::clearException(status); static_cast(this->cloopVTable)->send(this, status, level, msgType, length, message); @@ -1981,7 +1981,7 @@ namespace Firebird StatusType::checkException(status); } - template void startAndSend(StatusType* status, ITransaction* tra, int level, unsigned msgType, unsigned length, const void* message) + template void startAndSend(StatusType* status, ITransaction* tra, int level, unsigned msgType, unsigned length, const unsigned char* message) { StatusType::clearException(status); static_cast(this->cloopVTable)->startAndSend(this, status, tra, level, msgType, length, message); @@ -2122,7 +2122,6 @@ namespace Firebird unsigned (CLOOP_CARG *getStatementTimeout)(IAttachment* self, IStatus* status) throw(); void (CLOOP_CARG *setStatementTimeout)(IAttachment* self, IStatus* status, unsigned timeOut) throw(); IBatch* (CLOOP_CARG *createBatch)(IAttachment* self, IStatus* status, ITransaction* transaction, unsigned stmtLength, const char* sqlStmt, unsigned dialect, IMessageMetadata* inMetadata, unsigned parLength, const unsigned char* par) throw(); - unsigned (CLOOP_CARG *getRemoteProtocolVersion)(IAttachment* self, IStatus* status) throw(); }; protected: @@ -2341,20 +2340,6 @@ namespace Firebird StatusType::checkException(status); return ret; } - - template unsigned getRemoteProtocolVersion(StatusType* status) - { - if (cloopVTable->version < 4) - { - StatusType::setVersionError(status, "IAttachment", cloopVTable->version, 4); - StatusType::checkException(status); - return 0; - } - StatusType::clearException(status); - unsigned ret = static_cast(this->cloopVTable)->getRemoteProtocolVersion(this, status); - StatusType::checkException(status); - return ret; - } }; class IService : public IReferenceCounted @@ -9416,7 +9401,7 @@ namespace Firebird this->cloopVTable = &vTable; } - static void CLOOP_CARG cloopreceiveDispatcher(IRequest* self, IStatus* status, int level, unsigned msgType, unsigned length, void* message) throw() + static void CLOOP_CARG cloopreceiveDispatcher(IRequest* self, IStatus* status, int level, unsigned msgType, unsigned length, unsigned char* message) throw() { StatusType status2(status); @@ -9430,7 +9415,7 @@ namespace Firebird } } - static void CLOOP_CARG cloopsendDispatcher(IRequest* self, IStatus* status, int level, unsigned msgType, unsigned length, const void* message) throw() + static void CLOOP_CARG cloopsendDispatcher(IRequest* self, IStatus* status, int level, unsigned msgType, unsigned length, const unsigned char* message) throw() { StatusType status2(status); @@ -9472,7 +9457,7 @@ namespace Firebird } } - static void CLOOP_CARG cloopstartAndSendDispatcher(IRequest* self, IStatus* status, ITransaction* tra, int level, unsigned msgType, unsigned length, const void* message) throw() + static void CLOOP_CARG cloopstartAndSendDispatcher(IRequest* self, IStatus* status, ITransaction* tra, int level, unsigned msgType, unsigned length, const unsigned char* message) throw() { StatusType status2(status); @@ -9553,11 +9538,11 @@ namespace Firebird { } - 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 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 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 void* message) = 0; + virtual void startAndSend(StatusType* status, ITransaction* tra, int level, unsigned msgType, unsigned length, const unsigned char* message) = 0; virtual void unwind(StatusType* status, int level) = 0; virtual void free(StatusType* status) = 0; }; @@ -9815,7 +9800,6 @@ namespace Firebird this->getStatementTimeout = &Name::cloopgetStatementTimeoutDispatcher; this->setStatementTimeout = &Name::cloopsetStatementTimeoutDispatcher; this->createBatch = &Name::cloopcreateBatchDispatcher; - this->getRemoteProtocolVersion = &Name::cloopgetRemoteProtocolVersionDispatcher; } } vTable; @@ -10157,21 +10141,6 @@ namespace Firebird } } - static unsigned CLOOP_CARG cloopgetRemoteProtocolVersionDispatcher(IAttachment* self, IStatus* status) throw() - { - StatusType status2(status); - - try - { - return static_cast(self)->Name::getRemoteProtocolVersion(&status2); - } - catch (...) - { - StatusType::catchException(&status2); - return static_cast(0); - } - } - static void CLOOP_CARG cloopaddRefDispatcher(IReferenceCounted* self) throw() { try @@ -10234,7 +10203,6 @@ namespace Firebird virtual unsigned getStatementTimeout(StatusType* status) = 0; virtual void setStatementTimeout(StatusType* status, unsigned timeOut) = 0; virtual IBatch* createBatch(StatusType* status, ITransaction* transaction, unsigned stmtLength, const char* sqlStmt, unsigned dialect, IMessageMetadata* inMetadata, unsigned parLength, const unsigned char* par) = 0; - virtual unsigned getRemoteProtocolVersion(StatusType* status) = 0; }; template diff --git a/src/jrd/EngineInterface.h b/src/jrd/EngineInterface.h index 75e6f834fb..3576bae22d 100644 --- a/src/jrd/EngineInterface.h +++ b/src/jrd/EngineInterface.h @@ -277,15 +277,15 @@ public: // IRequest implementation int release(); void receive(Firebird::CheckStatusWrapper* status, int level, unsigned int msg_type, - unsigned int length, void* message); + unsigned int length, unsigned char* message); void send(Firebird::CheckStatusWrapper* status, int level, unsigned int msg_type, - unsigned int length, const void* message); + unsigned int length, const unsigned char* message); void getInfo(Firebird::CheckStatusWrapper* status, int level, unsigned int itemsLength, const unsigned char* items, unsigned int bufferLength, unsigned char* buffer); void start(Firebird::CheckStatusWrapper* status, Firebird::ITransaction* tra, int level); void startAndSend(Firebird::CheckStatusWrapper* status, Firebird::ITransaction* tra, int level, - unsigned int msg_type, unsigned int length, const void* message); + unsigned int msg_type, unsigned int length, const unsigned char* message); void unwind(Firebird::CheckStatusWrapper* status, int level); void free(Firebird::CheckStatusWrapper* status); @@ -396,7 +396,6 @@ public: Firebird::IBatch* createBatch(Firebird::CheckStatusWrapper* status, Firebird::ITransaction* transaction, unsigned stmtLength, const char* sqlStmt, unsigned dialect, Firebird::IMessageMetadata* inMetadata, unsigned parLength, const unsigned char* par); - unsigned int getRemoteProtocolVersion(Firebird::CheckStatusWrapper* status); public: explicit JAttachment(StableAttachmentPart* js); diff --git a/src/jrd/btr.cpp b/src/jrd/btr.cpp index fd0733b2bc..6a19d7457f 100644 --- a/src/jrd/btr.cpp +++ b/src/jrd/btr.cpp @@ -2250,7 +2250,7 @@ bool BTR_types_comparable(const dsc& target, const dsc& source) return (source.dsc_dtype <= dtype_long || source.dsc_dtype == dtype_int64); if (DTYPE_IS_NUMERIC(target.dsc_dtype)) - return (source.dsc_dtype <= dtype_double || source.dsc_dtype == dtype_int64); + return (source.dsc_dtype <= dtype_double || source.dsc_dtype == dtype_int64); //!!!!!!!! if (target.dsc_dtype == dtype_sql_date) return (source.dsc_dtype <= dtype_sql_date || source.dsc_dtype == dtype_timestamp); diff --git a/src/jrd/exe.cpp b/src/jrd/exe.cpp index 5c3b46d029..1862cf3893 100644 --- a/src/jrd/exe.cpp +++ b/src/jrd/exe.cpp @@ -614,7 +614,7 @@ void EXE_receive(thread_db* tdbb, jrd_req* request, USHORT msg, ULONG length, - void* buffer, + UCHAR* buffer, bool top_level) { /************************************** @@ -692,7 +692,7 @@ void EXE_receive(thread_db* tdbb, if (desc->isBlob()) { - const bid* id = (bid*) (reinterpret_cast(buffer) + (ULONG)(IPTR) desc->dsc_address); + const bid* id = (bid*) (buffer + (ULONG)(IPTR)desc->dsc_address); if (transaction->tra_blobs->locate(id->bid_temp_id())) { @@ -766,7 +766,7 @@ void EXE_release(thread_db* tdbb, jrd_req* request) } -void EXE_send(thread_db* tdbb, jrd_req* request, USHORT msg, ULONG length, const void* buffer) +void EXE_send(thread_db* tdbb, jrd_req* request, USHORT msg, ULONG length, const UCHAR* buffer) { /************************************** * diff --git a/src/jrd/exe_proto.h b/src/jrd/exe_proto.h index ea3dedcc2e..2bc4ae301e 100644 --- a/src/jrd/exe_proto.h +++ b/src/jrd/exe_proto.h @@ -46,9 +46,9 @@ const Jrd::StmtNode* EXE_looper(Jrd::thread_db* tdbb, Jrd::jrd_req* request, void EXE_execute_triggers(Jrd::thread_db*, Jrd::TrigVector**, Jrd::record_param*, Jrd::record_param*, enum TriggerAction, Jrd::StmtNode::WhichTrigger); -void EXE_receive(Jrd::thread_db*, Jrd::jrd_req*, USHORT, ULONG, void*, bool = false); +void EXE_receive(Jrd::thread_db*, Jrd::jrd_req*, USHORT, ULONG, UCHAR*, bool = false); void EXE_release(Jrd::thread_db*, Jrd::jrd_req*); -void EXE_send(Jrd::thread_db*, Jrd::jrd_req*, USHORT, ULONG, const void*); +void EXE_send(Jrd::thread_db*, Jrd::jrd_req*, USHORT, ULONG, const UCHAR*); void EXE_start(Jrd::thread_db*, Jrd::jrd_req*, Jrd::jrd_tra*); void EXE_unwind(Jrd::thread_db*, Jrd::jrd_req*); diff --git a/src/jrd/inf_pub.h b/src/jrd/inf_pub.h index da36ce0b54..77527aa6b0 100644 --- a/src/jrd/inf_pub.h +++ b/src/jrd/inf_pub.h @@ -148,7 +148,6 @@ enum db_info_types fb_info_ses_idle_timeout_run = 131, fb_info_conn_flags = 132, - fb_info_protocol_version = 133, fb_info_crypt_key = 133, fb_info_crypt_state = 134, diff --git a/src/jrd/jrd.cpp b/src/jrd/jrd.cpp index 630f4d080d..908d278396 100644 --- a/src/jrd/jrd.cpp +++ b/src/jrd/jrd.cpp @@ -3490,7 +3490,7 @@ JEvents* JAttachment::queEvents(CheckStatusWrapper* user_status, IEventCallback* void JRequest::receive(CheckStatusWrapper* user_status, int level, unsigned int msg_type, - unsigned int msg_length, void* msg) + unsigned int msg_length, unsigned char* msg) { /************************************** * @@ -3803,7 +3803,7 @@ int JBlob::seek(CheckStatusWrapper* user_status, int mode, int offset) void JRequest::send(CheckStatusWrapper* user_status, int level, unsigned int msg_type, - unsigned int msg_length, const void* msg) + unsigned int msg_length, const unsigned char* msg) { /************************************** * @@ -4028,7 +4028,7 @@ void JService::start(CheckStatusWrapper* user_status, unsigned int spbLength, co void JRequest::startAndSend(CheckStatusWrapper* user_status, ITransaction* tra, int level, - unsigned int msg_type, unsigned int msg_length, const void* msg) + unsigned int msg_type, unsigned int msg_length, const unsigned char* msg) { /************************************** * @@ -4827,12 +4827,6 @@ IBatch* JAttachment::createBatch(CheckStatusWrapper* status, ITransaction* trans } -unsigned int JAttachment::getRemoteProtocolVersion(Firebird::CheckStatusWrapper* status) -{ - return 0; // protocol == 0, i.e. no network, i.e. embedded connection -} - - int JResultSet::fetchNext(CheckStatusWrapper* user_status, void* buffer) { try @@ -8406,7 +8400,7 @@ void JRD_autocommit_ddl(thread_db* tdbb, jrd_tra* transaction) } -void JRD_receive(thread_db* tdbb, jrd_req* request, USHORT msg_type, ULONG msg_length, void* msg) +void JRD_receive(thread_db* tdbb, jrd_req* request, USHORT msg_type, ULONG msg_length, UCHAR* msg) { /************************************** * @@ -8430,7 +8424,7 @@ void JRD_receive(thread_db* tdbb, jrd_req* request, USHORT msg_type, ULONG msg_l } -void JRD_send(thread_db* tdbb, jrd_req* request, USHORT msg_type, ULONG msg_length, const void* msg) +void JRD_send(thread_db* tdbb, jrd_req* request, USHORT msg_type, ULONG msg_length, const UCHAR* msg) { /************************************** * @@ -8544,7 +8538,7 @@ void JRD_rollback_retaining(thread_db* tdbb, jrd_tra* transaction) void JRD_start_and_send(thread_db* tdbb, jrd_req* request, jrd_tra* transaction, - USHORT msg_type, ULONG msg_length, const void* msg) + USHORT msg_type, ULONG msg_length, const UCHAR* msg) { /************************************** * diff --git a/src/jrd/jrd_proto.h b/src/jrd/jrd_proto.h index 4c096b7996..7f303a2544 100644 --- a/src/jrd/jrd_proto.h +++ b/src/jrd/jrd_proto.h @@ -59,7 +59,7 @@ void JRD_print_procedure_info(Jrd::thread_db*, const char*); void JRD_autocommit_ddl(Jrd::thread_db* tdbb, Jrd::jrd_tra* transaction); void JRD_receive(Jrd::thread_db* tdbb, Jrd::jrd_req* request, USHORT msg_type, ULONG msg_length, - void* msg); + UCHAR* msg); void JRD_start(Jrd::thread_db* tdbb, Jrd::jrd_req* request, Jrd::jrd_tra* transaction); void JRD_commit_transaction(Jrd::thread_db* tdbb, Jrd::jrd_tra* transaction); @@ -67,9 +67,9 @@ void JRD_commit_retaining(Jrd::thread_db* tdbb, Jrd::jrd_tra* transaction); void JRD_rollback_transaction(Jrd::thread_db* tdbb, Jrd::jrd_tra* transaction); void JRD_rollback_retaining(Jrd::thread_db* tdbb, Jrd::jrd_tra* transaction); void JRD_send(Jrd::thread_db* tdbb, Jrd::jrd_req* request, USHORT msg_type, ULONG msg_length, - const void* msg); + const UCHAR* msg); void JRD_start_and_send(Jrd::thread_db* tdbb, Jrd::jrd_req* request, Jrd::jrd_tra* transaction, - USHORT msg_type, ULONG msg_length, const void* msg); + USHORT msg_type, ULONG msg_length, const UCHAR* msg); void JRD_start_transaction(Jrd::thread_db* tdbb, Jrd::jrd_tra** transaction, Jrd::Attachment* attachment, unsigned int tpb_length, const UCHAR* tpb); void JRD_unwind_request(Jrd::thread_db* tdbb, Jrd::jrd_req* request); diff --git a/src/jrd/status.h b/src/jrd/status.h index adbe1ca9b0..dfb07c823a 100644 --- a/src/jrd/status.h +++ b/src/jrd/status.h @@ -29,13 +29,90 @@ #ifndef JRD_STATUS_H #define JRD_STATUS_H -#include "../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 Jrd { typedef Firebird::CheckStatusWrapper FbStatusVector; - typedef Firebird::FbLocalStatus FbLocalStatus; - typedef Firebird::ThrowLocalStatus ThrowLocalStatus; + + template + 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 FbLocalStatus; + typedef LocalStatusWrapper ThrowLocalStatus; } #endif // JRD_STATUS_H diff --git a/src/jrd/val.h b/src/jrd/val.h index 926dc6eb0c..eb2c042cdd 100644 --- a/src/jrd/val.h +++ b/src/jrd/val.h @@ -50,8 +50,7 @@ public: }; const UCHAR DEFAULT_DOUBLE = dtype_double; - -const ULONG MAX_RECORD_SIZE = 1024 * 1024; // 1MB +const ULONG MAX_RECORD_SIZE = 65535; namespace Jrd { diff --git a/src/msgs/messages2.sql b/src/msgs/messages2.sql index 8e95cdad66..a87f11373d 100644 --- a/src/msgs/messages2.sql +++ b/src/msgs/messages2.sql @@ -970,7 +970,7 @@ Data source : @4', NULL, NULL) ('non_plugin_protocol', NULL, 'server.cpp', NULL, 0, 860, NULL, 'Plugin not supported by network protocol', NULL, NULL); ('message_format', NULL, 'server.cpp', NULL, 0, 861, NULL, 'Error parsing message format', NULL, NULL); ('batch_param_version', NULL, NULL, NULL, 0, 862, NULL, 'Wrong version of batch parameters block @1, should be @2', NULL, NULL); -('batch_msg_long', NULL, '** Unused **', NULL, 0, 863, NULL, 'Message size (@1) in batch exceeds internal buffer size (@2)', NULL, NULL); +('batch_msg_long', NULL, 'DsqlBatch.cpp', NULL, 0, 863, NULL, 'Message size (@1) in batch exceeds internal buffer size (@2)', NULL, NULL); ('batch_open', NULL, 'DsqlBatch.cpp', NULL, 0, 864, NULL, 'Batch already opened for this statement', NULL, NULL); ('batch_type', NULL, 'DsqlBatch.cpp', NULL, 0, 865, NULL, 'Invalid type of statement used in batch', NULL, NULL); ('batch_param', NULL, 'DsqlBatch.cpp', NULL, 0, 866, NULL, 'Statement used in batch must have parameters', NULL, NULL); diff --git a/src/remote/client/interface.cpp b/src/remote/client/interface.cpp index 77ddfc071b..3b2125206c 100644 --- a/src/remote/client/interface.cpp +++ b/src/remote/client/interface.cpp @@ -371,7 +371,6 @@ private: // working with blob stream buffer void newBlob() { - setBlobAlignment(); alignBlobBuffer(blobAlign); fb_assert(blobStream - blobStreamBuffer <= blobBufferSize); @@ -385,8 +384,6 @@ private: void alignBlobBuffer(unsigned alignment, ULONG* bs = NULL) { - fb_assert(alignment); - FB_UINT64 zeroFill = 0; UCHAR* newPointer = FB_ALIGN(blobStream, alignment); ULONG align = FB_ALIGN(blobStream, alignment) - blobStream; @@ -467,7 +464,6 @@ private: void flashBatch() { - setBlobAlignment(); alignBlobBuffer(blobAlign); ULONG size = blobStream - blobStreamBuffer; if (size) @@ -476,12 +472,6 @@ private: blobStream = blobStreamBuffer; } - if (messageStream) - { - sendMessagePacket(messageStream, messageStreamBuffer); - messageStream = 0; - } - batchActive = false; } @@ -631,15 +621,15 @@ public: // IRequest implementation int release(); void receive(CheckStatusWrapper* status, int level, unsigned int msg_type, - unsigned int length, void* message); + unsigned int length, unsigned char* message); void send(CheckStatusWrapper* status, int level, unsigned int msg_type, - unsigned int length, const void* message); + unsigned int length, const unsigned char* message); void getInfo(CheckStatusWrapper* status, int level, unsigned int itemsLength, const unsigned char* items, unsigned int bufferLength, unsigned char* buffer); void start(CheckStatusWrapper* status, Firebird::ITransaction* tra, int level); void startAndSend(CheckStatusWrapper* status, Firebird::ITransaction* tra, int level, unsigned int msg_type, - unsigned int length, const void* message); + unsigned int length, const unsigned char* message); void unwind(CheckStatusWrapper* status, int level); void free(CheckStatusWrapper* status); @@ -770,11 +760,6 @@ public: unsigned stmtLength, const char* sqlStmt, unsigned dialect, IMessageMetadata* inMetadata, unsigned parLength, const unsigned char* par); - unsigned getRemoteProtocolVersion(CheckStatusWrapper* status) - { - return rdb->rdb_port->port_protocol & FB_PROTOCOL_MASK; - } - public: Attachment(Rdb* handle, const PathName& path) : rdb(handle), dbPath(getPool(), path) @@ -5072,7 +5057,7 @@ Firebird::IEvents* Attachment::queEvents(CheckStatusWrapper* status, Firebird::I void Request::receive(CheckStatusWrapper* status, int level, unsigned int msg_type, - unsigned int msg_length, void* msg) + unsigned int msg_length, unsigned char* msg) { /************************************** * @@ -5585,7 +5570,7 @@ int Blob::seek(CheckStatusWrapper* status, int mode, int offset) void Request::send(CheckStatusWrapper* status, int level, unsigned int msg_type, - unsigned int /*length*/, const void* msg) + unsigned int /*length*/, const unsigned char* msg) { /************************************** * @@ -5616,7 +5601,7 @@ void Request::send(CheckStatusWrapper* status, int level, unsigned int msg_type, RMessage* message = request->rrq_rpt[msg_type].rrq_message; // We are lying here, but the interface shows for years this param as const - message->msg_address = const_cast(reinterpret_cast(msg)); + message->msg_address = const_cast(msg); PACKET* packet = &rdb->rdb_packet; packet->p_operation = op_send; @@ -5867,7 +5852,7 @@ void Service::start(CheckStatusWrapper* status, void Request::startAndSend(CheckStatusWrapper* status, Firebird::ITransaction* apiTra, int level, - unsigned int msg_type, unsigned int /*length*/, const void* msg) + unsigned int msg_type, unsigned int /*length*/, const unsigned char* msg) { /************************************** * @@ -5909,7 +5894,7 @@ void Request::startAndSend(CheckStatusWrapper* status, Firebird::ITransaction* a REMOTE_reset_request(request, 0); RMessage* message = request->rrq_rpt[msg_type].rrq_message; - message->msg_address = const_cast(reinterpret_cast(msg)); + message->msg_address = const_cast(msg); PACKET* packet = &rdb->rdb_packet; packet->p_operation = op_start_send_and_receive; diff --git a/src/remote/merge.cpp b/src/remote/merge.cpp index 8dc424a41a..c4563d7b8d 100644 --- a/src/remote/merge.cpp +++ b/src/remote/merge.cpp @@ -48,6 +48,7 @@ USHORT MERGE_database_info(const UCHAR* in, USHORT base_level, const UCHAR* version, const UCHAR* id) + //ULONG mask Was always zero { /************************************** * diff --git a/src/remote/protocol.cpp b/src/remote/protocol.cpp index 75fa9e8e73..9332a790a2 100644 --- a/src/remote/protocol.cpp +++ b/src/remote/protocol.cpp @@ -893,7 +893,7 @@ bool_t xdr_protocol(XDR* xdrs, PACKET* p) while (count--) { - DEB_RBATCH(fprintf(stderr, "BatRem: xdr packed msg\n")); + DEB_BATCH(fprintf(stderr, "BatRem: xdr packed msg\n")); if (!xdr_packed_message(xdrs, message, statement->rsr_format)) return P_FALSE(xdrs, p); message->msg_address += statement->rsr_batch_size; @@ -912,7 +912,7 @@ bool_t xdr_protocol(XDR* xdrs, PACKET* p) MAP(xdr_short, reinterpret_cast(b->p_batch_transaction)); if (xdrs->x_op != XDR_FREE) - DEB_RBATCH(fprintf(stderr, "BatRem: xdr execute\n")); + DEB_BATCH(fprintf(stderr, "BatRem: xdr execute\n")); return P_TRUE(xdrs, p); } @@ -931,7 +931,7 @@ bool_t xdr_protocol(XDR* xdrs, PACKET* p) rem_port* port = (rem_port*) xdrs->x_public; SSHORT statement_id = b->p_batch_statement; - DEB_RBATCH(fprintf(stderr, "BatRem: xdr CS %d\n", statement_id)); + DEB_BATCH(fprintf(stderr, "BatRem: xdr CS %d\n", statement_id)); Rsr* statement; if (statement_id >= 0) @@ -961,12 +961,12 @@ bool_t xdr_protocol(XDR* xdrs, PACKET* p) if ((xdrs->x_op == XDR_DECODE) && (!b->p_batch_updates)) { - DEB_RBATCH(fprintf(stderr, "BatRem: xdr reccount=%d\n", b->p_batch_reccount)); + DEB_BATCH(fprintf(stderr, "BatRem: xdr reccount=%d\n", b->p_batch_reccount)); statement->rsr_batch_cs->regSize(b->p_batch_reccount); } // Process update counters - DEB_RBATCH(fprintf(stderr, "BatRem: xdr up %d\n", b->p_batch_updates)); + DEB_BATCH(fprintf(stderr, "BatRem: xdr up %d\n", b->p_batch_updates)); for (unsigned i = 0; i < b->p_batch_updates; ++i) { SLONG v; @@ -988,7 +988,7 @@ bool_t xdr_protocol(XDR* xdrs, PACKET* p) // Process status vectors ULONG pos = 0u; LocalStatus to; - DEB_RBATCH(fprintf(stderr, "BatRem: xdr sv %d\n", b->p_batch_vectors)); + DEB_BATCH(fprintf(stderr, "BatRem: xdr sv %d\n", b->p_batch_vectors)); for (unsigned i = 0; i < b->p_batch_vectors; ++i, ++pos) { @@ -1026,7 +1026,7 @@ bool_t xdr_protocol(XDR* xdrs, PACKET* p) // Process status-less errors pos = 0u; - DEB_RBATCH(fprintf(stderr, "BatRem: xdr err %d\n", b->p_batch_errors)); + DEB_BATCH(fprintf(stderr, "BatRem: xdr err %d\n", b->p_batch_errors)); for (unsigned i = 0; i < b->p_batch_errors; ++i, ++pos) { @@ -1059,7 +1059,7 @@ bool_t xdr_protocol(XDR* xdrs, PACKET* p) MAP(xdr_short, reinterpret_cast(b->p_batch_statement)); if (xdrs->x_op != XDR_FREE) - DEB_RBATCH(fprintf(stderr, "BatRem: xdr release\n")); + DEB_BATCH(fprintf(stderr, "BatRem: xdr release\n")); return P_TRUE(xdrs, p); } diff --git a/src/remote/remote.h b/src/remote/remote.h index 93e238c503..26c1404d3d 100644 --- a/src/remote/remote.h +++ b/src/remote/remote.h @@ -64,7 +64,7 @@ //#define COMPRESS_DEBUG 1 #endif // WIRE_COMPRESS_SUPPORT -#define DEB_RBATCH(x) +#define DEB_BATCH(x) #define REM_SEND_OFFSET(bs) (0) #define REM_RECV_OFFSET(bs) (bs) diff --git a/src/yvalve/YObjects.h b/src/yvalve/YObjects.h index ae7bf8ede7..bf3c5de056 100644 --- a/src/yvalve/YObjects.h +++ b/src/yvalve/YObjects.h @@ -210,14 +210,14 @@ public: // IRequest implementation void receive(Firebird::CheckStatusWrapper* status, int level, unsigned int msgType, - unsigned int length, void* message); + unsigned int length, unsigned char* message); void send(Firebird::CheckStatusWrapper* status, int level, unsigned int msgType, - unsigned int length, const void* message); + unsigned int length, const unsigned char* message); void getInfo(Firebird::CheckStatusWrapper* status, int level, unsigned int itemsLength, const unsigned char* items, unsigned int bufferLength, unsigned char* buffer); void start(Firebird::CheckStatusWrapper* status, Firebird::ITransaction* transaction, int level); void startAndSend(Firebird::CheckStatusWrapper* status, Firebird::ITransaction* transaction, int level, - unsigned int msgType, unsigned int length, const void* message); + unsigned int msgType, unsigned int length, const unsigned char* message); void unwind(Firebird::CheckStatusWrapper* status, int level); void free(Firebird::CheckStatusWrapper* status); @@ -510,7 +510,6 @@ public: YBatch* createBatch(Firebird::CheckStatusWrapper* status, Firebird::ITransaction* transaction, unsigned stmtLength, const char* sqlStmt, unsigned dialect, Firebird::IMessageMetadata* inMetadata, unsigned parLength, const unsigned char* par); - unsigned int getRemoteProtocolVersion(Firebird::CheckStatusWrapper* status); public: Firebird::IProvider* provider; diff --git a/src/yvalve/why.cpp b/src/yvalve/why.cpp index 7e10029762..afe4e53050 100644 --- a/src/yvalve/why.cpp +++ b/src/yvalve/why.cpp @@ -3922,7 +3922,7 @@ void YRequest::destroy(unsigned dstrFlags) } void YRequest::receive(CheckStatusWrapper* status, int level, unsigned int msgType, - unsigned int length, void* message) + unsigned int length, unsigned char* message) { try { @@ -3936,7 +3936,7 @@ void YRequest::receive(CheckStatusWrapper* status, int level, unsigned int msgTy } void YRequest::send(CheckStatusWrapper* status, int level, unsigned int msgType, - unsigned int length, const void* message) + unsigned int length, const unsigned char* message) { try { @@ -3980,7 +3980,7 @@ void YRequest::start(CheckStatusWrapper* status, ITransaction* transaction, int } void YRequest::startAndSend(CheckStatusWrapper* status, ITransaction* transaction, int level, - unsigned int msgType, unsigned int length, const void* message) + unsigned int msgType, unsigned int length, const unsigned char* message) { try { @@ -5931,22 +5931,6 @@ YBatch* YAttachment::createBatch(CheckStatusWrapper* status, ITransaction* trans return NULL; } -unsigned int YAttachment::getRemoteProtocolVersion(CheckStatusWrapper* status) -{ - try - { - YEntry entry(status, this); - - return entry.next()->getRemoteProtocolVersion(status); - } - catch (const Exception& e) - { - e.stuffException(status); - } - - return 0; -} - //------------------------------------- From 0b0af90393b838bf3e3b7a989313720e926f012c Mon Sep 17 00:00:00 2001 From: Adriano dos Santos Fernandes Date: Fri, 16 Feb 2018 15:47:48 -0200 Subject: [PATCH 033/171] Misc. --- src/dsql/DdlNodes.epp | 2 +- src/jrd/inf_pub.h | 2 +- src/jrd/svc.cpp | 10 +++++----- src/jrd/validation.cpp | 2 +- src/jrd/vio.cpp | 1 + 5 files changed, 9 insertions(+), 8 deletions(-) diff --git a/src/dsql/DdlNodes.epp b/src/dsql/DdlNodes.epp index 9a376a99ed..06ee399726 100644 --- a/src/dsql/DdlNodes.epp +++ b/src/dsql/DdlNodes.epp @@ -11984,7 +11984,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) diff --git a/src/jrd/inf_pub.h b/src/jrd/inf_pub.h index 77527aa6b0..0ba0ef2219 100644 --- a/src/jrd/inf_pub.h +++ b/src/jrd/inf_pub.h @@ -140,7 +140,7 @@ enum db_info_types fb_info_pages_used = 124, fb_info_pages_free = 125, - // codes 126 and 127 are used for special purporses + // codes 126 and 127 are used for special purposes // do not use them here fb_info_ses_idle_timeout_db = 129, diff --git a/src/jrd/svc.cpp b/src/jrd/svc.cpp index a1853310ba..a8cf59c1c4 100644 --- a/src/jrd/svc.cpp +++ b/src/jrd/svc.cpp @@ -1648,23 +1648,23 @@ void Service::query(USHORT send_item_length, case isc_info_svc_get_env_msg: if (svc_user_flag & SVC_user_dba) { - TEXT PathBuffer[MAXPATHLEN]; + TEXT pathBuffer[MAXPATHLEN]; switch (item) { case isc_info_svc_get_env: - gds__prefix(PathBuffer, ""); + gds__prefix(pathBuffer, ""); break; case isc_info_svc_get_env_lock: - iscPrefixLock(PathBuffer, "", false); + iscPrefixLock(pathBuffer, "", false); break; case isc_info_svc_get_env_msg: - gds__prefix_msg(PathBuffer, ""); + gds__prefix_msg(pathBuffer, ""); } // Note: it is safe to use strlen to get a length of "buffer" // because gds_prefix[_lock|_msg] return a zero-terminated // string. - if (!(info = INF_put_item(item, static_cast(strlen(PathBuffer)), PathBuffer, info, end))) + if (!(info = INF_put_item(item, static_cast(strlen(pathBuffer)), pathBuffer, info, end))) return; } // Can not return error for service v.1 => simply ignore request diff --git a/src/jrd/validation.cpp b/src/jrd/validation.cpp index c459dfb6ed..55704f75d0 100644 --- a/src/jrd/validation.cpp +++ b/src/jrd/validation.cpp @@ -1376,7 +1376,7 @@ void Validation::garbage_collect() page->pip_min = bit; if (p[-1] == 0xFF && page->pip_extent > bit) - page->pip_extent = bit & ((ULONG)~7); + page->pip_extent = bit & ((ULONG) ~7); } DEBUG; } diff --git a/src/jrd/vio.cpp b/src/jrd/vio.cpp index 60fb39f3e5..1528172406 100644 --- a/src/jrd/vio.cpp +++ b/src/jrd/vio.cpp @@ -571,6 +571,7 @@ void VIO_backout(thread_db* tdbb, record_param* rpb, const jrd_tra* transaction) if (rpb->rpb_flags & rpb_delta) rpb->rpb_prior = data; } + gcLockGuard.release(); delete_record(tdbb, rpb, 0, NULL); From 3da584e505ce49766046c5a5faff7ff22df944c0 Mon Sep 17 00:00:00 2001 From: firebirds <> Date: Sat, 17 Feb 2018 00:04:03 +0000 Subject: [PATCH 034/171] increment build number --- src/jrd/build_no.h | 12 ++++++------ src/misc/writeBuildNum.sh | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/jrd/build_no.h b/src/jrd/build_no.h index 8e0541d1c3..864cbc8710 100644 --- a/src/jrd/build_no.h +++ b/src/jrd/build_no.h @@ -3,16 +3,16 @@ *** DO NOT EDIT *** TO CHANGE ANY INFORMATION IN HERE PLEASE EDIT src/misc/writeBuildNum.sh - FORMAL BUILD NUMBER:890 + FORMAL BUILD NUMBER:901 */ -#define PRODUCT_VER_STRING "4.0.0.890" -#define FILE_VER_STRING "WI-T4.0.0.890" -#define LICENSE_VER_STRING "WI-T4.0.0.890" -#define FILE_VER_NUMBER 4, 0, 0, 890 +#define PRODUCT_VER_STRING "4.0.0.901" +#define FILE_VER_STRING "WI-T4.0.0.901" +#define LICENSE_VER_STRING "WI-T4.0.0.901" +#define FILE_VER_NUMBER 4, 0, 0, 901 #define FB_MAJOR_VER "4" #define FB_MINOR_VER "0" #define FB_REV_NO "0" -#define FB_BUILD_NO "890" +#define FB_BUILD_NO "901" #define FB_BUILD_TYPE "T" #define FB_BUILD_SUFFIX "Firebird 4.0 Alpha 1" diff --git a/src/misc/writeBuildNum.sh b/src/misc/writeBuildNum.sh index 08120fe167..55e35c9062 100755 --- a/src/misc/writeBuildNum.sh +++ b/src/misc/writeBuildNum.sh @@ -9,7 +9,7 @@ BuildType=T MajorVer=4 MinorVer=0 RevNo=0 -BuildNum=890 +BuildNum=901 NowAt=`pwd` cd `dirname $0` From 95cd9d1908cd63444fe66e950a6068b03b936296 Mon Sep 17 00:00:00 2001 From: AlexPeshkoff Date: Mon, 19 Feb 2018 09:47:57 +0300 Subject: [PATCH 035/171] Hopefully better test for ICU presence --- builds/install/posix-common/posixLibrary.sh.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/builds/install/posix-common/posixLibrary.sh.in b/builds/install/posix-common/posixLibrary.sh.in index 19ba601f8f..270c0659a6 100644 --- a/builds/install/posix-common/posixLibrary.sh.in +++ b/builds/install/posix-common/posixLibrary.sh.in @@ -229,7 +229,7 @@ checkLibraries() { checkLibrary tomcrypt fi - checkLibrary icu + checkLibrary icudata } From a6d57fc4d89a304fa72c9eb6630a1694fae9c04e Mon Sep 17 00:00:00 2001 From: Alexander Peshkov Date: Mon, 19 Feb 2018 13:38:28 +0300 Subject: [PATCH 036/171] Gbak (#139) * Rewritten gbak using OO API * Make gbak correctly work with wide records (if record format to be made > 64K) * Improve gbak performance over network using batch interface * Enhanced template AutoPtr to make use of it more comfortable --- builds/posix/make.rules | 7 +- builds/win32/msvc10/common.vcxproj | 2 + builds/win32/msvc10/common.vcxproj.filters | 6 + builds/win32/msvc12/common.vcxproj | 2 + builds/win32/msvc12/common.vcxproj.filters | 6 + builds/win32/msvc14/common.vcxproj | 2 + builds/win32/msvc14/common.vcxproj.filters | 6 + builds/win32/preprocess.bat | 7 +- src/burp/OdsDetection.epp | 11 +- src/burp/backup.epp | 346 ++---- src/burp/burp.cpp | 249 ++-- src/burp/burp.h | 172 ++- src/burp/burp_proto.h | 10 +- src/burp/canon_proto.h | 4 +- src/burp/canonical.cpp | 14 +- src/burp/misc.cpp | 6 +- src/burp/misc_proto.h | 2 +- src/burp/restore.epp | 1229 +++++++++++++++----- src/common/CharSet.h | 22 +- src/common/classes/BlobWrapper.cpp | 271 +++++ src/common/classes/BlobWrapper.h | 95 ++ src/common/classes/alloc.h | 15 +- src/common/classes/auto.h | 49 +- src/common/classes/init.cpp | 2 +- src/common/config/config_file.cpp | 2 +- src/common/status.h | 116 ++ src/dsql/DsqlBatch.cpp | 128 +- src/dsql/DsqlBatch.h | 12 +- src/dsql/Parser.h | 2 +- src/gpre/obj_cxx.cpp | 14 +- src/include/fb_types.h | 1 + src/include/firebird/FirebirdInterface.idl | 7 +- src/include/firebird/IdlFbInterfaces.h | 24 +- src/intl/lc_icu.cpp | 4 +- src/isql/isql.epp | 2 +- src/isql/show.epp | 2 +- src/jrd/CryptoManager.cpp | 8 +- src/jrd/EngineInterface.h | 6 +- src/jrd/Mapping.cpp | 2 +- src/jrd/btr.cpp | 2 +- src/jrd/exe.cpp | 6 +- src/jrd/exe.h | 2 +- src/jrd/exe_proto.h | 4 +- src/jrd/extds/InternalDS.cpp | 2 +- src/jrd/extds/IscDS.cpp | 2 +- src/jrd/inf_pub.h | 1 + src/jrd/intl_builtin.cpp | 2 +- src/jrd/jrd.cpp | 12 +- src/jrd/jrd.h | 4 +- src/jrd/jrd_proto.h | 6 +- src/jrd/sort.cpp | 2 +- src/jrd/status.h | 81 +- src/jrd/svc.h | 2 +- src/jrd/val.h | 1 + src/lock/print.cpp | 2 +- src/msgs/messages2.sql | 2 +- src/remote/client/interface.cpp | 30 +- src/remote/merge.cpp | 1 - src/remote/protocol.cpp | 16 +- src/remote/remote.h | 4 +- src/remote/server/server.cpp | 2 +- src/utilities/ntrace/traceplugin.cpp | 2 +- src/yvalve/YObjects.h | 6 +- src/yvalve/why.cpp | 6 +- 64 files changed, 2060 insertions(+), 1005 deletions(-) create mode 100644 src/common/classes/BlobWrapper.cpp create mode 100644 src/common/classes/BlobWrapper.h create mode 100644 src/common/status.h diff --git a/builds/posix/make.rules b/builds/posix/make.rules index 6745d0f0ea..5fb7f97a54 100644 --- a/builds/posix/make.rules +++ b/builds/posix/make.rules @@ -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 $<) $@ diff --git a/builds/win32/msvc10/common.vcxproj b/builds/win32/msvc10/common.vcxproj index 67ec22755b..74c24fa2ae 100644 --- a/builds/win32/msvc10/common.vcxproj +++ b/builds/win32/msvc10/common.vcxproj @@ -25,6 +25,7 @@ + @@ -110,6 +111,7 @@ + diff --git a/builds/win32/msvc10/common.vcxproj.filters b/builds/win32/msvc10/common.vcxproj.filters index 3d0ba8081a..2d5acf3c51 100644 --- a/builds/win32/msvc10/common.vcxproj.filters +++ b/builds/win32/msvc10/common.vcxproj.filters @@ -222,6 +222,9 @@ classes + + classes + @@ -542,5 +545,8 @@ headers + + headers + \ No newline at end of file diff --git a/builds/win32/msvc12/common.vcxproj b/builds/win32/msvc12/common.vcxproj index ded46c0b63..2788b38ae7 100644 --- a/builds/win32/msvc12/common.vcxproj +++ b/builds/win32/msvc12/common.vcxproj @@ -25,6 +25,7 @@ + @@ -106,6 +107,7 @@ + diff --git a/builds/win32/msvc12/common.vcxproj.filters b/builds/win32/msvc12/common.vcxproj.filters index 3d0ba8081a..2d5acf3c51 100644 --- a/builds/win32/msvc12/common.vcxproj.filters +++ b/builds/win32/msvc12/common.vcxproj.filters @@ -222,6 +222,9 @@ classes + + classes + @@ -542,5 +545,8 @@ headers + + headers + \ No newline at end of file diff --git a/builds/win32/msvc14/common.vcxproj b/builds/win32/msvc14/common.vcxproj index 5b8841f6fc..25600b9c16 100644 --- a/builds/win32/msvc14/common.vcxproj +++ b/builds/win32/msvc14/common.vcxproj @@ -25,6 +25,7 @@ + @@ -106,6 +107,7 @@ + diff --git a/builds/win32/msvc14/common.vcxproj.filters b/builds/win32/msvc14/common.vcxproj.filters index 3d0ba8081a..2d5acf3c51 100644 --- a/builds/win32/msvc14/common.vcxproj.filters +++ b/builds/win32/msvc14/common.vcxproj.filters @@ -222,6 +222,9 @@ classes + + classes + @@ -542,5 +545,8 @@ headers + + headers + \ No newline at end of file diff --git a/builds/win32/preprocess.bat b/builds/win32/preprocess.bat index 42a50c3947..377da3d132 100644 --- a/builds/win32/preprocess.bat +++ b/builds/win32/preprocess.bat @@ -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 diff --git a/src/burp/OdsDetection.epp b/src/burp/OdsDetection.epp index f0a66545c4..cbe4e2032a 100644 --- a/src/burp/OdsDetection.epp +++ b/src/burp/OdsDetection.epp @@ -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) diff --git a/src/burp/backup.epp b/src/burp/backup.epp index 3d1f68d2e6..3d9d50ee8c 100644 --- a/src/burp/backup.epp +++ b/src/burp/backup.epp @@ -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 { @@ -173,7 +177,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 +188,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,7 +215,7 @@ 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(); @@ -229,23 +233,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; } @@ -465,7 +469,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 +831,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 +1020,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 +1092,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 +1157,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 +1255,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 +1271,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 +1292,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 +1342,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 +1351,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 +1384,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 +1407,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 +1430,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 +1566,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 +1620,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 +1629,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 +1643,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 +1669,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 +1687,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 +1729,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 +2160,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 +2173,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 +2219,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 +2230,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 +2265,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 +2325,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 +2423,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 +2457,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 +2557,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 +2587,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 +2615,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 +2693,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 +2757,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 +2792,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 +2834,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 +3088,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 +3197,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 +3428,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 +3495,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 +3685,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 +3721,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 +3765,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 +3895,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 +3931,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 +3972,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 +4041,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 +4124,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 +4241,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 +4280,7 @@ void write_types() * each type. * **************************************/ - isc_req_handle req_handle1 = 0; + Firebird::IRequest* req_handle1 = nullptr; BurpGlobals* tdgbl = BurpGlobals::getSpecific(); @@ -4414,7 +4320,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(); diff --git a/src/burp/burp.cpp b/src/burp/burp.cpp index 80b64161c8..7a2c83f131 100644 --- a/src/burp/burp.cpp +++ b/src/burp/burp.cpp @@ -65,6 +65,7 @@ #include #endif #include "../common/utils_proto.h" +#include "../common/status.h" #ifdef HAVE_UNISTD_H #include @@ -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(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(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; } @@ -1285,10 +1288,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 @@ -1319,9 +1320,10 @@ int gbak(Firebird::UtilSvc* uSvc) { close_out_transaction(action, &tdgbl->tr_handle); close_out_transaction(action, &tdgbl->global_trans); - if (isc_detach_database(tdgbl->status_vector, &tdgbl->db_handle)) + tdgbl->db_handle->detach(&tdgbl->status_vector); + if (tdgbl->status_vector->getState() & Firebird::IStatus::STATE_ERRORS) { - BURP_print_status(true, tdgbl->status_vector); + BURP_print_status(true, &tdgbl->status_vector); } } @@ -1428,7 +1430,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 +1518,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(arg1), arg2); + burp_output(false, format, text); } - void BURP_print(bool err, USHORT number, const SafeArg& arg) { /************************************** @@ -1577,7 +1577,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 +1592,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 +1622,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 +1635,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 +1712,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 +1727,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,38 +1813,37 @@ static gbak_action open_files(const TEXT* file1, * **************************************/ BurpGlobals* tdgbl = BurpGlobals::getSpecific(); - ISC_STATUS_ARRAY temp_status; - ISC_STATUS* status_vector = temp_status; + FbLocalStatus temp_status; + Firebird::CheckStatusWrapper* status_vector = &temp_status; // 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(dpb.getBuffer()))) + tdgbl->db_handle = Firebird::DispatcherPtr()->attachDatabase(status_vector, file1, + dpb.getBufferLength(), dpb.getBuffer()); + if (!status_vector->hasData()) { 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)) { + tdgbl->db_handle->detach(status_vector); + if (status_vector->hasData()) BURP_print_status(true, status_vector); - } 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 } 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); return QUIT; @@ -1965,10 +1967,9 @@ 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->hasData()) + BURP_print_status(true, status_vector); } return flag; @@ -2139,49 +2140,45 @@ 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(dpb.getBuffer()))) + if (sw_replace == IN_SW_BURP_C || sw_replace == IN_SW_BURP_R) { - if (sw_replace == IN_SW_BURP_C) + tdgbl->db_handle = Firebird::DispatcherPtr()->attachDatabase(status_vector, *file2, + dpb.getBufferLength(), dpb.getBuffer()); + if (status_vector->isEmpty()) { - 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) + if (sw_replace == IN_SW_BURP_C) { - ISC_STATUS_ARRAY status_vector2; - if (isc_detach_database(status_vector2, &tdgbl->db_handle)) { - BURP_print_status(false, status_vector2); - } + tdgbl->db_handle->detach(status_vector); + if (status_vector->hasData()) + 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 + { + tdgbl->db_handle->dropDatabase(status_vector); + if (status_vector->hasData()) + { + Firebird::FbLocalStatus status2; + tdgbl->db_handle->detach(&status2); + if (!status2.isSuccess()) + BURP_print_status(true, &status2); - // 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 + // msg 233 Cannot drop database %s, might be in use + } } } - } - 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 + 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. + 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 +2455,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 +2487,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 +2600,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; +} diff --git a/src/burp/burp.h b/src/burp/burp.h index a1dbf97d9a..c5fbd85ed6 100644 --- a/src/burp/burp.h +++ b/src/burp/burp.h @@ -31,6 +31,8 @@ #include #include "../jrd/ibase.h" +#include "firebird/Interface.h" +#include "firebird/Message.h" #include "../common/dsc.h" #include "../burp/misc_proto.h" #include "../yvalve/gds_proto.h" @@ -40,6 +42,8 @@ #include "../common/classes/fb_pair.h" #include "../common/classes/MetaName.h" #include "../../jrd/SimilarToMatcher.h" +#include "../common/status.h" +#include "../common/classes/ImplementHelper.h" #ifdef HAVE_UNISTD_H #include @@ -660,12 +664,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 +700,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 { @@ -928,7 +936,6 @@ public: // this is VERY dirty hack to keep current behaviour memset (&gbl_database_file_name, 0, &veryEnd - reinterpret_cast(&gbl_database_file_name)); - memset(status_vector, 0, sizeof(status_vector)); gbl_stat_flags = 0; gbl_stat_header = false; @@ -955,6 +962,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; @@ -973,6 +981,7 @@ public: burp_fil* gbl_sw_files; burp_fil* gbl_sw_backup_files; gfld* gbl_global_fields; + unsigned gbl_network_protocol; burp_act* action; ULONG io_buffer_size; redirect_vals sw_redirect; @@ -1001,11 +1010,10 @@ 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; + 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 +1023,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 +1099,9 @@ public: char veryEnd; //starting after this members must be initialized in constructor explicitly + Firebird::FbLocalStatus status_vector; + Firebird::ThrowLocalStatus throwStatus; + Firebird::Array > > defaultCollations; Firebird::UtilSvc* uSvc; @@ -1162,4 +1175,49 @@ enum burp_messages_vals { // BLOB buffer typedef Firebird::HalfStaticArray 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 + void singleSelect(Firebird::ITransaction* trans, M* msg) + { + stmt->execute(&tdgbl->throwStatus, tdgbl->tr_handle, nullptr, nullptr, msg->getMetadata(), msg->getData()); + } + + template + 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 +{ +public: + OutputVersion(const char* printFormat) + : format(printFormat) + { } + + void callback(Firebird::CheckStatusWrapper* status, const char* text); + +private: + const char* format; +}; + #endif // BURP_BURP_H diff --git a/src/burp/burp_proto.h b/src/burp/burp_proto.h index b8487b86ae..ed78a6a71f 100644 --- a/src/burp/burp_proto.h +++ b/src/burp/burp_proto.h @@ -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); diff --git a/src/burp/canon_proto.h b/src/burp/canon_proto.h index a377c8a508..f41e68ccbc 100644 --- a/src/burp/canon_proto.h +++ b/src/burp/canon_proto.h @@ -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 diff --git a/src/burp/canonical.cpp b/src/burp/canonical.cpp index 308add7663..365409929a 100644 --- a/src/burp/canonical.cpp +++ b/src/burp/canonical.cpp @@ -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) { /************************************** * diff --git a/src/burp/misc.cpp b/src/burp/misc.cpp index a25b8e1262..b4fa133edc 100644 --- a/src/burp/misc.cpp +++ b/src/burp/misc.cpp @@ -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; } } diff --git a/src/burp/misc_proto.h b/src/burp/misc_proto.h index c015cb4516..971309e8e1 100644 --- a/src/burp/misc_proto.h +++ b/src/burp/misc_proto.h @@ -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); diff --git a/src/burp/restore.epp b/src/burp/restore.epp index 99609475a5..beedb55f2d 100644 --- a/src/burp/restore.epp +++ b/src/burp/restore.epp @@ -30,6 +30,10 @@ #include #include #include +#ifdef HAVE_CTYPE_H +#include +#endif + #include "../burp/burp.h" #include "../jrd/align.h" #include "../jrd/flags.h" @@ -49,14 +53,16 @@ #include "../common/prett_proto.h" #endif #include "../common/classes/ClumpletWriter.h" -#include "../common/classes/UserBlob.h" +#include "../common/classes/BlobWrapper.h" #include "../common/classes/SafeArg.h" #include "../common/utils_proto.h" #include "memory_routines.h" #include "../burp/OdsDetection.h" #include "../auth/trusted/AuthSspi.h" +#include "../common/dsc_proto.h" using MsgFormat::SafeArg; +using Firebird::FbLocalStatus; // For service APIs the follow DB handle is a value stored @@ -67,8 +73,11 @@ using MsgFormat::SafeArg; 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) namespace // unnamed, private @@ -96,7 +105,7 @@ void add_access_dpb(BurpGlobals* tdgbl, Firebird::ClumpletWriter& dpb); void add_files(BurpGlobals* tdgbl, const char*); void bad_attribute(scan_attr_t, att_type, USHORT); void create_database(BurpGlobals* tdgbl, const TEXT*); -void decompress(BurpGlobals* tdgbl, UCHAR*, USHORT); +void decompress(BurpGlobals* tdgbl, UCHAR*, ULONG); void eat_blob(BurpGlobals* tdgbl); void eat_text(BurpGlobals* tdgbl); void eat_text2(BurpGlobals* tdgbl); @@ -107,12 +116,14 @@ void fix_security_class_name(BurpGlobals* tdgbl, TEXT* sec_class, bool is_field) // returned value is not checked by the caller! bool get_acl(BurpGlobals* tdgbl, const TEXT*, ISC_QUAD*, ISC_QUAD*); void get_array(BurpGlobals* tdgbl, burp_rel*, UCHAR*); -void get_blob(BurpGlobals* tdgbl, const burp_fld*, UCHAR*); +void get_blob(BurpGlobals* tdgbl, Firebird::IBatch* batch, const burp_fld*, UCHAR*); +void get_blob_old(BurpGlobals* tdgbl, const burp_fld*, UCHAR*); void get_blr_blob(BurpGlobals* tdgbl, ISC_QUAD&, bool); bool get_character_set(BurpGlobals* tdgbl); bool get_chk_constraint(BurpGlobals* tdgbl); bool get_collation(BurpGlobals* tdgbl); rec_type get_data(BurpGlobals* tdgbl, burp_rel*, bool); +rec_type get_data_old(BurpGlobals* tdgbl, burp_rel*); bool get_exception(BurpGlobals* tdgbl); burp_fld* get_field(BurpGlobals* tdgbl, burp_rel*); bool get_field_dimensions(BurpGlobals* tdgbl); @@ -267,7 +278,9 @@ int RESTORE_restore (const TEXT* file_name, const TEXT* database_name) * Recreate a database from a backup. * **************************************/ - isc_req_handle req_handle1 = 0, req_handle3 = 0, req_handle5 = 0; + Firebird::IRequest* req_handle1 = nullptr; + Firebird::IRequest* req_handle3 = nullptr; + Firebird::IRequest* req_handle5 = nullptr; BASED_ON RDB$INDICES.RDB$INDEX_NAME index_name; BurpGlobals* tdgbl = BurpGlobals::getSpecific(); @@ -304,7 +317,7 @@ int RESTORE_restore (const TEXT* file_name, const TEXT* database_name) case isc_sort_mem_err: case isc_no_dup: strcpy(index_name, (TEXT *)tdgbl->status_vector[3]); - BURP_print_status(false, tdgbl->status_vector); + BURP_print_status(false, &tdgbl->status_vector); FOR (REQUEST_HANDLE req_handle3) IDX IN RDB$INDICES WITH IDX.RDB$INDEX_NAME EQ index_name @@ -353,7 +366,7 @@ int RESTORE_restore (const TEXT* file_name, const TEXT* database_name) // Always try to activate deferred indices - it helps for some broken backups, // and in normal cases doesn't take much time to look for such indices. AP-2008. EXEC SQL SET TRANSACTION ISOLATION LEVEL READ COMMITTED NO_AUTO_UNDO; - if (gds_status[1]) + if (gds_status->hasData()) EXEC SQL SET TRANSACTION; // Activate first indexes that are not foreign keys @@ -397,7 +410,7 @@ int RESTORE_restore (const TEXT* file_name, const TEXT* database_name) END_ERROR; EXEC SQL SET TRANSACTION ISOLATION LEVEL READ COMMITTED NO_AUTO_UNDO; - if (gds_status[1]) + if (gds_status->hasData()) EXEC SQL SET TRANSACTION; // Only activate Foreign keys that have been marked for deferred @@ -423,9 +436,8 @@ int RESTORE_restore (const TEXT* file_name, const TEXT* database_name) // activating and creating deferred index %s bool fError = false; - isc_tr_handle activateIndexTran = 0; - ISC_STATUS_ARRAY local_status_vector; - ISC_STATUS* local_status = local_status_vector; + Firebird::ITransaction* activateIndexTran = nullptr; + FbLocalStatus local_status_vector; START_TRANSACTION activateIndexTran; FOR (TRANSACTION_HANDLE activateIndexTran REQUEST_HANDLE req_handle5) @@ -436,7 +448,7 @@ int RESTORE_restore (const TEXT* file_name, const TEXT* database_name) END_FOR; ON_ERROR fError = true; - memcpy(local_status, isc_status, sizeof (ISC_STATUS_ARRAY)); + fb_utils::copyStatus(&local_status_vector, isc_status); END_ERROR; MISC_release_request_silent(req_handle5); @@ -445,7 +457,7 @@ int RESTORE_restore (const TEXT* file_name, const TEXT* database_name) COMMIT activateIndexTran; ON_ERROR fError = true; - memcpy(local_status, isc_status, sizeof (ISC_STATUS_ARRAY)); + fb_utils::copyStatus(&local_status_vector, isc_status); END_ERROR; } if (fError) @@ -455,7 +467,7 @@ int RESTORE_restore (const TEXT* file_name, const TEXT* database_name) general_on_error (); END_ERROR; BURP_print (false, 173, index_name); - BURP_print_status(false, local_status); + BURP_print_status(false, &local_status_vector); tdgbl->flag_on_line = false; } END_FOR; @@ -474,17 +486,17 @@ int RESTORE_restore (const TEXT* file_name, const TEXT* database_name) BURP_verbose (68); // msg 68 committing meta data EXEC SQL COMMIT TRANSACTION tdgbl->global_trans; - if (gds_status[1]) + if (gds_status->hasData()) general_on_error (); // Check to see if there is a warning - if (gds_status[0] == isc_arg_gds && gds_status[1] == 0 && gds_status[2] != isc_arg_end) + if (gds_status->getState() & Firebird::IStatus::STATE_WARNINGS) { BURP_print_warning(gds_status); } } EXEC SQL SET TRANSACTION ISOLATION LEVEL READ COMMITTED NO_AUTO_UNDO; - if (gds_status[1]) + if (gds_status->hasData()) EXEC SQL SET TRANSACTION; // AB: Recalculate RDB$DBKEY_LENGTH for VIEWS @@ -532,7 +544,7 @@ int RESTORE_restore (const TEXT* file_name, const TEXT* database_name) END_ERROR; // Check to see if there is a warning - if (gds_status[0] == isc_arg_gds && gds_status[1] == 0 && gds_status[2] != isc_arg_end) + if (gds_status->getState() & Firebird::IStatus::STATE_WARNINGS) { BURP_print_warning(gds_status); } @@ -568,13 +580,12 @@ int RESTORE_restore (const TEXT* file_name, const TEXT* database_name) // set forced writes to the value which was in the header dpb.insertByte(isc_dpb_force_write, tdgbl->hdr_forced_writes ? 1 : 0); - FB_API_HANDLE db_handle = 0; - if (isc_attach_database(tdgbl->status_vector, 0, database_name, &db_handle, - dpb.getBufferLength(), reinterpret_cast(dpb.getBuffer()))) - { + Firebird::IAttachment* db_handle = Firebird::DispatcherPtr()->attachDatabase(&tdgbl->status_vector, database_name, + dpb.getBufferLength(), dpb.getBuffer()); + if (tdgbl->status_vector->hasData()) general_on_error(); - } - if (isc_detach_database (tdgbl->status_vector, &db_handle)) + db_handle->detach(&tdgbl->status_vector); + if (tdgbl->status_vector->hasData()) general_on_error(); if (!tdgbl->flag_on_line) @@ -597,12 +608,12 @@ int RESTORE_restore (const TEXT* file_name, const TEXT* database_name) dpb.insertByte(isc_dpb_set_db_readonly, 1); - if (isc_attach_database(tdgbl->status_vector, 0, database_name, &db_handle, - dpb.getBufferLength(), reinterpret_cast(dpb.getBuffer()))) - { + db_handle = Firebird::DispatcherPtr()->attachDatabase(&tdgbl->status_vector, database_name, + dpb.getBufferLength(), dpb.getBuffer()); + if (tdgbl->status_vector->hasData()) general_on_error(); - } - if (isc_detach_database (tdgbl->status_vector, &db_handle)) + db_handle->detach(&tdgbl->status_vector); + if (tdgbl->status_vector->hasData()) general_on_error(); } @@ -652,7 +663,7 @@ void add_files(BurpGlobals* tdgbl, const char* file_name) * addresses & commit this much. * **************************************/ - isc_req_handle req_handle1 = 0; + Firebird::IRequest* req_handle1 = nullptr; // store the RDB$FILES records @@ -703,7 +714,7 @@ void add_files(BurpGlobals* tdgbl, const char* file_name) ON_ERROR BURP_print (false, 174); // msg 174 cannot commit files - BURP_print_status (false, tdgbl->status_vector); + BURP_print_status (false, &tdgbl->status_vector); ROLLBACK; ON_ERROR general_on_error (); @@ -711,7 +722,7 @@ void add_files(BurpGlobals* tdgbl, const char* file_name) END_ERROR; EXEC SQL SET TRANSACTION NO_AUTO_UNDO; - if (gds_status[1]) + if (gds_status->hasData()) EXEC SQL SET TRANSACTION; } } @@ -765,6 +776,38 @@ void bad_attribute(scan_attr_t scan_next_attr, att_type bad_attr, USHORT type) } } +namespace { + +// Used to make sure that local calls to print stuff go to isqlGlob.Out +// and not to stdout if IUtil::version gets called + +class ProtocolVersion : + public Firebird::AutoIface > +{ +public: + ProtocolVersion(unsigned* v) + : version(v) + { + *version = 0; + } + + // IVersionCallback implementation + void callback(Firebird::CheckStatusWrapper*, const char* text) + { + const char* pm = ")/P"; + const char* pp = strstr(text, pm); + if (pp) + { + pp += strlen(pm); + *version = atoi(pp); + } + } + +private: + unsigned* version; +}; + +} // anonymous namespace void create_database(BurpGlobals* tdgbl, const TEXT* file_name) { @@ -844,7 +887,7 @@ void create_database(BurpGlobals* tdgbl, const TEXT* file_name) } if (record != rec_database) - BURP_error_redirect (NULL, 32); + BURP_error_redirect(NULL, 32); // msg 32 Expected database description record if (tdgbl->gbl_sw_page_size) @@ -926,7 +969,8 @@ void create_database(BurpGlobals* tdgbl, const TEXT* file_name) // When we restore backup files that came from prior // to V6, we force the SQL database dialect to 1 - dpb.insertByte(isc_dpb_sql_dialect, SQL_dialect_flag ? SQL_dialect : SQL_DIALECT_V5); + tdgbl->gbl_dialect = SQL_dialect_flag ? SQL_dialect : SQL_DIALECT_V5; + dpb.insertByte(isc_dpb_sql_dialect, tdgbl->gbl_dialect); // start database up shut down, // use single-user mode to avoid conflicts during restore process @@ -936,7 +980,7 @@ void create_database(BurpGlobals* tdgbl, const TEXT* file_name) dpb.insertByte(isc_dpb_no_db_triggers, 1); - ISC_STATUS_ARRAY status_vector; + FbLocalStatus status_vector; if (tdgbl->gbl_sw_fix_fss_metadata) { @@ -944,26 +988,38 @@ void create_database(BurpGlobals* tdgbl, const TEXT* file_name) fb_strlen(tdgbl->gbl_sw_fix_fss_metadata)); } - if (isc_create_database(status_vector, 0, file_name, &DB, - dpb.getBufferLength(), reinterpret_cast(dpb.getBuffer()), - 0)) + DB = Firebird::DispatcherPtr()->createDatabase(&status_vector, file_name, + dpb.getBufferLength(), dpb.getBuffer()); + if (status_vector->hasData()) { - BURP_error_redirect (status_vector, 33, SafeArg() << file_name); + BURP_error_redirect(&status_vector, 33, SafeArg() << file_name); // msg 33 failed to create database %s } + // get remote protocol version + ProtocolVersion pv(&tdgbl->gbl_network_protocol); + Firebird::UtilInterfacePtr()->getFbVersion(&status_vector, DB, &pv); + + // treat errors as old provider missing new calls + if (status_vector->hasData()) + { + status_vector->init(); + tdgbl->gbl_network_protocol = 1; + } + if (tdgbl->gbl_sw_version && !tdgbl->uSvc->isService()) { BURP_print(false, 139, file_name); // msg 139 Version(s) for database "%s" - isc_version(&DB, BURP_output_version, (void*)"\t%s\n"); + OutputVersion outputVersion("\t%s\n"); + Firebird::UtilInterfacePtr()->getFbVersion(&status_vector, DB, &outputVersion); } BURP_verbose (74, SafeArg() << file_name << page_size); // msg 74 created database %s, page_size %ld bytes } -void decompress(BurpGlobals* tdgbl, UCHAR* buffer, USHORT length) +void decompress(BurpGlobals* tdgbl, UCHAR* buffer, ULONG length) { /************************************** * @@ -1010,7 +1066,7 @@ void decompress(BurpGlobals* tdgbl, UCHAR* buffer, USHORT length) } if (p > end) { - BURP_error_redirect (NULL, 34); // msg 34 RESTORE: decompression length error + BURP_error_redirect(NULL, 34); // msg 34 RESTORE: decompression length error } } @@ -1080,7 +1136,7 @@ burp_rel* find_relation(BurpGlobals* tdgbl, const TEXT* name) } } - BURP_error_redirect (NULL, 35, SafeArg() << name); + BURP_error_redirect(NULL, 35, SafeArg() << name); // msg 35 can't find relation %s return NULL; @@ -1109,9 +1165,9 @@ void fix_security_class_name(BurpGlobals* tdgbl, TEXT* sec_class, bool is_field) if (tdgbl->runtimeODS < DB_VERSION_DDL11_2) return; - ISC_STATUS_ARRAY status_vector; + FbLocalStatus status_vector; - isc_req_handle& handle = tdgbl->handles_fix_security_class_name_req_handle1; + Firebird::IRequest*& handle = tdgbl->handles_fix_security_class_name_req_handle1; if (!handle) { @@ -1153,25 +1209,27 @@ void fix_security_class_name(BurpGlobals* tdgbl, TEXT* sec_class, bool is_field) const USHORT blr_length = blr - blr_buffer; fb_assert(blr_length <= sizeof(blr_buffer)); - if (isc_compile_request(status_vector, &DB, &handle, - blr_length, (const SCHAR*) blr_buffer)) + handle = DB->compileRequest(&status_vector, blr_length, blr_buffer); + if (status_vector->hasData()) { - BURP_error_redirect(status_vector, 316); + BURP_error_redirect(&status_vector, 316); // msg 316 Failed while fixing the security class name } } - if (isc_start_request(status_vector, &handle, &gds_trans, 0)) + handle->start(&status_vector, gds_trans, 0); + if (status_vector->hasData()) { - BURP_error_redirect(status_vector, 316); + BURP_error_redirect(&status_vector, 316); // msg 316 Failed while fixing the security class name } SINT64 id = 0; - if (isc_receive(status_vector, &handle, 0, sizeof(SINT64), &id, 0)) + handle->receive(&status_vector, 0, 0, sizeof(SINT64), &id); + if (status_vector->hasData()) { - BURP_error_redirect(status_vector, 316); + BURP_error_redirect(&status_vector, 316); // msg 316 Failed while fixing the security class name } @@ -1194,7 +1252,7 @@ void general_on_error() **************************************/ BurpGlobals* tdgbl = BurpGlobals::getSpecific(); - if (isc_status[1] == isc_malformed_string) + if (isc_status->getErrors()[1] == isc_malformed_string) { Firebird::Arg::StatusVector oldVector(isc_status); Firebird::Arg::Gds newVector(isc_gbak_invalid_metadata); @@ -1239,20 +1297,20 @@ bool get_acl(BurpGlobals* tdgbl, const TEXT* owner_nm, ISC_QUAD* blob_id, ISC_QU // Open the blob and get it's vital statistics - ISC_STATUS_ARRAY status_vector; - UserBlob blob(status_vector); + FbLocalStatus status_vector; + BlobWrapper blob(&status_vector); if (! blob.open(DB, gds_trans, *blob_id)) { // msg 24 isc_open_blob failed - BURP_error_redirect (status_vector, 24); + BURP_error_redirect(&status_vector, 24); } UCHAR blob_info[32]; if (!blob.getInfo(sizeof(blr_items), blr_items, sizeof(blob_info), blob_info)) { // msg 20 isc_blob_info failed - BURP_error_redirect (status_vector, 20); + BURP_error_redirect(&status_vector, 20); } ULONG length = 0; @@ -1296,7 +1354,7 @@ bool get_acl(BurpGlobals* tdgbl, const TEXT* owner_nm, ISC_QUAD* blob_id, ISC_QU // CVC: do you return, without closing the blob, dear function??? if (!blob.close()) { - BURP_error_redirect (status_vector, 23); + BURP_error_redirect(&status_vector, 23); // msg 23 isc_close_blob failed } return false; @@ -1307,7 +1365,7 @@ bool get_acl(BurpGlobals* tdgbl, const TEXT* owner_nm, ISC_QUAD* blob_id, ISC_QU { if (!blob.close()) { - BURP_error_redirect (status_vector, 23); + BURP_error_redirect(&status_vector, 23); // msg 23 isc_close_blob failed } return false; @@ -1329,7 +1387,7 @@ bool get_acl(BurpGlobals* tdgbl, const TEXT* owner_nm, ISC_QUAD* blob_id, ISC_QU if (!blob.getData(length, buffer, return_length)) { // msg 22 gds_$get_segment failed - BURP_error_redirect (status_vector, 22); + BURP_error_redirect(&status_vector, 22); } // protect ourselves length = return_length; @@ -1337,7 +1395,7 @@ bool get_acl(BurpGlobals* tdgbl, const TEXT* owner_nm, ISC_QUAD* blob_id, ISC_QU if (!blob.close()) { // msg 23 isc_close_blob failed - BURP_error_redirect (status_vector, 23); + BURP_error_redirect(&status_vector, 23); } const UCHAR* from = buffer + 3; // skip ACL_version, ACL_id_list, and id_person @@ -1378,19 +1436,19 @@ bool get_acl(BurpGlobals* tdgbl, const TEXT* owner_nm, ISC_QUAD* blob_id, ISC_QU if (!blob.create(DB, gds_trans, *new_blob_id)) { // msg 37 isc_create_blob failed - BURP_error_redirect (status_vector, 37); + BURP_error_redirect(&status_vector, 37); } if (!blob.putData(new_len, new_buffer)) { // msg 38 isc_put_segment failed - BURP_error_redirect (status_vector, 38); + BURP_error_redirect(&status_vector, 38); } if (!blob.close()) { // msg 23 isc_close_blob failed - BURP_error_redirect (status_vector, 23); + BURP_error_redirect(&status_vector, 23); } return true; @@ -1410,7 +1468,7 @@ void get_array(BurpGlobals* tdgbl, burp_rel* relation, UCHAR* record_buffer) * **************************************/ burp_fld* field = NULL; - ISC_STATUS_ARRAY status_vector; + FbLocalStatus status_vector; USHORT count, field_number, field_length = 0; UCHAR* buffer = NULL; UCHAR* p = NULL; @@ -1442,7 +1500,7 @@ void get_array(BurpGlobals* tdgbl, burp_rel* relation, UCHAR* record_buffer) break; } if (!field) { - BURP_error_redirect (NULL, 36); // msg 36 Can't find field for blob + BURP_error_redirect(NULL, 36); // msg 36 Can't find field for blob } field_length = field->fld_length; @@ -1727,7 +1785,7 @@ void get_array(BurpGlobals* tdgbl, burp_rel* relation, UCHAR* record_buffer) if (get_attribute(&attribute, tdgbl) != att_xdr_array) { // msg 55 Expected XDR record length - BURP_error_redirect (NULL, 55); + BURP_error_redirect(NULL, 55); } else { @@ -1752,18 +1810,17 @@ void get_array(BurpGlobals* tdgbl, burp_rel* relation, UCHAR* record_buffer) get_block(tdgbl, p, lcount); if (tdgbl->gbl_sw_transportable) - CAN_slice (&xdr_buffer, &xdr_slice, FALSE, /*blr_length,*/ blr_buffer); + CAN_slice (&xdr_buffer, &xdr_slice, false, blr_buffer); } - if (isc_put_slice(status_vector, &DB, &gds_trans, - blob_id, blr_length, reinterpret_cast(blr_buffer), - 0, // param length for subset of an array handling - NULL, // param for subset of an array handling - elements_written * field->fld_length, buffer + data_at)) + DB->putSlice(&status_vector, gds_trans, blob_id, blr_length, blr_buffer, + 0, NULL, // parameters for subset of an array handling + elements_written * field->fld_length, buffer + data_at); + if (status_vector->hasData()) { BURP_print (false, 81, field->fld_name); // msg 81 error accessing blob field %s -- continuing - BURP_print_status (true, status_vector); + BURP_print_status (true, &status_vector); #ifdef DEBUG PRETTY_print_sdl (blr_buffer, NULL, NULL, 0); #endif @@ -1853,7 +1910,7 @@ void get_array(BurpGlobals* tdgbl, burp_rel* relation, UCHAR* record_buffer) { if (get_attribute(&attribute, tdgbl) != att_xdr_array) { - BURP_error_redirect (NULL, 55); + BURP_error_redirect(NULL, 55); // msg 55 Expected XDR record length } else @@ -1879,19 +1936,17 @@ void get_array(BurpGlobals* tdgbl, burp_rel* relation, UCHAR* record_buffer) get_block(tdgbl, p, lcount); if (tdgbl->gbl_sw_transportable) - CAN_slice (&xdr_buffer, &xdr_slice, FALSE, /*blr_length,*/ blr_buffer); + CAN_slice (&xdr_buffer, &xdr_slice, false, blr_buffer); - if (isc_put_slice(status_vector, &DB, &gds_trans, - blob_id, blr_length, - reinterpret_cast(blr_buffer), - 0, // param length for subset of an array handling - NULL, // param for subset of an array handling - return_length, buffer)) + DB->putSlice(&status_vector, gds_trans, blob_id, blr_length, blr_buffer, + 0, NULL, // parameters for subset of an array handling + return_length, buffer); + if (status_vector->hasData()) { 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 @@ -1904,7 +1959,7 @@ void get_array(BurpGlobals* tdgbl, burp_rel* relation, UCHAR* record_buffer) BURP_free (xdr_buffer.lstr_address); } -void get_blob(BurpGlobals* tdgbl, const burp_fld* fields, UCHAR* record_buffer) +void get_blob(BurpGlobals* tdgbl, Firebird::IBatch* batch, const burp_fld* fields, UCHAR* record_buffer) { /************************************** * @@ -1965,20 +2020,122 @@ void get_blob(BurpGlobals* tdgbl, const burp_fld* fields, UCHAR* record_buffer) if (!field) { - BURP_error_redirect (NULL, 36); + BURP_error_redirect(NULL, 36); // msg 36 Can't find field for blob } // Create new blob ISC_QUAD* blob_id = (ISC_QUAD*) ((UCHAR*) record_buffer + field->fld_offset); - ISC_STATUS_ARRAY status_vector; - UserBlob blob(status_vector); + const UCHAR blob_desc[] = {isc_bpb_version1, isc_bpb_type, 1, blob_type}; + + BlobBuffer local_buffer; + UCHAR* const buffer = local_buffer.getBuffer(max_segment); + + FbLocalStatus status_vector; + bool first = true; + + // Eat up blob segments + + for (; segments > 0; --segments) + { + USHORT length = get(tdgbl); + length |= get(tdgbl) << 8; + if (length) + get_block(tdgbl, buffer, length); + + if (first) + batch->addBlob(&status_vector, length, buffer, blob_id, sizeof(blob_desc), blob_desc); + else + batch->appendBlobData(&status_vector, length, buffer); + + if (status_vector->hasData()) + { + BURP_error_redirect(&status_vector, 38); // !!!!!!!!! new message + // msg 38 isc_put_segment failed + } + + first = false; + } +} + + +void get_blob_old(BurpGlobals* tdgbl, const burp_fld* fields, UCHAR* record_buffer) +{ +/************************************** + * + * g e t _ b l o b + * + ************************************** + * + * Functional description + * Read blob attributes and copy data from input file to nice, + * shiny, new blob. + * + **************************************/ + + // Pick up attributes + + ULONG segments = 0; + USHORT field_number = MAX_USHORT; + USHORT max_segment = 0; + UCHAR blob_type = 0; + + att_type attribute; + scan_attr_t scan_next_attr; + skip_init(&scan_next_attr); + + while (skip_scan(&scan_next_attr), get_attribute(&attribute, tdgbl) != att_blob_data) + { + switch (attribute) + { + case att_blob_field_number: + field_number = (USHORT) get_int32(tdgbl); + break; + + case att_blob_max_segment: + max_segment = (USHORT) get_int32(tdgbl); + break; + + case att_blob_number_segments: + segments = get_int32(tdgbl); + break; + + case att_blob_type: + blob_type = (UCHAR) get_int32(tdgbl); + break; + + default: + bad_attribute(scan_next_attr, attribute, 64); + // msg 64 blob + break; + } + } + + // Find the field associated with the blob + const burp_fld* field; + for (field = fields; field; field = field->fld_next) + { + if (field->fld_number == field_number) + break; + } + + if (!field) + { + BURP_error_redirect(NULL, 36); + // msg 36 Can't find field for blob + } + + // Create new blob + + ISC_QUAD* blob_id = (ISC_QUAD*) ((UCHAR*) record_buffer + field->fld_offset); + FbLocalStatus status_vector; + BlobWrapper blob(&status_vector); const UCHAR blob_desc[] = {isc_bpb_version1, isc_bpb_type, 1, blob_type}; if (!blob.create(DB, gds_trans, *blob_id, sizeof(blob_desc), blob_desc)) { - BURP_error_redirect (status_vector, 37); + BURP_error_redirect(&status_vector, 37); // msg 37 isc_create_blob failed } @@ -1998,13 +2155,13 @@ void get_blob(BurpGlobals* tdgbl, const burp_fld* fields, UCHAR* record_buffer) } if (!blob.putSegment(length, buffer)) { - BURP_error_redirect (status_vector, 38); + BURP_error_redirect(&status_vector, 38); // msg 38 isc_put_segment failed } } if (!blob.close()) - BURP_error_redirect (status_vector, 23); + BURP_error_redirect(&status_vector, 23); // msg 23 isc_close_blob failed } @@ -2027,17 +2184,13 @@ void get_blr_blob(BurpGlobals* tdgbl, ISC_QUAD& blob_id, bool glb_trans) // Create new blob - isc_tr_handle local_trans; - if (glb_trans && tdgbl->global_trans) - local_trans = tdgbl->global_trans; - else - local_trans = gds_trans; + Firebird::ITransaction* local_trans = (glb_trans && tdgbl->global_trans) ? tdgbl->global_trans : gds_trans; - ISC_STATUS_ARRAY status_vector; - UserBlob blob(status_vector); + FbLocalStatus status_vector; + BlobWrapper blob(&status_vector); if (!blob.create(DB, local_trans, blob_id)) { - BURP_error_redirect (status_vector, 37); + BURP_error_redirect(&status_vector, 37); // msg 37 isc_create_blob failed } @@ -2057,12 +2210,12 @@ void get_blr_blob(BurpGlobals* tdgbl, ISC_QUAD& blob_id, bool glb_trans) if (!blob.putData(length, buffer)) { - BURP_error_redirect (status_vector, 38); + BURP_error_redirect(&status_vector, 38); // msg 38 isc_put_segment failed } if (!blob.close()) - BURP_error_redirect (status_vector, 23); + BURP_error_redirect(&status_vector, 23); // msg 23 isc_close_blob failed } @@ -2710,18 +2863,521 @@ rec_type get_data(BurpGlobals* tdgbl, burp_rel* relation, bool skip_relation) * Write data records for a relation. * **************************************/ - isc_req_handle req_handle = 0; - BASED_ON RDB$INDICES.RDB$INDEX_NAME index_name; + ULONG records = 0; + rec_type record; + burp_fld* field; // If we're only doing meta-data, ignore data records if (tdgbl->gbl_sw_meta || skip_relation) return ignore_data(tdgbl, relation); + // For old versions and embedded connections switch to old style method + // Avoid if possible switch to old style when system domains are used in a table + + if (tdgbl->gbl_network_protocol == 0) + { + bool sysDomFlag = false; + + for (field = relation->rel_fields; field && !sysDomFlag; field = field->fld_next) + { + if (field->fld_flags & FLD_computed) + continue; + + const char* dom = field->fld_source; + if (strncmp(dom, "RDB$", 4) != 0) + continue; + + for (dom += 4; *dom; ++dom) + { +#ifdef HAVE_CTYPE_H + if (!isdigit(*dom)) +#else + if (*dom < '0' || *dom > '9') +#endif + { + sysDomFlag = true; + break; + } + } + } + + if (!sysDomFlag) + return get_data_old(tdgbl, relation); + } + else if (tdgbl->gbl_network_protocol < 16) + return get_data_old(tdgbl, relation); + + // Number of fields in a message + + unsigned count = 0; + for (field = relation->rel_fields; field; field = field->fld_next) + { + if (!(field->fld_flags & FLD_computed)) + ++count; + } + + // Time to generate SQL and message metadata to store data. Whoppee. + + try + { + Firebird::string name(relation->rel_name); + BURP_makeSymbol(tdgbl, name); + Firebird::string sqlStatement; + sqlStatement.printf("insert into %s(", name.c_str()); + + Firebird::RefPtr builder(Firebird::REF_NO_INCR, + Firebird::MasterInterfacePtr()->getMetadataBuilder(fbStatus, count)); + if (fbStatus->hasData()) + general_on_error(); + + RCRD_OFFSET offset = 0; + count = 0; + for (field = relation->rel_fields; field; field = field->fld_next) + { + if (field->fld_flags & FLD_computed) + continue; + + USHORT dtype = field->fld_type; + + // arrays are of various fld_types but are really blobs + + if (field->fld_flags & FLD_array) + dtype = blr_blob; + + DSC desc; + if (!DSC_make_descriptor(&desc, dtype, field->fld_scale, field->fld_length, + field->fld_sub_type, field->fld_character_set_id, field->fld_collation_id)) + { + BURP_error(26, true, SafeArg() << dtype); + // msg 26 datatype %ld not understood + } + + SSHORT alignment = type_alignments[desc.dsc_dtype]; + if (alignment) + offset = FB_ALIGN(offset, alignment); + field->fld_offset = offset; + offset += field->fld_total_len = desc.dsc_length; + + SLONG sqlLength, sqlSubType, sqlScale, sqlType; + desc.getSqlInfo(&sqlLength, &sqlSubType, &sqlScale, &sqlType); + SLONG characterSetId = field->fld_character_set_id; + + if (tdgbl->gbl_sw_fix_fss_data && field->fld_character_set_id == CS_UNICODE_FSS && + ((sqlType == SQL_BLOB && field->fld_sub_type == isc_blob_text && !(field->fld_flags & FLD_array)) || + sqlType == SQL_TEXT || sqlType == SQL_VARYING)) + { + characterSetId = tdgbl->gbl_sw_fix_fss_data_id; + } + else if (field->fld_flags & FLD_array) + { + sqlType = SQL_QUAD; + sqlScale = 0; + } + + builder->setType(&tdgbl->throwStatus, count, sqlType); + builder->setSubType(&tdgbl->throwStatus, count, sqlSubType); + builder->setLength(&tdgbl->throwStatus, count, sqlLength); + builder->setScale(&tdgbl->throwStatus, count, sqlScale); + builder->setCharSet(&tdgbl->throwStatus, count, characterSetId); + + name = field->fld_name; + BURP_makeSymbol(tdgbl, name); + sqlStatement += name; + sqlStatement += ", "; + + field->fld_parameter = count++; + } + + fb_assert(sqlStatement.end()[-2] == ','); + sqlStatement.end()[-2] = ')'; + + Firebird::RefPtr meta(Firebird::REF_NO_INCR, + builder->getMetadata(&tdgbl->throwStatus)); + builder = nullptr; + + sqlStatement += "values ("; + + count = 0; + for (field = relation->rel_fields; field; field = field->fld_next) + { + if (field->fld_flags & FLD_computed) + continue; + + offset = FB_ALIGN(offset, sizeof(SSHORT)); + field->fld_missing_parameter = count; + field->fld_missing_offset = offset; + offset += sizeof(SSHORT); + + field->fld_sql = meta->getOffset(&tdgbl->throwStatus, count); + field->fld_null = meta->getNullOffset(&tdgbl->throwStatus, count); + + if (tdgbl->gbl_sw_transportable) + { + field->fld_offset = field->fld_sql; + field->fld_missing_offset = field->fld_null; + } + + sqlStatement += "?, "; + ++count; + } + + fb_assert(sqlStatement.end()[-2] == ','); + sqlStatement.end()[-2] = ')'; + + RCRD_LENGTH length = offset; + + // Create batch + + const int GBAK_BATCH_STEP = 1000; + Firebird::AutoDispose pb(Firebird::UtilInterfacePtr()-> + getXpbBuilder(&tdgbl->throwStatus, Firebird::IXpbBuilder::BATCH, NULL, 0)); + pb->insertInt(&tdgbl->throwStatus, Firebird::IBatch::TAG_MULTIERROR, 1); + pb->insertInt(&tdgbl->throwStatus, Firebird::IBatch::TAG_BLOB_POLICY, Firebird::IBatch::BLOB_ID_ENGINE); + pb->insertInt(&tdgbl->throwStatus, Firebird::IBatch::TAG_DETAILED_ERRORS, GBAK_BATCH_STEP); + pb->insertInt(&tdgbl->throwStatus, Firebird::IBatch::TAG_BUFFER_BYTES_SIZE, 0); + + Firebird::RefPtr batch(DB-> + createBatch(fbStatus, gds_trans, sqlStatement.length(), sqlStatement.c_str(), tdgbl->gbl_dialect, + meta, pb->getBufferLength(&tdgbl->throwStatus), pb->getBuffer(&tdgbl->throwStatus))); + if (fbStatus->hasData()) + { + // Possible reason of fail - use of keywords as fields in old backup + // Try to roll back to use of old version (fieldnames independent) + BURP_print(false, 27/*, sqlStatement.c_str()*/); // msg 27 isc_compile_request failed !!!!!!!! new WARNING + return get_data_old(tdgbl, relation); + } + + UCHAR* buffer = NULL; + Firebird::Array requestBuffer; + + BURP_verbose(124, relation->rel_name); // msg 124 restoring data for relation %s + + lstring data; + data.lstr_allocated = 0; + data.lstr_address = NULL; + Firebird::Array dataBuffer; + RCRD_LENGTH old_length = 0; + + Firebird::Array sqlBuffer; + UCHAR* sql = sqlBuffer.getBuffer(meta->getMessageLength(&tdgbl->throwStatus)); + + while (true) + { + if (get(tdgbl) != att_data_length) + BURP_error_redirect(NULL, 39); // msg 39 expected record length + RCRD_LENGTH len = get_int32(tdgbl); + + if (!tdgbl->gbl_sw_transportable && len != length) + { +#ifdef sparc + if (!old_length) + old_length = recompute_length(tdgbl, relation); +#endif + if (len != old_length) + { + BURP_error(40, true, SafeArg() << length << len); + // msg 40 wrong length record, expected %ld encountered %ld + } + } + + if (!buffer) + buffer = requestBuffer.getBuffer(MAX (length, len)); + + UCHAR* p; + if (tdgbl->gbl_sw_transportable) + { + if (get(tdgbl) != att_xdr_length) + { + BURP_error_redirect(NULL, 55); + // msg 55 Expected XDR record length + } + else + { + data.lstr_length = len = get_int32(tdgbl); + if (len > data.lstr_allocated) + { + data.lstr_allocated = len; + data.lstr_address = dataBuffer.getBuffer(data.lstr_allocated); + } + p = data.lstr_address; + } + } + else + p = buffer; + + if (get(tdgbl) != att_data_data) + BURP_error_redirect(NULL, 41); // msg 41 expected data attribute + + if (tdgbl->gbl_sw_compress) + decompress (tdgbl, p, len); + else + get_block(tdgbl, p, len); + + if (old_length) + realign (tdgbl, buffer, relation); + + if (tdgbl->gbl_sw_transportable) + { + buffer = sql; + CAN_encode_decode(relation, &data, buffer, false, true); + } + + if ((++records % tdgbl->verboseInterval) == 0) + BURP_verbose(107, SafeArg() << records); + + for (field = relation->rel_fields; field; field = field->fld_next) + { + if (!(field->fld_flags & FLD_computed)) + { + if (field->fld_type == blr_blob || (field->fld_flags & FLD_array)) + { + ISC_QUAD* blob_id = (ISC_QUAD*) &buffer[field->fld_offset]; + blob_id->gds_quad_high = 0; + blob_id->gds_quad_low = 0; + } + } + } + + get_record(&record, tdgbl); + while (record == rec_blob || record == rec_array) + { + if (record == rec_blob) + get_blob (tdgbl, batch, relation->rel_fields, buffer); + else if (record == rec_array) + get_array (tdgbl, relation, buffer); + get_record(&record, tdgbl); + } + + if (!tdgbl->gbl_sw_transportable) + { + for (field = relation->rel_fields; field; field = field->fld_next) + { + if (field->fld_flags & FLD_computed) + continue; + + // convert record to SQL format + + memcpy(&sql[field->fld_sql], &buffer[field->fld_offset], field->fld_total_len); + memcpy(&sql[field->fld_null], &buffer[field->fld_missing_offset], sizeof(SSHORT)); + } + } + + batch->add(&tdgbl->throwStatus, 1, sql); + if ((records % 1000 != 0) && (record == rec_data)) + continue; + + Firebird::AutoDispose cs(batch->execute(&tdgbl->throwStatus, gds_trans)); + if (tdgbl->throwStatus->getState() & Firebird::IStatus::STATE_WARNINGS) + BURP_print_warning(&tdgbl->throwStatus); + + for (unsigned pos = 0; + pos = cs->findError(&tdgbl->throwStatus, pos), + pos != Firebird::IBatchCompletionState::NO_MORE_ERRORS; + ++pos) + { + Firebird::LocalStatus status_vector; + cs->getStatus(&tdgbl->throwStatus, &status_vector, pos); + ISC_STATUS code = status_vector.getErrors()[1]; + + if (code == isc_not_valid) + { + if (tdgbl->gbl_sw_incremental) + { + BURP_print (false, 138, relation->rel_name); + // msg 138 validation error on field in relation %s + BURP_print_status (false, &status_vector); + } + else + BURP_error_redirect(&status_vector, 47); + // msg 47 warning -- record could not be restored + } + else if (code == isc_malformed_string) + { + if (tdgbl->gbl_sw_incremental) + { + // msg 114 restore failed for record in relation %s + BURP_print(false, 114, relation->rel_name); + + BURP_print_status(false, &status_vector); + BURP_print(false, 342); // isc_gbak_invalid_data + } + else + BURP_error_redirect(&status_vector, 342); // isc_gbak_invalid_data + } + else + { + if (tdgbl->gbl_sw_incremental) + { + BURP_print (false, 114, relation->rel_name); + // msg 114 restore failed for record in relation %s + BURP_print_status (false, &status_vector); + } + else + BURP_error_redirect(&status_vector, 48); + // msg 48 isc_send failed + } + + records--; + } + + if (record != rec_data) + break; + } // while (true) + } + catch (const Firebird::FbException& ex) + { + BURP_print_status (true, ex.getStatus()); + BURP_abort(); + } + + if (tdgbl->gbl_sw_incremental) + { + BURP_verbose(72, relation->rel_name); + // msg 72 committing data for relation %s + COMMIT + // existing ON_ERROR continues past error, beck + ON_ERROR + + // Fix for bug_no 8055: + // don't throw away the database just because an index + // could not be made + + // don't bring the database on-line + tdgbl->flag_on_line = false; + ISC_STATUS error_code; + while (error_code = tdgbl->status_vector[1]) + { + BASED_ON RDB$INDICES.RDB$INDEX_NAME index_name; + Firebird::IRequest* req_handle = 0; + + switch (error_code) + { + case isc_sort_mem_err: + case isc_no_dup: + strcpy(index_name, (TEXT*) tdgbl->status_vector[3]); + BURP_print_status(false, &tdgbl->status_vector); + + FOR (REQUEST_HANDLE req_handle) + IDX IN RDB$INDICES + WITH IDX.RDB$INDEX_NAME EQ index_name + { + MODIFY IDX USING + IDX.RDB$INDEX_INACTIVE = TRUE; + BURP_print(false, 240, index_name); + // msg 240 Index \"%s\" failed to activate because: + if ( error_code == isc_no_dup ) + { + BURP_print(false, 241); + // msg 241 The unique index has duplicate values or NULLs + BURP_print(false, 242); + // msg 242 Delete or Update duplicate values or NULLs, and activate index with + } + else + { + BURP_print(false, 244); + // msg 244 Not enough disk space to create the sort file for an index + BURP_print(false, 245); + // msg 245 Set the TMP environment variable to a directory on a filesystem that does have enough space, and activate index with + } + BURP_print(false, 243, index_name); + // msg 243 ALTER INDEX \"%s\" ACTIVE + END_MODIFY; + } + END_FOR; + // commit one more time + COMMIT + ON_ERROR + continue; + END_ERROR + break; + default: + BURP_print(false, 69, relation->rel_name); + // msg 69 commit failed on relation %s + BURP_print_status (false, &tdgbl->status_vector); + ROLLBACK; + ON_ERROR + general_on_error(); + END_ERROR; + break; + } // end of switch + } // end of while + END_ERROR; + + EXEC SQL SET TRANSACTION NO_AUTO_UNDO; + if (gds_status->hasData()) + EXEC SQL SET TRANSACTION; + } + + BURP_verbose(107, SafeArg() << records); + // msg 107 %ld records restored + + return record; +} + +// We have a corrupt backup, save the restore process from becoming useless. +void fix_exception(BurpGlobals* tdgbl, const char* exc_name, scan_attr_t& scan_next_attr, + const att_type attribute, att_type& failed_attrib, UCHAR*& msg_ptr, ULONG& l2, bool& msg_seen) +{ + if (msg_seen && (tdgbl->RESTORE_format == 7 || tdgbl->RESTORE_format == 8)) + { + if (!failed_attrib) + { + failed_attrib = attribute; + BURP_print(false, 313, SafeArg() << failed_attrib << exc_name); + } + + // Notice we use 1021 instead of 1023 because this is the maximum length + // for this field in v2.0 and v2.1 and they produce the corrupt backups. + const unsigned int FIELD_LIMIT = 1021; + + if (FIELD_LIMIT < l2 + 1) // not enough space + { + bad_attribute(scan_next_attr, failed_attrib, 287); + return; + } + + const unsigned int remaining = FIELD_LIMIT - l2; + + *msg_ptr++ = char(attribute); // (1) + + UCHAR* rc_ptr = get_block(tdgbl, msg_ptr, MIN(remaining - 1, 255)); + if (remaining > 1 && rc_ptr == msg_ptr) // we couldn't read anything + { + bad_attribute(scan_next_attr, failed_attrib, 287); + return; + } + + l2 += rc_ptr - msg_ptr + 1; // + 1 because (1) + msg_ptr = rc_ptr; + *msg_ptr = 0; + + if (l2 == FIELD_LIMIT) + msg_seen = false; + } + else + bad_attribute(scan_next_attr, attribute, 287); // msg 287 exception +} + +rec_type get_data_old(BurpGlobals* tdgbl, burp_rel* relation) +{ +/************************************** + * + * g e t _ d a t a _ o l d + * + ************************************** + * + * Functional description + * Write data records for a relation. + * + **************************************/ + Firebird::IRequest* req_handle = 0; + BASED_ON RDB$INDICES.RDB$INDEX_NAME index_name; + // Start by counting the interesting fields RCRD_OFFSET offset = 0; - ULONG length = 0; + RCRD_LENGTH length = 0; USHORT count = 0; burp_fld* field; @@ -2734,8 +3390,7 @@ rec_type get_data(BurpGlobals* tdgbl, burp_rel* relation, bool skip_relation) } } - if (tdgbl->RESTORE_format >= 2) - count += count; + count += count; // Time to generate blr to store data. Whoppee. @@ -2846,19 +3501,16 @@ rec_type get_data(BurpGlobals* tdgbl, burp_rel* relation, bool skip_relation) offset += length; } - // If this is format version 2, build fields for null flags - - if (tdgbl->RESTORE_format >= 2) - for (field = relation->rel_fields; field; field = field->fld_next) - { - if (field->fld_flags & FLD_computed) - continue; - add_byte(blr, blr_short); - add_byte(blr, 0); - offset = FB_ALIGN(offset, sizeof(SSHORT)); - field->fld_missing_parameter = count++; - offset += sizeof(SSHORT); - } + for (field = relation->rel_fields; field; field = field->fld_next) + { + if (field->fld_flags & FLD_computed) + continue; + add_byte(blr, blr_short); + add_byte(blr, 0); + offset = FB_ALIGN(offset, sizeof(SSHORT)); + field->fld_missing_parameter = count++; + offset += sizeof(SSHORT); + } length = offset; @@ -2878,19 +3530,12 @@ rec_type get_data(BurpGlobals* tdgbl, burp_rel* relation, bool skip_relation) if (field->fld_flags & FLD_computed) continue; add_byte(blr, blr_assignment); - if (tdgbl->RESTORE_format >= 2) - { - add_byte(blr, blr_parameter2); - add_byte(blr, 0); - add_word(blr, field->fld_parameter); - add_word(blr, field->fld_missing_parameter); - } - else - { - add_byte(blr, blr_parameter); - add_byte(blr, 0); - add_word(blr, field->fld_parameter); - } + + add_byte(blr, blr_parameter2); + add_byte(blr, 0); + add_word(blr, field->fld_parameter); + add_word(blr, field->fld_missing_parameter); + add_byte(blr, blr_field); add_byte(blr, 0); add_string(blr, field->fld_name); @@ -2902,24 +3547,23 @@ rec_type get_data(BurpGlobals* tdgbl, burp_rel* relation, bool skip_relation) // Compile request - USHORT blr_length = blr - blr_buffer; + ULONG blr_length = blr - blr_buffer; #ifdef DEBUG fb_print_blr(blr_buffer, blr_length, NULL, NULL, 0); #endif - FB_API_HANDLE request = 0; - ISC_STATUS_ARRAY status_vector; - - if (isc_compile_request (status_vector, &DB, &request, - blr_length, reinterpret_cast(blr_buffer))) + FbLocalStatus status_vector; + Firebird::RefPtr request(Firebird::REF_NO_INCR, + DB->compileRequest(&status_vector, blr_length, blr_buffer)); + if (status_vector->hasData()) { fb_print_blr(blr_buffer, blr_length, NULL, NULL, 0); if (!tdgbl->gbl_sw_incremental) - BURP_error_redirect (status_vector, 27); // msg 27 isc_compile_request failed + BURP_error_redirect(&status_vector, 27); // msg 27 isc_compile_request failed else { - BURP_print_status (false, status_vector); + BURP_print_status (false, &status_vector); BURP_free (blr_buffer); return ignore_data(tdgbl, relation); } @@ -2942,8 +3586,10 @@ rec_type get_data(BurpGlobals* tdgbl, burp_rel* relation, bool skip_relation) while (true) { if (get(tdgbl) != att_data_length) - BURP_error_redirect (NULL, 39); // msg 39 expected record length - USHORT len = (USHORT) get_int32(tdgbl); + BURP_error_redirect(NULL, 39); // msg 39 expected record length + + RCRD_LENGTH len = get_int32(tdgbl); + if (!tdgbl->gbl_sw_transportable && len != length) { #ifdef sparc @@ -2956,19 +3602,19 @@ rec_type get_data(BurpGlobals* tdgbl, burp_rel* relation, bool skip_relation) // msg 40 wrong length record, expected %ld encountered %ld } } - if (!buffer) { + + if (!buffer) buffer = (SSHORT *) BURP_alloc (MAX (length, len)); - } UCHAR* p; if (tdgbl->gbl_sw_transportable) { if (get(tdgbl) != att_xdr_length) - BURP_error_redirect (NULL, 55); + BURP_error_redirect(NULL, 55); // msg 55 Expected XDR record length else { - data.lstr_length = len = (USHORT) get_int32(tdgbl); + data.lstr_length = len = get_int32(tdgbl); if (len > data.lstr_allocated) { data.lstr_allocated = len; @@ -2976,26 +3622,26 @@ rec_type get_data(BurpGlobals* tdgbl, burp_rel* relation, bool skip_relation) BURP_free (data.lstr_address); data.lstr_address = BURP_alloc(data.lstr_allocated); } + p = data.lstr_address; } } else p = reinterpret_cast(buffer); + if (get(tdgbl) != att_data_data) - BURP_error_redirect (NULL, 41); // msg 41 expected data attribute + BURP_error_redirect(NULL, 41); // msg 41 expected data attribute if (tdgbl->gbl_sw_compress) decompress (tdgbl, p, len); else - { get_block(tdgbl, p, len); - } if (old_length) realign (tdgbl, (UCHAR*) buffer, relation); if (tdgbl->gbl_sw_transportable) - CAN_encode_decode (relation, &data, (UCHAR *)buffer, FALSE); + CAN_encode_decode(relation, &data, (UCHAR *)buffer, false); records++; @@ -3019,49 +3665,50 @@ rec_type get_data(BurpGlobals* tdgbl, burp_rel* relation, bool skip_relation) while (record == rec_blob || record == rec_array) { if (record == rec_blob) - get_blob (tdgbl, relation->rel_fields, (UCHAR *) buffer); + get_blob_old(tdgbl, relation->rel_fields, (UCHAR *) buffer); else if (record == rec_array) - get_array (tdgbl, relation, (UCHAR *) buffer); + get_array(tdgbl, relation, (UCHAR *) buffer); get_record(&record, tdgbl); } - ISC_STATUS s; - // ASF: Preferable we should call isc_start_and_send only when records == 1, but this leaks // memory when there are blobs and arrays fields - CORE-3802. if (resync || records % 1000 == 1) - s = isc_start_and_send(status_vector, &request, &gds_trans, 0, (USHORT) length, buffer, 0); + request->startAndSend(&status_vector, gds_trans, 0, 0, length, buffer); else - s = isc_send(status_vector, &request, 0, (USHORT) length, buffer, 0); + request->send(&status_vector, 0, 0, length, buffer); - resync = (s != 0); + resync = false; - if (s) + if (status_vector->hasData()) { - if (status_vector[1] == isc_not_valid) + resync = true; + ISC_STATUS code = status_vector->getErrors()[1]; + + if (code == isc_not_valid) { if (tdgbl->gbl_sw_incremental) { BURP_print (false, 138, relation->rel_name); // msg 138 validation error on field in relation %s - BURP_print_status (false, status_vector); + BURP_print_status (false, &status_vector); } else - BURP_error_redirect (status_vector, 47); + BURP_error_redirect(&status_vector, 47); // msg 47 warning -- record could not be restored } - else if (status_vector[1] == isc_malformed_string) + else if (code == isc_malformed_string) { if (tdgbl->gbl_sw_incremental) { // msg 114 restore failed for record in relation %s BURP_print(false, 114, relation->rel_name); - BURP_print_status(false, status_vector); + BURP_print_status(false, &status_vector); BURP_print(false, 342); // isc_gbak_invalid_data } else - BURP_error_redirect(status_vector, 342); // isc_gbak_invalid_data + BURP_error_redirect(&status_vector, 342); // isc_gbak_invalid_data } else { @@ -3069,11 +3716,10 @@ rec_type get_data(BurpGlobals* tdgbl, burp_rel* relation, bool skip_relation) { BURP_print (false, 114, relation->rel_name); // msg 114 restore failed for record in relation %s - BURP_print_status (false, status_vector); + BURP_print_status (false, &status_vector); } else - BURP_error_redirect (status_vector, 48); - // msg 48 isc_send failed + BURP_error_redirect(&status_vector, 48); // msg 48 isc_send failed } records--; @@ -3087,7 +3733,8 @@ rec_type get_data(BurpGlobals* tdgbl, burp_rel* relation, bool skip_relation) if (data.lstr_address) BURP_free (data.lstr_address); - isc_release_request(status_vector, &request); + request = nullptr; + if (tdgbl->gbl_sw_incremental) { BURP_verbose (72, relation->rel_name); @@ -3110,7 +3757,7 @@ rec_type get_data(BurpGlobals* tdgbl, burp_rel* relation, bool skip_relation) case isc_sort_mem_err: case isc_no_dup: strcpy(index_name, (TEXT *)tdgbl->status_vector[3]); - BURP_print_status(false, tdgbl->status_vector); + BURP_print_status(false, &tdgbl->status_vector); FOR (REQUEST_HANDLE req_handle) IDX IN RDB$INDICES WITH IDX.RDB$INDEX_NAME EQ index_name MODIFY IDX USING @@ -3144,7 +3791,7 @@ rec_type get_data(BurpGlobals* tdgbl, burp_rel* relation, bool skip_relation) default: BURP_print (false, 69, relation->rel_name); // msg 69 commit failed on relation %s - BURP_print_status (false, tdgbl->status_vector); + BURP_print_status(false, &tdgbl->status_vector); ROLLBACK; ON_ERROR general_on_error (); @@ -3155,7 +3802,7 @@ rec_type get_data(BurpGlobals* tdgbl, burp_rel* relation, bool skip_relation) END_ERROR; EXEC SQL SET TRANSACTION NO_AUTO_UNDO; - if (gds_status[1]) + if (gds_status->hasData()) EXEC SQL SET TRANSACTION; } BURP_verbose (107, SafeArg() << records); @@ -3164,49 +3811,6 @@ rec_type get_data(BurpGlobals* tdgbl, burp_rel* relation, bool skip_relation) return record; } -// We have a corrupt backup, save the restore process from becoming useless. -void fix_exception(BurpGlobals* tdgbl, const char* exc_name, scan_attr_t& scan_next_attr, - const att_type attribute, att_type& failed_attrib, UCHAR*& msg_ptr, ULONG& l2, bool& msg_seen) -{ - if (msg_seen && (tdgbl->RESTORE_format == 7 || tdgbl->RESTORE_format == 8)) - { - if (!failed_attrib) - { - failed_attrib = attribute; - BURP_print(false, 313, SafeArg() << failed_attrib << exc_name); - } - - // Notice we use 1021 instead of 1023 because this is the maximum length - // for this field in v2.0 and v2.1 and they produce the corrupt backups. - const unsigned int FIELD_LIMIT = 1021; - - if (FIELD_LIMIT < l2 + 1) // not enough space - { - bad_attribute(scan_next_attr, failed_attrib, 287); - return; - } - const unsigned int remaining = FIELD_LIMIT - l2; - - *msg_ptr++ = char(attribute); // (1) - - UCHAR* rc_ptr = get_block(tdgbl, msg_ptr, MIN(remaining - 1, 255)); - if (remaining > 1 && rc_ptr == msg_ptr) // we couldn't read anything - { - bad_attribute(scan_next_attr, failed_attrib, 287); - return; - } - - l2 += rc_ptr - msg_ptr + 1; // + 1 because (1) - msg_ptr = rc_ptr; - *msg_ptr = 0; - - if (l2 == FIELD_LIMIT) - msg_seen = false; - } - else - bad_attribute(scan_next_attr, attribute, 287); // msg 287 exception -} - bool get_exception(BurpGlobals* tdgbl) { /************************************** @@ -3545,7 +4149,7 @@ burp_fld* get_field(BurpGlobals* tdgbl, burp_rel* relation) // If it is a view and there is a global transaction then use it bool global_tr = false; - isc_tr_handle local_trans; + Firebird::ITransaction* local_trans; if ((relation->rel_flags & REL_view) && tdgbl->global_trans) { local_trans = tdgbl->global_trans; @@ -3597,6 +4201,7 @@ burp_fld* get_field(BurpGlobals* tdgbl, burp_rel* relation) case att_field_source: GET_TEXT(X.RDB$FIELD_SOURCE); + strcpy(field->fld_source, X.RDB$FIELD_SOURCE); break; case att_field_security_class: @@ -3799,6 +4404,7 @@ burp_fld* get_field(BurpGlobals* tdgbl, burp_rel* relation) case att_field_source: GET_TEXT(X.RDB$FIELD_SOURCE); + strcpy(field->fld_source, X.RDB$FIELD_SOURCE); break; case att_field_security_class: @@ -4386,7 +4992,7 @@ bool get_function(BurpGlobals* tdgbl) strcpy(function_name, X.RDB$FUNCTION_NAME); END_STORE; ON_ERROR - if (gds_status[1] != isc_no_dup) + if (gds_status->getErrors()[1] != isc_no_dup) general_on_error (); else existFlag = true; @@ -4513,7 +5119,7 @@ bool get_function(BurpGlobals* tdgbl) END_STORE; ON_ERROR - if (gds_status[1] != isc_no_dup) + if (gds_status->getErrors()[1] != isc_no_dup) general_on_error (); else existFlag = true; @@ -6462,22 +7068,22 @@ void get_misc_blob(BurpGlobals* tdgbl, ISC_QUAD& blob_id, bool glb_trans) * shiney, new blob. * **************************************/ - ISC_STATUS_ARRAY status_vector; + FbLocalStatus status_vector; const FB_SIZE_T length = get_int32(tdgbl); // Create new blob - isc_tr_handle local_trans; + Firebird::ITransaction* local_trans; if (glb_trans && tdgbl->global_trans) local_trans = tdgbl->global_trans; else local_trans = gds_trans; - UserBlob blob(status_vector); + BlobWrapper blob(&status_vector); if (!blob.create(DB, local_trans, blob_id)) { - BURP_error_redirect (status_vector, 37); + BURP_error_redirect(&status_vector, 37); // msg 37 isc_create_blob failed } @@ -6492,12 +7098,12 @@ void get_misc_blob(BurpGlobals* tdgbl, ISC_QUAD& blob_id, bool glb_trans) if (!blob.putData(length, buffer)) { - BURP_error_redirect (status_vector, 38); + BURP_error_redirect(&status_vector, 38); // msg 38 isc_put_segment failed } if (!blob.close()) - BURP_error_redirect (status_vector, 23); + BURP_error_redirect(&status_vector, 23); // msg 23 isc_close_blob failed } @@ -6567,7 +7173,7 @@ bool get_package(BurpGlobals* tdgbl) if (tdgbl->RESTORE_format < 10) return false; - isc_tr_handle local_trans = tdgbl->global_trans ? tdgbl->global_trans : gds_trans; + Firebird::ITransaction* local_trans = tdgbl->global_trans ? tdgbl->global_trans : gds_trans; burp_pkg* package = (burp_pkg*) BURP_alloc_zero(sizeof(burp_pkg)); package->pkg_next = tdgbl->packages; @@ -6674,7 +7280,7 @@ bool get_procedure(BurpGlobals* tdgbl) SSHORT l; scan_attr_t scan_next_attr; - isc_tr_handle local_trans = tdgbl->global_trans ? tdgbl->global_trans : gds_trans; + Firebird::ITransaction* local_trans = tdgbl->global_trans ? tdgbl->global_trans : gds_trans; burp_prc* procedure = (burp_prc*) BURP_alloc_zero (sizeof(burp_prc)); procedure->prc_next = tdgbl->procedures; @@ -7018,7 +7624,7 @@ bool get_procedure_prm (BurpGlobals* tdgbl, GDS_NAME package_name, GDS_NAME proc TEXT temp[GDS_NAME_LEN]; scan_attr_t scan_next_attr; - isc_tr_handle local_trans = tdgbl->global_trans ? tdgbl->global_trans : gds_trans; + Firebird::ITransaction* local_trans = tdgbl->global_trans ? tdgbl->global_trans : gds_trans; if (tdgbl->runtimeODS >= DB_VERSION_DDL11_1) { @@ -7338,8 +7944,8 @@ bool get_relation(BurpGlobals* tdgbl) **************************************/ SLONG rel_flags = 0, sys_flag = fb_sysflag_user, type = rel_persistent; bool rel_flags_null = true; - ISC_QUAD view_blr = isc_blob_null, view_src = isc_blob_null, - rel_desc = isc_blob_null, ext_desc = isc_blob_null; + ISC_QUAD view_blr = fbBlobNull, view_src = fbBlobNull, + rel_desc = fbBlobNull, ext_desc = fbBlobNull; bool view_blr_null = true, view_src_null = true, rel_desc_null = true, ext_desc_null = true; FB_BOOLEAN sql_security = FB_FALSE; @@ -7367,7 +7973,7 @@ bool get_relation(BurpGlobals* tdgbl) END_ERROR; EXEC SQL SET TRANSACTION NO_AUTO_UNDO; - if (gds_status[1]) + if (gds_status->hasData()) EXEC SQL SET TRANSACTION; } @@ -7491,7 +8097,7 @@ bool get_relation(BurpGlobals* tdgbl) } // If this is a view and there is a global transaction then use it - isc_tr_handle local_trans; + Firebird::ITransaction* local_trans; if (view_blr_null || !tdgbl->global_trans) local_trans = gds_trans; else @@ -7586,14 +8192,14 @@ bool get_relation(BurpGlobals* tdgbl) ON_ERROR BURP_print (false, 171, relation->rel_name); // msg 171: error committing metadata for relation %s - BURP_print_status (false, tdgbl->status_vector); + BURP_print_status (false, &tdgbl->status_vector); ROLLBACK; ON_ERROR general_on_error (); END_ERROR; END_ERROR; EXEC SQL SET TRANSACTION NO_AUTO_UNDO; - if (gds_status[1]) + if (gds_status->hasData()) EXEC SQL SET TRANSACTION; } return true; @@ -7630,7 +8236,7 @@ bool get_relation(BurpGlobals* tdgbl) END_ERROR; EXEC SQL SET TRANSACTION NO_AUTO_UNDO; - if (gds_status[1]) + if (gds_status->hasData()) EXEC SQL SET TRANSACTION; get_data(tdgbl, relation, tdgbl->skipRelation(rel_name)); @@ -7749,7 +8355,7 @@ bool get_relation_data(BurpGlobals* tdgbl) } if (!relation) - BURP_error_redirect (NULL, 49); + BURP_error_redirect(NULL, 49); // msg 49 no relation name for data // Eat up misc. records @@ -8148,10 +8754,14 @@ bool get_mapping(BurpGlobals* tdgbl) "UPDATE OR INSERT INTO RDB$ROLES(RDB$ROLE_NAME, RDB$SYSTEM_FLAG) VALUES", ADMIN_ROLE, 6, // constant 6 turns on auto admin mapping in FB 2.5 "MATCHING (RDB$ROLE_NAME)"); - isc_dsql_execute_immediate(tdgbl->status_vector, &tdgbl->db_handle, &tdgbl->tr_handle, - sql.length(), sql.c_str(), 1, NULL); - if (tdgbl->status_vector[1]) + try { + BurpSql mapRole(tdgbl, sql.c_str()); + mapRole.execute(tdgbl->tr_handle); + } + catch (const Firebird::FbException& ex) + { + fb_utils::copyStatus(&tdgbl->status_vector, ex.getStatus()); general_on_error (); } } @@ -8281,14 +8891,14 @@ void get_source_blob(BurpGlobals* tdgbl, ISC_QUAD& blob_id, bool glb_trans) * input file to nice, shiney, new blob. * **************************************/ - ISC_STATUS_ARRAY status_vector; + FbLocalStatus status_vector; SLONG length = get_int32(tdgbl); // Create new blob - UserBlob blob(status_vector); - isc_tr_handle local_trans; + BlobWrapper blob(&status_vector); + Firebird::ITransaction* local_trans; if (glb_trans && tdgbl->global_trans) local_trans = tdgbl->global_trans; else @@ -8326,7 +8936,7 @@ void get_source_blob(BurpGlobals* tdgbl, ISC_QUAD& blob_id, bool glb_trans) if (!ok) { - BURP_error_redirect (status_vector, 37); + BURP_error_redirect(&status_vector, 37); // msg 37 isc_create_blob failed } @@ -8345,13 +8955,13 @@ void get_source_blob(BurpGlobals* tdgbl, ISC_QUAD& blob_id, bool glb_trans) if (!blob.putSegment(seg_len, buffer)) { - BURP_error_redirect (status_vector, 38); + BURP_error_redirect(&status_vector, 38); // msg 38 isc_put_segment failed } } if (!blob.close()) - BURP_error_redirect (status_vector, 23); + BURP_error_redirect(&status_vector, 23); // msg 23 isc_close_blob failed } @@ -8370,7 +8980,7 @@ USHORT get_text(BurpGlobals* tdgbl, TEXT* text, ULONG length) const ULONG l = get(tdgbl); if (length <= l) - BURP_error_redirect (NULL, 46); + BURP_error_redirect(NULL, 46); // msg 46 string truncated if (l) @@ -8399,7 +9009,7 @@ USHORT get_text2(BurpGlobals* tdgbl, TEXT* text, ULONG length) if (length <= len) { - BURP_error_redirect (NULL, 46); + BURP_error_redirect(NULL, 46); // msg 46 string truncated } @@ -8519,14 +9129,14 @@ bool get_trigger_old (BurpGlobals* tdgbl, burp_rel* relation) ON_ERROR BURP_print (false, 94, name); // msg 94 trigger %s is invalid - BURP_print_status (false, tdgbl->status_vector); + BURP_print_status(false, &tdgbl->status_vector); ROLLBACK; ON_ERROR general_on_error (); END_ERROR; END_ERROR; EXEC SQL SET TRANSACTION NO_AUTO_UNDO; - if (gds_status[1]) + if (gds_status->hasData()) EXEC SQL SET TRANSACTION; } @@ -8549,7 +9159,7 @@ bool get_trigger(BurpGlobals* tdgbl) BASED_ON RDB$TRIGGERS.RDB$TRIGGER_NAME name; scan_attr_t scan_next_attr; - isc_tr_handle local_trans = tdgbl->global_trans ? tdgbl->global_trans : gds_trans; + Firebird::ITransaction* local_trans = tdgbl->global_trans ? tdgbl->global_trans : gds_trans; if (tdgbl->runtimeODS >= DB_VERSION_DDL11_1) { @@ -8835,14 +9445,14 @@ bool get_trigger(BurpGlobals* tdgbl) ON_ERROR BURP_print (false, 94, name); // msg 94 trigger %s is invalid - BURP_print_status (false, tdgbl->status_vector); + BURP_print_status(false, &tdgbl->status_vector); ROLLBACK; ON_ERROR general_on_error (); END_ERROR; END_ERROR; EXEC SQL SET TRANSACTION NO_AUTO_UNDO; - if (gds_status[1]) + if (gds_status->hasData()) EXEC SQL SET TRANSACTION; } @@ -8911,7 +9521,7 @@ bool get_trigger_message(BurpGlobals* tdgbl) if (tdgbl->runtimeODS < DB_VERSION_DDL11) message[78] = 0; - isc_tr_handle local_trans = tdgbl->global_trans ? tdgbl->global_trans : gds_trans; + Firebird::ITransaction* local_trans = tdgbl->global_trans ? tdgbl->global_trans : gds_trans; STORE (TRANSACTION_HANDLE local_trans REQUEST_HANDLE tdgbl->handles_get_trigger_message_req_handle2) @@ -8931,14 +9541,14 @@ bool get_trigger_message(BurpGlobals* tdgbl) ON_ERROR BURP_print (false, 94, name); // msg 94 trigger %s is invalid - BURP_print_status (false, tdgbl->status_vector); + BURP_print_status(false, &tdgbl->status_vector); ROLLBACK; ON_ERROR general_on_error (); END_ERROR; END_ERROR; EXEC SQL SET TRANSACTION NO_AUTO_UNDO; - if (gds_status[1]) + if (gds_status->hasData()) EXEC SQL SET TRANSACTION; } @@ -9107,7 +9717,7 @@ bool get_user_privilege(BurpGlobals* tdgbl) } // Check if object exists - isc_tr_handle local_trans = 0; + Firebird::ITransaction* local_trans = nullptr; bool exists = false; // if grantor is not set than it's system privilege which should not be restored if (grantor[0]) @@ -9287,7 +9897,7 @@ bool get_view(BurpGlobals* tdgbl, burp_rel* relation) // If there is a global transaction then use it - isc_tr_handle local_trans = tdgbl->global_trans ? tdgbl->global_trans : gds_trans; + Firebird::ITransaction* local_trans = tdgbl->global_trans ? tdgbl->global_trans : gds_trans; if (tdgbl->runtimeODS >= DB_VERSION_DDL12) { @@ -9446,7 +10056,7 @@ void ignore_array(BurpGlobals* tdgbl, burp_rel* relation) break; } if (!field) - BURP_error_redirect (NULL, 36); + BURP_error_redirect(NULL, 36); // msg 36 Can't find field for blob break; @@ -9484,7 +10094,7 @@ void ignore_array(BurpGlobals* tdgbl, burp_rel* relation) if (tdgbl->gbl_sw_transportable) { if (get_attribute(&attribute, tdgbl) != att_xdr_array) - BURP_error_redirect (NULL, 55); + BURP_error_redirect(NULL, 55); // msg 55 Expected XDR record length else { @@ -9579,19 +10189,19 @@ rec_type ignore_data(BurpGlobals* tdgbl, burp_rel* relation) while (true) { if (get(tdgbl) != att_data_length) - BURP_error_redirect (NULL, 39); + BURP_error_redirect(NULL, 39); // msg 39 expected record length USHORT len = (USHORT) get_int32(tdgbl); if (tdgbl->gbl_sw_transportable) { if (get(tdgbl) != att_xdr_length) - BURP_error_redirect (NULL, 55); + BURP_error_redirect(NULL, 55); // msg 55 Expected XDR record length else len = (USHORT) get_int32(tdgbl); } if (get(tdgbl) != att_data_data) - BURP_error_redirect (NULL, 41); + BURP_error_redirect(NULL, 41); // msg 41 expected data attribute if (len) { @@ -9667,19 +10277,14 @@ void realign(BurpGlobals* tdgbl, UCHAR* buffer, const burp_rel* relation) } } - // If this is format version 2 or greater, build fields for null flags - - if (tdgbl->RESTORE_format >= 2) + for (const burp_fld* field = relation->rel_fields; field; field = field->fld_next) { - for (const burp_fld* field = relation->rel_fields; field; field = field->fld_next) - { - if (field->fld_flags & FLD_computed) - continue; - p = FB_ALIGN(p, sizeof(SSHORT)); - q = FB_ALIGN(q, sizeof(SSHORT)); - *p++ = *q++; - *p++ = *q++; - } + if (field->fld_flags & FLD_computed) + continue; + p = FB_ALIGN(p, sizeof(SSHORT)); + q = FB_ALIGN(q, sizeof(SSHORT)); + *p++ = *q++; + *p++ = *q++; } } @@ -9729,17 +10334,12 @@ USHORT recompute_length(BurpGlobals* tdgbl, burp_rel* relation) offset += length; } - // If this is format version 2, build fields for null flags - - if (tdgbl->RESTORE_format >= 2) + for (const burp_fld* field = relation->rel_fields; field; field = field->fld_next) { - for (const burp_fld* field = relation->rel_fields; field; field = field->fld_next) - { - if (field->fld_flags & FLD_computed) - continue; - offset = FB_ALIGN(offset, sizeof(SSHORT)); - offset += sizeof(SSHORT); - } + if (field->fld_flags & FLD_computed) + continue; + offset = FB_ALIGN(offset, sizeof(SSHORT)); + offset += sizeof(SSHORT); } return offset; @@ -9773,9 +10373,9 @@ bool restore(BurpGlobals* tdgbl, const TEXT* file_name, const TEXT* database_nam // restore only from those backup files created by current or previous GBAK - if (tdgbl->RESTORE_format < 1 || tdgbl->RESTORE_format > ATT_BACKUP_FORMAT) + if (tdgbl->RESTORE_format < 2 || tdgbl->RESTORE_format > ATT_BACKUP_FORMAT) { - BURP_error(344, true, SafeArg() << tdgbl->RESTORE_format << 1 << ATT_BACKUP_FORMAT); + BURP_error(344, true, SafeArg() << tdgbl->RESTORE_format << 2 << ATT_BACKUP_FORMAT); // msg 44 Expected backup version @2..@3. Found @1 } @@ -9784,7 +10384,7 @@ bool restore(BurpGlobals* tdgbl, const TEXT* file_name, const TEXT* database_nam create_database(tdgbl, database_name); EXEC SQL SET TRANSACTION NO_AUTO_UNDO; - if (gds_status[1]) + if (gds_status->hasData()) EXEC SQL SET TRANSACTION; // For V4.0, start a read commited transaction. This will be used @@ -9804,7 +10404,10 @@ bool restore(BurpGlobals* tdgbl, const TEXT* file_name, const TEXT* database_nam // msg 129 started transaction att_type attribute; - isc_req_handle req_handle2 = 0, req_handle3 = 0, req_handle4 = 0, req_handle5 = 0; + Firebird::IRequest* req_handle2 = nullptr; + Firebird::IRequest* req_handle3 = nullptr; + Firebird::IRequest* req_handle4 = nullptr; + Firebird::IRequest* req_handle5 = nullptr; while (get_attribute(&attribute, tdgbl) != att_end) { @@ -10093,7 +10696,7 @@ bool restore(BurpGlobals* tdgbl, const TEXT* file_name, const TEXT* database_nam general_on_error (); END_ERROR; EXEC SQL SET TRANSACTION NO_AUTO_UNDO; - if (gds_status[1]) + if (gds_status->hasData()) EXEC SQL SET TRANSACTION; flag = false; } @@ -10152,7 +10755,7 @@ bool restore(BurpGlobals* tdgbl, const TEXT* file_name, const TEXT* database_nam if (tdgbl->defaultCollations.getCount() > 0) { - isc_req_handle req_handle5 = 0; + Firebird::IRequest* req_handle5 = nullptr; FOR (REQUEST_HANDLE req_handle5) CS IN RDB$CHARACTER_SETS @@ -10196,7 +10799,7 @@ bool restore(BurpGlobals* tdgbl, const TEXT* file_name, const TEXT* database_nam general_on_error (); END_ERROR; EXEC SQL SET TRANSACTION NO_AUTO_UNDO; - if (gds_status[1]) + if (gds_status->hasData()) EXEC SQL SET TRANSACTION; } @@ -10208,7 +10811,7 @@ bool restore(BurpGlobals* tdgbl, const TEXT* file_name, const TEXT* database_nam if (tdgbl->gbl_sw_kill) { - isc_req_handle req_handle5 = 0; + Firebird::IRequest* req_handle5 = nullptr; FOR (REQUEST_HANDLE req_handle5) FIL IN RDB$FILES WITH FIL.RDB$SHADOW_NUMBER NOT MISSING @@ -10226,7 +10829,7 @@ bool restore(BurpGlobals* tdgbl, const TEXT* file_name, const TEXT* database_nam } // update statistics for system indices - isc_req_handle req_handle6 = 0; + Firebird::IRequest* req_handle6 = nullptr; FOR (REQUEST_HANDLE req_handle6) IND IN RDB$INDICES WITH IND.RDB$SYSTEM_FLAG EQ 1 @@ -10259,7 +10862,7 @@ void restore_security_class(BurpGlobals* tdgbl, const TEXT* owner_nm, const TEXT * restore the ownership of the relation in the ACL list * **************************************/ - isc_req_handle req_handle2 = 0; + Firebird::IRequest* req_handle2 = nullptr; //isc_tr_handle local_trans = gds_trans; @@ -10316,7 +10919,7 @@ USHORT get_view_base_relation_count(BurpGlobals* tdgbl, return 0; } - isc_req_handle req_handle1 = 0; + Firebird::IRequest* req_handle1 = nullptr; USHORT result = 0; @@ -10443,7 +11046,6 @@ void store_blr_gen_id(BurpGlobals* tdgbl, const TEXT* gen_name, SINT64 value, SI } - FB_API_HANDLE gen_id_reqh = 0; UCHAR blr_buffer[100]; // enough to fit blr UCHAR* blr = blr_buffer; @@ -10499,26 +11101,24 @@ void store_blr_gen_id(BurpGlobals* tdgbl, const TEXT* gen_name, SINT64 value, SI const USHORT blr_length = blr - blr_buffer; fb_assert(blr_length <= sizeof(blr_buffer)); - ISC_STATUS_ARRAY status_vector; - if (isc_compile_request (status_vector, &DB, &gen_id_reqh, - blr_length, (const SCHAR*) blr_buffer)) + FbLocalStatus status_vector; + Firebird::RefPtr gen_id_reqh(Firebird::REF_NO_INCR, + DB->compileRequest(&status_vector, blr_length, blr_buffer)); + if (status_vector->hasData()) { fb_print_blr(blr_buffer, blr_length, NULL, NULL, 0); - BURP_error_redirect (status_vector, 42); // msg 42 Failed in store_blr_gen_id + BURP_error_redirect(&status_vector, 42); // msg 42 Failed in store_blr_gen_id } - if (isc_start_request (status_vector, &gen_id_reqh, - &gds_trans, // use the same one generated by gpre - 0)) + gen_id_reqh->start(&status_vector, gds_trans, 0); + if (status_vector->hasData()) { fb_print_blr(blr_buffer, blr_length, NULL, NULL, 0); - BURP_error_redirect (status_vector, 42); // msg 42 Failed in store_blr_gen_id + BURP_error_redirect(&status_vector, 42); // msg 42 Failed in store_blr_gen_id } BURP_verbose (185, SafeArg() << gen_name << value); // msg 185 restoring generator %s value: %ld - - isc_release_request (status_vector, &gen_id_reqh); } @@ -10535,7 +11135,7 @@ void update_global_field(BurpGlobals* tdgbl) * The blobs have been created already. * **************************************/ - isc_req_handle req_handle1 = 0; + Firebird::IRequest* req_handle1 = nullptr; for (gfld* gfield = tdgbl->gbl_global_fields; gfield; ) { @@ -10600,7 +11200,9 @@ void update_global_field(BurpGlobals* tdgbl) void update_ownership(BurpGlobals* tdgbl) { - isc_req_handle req_handle2 = 0, req_handle4 = 0, req_handle6 = 0; + Firebird::IRequest* req_handle2 = nullptr; + Firebird::IRequest* req_handle4 = nullptr; + Firebird::IRequest* req_handle6 = nullptr; BURP_verbose(358); // Change ownership of any packages @@ -10740,7 +11342,7 @@ void update_view_dbkey_lengths(BurpGlobals* tdgbl) * numeric overflow, or string truncation" error. * **************************************/ - isc_req_handle req_handle2 = 0; + Firebird::IRequest* req_handle2 = nullptr; BURP_verbose(357); @@ -10784,7 +11386,8 @@ void fix_missing_privileges(BurpGlobals* tdgbl) BURP_verbose(359); GDS_NAME owner_name; - isc_req_handle req_handle1 = 0, req_handle2 = 0; + Firebird::IRequest* req_handle1 = nullptr; + Firebird::IRequest* req_handle2 = nullptr; FOR (REQUEST_HANDLE req_handle1) REL IN RDB$RELATIONS @@ -10886,8 +11489,16 @@ void fix_generator(BurpGlobals* tdgbl, const FixGenerator* g) /* SELECT 2 */ g->name, /* SET GEN */ g->name); - if (isc_execute_immediate(isc_status, &DB, &gds_trans, 0, sql.c_str()) != 0) - general_on_error(); + try + { + BurpSql fixGen(tdgbl, sql.c_str()); + fixGen.execute(gds_trans); + } + catch (const Firebird::FbException& ex) + { + fb_utils::copyStatus(&tdgbl->status_vector, ex.getStatus()); + general_on_error (); + } } static const FixGenerator genToFix[] = diff --git a/src/common/CharSet.h b/src/common/CharSet.h index 8e61b73aff..2e76dbc53a 100644 --- a/src/common/CharSet.h +++ b/src/common/CharSet.h @@ -33,21 +33,23 @@ #include "CsConvert.h" #include "IntlUtil.h" +namespace Firebird { + + template <> + inline void SimpleDelete::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: diff --git a/src/common/classes/BlobWrapper.cpp b/src/common/classes/BlobWrapper.cpp new file mode 100644 index 0000000000..6ae3d58164 --- /dev/null +++ b/src/common/classes/BlobWrapper.cpp @@ -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(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(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(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(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; +} diff --git a/src/common/classes/BlobWrapper.h b/src/common/classes/BlobWrapper.h new file mode 100644 index 0000000000..4c52de59d2 --- /dev/null +++ b/src/common/classes/BlobWrapper.h @@ -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 +#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 + diff --git a/src/common/classes/alloc.h b/src/common/classes/alloc.h index 579c6662c3..e04520f0a9 100644 --- a/src/common/classes/alloc.h +++ b/src/common/classes/alloc.h @@ -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 AutoMemoryPool; + template <> + inline void SimpleDelete::clear(MemoryPool* pool) + { + if (pool) + MemoryPool::deletePool(pool); + } + + typedef AutoPtr AutoMemoryPool; } // namespace Firebird diff --git a/src/common/classes/auto.h b/src/common/classes/auto.h index a6c1ed719b..cef49caf6c 100644 --- a/src/common/classes/auto.h +++ b/src/common/classes/auto.h @@ -46,6 +46,15 @@ public: } }; +template <> +inline void SimpleDelete::clear(FILE* f) +{ + if (f) { + fclose(f); + } +} + + template class ArrayDelete { @@ -56,6 +65,7 @@ public: } }; + template class SimpleRelease { @@ -84,24 +94,24 @@ public: }; -template > +template class Clear = SimpleDelete > class AutoPtr { private: Where* ptr; public: - AutoPtr(Where* v = NULL) + AutoPtr(Where* v = NULL) : ptr(v) {} ~AutoPtr() { - Clear::clear(ptr); + Clear::clear(ptr); } - AutoPtr& operator= (Where* v) + AutoPtr& operator= (Where* v) { - Clear::clear(ptr); + Clear::clear(ptr); ptr = v; return *this; } @@ -157,14 +167,24 @@ public: { if (v != ptr) { - Clear::clear(ptr); + Clear::clear(ptr); ptr = v; } } private: - AutoPtr(AutoPtr&); - void operator=(AutoPtr&); + AutoPtr(AutoPtr&); + void operator=(AutoPtr&); +}; + + +template +class AutoDispose : public AutoPtr +{ +public: + AutoDispose(ID* v = nullptr) + : AutoPtr(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 diff --git a/src/common/classes/init.cpp b/src/common/classes/init.cpp index 7f67d05f3d..9f28f6e720 100644 --- a/src/common/classes/init.cpp +++ b/src/common/classes/init.cpp @@ -93,7 +93,7 @@ namespace return; #ifdef DEBUG_GDS_ALLOC - Firebird::AutoPtr file; + Firebird::AutoPtr file; { // scope Firebird::PathName name = "memdebug.log"; diff --git a/src/common/config/config_file.cpp b/src/common/config/config_file.cpp index b36c0a1a8a..26ede13bce 100644 --- a/src/common/config/config_file.cpp +++ b/src/common/config/config_file.cpp @@ -109,7 +109,7 @@ public: } private: - AutoPtr file; + AutoPtr file; Firebird::PathName fileName; unsigned int l; }; diff --git a/src/common/status.h b/src/common/status.h new file mode 100644 index 0000000000..51717b384d --- /dev/null +++ b/src/common/status.h @@ -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 + * 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 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 FbLocalStatus; + typedef LocalStatusWrapper ThrowLocalStatus; +} + +#endif // COMMON_STATUS_H diff --git a/src/dsql/DsqlBatch.cpp b/src/dsql/DsqlBatch.cpp index cf47aceaab..666a301ebf 100644 --- a/src/dsql/DsqlBatch.cpp +++ b/src/dsql/DsqlBatch.cpp @@ -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(flow.data); + ISC_QUAD batchBlobId = *reinterpret_cast(flow.data); ULONG* blobSize = reinterpret_cast(flow.data + sizeof(ISC_QUAD)); ULONG* bpbSize = reinterpret_cast(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(&engineBlobId), batchBlobId); + + //DEB_BATCH(fprintf(stderr, "B-ID: (%x,%x)\n", batchBlobId.gds_quad_high, batchBlobId.gds_quad_low)); + registerBlob(reinterpret_cast(&engineBlobId), &batchBlobId); } } @@ -657,7 +654,7 @@ private: fb_assert(req); // prepare completion interface - AutoPtr > completionState + AutoPtr completionState (FB_NEW BatchCompletionState(m_flags & (1 << IBatch::TAG_RECORD_COUNTS), m_detailed)); AutoSetRestore batchFlag(&req->req_batch, true); const dsql_msg* message = m_request->getStatement()->getSendMsg(); @@ -702,6 +699,9 @@ private: continue; ISC_QUAD* id = reinterpret_cast(&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; diff --git a/src/dsql/DsqlBatch.h b/src/dsql/DsqlBatch.h index 0816386008..6d55e40aa0 100644 --- a/src/dsql/DsqlBatch.h +++ b/src/dsql/DsqlBatch.h @@ -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 Cache; - Firebird::AutoPtr m_cache; + typedef Firebird::Array Cache; + Cache m_cache; Firebird::AutoPtr m_space; - ULONG m_used, m_got, m_limit, m_shift; + ULONG m_used, m_got, m_limit, m_shift, m_cacheCapacity; }; struct BlobMeta diff --git a/src/dsql/Parser.h b/src/dsql/Parser.h index cd73ce1980..2422f2f61a 100644 --- a/src/dsql/Parser.h +++ b/src/dsql/Parser.h @@ -271,7 +271,7 @@ private: clause = value; } - template + template class Delete> void setClause(Firebird::AutoPtr& clause, const char* duplicateMsg, T* value) { checkDuplicateClause(clause, duplicateMsg); diff --git a/src/gpre/obj_cxx.cpp b/src/gpre/obj_cxx.cpp index b083241c55..a5811cf427 100644 --- a/src/gpre/obj_cxx.cpp +++ b/src/gpre/obj_cxx.cpp @@ -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); } diff --git a/src/include/fb_types.h b/src/include/fb_types.h index cf691ca91b..7030f4b792 100644 --- a/src/include/fb_types.h +++ b/src/include/fb_types.h @@ -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, diff --git a/src/include/firebird/FirebirdInterface.idl b/src/include/firebird/FirebirdInterface.idl index 511e5fbf8d..086682a293 100644 --- a/src/include/firebird/FirebirdInterface.idl +++ b/src/include/firebird/FirebirdInterface.idl @@ -514,15 +514,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 +599,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, diff --git a/src/include/firebird/IdlFbInterfaces.h b/src/include/firebird/IdlFbInterfaces.h index 85b1d2d22e..9c6fda1081 100644 --- a/src/include/firebird/IdlFbInterfaces.h +++ b/src/include/firebird/IdlFbInterfaces.h @@ -1931,11 +1931,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 +1953,14 @@ namespace Firebird public: static const unsigned VERSION = 3; - template void receive(StatusType* status, int level, unsigned msgType, unsigned length, unsigned char* message) + template void receive(StatusType* status, int level, unsigned msgType, unsigned length, void* message) { StatusType::clearException(status); static_cast(this->cloopVTable)->receive(this, status, level, msgType, length, message); StatusType::checkException(status); } - template void send(StatusType* status, int level, unsigned msgType, unsigned length, const unsigned char* message) + template void send(StatusType* status, int level, unsigned msgType, unsigned length, const void* message) { StatusType::clearException(status); static_cast(this->cloopVTable)->send(this, status, level, msgType, length, message); @@ -1981,7 +1981,7 @@ namespace Firebird StatusType::checkException(status); } - template void startAndSend(StatusType* status, ITransaction* tra, int level, unsigned msgType, unsigned length, const unsigned char* message) + template void startAndSend(StatusType* status, ITransaction* tra, int level, unsigned msgType, unsigned length, const void* message) { StatusType::clearException(status); static_cast(this->cloopVTable)->startAndSend(this, status, tra, level, msgType, length, message); @@ -9401,7 +9401,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 +9415,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 +9457,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 +9538,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; }; diff --git a/src/intl/lc_icu.cpp b/src/intl/lc_icu.cpp index a2d748b732..e5eced3a14 100644 --- a/src/intl/lc_icu.cpp +++ b/src/intl/lc_icu.cpp @@ -99,7 +99,7 @@ static bool texttype_unicode_init(texttype* tt, // test if that charset exist if (!LD_lookup_charset(cs, charSetName, configInfo)) { - Jrd::CharSet::Delete::clear(cs); + Firebird::SimpleDelete::clear(cs); return false; } @@ -120,7 +120,7 @@ bool LCICU_setup_attributes(const ASCII* name, const ASCII* charSetName, const A if (len > 8 && strcmp(name + len - 8, "_UNICODE") == 0) { - AutoPtr cs(FB_NEW_POOL(*getDefaultMemoryPool()) charset); + AutoPtr cs(FB_NEW_POOL(*getDefaultMemoryPool()) charset); memset(cs, 0, sizeof(*cs)); // test if that charset exist diff --git a/src/isql/isql.epp b/src/isql/isql.epp index 5c1b555351..e51b6e06bc 100644 --- a/src/isql/isql.epp +++ b/src/isql/isql.epp @@ -311,7 +311,7 @@ static inline int fb_isdigit(const char c) IsqlGlobals::IsqlGlobals() { - Firebird::AutoPtr > + Firebird::AutoPtr status_vector(fbMaster->getStatus()); Firebird::CheckStatusWrapper statusWrapper(status_vector); diff --git a/src/isql/show.epp b/src/isql/show.epp index d9b0edddd4..b2bf924f23 100644 --- a/src/isql/show.epp +++ b/src/isql/show.epp @@ -392,7 +392,7 @@ bool SHOW_dbb_parameters(Firebird::IAttachment* db_handle, UCHAR buffer[BUFFER_LENGTH400]; TEXT msg[MSG_LENGTH]; - Firebird::AutoPtr > + Firebird::AutoPtr status_vector(fbMaster->getStatus()); Firebird::CheckStatusWrapper statusWrapper(status_vector); db_handle->getInfo(&statusWrapper, item_length, db_itemsL, sizeof(buffer), buffer); diff --git a/src/jrd/CryptoManager.cpp b/src/jrd/CryptoManager.cpp index cd46c34b84..25ee955f6a 100644 --- a/src/jrd/CryptoManager.cpp +++ b/src/jrd/CryptoManager.cpp @@ -70,18 +70,16 @@ namespace { const int MAX_PLUGIN_NAME_LEN = 31; + template class ReleasePlugin { public: - static void clear(IPluginBase* ptr) + static void clear(P* ptr) { if (ptr) - { PluginManagerInterfacePtr()->releasePlugin(ptr); - } } }; - } @@ -271,7 +269,7 @@ namespace Jrd { } private: - AutoPtr > buffer; + AutoPtr buffer; }; CryptoManager::CryptoManager(thread_db* tdbb) diff --git a/src/jrd/EngineInterface.h b/src/jrd/EngineInterface.h index 3576bae22d..a31ccabe35 100644 --- a/src/jrd/EngineInterface.h +++ b/src/jrd/EngineInterface.h @@ -277,15 +277,15 @@ public: // IRequest implementation int release(); void receive(Firebird::CheckStatusWrapper* status, int level, unsigned int msg_type, - unsigned int length, unsigned char* message); + unsigned int length, void* message); void send(Firebird::CheckStatusWrapper* status, int level, unsigned int msg_type, - unsigned int length, const unsigned char* message); + unsigned int length, const void* message); void getInfo(Firebird::CheckStatusWrapper* status, int level, unsigned int itemsLength, const unsigned char* items, unsigned int bufferLength, unsigned char* buffer); void start(Firebird::CheckStatusWrapper* status, Firebird::ITransaction* tra, int level); void startAndSend(Firebird::CheckStatusWrapper* status, Firebird::ITransaction* tra, int level, - unsigned int msg_type, unsigned int length, const unsigned char* message); + unsigned int msg_type, unsigned int length, const void* message); void unwind(Firebird::CheckStatusWrapper* status, int level); void free(Firebird::CheckStatusWrapper* status); diff --git a/src/jrd/Mapping.cpp b/src/jrd/Mapping.cpp index 61300ed67c..7683f9439d 100644 --- a/src/jrd/Mapping.cpp +++ b/src/jrd/Mapping.cpp @@ -1089,7 +1089,7 @@ private: par.getMetadata(), par.getBuffer(), nullptr, nullptr, 0)); RefPtr meta(curs->getMetadata(&st)); - AutoPtr > buffer(FB_NEW UCHAR[meta->getMessageLength(&st)]); + AutoPtr buffer(FB_NEW UCHAR[meta->getMessageLength(&st)]); UCHAR* bits = buffer + meta->getOffset(&st, 0); UserId::Privileges g, l; diff --git a/src/jrd/btr.cpp b/src/jrd/btr.cpp index 6a19d7457f..fd0733b2bc 100644 --- a/src/jrd/btr.cpp +++ b/src/jrd/btr.cpp @@ -2250,7 +2250,7 @@ bool BTR_types_comparable(const dsc& target, const dsc& source) return (source.dsc_dtype <= dtype_long || source.dsc_dtype == dtype_int64); if (DTYPE_IS_NUMERIC(target.dsc_dtype)) - return (source.dsc_dtype <= dtype_double || source.dsc_dtype == dtype_int64); //!!!!!!!! + return (source.dsc_dtype <= dtype_double || source.dsc_dtype == dtype_int64); if (target.dsc_dtype == dtype_sql_date) return (source.dsc_dtype <= dtype_sql_date || source.dsc_dtype == dtype_timestamp); diff --git a/src/jrd/exe.cpp b/src/jrd/exe.cpp index 1862cf3893..5c3b46d029 100644 --- a/src/jrd/exe.cpp +++ b/src/jrd/exe.cpp @@ -614,7 +614,7 @@ void EXE_receive(thread_db* tdbb, jrd_req* request, USHORT msg, ULONG length, - UCHAR* buffer, + void* buffer, bool top_level) { /************************************** @@ -692,7 +692,7 @@ void EXE_receive(thread_db* tdbb, if (desc->isBlob()) { - const bid* id = (bid*) (buffer + (ULONG)(IPTR)desc->dsc_address); + const bid* id = (bid*) (reinterpret_cast(buffer) + (ULONG)(IPTR) desc->dsc_address); if (transaction->tra_blobs->locate(id->bid_temp_id())) { @@ -766,7 +766,7 @@ void EXE_release(thread_db* tdbb, jrd_req* request) } -void EXE_send(thread_db* tdbb, jrd_req* request, USHORT msg, ULONG length, const UCHAR* buffer) +void EXE_send(thread_db* tdbb, jrd_req* request, USHORT msg, ULONG length, const void* buffer) { /************************************** * diff --git a/src/jrd/exe.h b/src/jrd/exe.h index a1b305e3cd..206dd70b53 100644 --- a/src/jrd/exe.h +++ b/src/jrd/exe.h @@ -633,7 +633,7 @@ inline void CompilerScratch::csb_repeat::deactivate() class StatusXcp { - FbLocalStatus status; + Firebird::FbLocalStatus status; public: StatusXcp(); diff --git a/src/jrd/exe_proto.h b/src/jrd/exe_proto.h index 2bc4ae301e..ea3dedcc2e 100644 --- a/src/jrd/exe_proto.h +++ b/src/jrd/exe_proto.h @@ -46,9 +46,9 @@ const Jrd::StmtNode* EXE_looper(Jrd::thread_db* tdbb, Jrd::jrd_req* request, void EXE_execute_triggers(Jrd::thread_db*, Jrd::TrigVector**, Jrd::record_param*, Jrd::record_param*, enum TriggerAction, Jrd::StmtNode::WhichTrigger); -void EXE_receive(Jrd::thread_db*, Jrd::jrd_req*, USHORT, ULONG, UCHAR*, bool = false); +void EXE_receive(Jrd::thread_db*, Jrd::jrd_req*, USHORT, ULONG, void*, bool = false); void EXE_release(Jrd::thread_db*, Jrd::jrd_req*); -void EXE_send(Jrd::thread_db*, Jrd::jrd_req*, USHORT, ULONG, const UCHAR*); +void EXE_send(Jrd::thread_db*, Jrd::jrd_req*, USHORT, ULONG, const void*); void EXE_start(Jrd::thread_db*, Jrd::jrd_req*, Jrd::jrd_tra*); void EXE_unwind(Jrd::thread_db*, Jrd::jrd_req*); diff --git a/src/jrd/extds/InternalDS.cpp b/src/jrd/extds/InternalDS.cpp index 2f3301fdf8..67b111a4f0 100644 --- a/src/jrd/extds/InternalDS.cpp +++ b/src/jrd/extds/InternalDS.cpp @@ -118,7 +118,7 @@ InternalConnection::~InternalConnection() } // Status helper -class IntStatus : public Jrd::FbLocalStatus +class IntStatus : public Firebird::FbLocalStatus { public: explicit IntStatus(FbStatusVector *p) diff --git a/src/jrd/extds/IscDS.cpp b/src/jrd/extds/IscDS.cpp index 194a9fdb8f..baf56db3cd 100644 --- a/src/jrd/extds/IscDS.cpp +++ b/src/jrd/extds/IscDS.cpp @@ -1525,7 +1525,7 @@ ISC_STATUS ISC_EXPORT IscProvider::fb_database_crypt_callback(FbStatusVector* us return notImplemented(user_status); } -ISC_STATUS ISC_EXPORT IscProvider::fb_dsql_set_timeout(Jrd::FbStatusVector* user_status, +ISC_STATUS ISC_EXPORT IscProvider::fb_dsql_set_timeout(FbStatusVector* user_status, isc_stmt_handle* stmt_handle, ULONG timeout) { diff --git a/src/jrd/inf_pub.h b/src/jrd/inf_pub.h index 0ba0ef2219..a3513f98be 100644 --- a/src/jrd/inf_pub.h +++ b/src/jrd/inf_pub.h @@ -148,6 +148,7 @@ enum db_info_types fb_info_ses_idle_timeout_run = 131, fb_info_conn_flags = 132, + fb_info_protocol_version = 133, fb_info_crypt_key = 133, fb_info_crypt_state = 134, diff --git a/src/jrd/intl_builtin.cpp b/src/jrd/intl_builtin.cpp index 36664c5ac6..da94a9ac10 100644 --- a/src/jrd/intl_builtin.cpp +++ b/src/jrd/intl_builtin.cpp @@ -1717,7 +1717,7 @@ ULONG INTL_builtin_setup_attributes(const ASCII* textTypeName, const ASCII* char // the preprocessor, but this is a task for another day. if (strstr(textTypeName, "UNICODE") && strcmp(textTypeName, "UNICODE_FSS") != 0) { - Firebird::AutoPtr cs(FB_NEW charset); + Firebird::AutoPtr cs(FB_NEW charset); memset(cs, 0, sizeof(*cs)); // test if that charset exists diff --git a/src/jrd/jrd.cpp b/src/jrd/jrd.cpp index 908d278396..27d335ba12 100644 --- a/src/jrd/jrd.cpp +++ b/src/jrd/jrd.cpp @@ -3490,7 +3490,7 @@ JEvents* JAttachment::queEvents(CheckStatusWrapper* user_status, IEventCallback* void JRequest::receive(CheckStatusWrapper* user_status, int level, unsigned int msg_type, - unsigned int msg_length, unsigned char* msg) + unsigned int msg_length, void* msg) { /************************************** * @@ -3803,7 +3803,7 @@ int JBlob::seek(CheckStatusWrapper* user_status, int mode, int offset) void JRequest::send(CheckStatusWrapper* user_status, int level, unsigned int msg_type, - unsigned int msg_length, const unsigned char* msg) + unsigned int msg_length, const void* msg) { /************************************** * @@ -4028,7 +4028,7 @@ void JService::start(CheckStatusWrapper* user_status, unsigned int spbLength, co void JRequest::startAndSend(CheckStatusWrapper* user_status, ITransaction* tra, int level, - unsigned int msg_type, unsigned int msg_length, const unsigned char* msg) + unsigned int msg_type, unsigned int msg_length, const void* msg) { /************************************** * @@ -8400,7 +8400,7 @@ void JRD_autocommit_ddl(thread_db* tdbb, jrd_tra* transaction) } -void JRD_receive(thread_db* tdbb, jrd_req* request, USHORT msg_type, ULONG msg_length, UCHAR* msg) +void JRD_receive(thread_db* tdbb, jrd_req* request, USHORT msg_type, ULONG msg_length, void* msg) { /************************************** * @@ -8424,7 +8424,7 @@ void JRD_receive(thread_db* tdbb, jrd_req* request, USHORT msg_type, ULONG msg_l } -void JRD_send(thread_db* tdbb, jrd_req* request, USHORT msg_type, ULONG msg_length, const UCHAR* msg) +void JRD_send(thread_db* tdbb, jrd_req* request, USHORT msg_type, ULONG msg_length, const void* msg) { /************************************** * @@ -8538,7 +8538,7 @@ void JRD_rollback_retaining(thread_db* tdbb, jrd_tra* transaction) void JRD_start_and_send(thread_db* tdbb, jrd_req* request, jrd_tra* transaction, - USHORT msg_type, ULONG msg_length, const UCHAR* msg) + USHORT msg_type, ULONG msg_length, const void* msg) { /************************************** * diff --git a/src/jrd/jrd.h b/src/jrd/jrd.h index 16aca4f54a..d2b272f9a4 100644 --- a/src/jrd/jrd.h +++ b/src/jrd/jrd.h @@ -768,7 +768,7 @@ private: ThreadContextHolder(const ThreadContextHolder&); ThreadContextHolder& operator= (const ThreadContextHolder&); - FbLocalStatus localStatus; + Firebird::FbLocalStatus localStatus; FbStatusVector* currentStatus; thread_db context; }; @@ -808,7 +808,7 @@ public: } private: - FbLocalStatus m_local_status; + Firebird::FbLocalStatus m_local_status; thread_db* const m_tdbb; FbStatusVector* const m_old_status; diff --git a/src/jrd/jrd_proto.h b/src/jrd/jrd_proto.h index 7f303a2544..4c096b7996 100644 --- a/src/jrd/jrd_proto.h +++ b/src/jrd/jrd_proto.h @@ -59,7 +59,7 @@ void JRD_print_procedure_info(Jrd::thread_db*, const char*); void JRD_autocommit_ddl(Jrd::thread_db* tdbb, Jrd::jrd_tra* transaction); void JRD_receive(Jrd::thread_db* tdbb, Jrd::jrd_req* request, USHORT msg_type, ULONG msg_length, - UCHAR* msg); + void* msg); void JRD_start(Jrd::thread_db* tdbb, Jrd::jrd_req* request, Jrd::jrd_tra* transaction); void JRD_commit_transaction(Jrd::thread_db* tdbb, Jrd::jrd_tra* transaction); @@ -67,9 +67,9 @@ void JRD_commit_retaining(Jrd::thread_db* tdbb, Jrd::jrd_tra* transaction); void JRD_rollback_transaction(Jrd::thread_db* tdbb, Jrd::jrd_tra* transaction); void JRD_rollback_retaining(Jrd::thread_db* tdbb, Jrd::jrd_tra* transaction); void JRD_send(Jrd::thread_db* tdbb, Jrd::jrd_req* request, USHORT msg_type, ULONG msg_length, - const UCHAR* msg); + const void* msg); void JRD_start_and_send(Jrd::thread_db* tdbb, Jrd::jrd_req* request, Jrd::jrd_tra* transaction, - USHORT msg_type, ULONG msg_length, const UCHAR* msg); + USHORT msg_type, ULONG msg_length, const void* msg); void JRD_start_transaction(Jrd::thread_db* tdbb, Jrd::jrd_tra** transaction, Jrd::Attachment* attachment, unsigned int tpb_length, const UCHAR* tpb); void JRD_unwind_request(Jrd::thread_db* tdbb, Jrd::jrd_req* request); diff --git a/src/jrd/sort.cpp b/src/jrd/sort.cpp index 8a5e03cfa2..95299f83ef 100644 --- a/src/jrd/sort.cpp +++ b/src/jrd/sort.cpp @@ -499,7 +499,7 @@ void Sort::sort(thread_db* tdbb) ++run_count; } - AutoPtr > streams( + AutoPtr streams( FB_NEW_POOL(m_owner->getPool()) run_merge_hdr*[run_count]); run_merge_hdr** m1 = streams; diff --git a/src/jrd/status.h b/src/jrd/status.h index dfb07c823a..1f8bb906ee 100644 --- a/src/jrd/status.h +++ b/src/jrd/status.h @@ -29,90 +29,11 @@ #ifndef JRD_STATUS_H #define JRD_STATUS_H -#include "../common/StatusHolder.h" -#include "../common/utils_proto.h" - -const int MAX_ERRMSG_LEN = 128; -const int MAX_ERRSTR_LEN = 1024; +#include "../common/status.h" namespace Jrd { typedef Firebird::CheckStatusWrapper FbStatusVector; - - template - 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 FbLocalStatus; - typedef LocalStatusWrapper ThrowLocalStatus; } #endif // JRD_STATUS_H diff --git a/src/jrd/svc.h b/src/jrd/svc.h index c69ddaacc2..6527029149 100644 --- a/src/jrd/svc.h +++ b/src/jrd/svc.h @@ -277,7 +277,7 @@ private: static THREAD_ENTRY_DECLARE run(THREAD_ENTRY_PARAM arg); private: - FbLocalStatus svc_status; // status vector for running service + Firebird::FbLocalStatus svc_status; // status vector for running service Firebird::string svc_parsed_sw; // Here point elements of argv ULONG svc_stdout_head; ULONG svc_stdout_tail; diff --git a/src/jrd/val.h b/src/jrd/val.h index eb2c042cdd..7e7969340e 100644 --- a/src/jrd/val.h +++ b/src/jrd/val.h @@ -50,6 +50,7 @@ public: }; const UCHAR DEFAULT_DOUBLE = dtype_double; + const ULONG MAX_RECORD_SIZE = 65535; namespace Jrd { diff --git a/src/lock/print.cpp b/src/lock/print.cpp index 12b27cec13..fafce7e15e 100644 --- a/src/lock/print.cpp +++ b/src/lock/print.cpp @@ -569,7 +569,7 @@ int CLIB_ROUTINE main( int argc, char *argv[]) exit(FINI_OK); } - Firebird::AutoPtr > buffer; + Firebird::AutoPtr buffer; lhb* LOCK_header = NULL; Firebird::AutoPtr shmem_data; diff --git a/src/msgs/messages2.sql b/src/msgs/messages2.sql index a87f11373d..8e95cdad66 100644 --- a/src/msgs/messages2.sql +++ b/src/msgs/messages2.sql @@ -970,7 +970,7 @@ Data source : @4', NULL, NULL) ('non_plugin_protocol', NULL, 'server.cpp', NULL, 0, 860, NULL, 'Plugin not supported by network protocol', NULL, NULL); ('message_format', NULL, 'server.cpp', NULL, 0, 861, NULL, 'Error parsing message format', NULL, NULL); ('batch_param_version', NULL, NULL, NULL, 0, 862, NULL, 'Wrong version of batch parameters block @1, should be @2', NULL, NULL); -('batch_msg_long', NULL, 'DsqlBatch.cpp', NULL, 0, 863, NULL, 'Message size (@1) in batch exceeds internal buffer size (@2)', NULL, NULL); +('batch_msg_long', NULL, '** Unused **', NULL, 0, 863, NULL, 'Message size (@1) in batch exceeds internal buffer size (@2)', NULL, NULL); ('batch_open', NULL, 'DsqlBatch.cpp', NULL, 0, 864, NULL, 'Batch already opened for this statement', NULL, NULL); ('batch_type', NULL, 'DsqlBatch.cpp', NULL, 0, 865, NULL, 'Invalid type of statement used in batch', NULL, NULL); ('batch_param', NULL, 'DsqlBatch.cpp', NULL, 0, 866, NULL, 'Statement used in batch must have parameters', NULL, NULL); diff --git a/src/remote/client/interface.cpp b/src/remote/client/interface.cpp index 3b2125206c..b69b3bc657 100644 --- a/src/remote/client/interface.cpp +++ b/src/remote/client/interface.cpp @@ -371,6 +371,7 @@ private: // working with blob stream buffer void newBlob() { + setBlobAlignment(); alignBlobBuffer(blobAlign); fb_assert(blobStream - blobStreamBuffer <= blobBufferSize); @@ -384,6 +385,8 @@ private: void alignBlobBuffer(unsigned alignment, ULONG* bs = NULL) { + fb_assert(alignment); + FB_UINT64 zeroFill = 0; UCHAR* newPointer = FB_ALIGN(blobStream, alignment); ULONG align = FB_ALIGN(blobStream, alignment) - blobStream; @@ -464,6 +467,7 @@ private: void flashBatch() { + setBlobAlignment(); alignBlobBuffer(blobAlign); ULONG size = blobStream - blobStreamBuffer; if (size) @@ -472,13 +476,19 @@ private: blobStream = blobStreamBuffer; } + if (messageStream) + { + sendMessagePacket(messageStream, messageStreamBuffer); + messageStream = 0; + } + batchActive = false; } void sendBlobPacket(unsigned size, const UCHAR* ptr); void sendMessagePacket(unsigned size, const UCHAR* ptr); - Firebird::AutoPtr > messageStreamBuffer, blobStreamBuffer; + Firebird::AutoPtr messageStreamBuffer, blobStreamBuffer; ULONG messageStream; UCHAR* blobStream; ULONG* sizePointer; @@ -621,15 +631,15 @@ public: // IRequest implementation int release(); void receive(CheckStatusWrapper* status, int level, unsigned int msg_type, - unsigned int length, unsigned char* message); + unsigned int length, void* message); void send(CheckStatusWrapper* status, int level, unsigned int msg_type, - unsigned int length, const unsigned char* message); + unsigned int length, const void* message); void getInfo(CheckStatusWrapper* status, int level, unsigned int itemsLength, const unsigned char* items, unsigned int bufferLength, unsigned char* buffer); void start(CheckStatusWrapper* status, Firebird::ITransaction* tra, int level); void startAndSend(CheckStatusWrapper* status, Firebird::ITransaction* tra, int level, unsigned int msg_type, - unsigned int length, const unsigned char* message); + unsigned int length, const void* message); void unwind(CheckStatusWrapper* status, int level); void free(CheckStatusWrapper* status); @@ -2665,7 +2675,7 @@ IBatchCompletionState* Batch::execute(CheckStatusWrapper* status, ITransaction* send_packet(port, packet); statement->rsr_batch_size = alignedSize; - AutoPtr > + AutoPtr cs(FB_NEW BatchCompletionState(flags & (1 << IBatch::TAG_RECORD_COUNTS), 256)); statement->rsr_batch_cs = cs; receive_packet(port, packet); @@ -5057,7 +5067,7 @@ Firebird::IEvents* Attachment::queEvents(CheckStatusWrapper* status, Firebird::I void Request::receive(CheckStatusWrapper* status, int level, unsigned int msg_type, - unsigned int msg_length, unsigned char* msg) + unsigned int msg_length, void* msg) { /************************************** * @@ -5570,7 +5580,7 @@ int Blob::seek(CheckStatusWrapper* status, int mode, int offset) void Request::send(CheckStatusWrapper* status, int level, unsigned int msg_type, - unsigned int /*length*/, const unsigned char* msg) + unsigned int /*length*/, const void* msg) { /************************************** * @@ -5601,7 +5611,7 @@ void Request::send(CheckStatusWrapper* status, int level, unsigned int msg_type, RMessage* message = request->rrq_rpt[msg_type].rrq_message; // We are lying here, but the interface shows for years this param as const - message->msg_address = const_cast(msg); + message->msg_address = const_cast(static_cast(msg)); PACKET* packet = &rdb->rdb_packet; packet->p_operation = op_send; @@ -5852,7 +5862,7 @@ void Service::start(CheckStatusWrapper* status, void Request::startAndSend(CheckStatusWrapper* status, Firebird::ITransaction* apiTra, int level, - unsigned int msg_type, unsigned int /*length*/, const unsigned char* msg) + unsigned int msg_type, unsigned int /*length*/, const void* msg) { /************************************** * @@ -5894,7 +5904,7 @@ void Request::startAndSend(CheckStatusWrapper* status, Firebird::ITransaction* a REMOTE_reset_request(request, 0); RMessage* message = request->rrq_rpt[msg_type].rrq_message; - message->msg_address = const_cast(msg); + message->msg_address = const_cast(static_cast(msg)); PACKET* packet = &rdb->rdb_packet; packet->p_operation = op_start_send_and_receive; diff --git a/src/remote/merge.cpp b/src/remote/merge.cpp index c4563d7b8d..8dc424a41a 100644 --- a/src/remote/merge.cpp +++ b/src/remote/merge.cpp @@ -48,7 +48,6 @@ USHORT MERGE_database_info(const UCHAR* in, USHORT base_level, const UCHAR* version, const UCHAR* id) - //ULONG mask Was always zero { /************************************** * diff --git a/src/remote/protocol.cpp b/src/remote/protocol.cpp index 9332a790a2..75fa9e8e73 100644 --- a/src/remote/protocol.cpp +++ b/src/remote/protocol.cpp @@ -893,7 +893,7 @@ bool_t xdr_protocol(XDR* xdrs, PACKET* p) while (count--) { - DEB_BATCH(fprintf(stderr, "BatRem: xdr packed msg\n")); + DEB_RBATCH(fprintf(stderr, "BatRem: xdr packed msg\n")); if (!xdr_packed_message(xdrs, message, statement->rsr_format)) return P_FALSE(xdrs, p); message->msg_address += statement->rsr_batch_size; @@ -912,7 +912,7 @@ bool_t xdr_protocol(XDR* xdrs, PACKET* p) MAP(xdr_short, reinterpret_cast(b->p_batch_transaction)); if (xdrs->x_op != XDR_FREE) - DEB_BATCH(fprintf(stderr, "BatRem: xdr execute\n")); + DEB_RBATCH(fprintf(stderr, "BatRem: xdr execute\n")); return P_TRUE(xdrs, p); } @@ -931,7 +931,7 @@ bool_t xdr_protocol(XDR* xdrs, PACKET* p) rem_port* port = (rem_port*) xdrs->x_public; SSHORT statement_id = b->p_batch_statement; - DEB_BATCH(fprintf(stderr, "BatRem: xdr CS %d\n", statement_id)); + DEB_RBATCH(fprintf(stderr, "BatRem: xdr CS %d\n", statement_id)); Rsr* statement; if (statement_id >= 0) @@ -961,12 +961,12 @@ bool_t xdr_protocol(XDR* xdrs, PACKET* p) if ((xdrs->x_op == XDR_DECODE) && (!b->p_batch_updates)) { - DEB_BATCH(fprintf(stderr, "BatRem: xdr reccount=%d\n", b->p_batch_reccount)); + DEB_RBATCH(fprintf(stderr, "BatRem: xdr reccount=%d\n", b->p_batch_reccount)); statement->rsr_batch_cs->regSize(b->p_batch_reccount); } // Process update counters - DEB_BATCH(fprintf(stderr, "BatRem: xdr up %d\n", b->p_batch_updates)); + DEB_RBATCH(fprintf(stderr, "BatRem: xdr up %d\n", b->p_batch_updates)); for (unsigned i = 0; i < b->p_batch_updates; ++i) { SLONG v; @@ -988,7 +988,7 @@ bool_t xdr_protocol(XDR* xdrs, PACKET* p) // Process status vectors ULONG pos = 0u; LocalStatus to; - DEB_BATCH(fprintf(stderr, "BatRem: xdr sv %d\n", b->p_batch_vectors)); + DEB_RBATCH(fprintf(stderr, "BatRem: xdr sv %d\n", b->p_batch_vectors)); for (unsigned i = 0; i < b->p_batch_vectors; ++i, ++pos) { @@ -1026,7 +1026,7 @@ bool_t xdr_protocol(XDR* xdrs, PACKET* p) // Process status-less errors pos = 0u; - DEB_BATCH(fprintf(stderr, "BatRem: xdr err %d\n", b->p_batch_errors)); + DEB_RBATCH(fprintf(stderr, "BatRem: xdr err %d\n", b->p_batch_errors)); for (unsigned i = 0; i < b->p_batch_errors; ++i, ++pos) { @@ -1059,7 +1059,7 @@ bool_t xdr_protocol(XDR* xdrs, PACKET* p) MAP(xdr_short, reinterpret_cast(b->p_batch_statement)); if (xdrs->x_op != XDR_FREE) - DEB_BATCH(fprintf(stderr, "BatRem: xdr release\n")); + DEB_RBATCH(fprintf(stderr, "BatRem: xdr release\n")); return P_TRUE(xdrs, p); } diff --git a/src/remote/remote.h b/src/remote/remote.h index 26c1404d3d..1c18a3a86a 100644 --- a/src/remote/remote.h +++ b/src/remote/remote.h @@ -64,7 +64,7 @@ //#define COMPRESS_DEBUG 1 #endif // WIRE_COMPRESS_SUPPORT -#define DEB_BATCH(x) +#define DEB_RBATCH(x) #define REM_SEND_OFFSET(bs) (0) #define REM_RECV_OFFSET(bs) (bs) @@ -123,7 +123,7 @@ namespace os_utils struct rem_port; -typedef Firebird::AutoPtr > UCharArrayAutoPtr; +typedef Firebird::AutoPtr UCharArrayAutoPtr; typedef Firebird::RefPtr ServAttachment; typedef Firebird::RefPtr ServBlob; diff --git a/src/remote/server/server.cpp b/src/remote/server/server.cpp index 90e1b91eea..089127cf96 100644 --- a/src/remote/server/server.cpp +++ b/src/remote/server/server.cpp @@ -3503,7 +3503,7 @@ void rem_port::batch_exec(P_BATCH_EXEC* batch, PACKET* sendL) Rtr* transaction = NULL; getHandle(transaction, batch->p_batch_transaction); - AutoPtr > + AutoPtr ics(statement->rsr_batch->execute(&status_vector, transaction->rtr_iface)); if (status_vector.getState() & IStatus::STATE_ERRORS) diff --git a/src/utilities/ntrace/traceplugin.cpp b/src/utilities/ntrace/traceplugin.cpp index 739e324f81..e14549be24 100644 --- a/src/utilities/ntrace/traceplugin.cpp +++ b/src/utilities/ntrace/traceplugin.cpp @@ -84,7 +84,7 @@ Firebird::ITracePlugin* TraceFactoryImpl::trace_create(Firebird::CheckStatusWrap return NULL; // Plugin is not needed, no error happened. } - Firebird::AutoPtr > + Firebird::AutoPtr logWriter(initInfo->getLogWriter()); if (logWriter) diff --git a/src/yvalve/YObjects.h b/src/yvalve/YObjects.h index bf3c5de056..ba10480527 100644 --- a/src/yvalve/YObjects.h +++ b/src/yvalve/YObjects.h @@ -210,14 +210,14 @@ public: // IRequest implementation void receive(Firebird::CheckStatusWrapper* status, int level, unsigned int msgType, - unsigned int length, unsigned char* message); + unsigned int length, void* message); void send(Firebird::CheckStatusWrapper* status, int level, unsigned int msgType, - unsigned int length, const unsigned char* message); + unsigned int length, const void* message); void getInfo(Firebird::CheckStatusWrapper* status, int level, unsigned int itemsLength, const unsigned char* items, unsigned int bufferLength, unsigned char* buffer); void start(Firebird::CheckStatusWrapper* status, Firebird::ITransaction* transaction, int level); void startAndSend(Firebird::CheckStatusWrapper* status, Firebird::ITransaction* transaction, int level, - unsigned int msgType, unsigned int length, const unsigned char* message); + unsigned int msgType, unsigned int length, const void* message); void unwind(Firebird::CheckStatusWrapper* status, int level); void free(Firebird::CheckStatusWrapper* status); diff --git a/src/yvalve/why.cpp b/src/yvalve/why.cpp index afe4e53050..8f77e5ccb1 100644 --- a/src/yvalve/why.cpp +++ b/src/yvalve/why.cpp @@ -3922,7 +3922,7 @@ void YRequest::destroy(unsigned dstrFlags) } void YRequest::receive(CheckStatusWrapper* status, int level, unsigned int msgType, - unsigned int length, unsigned char* message) + unsigned int length, void* message) { try { @@ -3936,7 +3936,7 @@ void YRequest::receive(CheckStatusWrapper* status, int level, unsigned int msgTy } void YRequest::send(CheckStatusWrapper* status, int level, unsigned int msgType, - unsigned int length, const unsigned char* message) + unsigned int length, const void* message) { try { @@ -3980,7 +3980,7 @@ void YRequest::start(CheckStatusWrapper* status, ITransaction* transaction, int } void YRequest::startAndSend(CheckStatusWrapper* status, ITransaction* transaction, int level, - unsigned int msgType, unsigned int length, const unsigned char* message) + unsigned int msgType, unsigned int length, const void* message) { try { From 578a83a8582a7a69c4e0d8801faee8bcf7d30ede Mon Sep 17 00:00:00 2001 From: Roman Simakov Date: Mon, 19 Feb 2018 15:48:14 +0300 Subject: [PATCH 037/171] Fixed CORE-5747: User can grant USAGE privilege by himself. Error messages were corrected. Note: GRANT OPTION is being checked taking into account currently used ROLES --- src/dsql/DdlNodes.epp | 104 ++++++++++++++++++++++++++++++++--------- src/dsql/DdlNodes.h | 4 +- src/jrd/drq.h | 1 + src/msgs/messages2.sql | 2 + 4 files changed, 87 insertions(+), 24 deletions(-) diff --git a/src/dsql/DdlNodes.epp b/src/dsql/DdlNodes.epp index 06ee399726..6bbe339a3c 100644 --- a/src/dsql/DdlNodes.epp +++ b/src/dsql/DdlNodes.epp @@ -11286,7 +11286,9 @@ void GrantRevokeNode::grantRevoke(thread_db* tdbb, jrd_tra* transaction, const G } } - 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); @@ -11296,7 +11298,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 @@ -11312,7 +11314,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; @@ -11434,17 +11436,32 @@ 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); } } @@ -11507,7 +11524,7 @@ 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 { @@ -11560,7 +11577,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) { @@ -11744,13 +11761,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); } } @@ -11838,7 +11855,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); @@ -11846,23 +11865,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) diff --git a/src/dsql/DdlNodes.h b/src/dsql/DdlNodes.h index cf3e285f63..ead1dc80b6 100644 --- a/src/dsql/DdlNodes.h +++ b/src/dsql/DdlNodes.h @@ -2210,13 +2210,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, diff --git a/src/jrd/drq.h b/src/jrd/drq.h index d43c32b7c8..2d6c82fc1e 100644 --- a/src/jrd/drq.h +++ b/src/jrd/drq.h @@ -234,6 +234,7 @@ enum drq_type_t drq_l_trigger_relname, // lookup relation name for trigger drq_l_grant_option, // lookup grant option for privilege drq_l_granted_roles, // lookup granted roles + drq_l_grant_object, // check grantor can grant object drq_MAX }; diff --git a/src/msgs/messages2.sql b/src/msgs/messages2.sql index 8e95cdad66..d238bfad5a 100644 --- a/src/msgs/messages2.sql +++ b/src/msgs/messages2.sql @@ -2074,6 +2074,8 @@ COMMIT WORK; ('dyn_cant_use_zero_inc_ident', NULL, 'DdlNodes.epp', NULL, 8, 296, NULL, 'INCREMENT BY 0 is an illegal option for identity column @1 of table @2', NULL, NULL); ('dyn_concur_alter_database', 'AlterDatabaseNode::execute', 'DdlNodes.epp', NULL, 8, 297, NULL, 'Concurrent ALTER DATABASE is not supported', NULL, NULL); ('dyn_incompat_alter_database', 'AlterDatabaseNode::execute', 'DdlNodes.epp', NULL, 8, 298, NULL, 'Incompatible ALTER DATABASE clauses: ''@1'' and ''@2''', NULL, NULL); +(NULL, 'checkGrantorCanGrantObject', 'DdlNodes.epp', NULL, 8, 299, NULL, 'no @1 privilege with grant option on DDL @2', NULL, NULL); +(NULL, 'checkGrantorCanGrantObject', 'DdlNodes.epp', NULL, 8, 300, NULL, 'no @1 privilege with grant option on object @2', NULL, NULL); COMMIT WORK; -- TEST (NULL, 'main', 'test.c', NULL, 11, 0, NULL, 'This is a modified text message', NULL, NULL); From caff163fe2694ddce977d17486048407e46735f0 Mon Sep 17 00:00:00 2001 From: Roman Simakov Date: Mon, 19 Feb 2018 16:17:06 +0300 Subject: [PATCH 038/171] Fixed CORE-5753: Parser allows to use GRANT OPTION for FUNCTION and PACKAGE. --- src/dsql/DdlNodes.epp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/dsql/DdlNodes.epp b/src/dsql/DdlNodes.epp index 6bbe339a3c..013ccdd33f 100644 --- a/src/dsql/DdlNodes.epp +++ b/src/dsql/DdlNodes.epp @@ -11281,6 +11281,14 @@ 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; } From 4163b7f0282e490662869d861b9a6c7a92617f05 Mon Sep 17 00:00:00 2001 From: Roman Simakov Date: Mon, 19 Feb 2018 17:07:47 +0300 Subject: [PATCH 039/171] Fixed CORE-5754: ALTER TRIGGER check privilege for alter database instead of table --- src/dsql/DdlNodes.epp | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/src/dsql/DdlNodes.epp b/src/dsql/DdlNodes.epp index 013ccdd33f..82f49044e4 100644 --- a/src/dsql/DdlNodes.epp +++ b/src/dsql/DdlNodes.epp @@ -3485,6 +3485,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; @@ -3509,26 +3529,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(); From 05d79bed812bc7cec57a8ec8da4649928e4694b8 Mon Sep 17 00:00:00 2001 From: AlexPeshkoff Date: Mon, 19 Feb 2018 20:21:09 +0300 Subject: [PATCH 040/171] Added new messages for gbak --- src/burp/restore.epp | 10 ++++++---- src/msgs/facilities2.sql | 2 +- src/msgs/messages2.sql | 2 ++ 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/burp/restore.epp b/src/burp/restore.epp index beedb55f2d..3ad62c59bc 100644 --- a/src/burp/restore.epp +++ b/src/burp/restore.epp @@ -2051,8 +2051,8 @@ void get_blob(BurpGlobals* tdgbl, Firebird::IBatch* batch, const burp_fld* field if (status_vector->hasData()) { - BURP_error_redirect(&status_vector, 38); // !!!!!!!!! new message - // msg 38 isc_put_segment failed + BURP_error_redirect(&status_vector, 370); + // msg 370 could not append BLOB data to batch } first = false; @@ -3042,9 +3042,11 @@ rec_type get_data(BurpGlobals* tdgbl, burp_rel* relation, bool skip_relation) meta, pb->getBufferLength(&tdgbl->throwStatus), pb->getBuffer(&tdgbl->throwStatus))); if (fbStatus->hasData()) { - // Possible reason of fail - use of keywords as fields in old backup + BURP_print(false, 371, relation->rel_name); + // msg 371 could not start batch when restoring table @1, trying old way + + // Possible reason of fail - use of keywords as fields in old backup of dialect1 DB // Try to roll back to use of old version (fieldnames independent) - BURP_print(false, 27/*, sqlStatement.c_str()*/); // msg 27 isc_compile_request failed !!!!!!!! new WARNING return get_data_old(tdgbl, relation); } diff --git a/src/msgs/facilities2.sql b/src/msgs/facilities2.sql index 5f64eef7eb..dd5306366e 100644 --- a/src/msgs/facilities2.sql +++ b/src/msgs/facilities2.sql @@ -9,7 +9,7 @@ set bulk_insert INSERT INTO FACILITIES (LAST_CHANGE, FACILITY, FAC_CODE, MAX_NUM ('2018-01-15 00:15:00', 'DYN', 8, 299) ('1996-11-07 13:39:40', 'INSTALL', 10, 1) ('1996-11-07 13:38:41', 'TEST', 11, 4) -('2015-07-23 14:20:00', 'GBAK', 12, 370) +('2018-02-19 19:40:00', 'GBAK', 12, 372) ('2015-08-05 12:40:00', 'SQLERR', 13, 1045) ('1996-11-07 13:38:42', 'SQLWARN', 14, 613) ('2006-09-10 03:04:31', 'JRD_BUGCHK', 15, 307) diff --git a/src/msgs/messages2.sql b/src/msgs/messages2.sql index d238bfad5a..799d195cfd 100644 --- a/src/msgs/messages2.sql +++ b/src/msgs/messages2.sql @@ -2462,6 +2462,8 @@ ERROR: Backup incomplete', NULL, NULL); ('gbak_wrong_perf', 'api_gbak/gbak', 'burp.cpp', NULL, 12, 367, NULL, 'wrong char "@1" at statistics parameter', NULL, NULL); ('gbak_too_long_perf', 'api_gbak/gbak', 'burp.cpp', NULL, 12, 368, NULL, 'too many chars at statistics parameter', NULL, NULL); (NULL, 'api_gbak/gbak', 'burp.cpp', NULL, 12, 369, NULL, 'total statistics', NULL, NULL); +(NULL, 'get_blob', 'restore.epp', NULL, 12, 370, NULL, 'could not append BLOB data to batch', NULL, NULL); +(NULL, 'get_data', 'restore.epp', NULL, 12, 371, NULL, 'could not start batch when restoring table @1, trying old way', NULL, NULL); -- SQLERR (NULL, NULL, NULL, NULL, 13, 1, NULL, 'Firebird error', NULL, NULL); (NULL, NULL, NULL, NULL, 13, 74, NULL, 'Rollback not performed', NULL, NULL); From e17a0fac76ced6411238ca31aae73f46c0d625d1 Mon Sep 17 00:00:00 2001 From: firebirds <> Date: Tue, 20 Feb 2018 00:04:18 +0000 Subject: [PATCH 041/171] increment build number --- src/jrd/build_no.h | 12 ++++++------ src/misc/writeBuildNum.sh | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/jrd/build_no.h b/src/jrd/build_no.h index 864cbc8710..87ec8d2af2 100644 --- a/src/jrd/build_no.h +++ b/src/jrd/build_no.h @@ -3,16 +3,16 @@ *** DO NOT EDIT *** TO CHANGE ANY INFORMATION IN HERE PLEASE EDIT src/misc/writeBuildNum.sh - FORMAL BUILD NUMBER:901 + FORMAL BUILD NUMBER:907 */ -#define PRODUCT_VER_STRING "4.0.0.901" -#define FILE_VER_STRING "WI-T4.0.0.901" -#define LICENSE_VER_STRING "WI-T4.0.0.901" -#define FILE_VER_NUMBER 4, 0, 0, 901 +#define PRODUCT_VER_STRING "4.0.0.907" +#define FILE_VER_STRING "WI-T4.0.0.907" +#define LICENSE_VER_STRING "WI-T4.0.0.907" +#define FILE_VER_NUMBER 4, 0, 0, 907 #define FB_MAJOR_VER "4" #define FB_MINOR_VER "0" #define FB_REV_NO "0" -#define FB_BUILD_NO "901" +#define FB_BUILD_NO "907" #define FB_BUILD_TYPE "T" #define FB_BUILD_SUFFIX "Firebird 4.0 Alpha 1" diff --git a/src/misc/writeBuildNum.sh b/src/misc/writeBuildNum.sh index 55e35c9062..cc697de5db 100755 --- a/src/misc/writeBuildNum.sh +++ b/src/misc/writeBuildNum.sh @@ -9,7 +9,7 @@ BuildType=T MajorVer=4 MinorVer=0 RevNo=0 -BuildNum=901 +BuildNum=907 NowAt=`pwd` cd `dirname $0` From 7b61282da52d03d8df8c0e4ad60c36cc8083e5f6 Mon Sep 17 00:00:00 2001 From: AlexPeshkoff Date: Tue, 20 Feb 2018 13:59:02 +0300 Subject: [PATCH 042/171] Fixed INF processing --- src/jrd/inf.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/jrd/inf.cpp b/src/jrd/inf.cpp index fcad6b4265..9b32e50917 100644 --- a/src/jrd/inf.cpp +++ b/src/jrd/inf.cpp @@ -780,6 +780,7 @@ void INF_database_info(thread_db* tdbb, return; } + continue; } buffer[0] = item; From 8eee0ce39adce0d0ebac6baffae528395e631cb8 Mon Sep 17 00:00:00 2001 From: Adriano dos Santos Fernandes Date: Tue, 20 Feb 2018 11:41:28 -0300 Subject: [PATCH 043/171] Misc. --- src/dsql/DdlNodes.epp | 8 ++++---- src/jrd/exe.cpp | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/dsql/DdlNodes.epp b/src/dsql/DdlNodes.epp index 82f49044e4..c2ff7f35a5 100644 --- a/src/dsql/DdlNodes.epp +++ b/src/dsql/DdlNodes.epp @@ -11466,10 +11466,10 @@ void GrantRevokeNode::grantRevoke(thread_db* tdbb, jrd_tra* transaction, const G { 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); + // 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); } } diff --git a/src/jrd/exe.cpp b/src/jrd/exe.cpp index 5c3b46d029..ceb8c74de0 100644 --- a/src/jrd/exe.cpp +++ b/src/jrd/exe.cpp @@ -692,7 +692,7 @@ void EXE_receive(thread_db* tdbb, if (desc->isBlob()) { - const bid* id = (bid*) (reinterpret_cast(buffer) + (ULONG)(IPTR) desc->dsc_address); + const bid* id = (bid*) (static_cast(buffer) + (ULONG)(IPTR) desc->dsc_address); if (transaction->tra_blobs->locate(id->bid_temp_id())) { From f6419f235c0bb37f6b2330974758347119d92352 Mon Sep 17 00:00:00 2001 From: AlexPeshkoff Date: Tue, 20 Feb 2018 18:18:18 +0300 Subject: [PATCH 044/171] Fixed CORE-5742: Incorrect error message in iSQL when trying to create database with wrong password --- src/yvalve/preparse.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/yvalve/preparse.cpp b/src/yvalve/preparse.cpp index e74278460a..5f8e0b9e35 100644 --- a/src/yvalve/preparse.cpp +++ b/src/yvalve/preparse.cpp @@ -170,9 +170,9 @@ bool PREPARSE_execute(CheckStatusWrapper* status, Why::YAttachment** ptrAtt, } bool hasUser = true; + status->init(); for (int qStrip = 0; qStrip < 2; ++qStrip) { - status->init(); hasUser = false; Tokens tks; @@ -297,7 +297,8 @@ bool PREPARSE_execute(CheckStatusWrapper* status, Why::YAttachment** ptrAtt, } catch (const Exception& ex) { - ex.stuffException(status); + if (!(status->getState() & IStatus::STATE_ERRORS)) + ex.stuffException(status); return true; } From b88a968dbf2f795acaf12c5a764fe7037d0cb314 Mon Sep 17 00:00:00 2001 From: AlexPeshkoff Date: Tue, 20 Feb 2018 19:37:18 +0300 Subject: [PATCH 045/171] Print new message only in verbose mode --- src/burp/restore.epp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/burp/restore.epp b/src/burp/restore.epp index 3ad62c59bc..263b1a9c12 100644 --- a/src/burp/restore.epp +++ b/src/burp/restore.epp @@ -3042,7 +3042,7 @@ rec_type get_data(BurpGlobals* tdgbl, burp_rel* relation, bool skip_relation) meta, pb->getBufferLength(&tdgbl->throwStatus), pb->getBuffer(&tdgbl->throwStatus))); if (fbStatus->hasData()) { - BURP_print(false, 371, relation->rel_name); + BURP_verbose(371, relation->rel_name); // msg 371 could not start batch when restoring table @1, trying old way // Possible reason of fail - use of keywords as fields in old backup of dialect1 DB From 3947506346ed2be61693056de0cb5758e01200cb Mon Sep 17 00:00:00 2001 From: firebirds <> Date: Wed, 21 Feb 2018 00:04:14 +0000 Subject: [PATCH 046/171] increment build number --- src/jrd/build_no.h | 12 ++++++------ src/misc/writeBuildNum.sh | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/jrd/build_no.h b/src/jrd/build_no.h index 87ec8d2af2..1e53daf3fe 100644 --- a/src/jrd/build_no.h +++ b/src/jrd/build_no.h @@ -3,16 +3,16 @@ *** DO NOT EDIT *** TO CHANGE ANY INFORMATION IN HERE PLEASE EDIT src/misc/writeBuildNum.sh - FORMAL BUILD NUMBER:907 + FORMAL BUILD NUMBER:911 */ -#define PRODUCT_VER_STRING "4.0.0.907" -#define FILE_VER_STRING "WI-T4.0.0.907" -#define LICENSE_VER_STRING "WI-T4.0.0.907" -#define FILE_VER_NUMBER 4, 0, 0, 907 +#define PRODUCT_VER_STRING "4.0.0.911" +#define FILE_VER_STRING "WI-T4.0.0.911" +#define LICENSE_VER_STRING "WI-T4.0.0.911" +#define FILE_VER_NUMBER 4, 0, 0, 911 #define FB_MAJOR_VER "4" #define FB_MINOR_VER "0" #define FB_REV_NO "0" -#define FB_BUILD_NO "907" +#define FB_BUILD_NO "911" #define FB_BUILD_TYPE "T" #define FB_BUILD_SUFFIX "Firebird 4.0 Alpha 1" diff --git a/src/misc/writeBuildNum.sh b/src/misc/writeBuildNum.sh index cc697de5db..d891299535 100755 --- a/src/misc/writeBuildNum.sh +++ b/src/misc/writeBuildNum.sh @@ -9,7 +9,7 @@ BuildType=T MajorVer=4 MinorVer=0 RevNo=0 -BuildNum=907 +BuildNum=911 NowAt=`pwd` cd `dirname $0` From 9afef198c17368276ccd7a428e159c1ca5684a60 Mon Sep 17 00:00:00 2001 From: Dmitry Yemanov Date: Wed, 21 Feb 2018 10:48:37 +0300 Subject: [PATCH 047/171] Postfix for CORE-2284/CORE-5677, fixes regression CORE-5756 --- src/jrd/dfw.epp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/jrd/dfw.epp b/src/jrd/dfw.epp index 50b4a16230..1ca00a885b 100644 --- a/src/jrd/dfw.epp +++ b/src/jrd/dfw.epp @@ -3556,7 +3556,8 @@ static bool create_relation(thread_db* tdbb, SSHORT phase, DeferredWork* work, j FOR(REQUEST_HANDLE request) X IN RDB$RELATIONS WITH - X.RDB$RELATION_NAME EQ work->dfw_name.c_str() + X.RDB$RELATION_NAME EQ work->dfw_name.c_str() AND + X.RDB$RELATION_ID NOT MISSING { rel_id = X.RDB$RELATION_ID; From f7a663f3a07a4d1f2d8564e54798f5d13fe3d014 Mon Sep 17 00:00:00 2001 From: firebirds <> Date: Thu, 22 Feb 2018 00:04:43 +0000 Subject: [PATCH 048/171] increment build number --- src/jrd/build_no.h | 12 ++++++------ src/misc/writeBuildNum.sh | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/jrd/build_no.h b/src/jrd/build_no.h index 1e53daf3fe..61ae582b3b 100644 --- a/src/jrd/build_no.h +++ b/src/jrd/build_no.h @@ -3,16 +3,16 @@ *** DO NOT EDIT *** TO CHANGE ANY INFORMATION IN HERE PLEASE EDIT src/misc/writeBuildNum.sh - FORMAL BUILD NUMBER:911 + FORMAL BUILD NUMBER:912 */ -#define PRODUCT_VER_STRING "4.0.0.911" -#define FILE_VER_STRING "WI-T4.0.0.911" -#define LICENSE_VER_STRING "WI-T4.0.0.911" -#define FILE_VER_NUMBER 4, 0, 0, 911 +#define PRODUCT_VER_STRING "4.0.0.912" +#define FILE_VER_STRING "WI-T4.0.0.912" +#define LICENSE_VER_STRING "WI-T4.0.0.912" +#define FILE_VER_NUMBER 4, 0, 0, 912 #define FB_MAJOR_VER "4" #define FB_MINOR_VER "0" #define FB_REV_NO "0" -#define FB_BUILD_NO "911" +#define FB_BUILD_NO "912" #define FB_BUILD_TYPE "T" #define FB_BUILD_SUFFIX "Firebird 4.0 Alpha 1" diff --git a/src/misc/writeBuildNum.sh b/src/misc/writeBuildNum.sh index d891299535..d14e52ecd8 100755 --- a/src/misc/writeBuildNum.sh +++ b/src/misc/writeBuildNum.sh @@ -9,7 +9,7 @@ BuildType=T MajorVer=4 MinorVer=0 RevNo=0 -BuildNum=911 +BuildNum=912 NowAt=`pwd` cd `dirname $0` From 1888eab6f36581fec07e18e70de26aace9e96d95 Mon Sep 17 00:00:00 2001 From: AlexPeshkoff Date: Sun, 25 Feb 2018 20:06:33 +0300 Subject: [PATCH 049/171] Fixed CORE-5757: deadlock with events --- src/remote/inet.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/remote/inet.cpp b/src/remote/inet.cpp index 6ea7c60e6a..f7d0e04b4c 100644 --- a/src/remote/inet.cpp +++ b/src/remote/inet.cpp @@ -2090,6 +2090,8 @@ static void select_port(rem_port* main_port, Select* selct, RemPortPtr& port) case Select::SEL_BAD: if (port->port_state == rem_port::BROKEN || (port->port_flags & PORT_connecting)) continue; + if (port->port_flags & PORT_async) + continue; return; case Select::SEL_DISCONNECTED: From 42630c1c836a7d21b765303d20a7a2a3624db99c Mon Sep 17 00:00:00 2001 From: hvlad Date: Mon, 26 Feb 2018 18:52:58 +0200 Subject: [PATCH 050/171] Fixed bug CORE-5760 : Server process crashes while restoring database --- src/common/classes/vector.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common/classes/vector.h b/src/common/classes/vector.h index e0221238f6..3f6e1d3124 100644 --- a/src/common/classes/vector.h +++ b/src/common/classes/vector.h @@ -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) From 6e461ec1c56980dab34daf09af1894cf9a93a8b6 Mon Sep 17 00:00:00 2001 From: AlexPeshkoff Date: Tue, 27 Feb 2018 15:19:08 +0300 Subject: [PATCH 051/171] Fixed CORE-5762: Wrong transaction number in RDB$PAGES relation may cause infinite recusrion in engine and segfault --- src/jrd/dpm.epp | 6 ++++++ src/msgs/facilities2.sql | 2 +- src/msgs/messages2.sql | 1 + 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/jrd/dpm.epp b/src/jrd/dpm.epp index 46443a11bd..f64d6694e5 100644 --- a/src/jrd/dpm.epp +++ b/src/jrd/dpm.epp @@ -3106,6 +3106,12 @@ static bool get_header(WIN* window, USHORT line, record_param* rpb) rpb->rpb_b_line = header->rhdf_b_line; rpb->rpb_transaction_nr = Ods::getTraNum(header); rpb->rpb_format_number = header->rhdf_format; + + if (rpb->rpb_relation->rel_id == 0 /*i.e.RDB$PAGES*/ && rpb->rpb_transaction_nr != 0) + { + // RDB$PAGES relation should be modified only by system transaction + BUGCHECK(307); + } } FB_SIZE_T header_size; diff --git a/src/msgs/facilities2.sql b/src/msgs/facilities2.sql index dd5306366e..5f810973aa 100644 --- a/src/msgs/facilities2.sql +++ b/src/msgs/facilities2.sql @@ -12,7 +12,7 @@ set bulk_insert INSERT INTO FACILITIES (LAST_CHANGE, FACILITY, FAC_CODE, MAX_NUM ('2018-02-19 19:40:00', 'GBAK', 12, 372) ('2015-08-05 12:40:00', 'SQLERR', 13, 1045) ('1996-11-07 13:38:42', 'SQLWARN', 14, 613) -('2006-09-10 03:04:31', 'JRD_BUGCHK', 15, 307) +('2018-02-27 14:50:31', 'JRD_BUGCHK', 15, 308) ('2016-05-26 13:53:45', 'ISQL', 17, 196) ('2010-07-10 10:50:30', 'GSEC', 18, 105) ('2017-03-09 21:51:33', 'GSTAT', 21, 61) diff --git a/src/msgs/messages2.sql b/src/msgs/messages2.sql index 799d195cfd..9c54081a41 100644 --- a/src/msgs/messages2.sql +++ b/src/msgs/messages2.sql @@ -2924,6 +2924,7 @@ COMMIT WORK; (NULL, 'CMP_get_desc', 'cmp.cpp', NULL, 15, 306, NULL, 'Found array data type with more than 16 dimensions', NULL, NULL); -- Do not change the arguments of the previous JRD_BUGCHK messages. -- Write the new JRD_BUGCHK messages here. +(NULL, 'get_header', 'dpm.epp', NULL, 15, 307, NULL, 'RDB$PAGES written by non-system transaction, DB appears to be damaged', NULL, NULL); -- ISQL ('GEN_ERR', 'errmsg', 'isql.e', NULL, 17, 0, NULL, 'Statement failed, SQLSTATE = @1', NULL, NULL); ('USAGE', 'ISQL_main', 'isql.epp', NULL, 17, 1, NULL, 'usage: isql [options] []', NULL, NULL); From fca4da841ebfe1414df5b7836095b4c0a3f830f5 Mon Sep 17 00:00:00 2001 From: hvlad Date: Wed, 28 Feb 2018 18:38:50 +0200 Subject: [PATCH 052/171] Return back lost checkouts at sorting module. It allows to handle AST requests during long sorts. --- src/jrd/sort.cpp | 19 +++++++++++-------- src/jrd/sort.h | 6 +++--- 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/src/jrd/sort.cpp b/src/jrd/sort.cpp index 95299f83ef..1de778e1c6 100644 --- a/src/jrd/sort.cpp +++ b/src/jrd/sort.cpp @@ -388,7 +388,7 @@ void Sort::put(thread_db* tdbb, ULONG** record_address) if ((UCHAR*) record < m_memory + m_longs || (UCHAR*) NEXT_RECORD(record) <= (UCHAR*) (m_next_pointer + 1)) { - putRun(); + putRun(tdbb); while (true) { run_control* run = m_runs; @@ -456,7 +456,7 @@ void Sort::sort(thread_db* tdbb) // and we're ready for output. if (!m_runs) { - sort(); + sortBuffer(tdbb); m_next_pointer = m_first_pointer + 1; m_flags |= scb_sorted; return; @@ -464,7 +464,7 @@ void Sort::sort(thread_db* tdbb) // Write the last records as a run_control - putRun(); + putRun(tdbb); CHECK_FILE(NULL); @@ -1895,7 +1895,7 @@ ULONG Sort::order() } -void Sort::orderAndSave() +void Sort::orderAndSave(thread_db* tdbb) { /************************************** * @@ -1907,6 +1907,8 @@ void Sort::orderAndSave() * scratch file as one big chunk * **************************************/ + EngineCheckout(tdbb, FB_FUNCTION); + run_control* run = m_runs; run->run_records = 0; @@ -1954,7 +1956,7 @@ void Sort::orderAndSave() } -void Sort::putRun() +void Sort::putRun(thread_db* tdbb) { /************************************** * @@ -1982,16 +1984,16 @@ void Sort::putRun() // Do the in-core sort. The first phase a duplicate handling we be performed // in "sort". - sort(); + sortBuffer(tdbb); // Re-arrange records in physical order so they can be dumped in a single write // operation - orderAndSave(); + orderAndSave(tdbb); } -void Sort::sort() +void Sort::sortBuffer(thread_db* tdbb) { /************************************** * @@ -2001,6 +2003,7 @@ void Sort::sort() * been requested, detect and handle them. * **************************************/ + EngineCheckout(tdbb, FB_FUNCTION); // First, insert a pointer to the high key diff --git a/src/jrd/sort.h b/src/jrd/sort.h index e6e95ac151..07daffed4b 100644 --- a/src/jrd/sort.h +++ b/src/jrd/sort.h @@ -282,9 +282,9 @@ private: void init(); void mergeRuns(USHORT); ULONG order(); - void orderAndSave(); - void putRun(); - void sort(); + void orderAndSave(Jrd::thread_db*); + void putRun(Jrd::thread_db*); + void sortBuffer(Jrd::thread_db*); void sortRunsBySeek(int); #ifdef DEV_BUILD From 951438e59b2619eca620a831ea50f45c75a7ab44 Mon Sep 17 00:00:00 2001 From: firebirds <> Date: Sat, 3 Mar 2018 00:02:08 +0000 Subject: [PATCH 053/171] increment build number --- src/jrd/build_no.h | 12 ++++++------ src/misc/writeBuildNum.sh | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/jrd/build_no.h b/src/jrd/build_no.h index 61ae582b3b..0430d5aba1 100644 --- a/src/jrd/build_no.h +++ b/src/jrd/build_no.h @@ -3,16 +3,16 @@ *** DO NOT EDIT *** TO CHANGE ANY INFORMATION IN HERE PLEASE EDIT src/misc/writeBuildNum.sh - FORMAL BUILD NUMBER:912 + FORMAL BUILD NUMBER:916 */ -#define PRODUCT_VER_STRING "4.0.0.912" -#define FILE_VER_STRING "WI-T4.0.0.912" -#define LICENSE_VER_STRING "WI-T4.0.0.912" -#define FILE_VER_NUMBER 4, 0, 0, 912 +#define PRODUCT_VER_STRING "4.0.0.916" +#define FILE_VER_STRING "WI-T4.0.0.916" +#define LICENSE_VER_STRING "WI-T4.0.0.916" +#define FILE_VER_NUMBER 4, 0, 0, 916 #define FB_MAJOR_VER "4" #define FB_MINOR_VER "0" #define FB_REV_NO "0" -#define FB_BUILD_NO "912" +#define FB_BUILD_NO "916" #define FB_BUILD_TYPE "T" #define FB_BUILD_SUFFIX "Firebird 4.0 Alpha 1" diff --git a/src/misc/writeBuildNum.sh b/src/misc/writeBuildNum.sh index d14e52ecd8..f1bda4abf4 100755 --- a/src/misc/writeBuildNum.sh +++ b/src/misc/writeBuildNum.sh @@ -9,7 +9,7 @@ BuildType=T MajorVer=4 MinorVer=0 RevNo=0 -BuildNum=912 +BuildNum=916 NowAt=`pwd` cd `dirname $0` From f989c6226b64daba07cf34744f39e1bc6a4981d3 Mon Sep 17 00:00:00 2001 From: AlexPeshkoff Date: Wed, 7 Mar 2018 20:21:07 +0300 Subject: [PATCH 054/171] An example of accessing DECFLOAT data in UDR --- examples/udr/Functions.cpp | 80 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) diff --git a/examples/udr/Functions.cpp b/examples/udr/Functions.cpp index 83be8aee6a..749861c434 100644 --- a/examples/udr/Functions.cpp +++ b/examples/udr/Functions.cpp @@ -153,6 +153,86 @@ 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 inMetadata(metadata->getInputMetadata(status)); + aOffset = inMetadata->getOffset(status, 0); + bOffset = inMetadata->getOffset(status, 1); + + AutoRelease 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 + + //------------------------------------------------------------------------------ From 1636227d401f3c7e9678dc8cd317af5fae9a56bc Mon Sep 17 00:00:00 2001 From: AlexPeshkoff Date: Wed, 7 Mar 2018 20:22:18 +0300 Subject: [PATCH 055/171] Changed representation of high precision DECIMAL/NUMERIC to be exactly the same as for DECFLOAT(34) --- src/common/DecFloat.h | 4 +- src/dsql/dsql.cpp | 8 +- src/dsql/movd.cpp | 4 +- src/dsql/movd_proto.h | 2 +- src/include/firebird/FirebirdInterface.idl | 12 -- src/include/firebird/IdlFbInterfaces.h | 180 --------------------- src/include/firebird/Message.h | 6 - src/include/types_pub.h | 5 - src/isql/isql.epp | 62 +------ src/isql/isql.h | 2 - src/jrd/ExtEngineManager.cpp | 16 +- src/jrd/Function.epp | 4 +- src/jrd/Routine.cpp | 7 +- src/jrd/Routine.h | 2 +- src/jrd/met.epp | 4 +- src/jrd/mov.cpp | 36 +++++ src/jrd/mov_proto.h | 1 + src/yvalve/YObjects.h | 1 - src/yvalve/utl.cpp | 50 ------ 19 files changed, 71 insertions(+), 335 deletions(-) diff --git a/src/common/DecFloat.h b/src/common/DecFloat.h index 1d33ecf061..53f2066f03 100644 --- a/src/common/DecFloat.h +++ b/src/common/DecFloat.h @@ -132,6 +132,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 +148,6 @@ public: #endif private: - void setScale(DecimalStatus decSt, int scale); - decQuad dec; }; diff --git a/src/dsql/dsql.cpp b/src/dsql/dsql.cpp index f8f14f817b..9331abbac4 100644 --- a/src/dsql/dsql.cpp +++ b/src/dsql/dsql.cpp @@ -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(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) diff --git a/src/dsql/movd.cpp b/src/dsql/movd.cpp index 080c1ea744..d9fbe42e60 100644 --- a/src/dsql/movd.cpp +++ b/src/dsql/movd.cpp @@ -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) { diff --git a/src/dsql/movd_proto.h b/src/dsql/movd_proto.h index 60f1c18288..5a230b42c7 100644 --- a/src/dsql/movd_proto.h +++ b/src/dsql/movd_proto.h @@ -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 diff --git a/src/include/firebird/FirebirdInterface.idl b/src/include/firebird/FirebirdInterface.idl index 086682a293..d35ba75599 100644 --- a/src/include/firebird/FirebirdInterface.idl +++ b/src/include/firebird/FirebirdInterface.idl @@ -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 @@ -1062,7 +1061,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 @@ -1468,13 +1466,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); -} diff --git a/src/include/firebird/IdlFbInterfaces.h b/src/include/firebird/IdlFbInterfaces.h index 9c6fda1081..e9f879bd35 100644 --- a/src/include/firebird/IdlFbInterfaces.h +++ b/src/include/firebird/IdlFbInterfaces.h @@ -115,7 +115,6 @@ namespace Firebird class IUdrPlugin; class IDecFloat16; class IDecFloat34; - class IDecFixed; // Interfaces declarations @@ -3938,7 +3937,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 +4079,6 @@ namespace Firebird StatusType::checkException(status); return ret; } - - template 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(this->cloopVTable)->getDecFixed(this, status); - StatusType::checkException(status); - return ret; - } }; class IOffsetsCallback : public IVersioned @@ -5676,58 +5660,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(this->cloopVTable)->toBcd(this, from, sign, bcd); - } - - template void toString(StatusType* status, const FB_DEC_FIXED* from, int scale, unsigned bufferLength, char* buffer) - { - StatusType::clearException(status); - static_cast(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(this->cloopVTable)->fromBcd(this, sign, bcd, to); - } - - template void fromString(StatusType* status, const char* from, int scale, FB_DEC_FIXED* to) - { - StatusType::clearException(status); - static_cast(this->cloopVTable)->fromString(this, status, from, scale, to); - StatusType::checkException(status); - } - }; - // Interfaces implementations template @@ -13809,7 +13741,6 @@ namespace Firebird this->createEventBlock = &Name::cloopcreateEventBlockDispatcher; this->getDecFloat16 = &Name::cloopgetDecFloat16Dispatcher; this->getDecFloat34 = &Name::cloopgetDecFloat34Dispatcher; - this->getDecFixed = &Name::cloopgetDecFixedDispatcher; } } vTable; @@ -14037,21 +13968,6 @@ namespace Firebird return static_cast(0); } } - - static IDecFixed* CLOOP_CARG cloopgetDecFixedDispatcher(IUtil* self, IStatus* status) throw() - { - StatusType status2(status); - - try - { - return static_cast(self)->Name::getDecFixed(&status2); - } - catch (...) - { - StatusType::catchException(&status2); - return static_cast(0); - } - } }; template > > @@ -14083,7 +13999,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 @@ -17481,101 +17396,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 - 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(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(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(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(self)->Name::fromString(&status2, from, scale, to); - } - catch (...) - { - StatusType::catchException(&status2); - } - } - }; - - template > > - class IDecFixedImpl : public IDecFixedBaseImpl - { - 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; - }; }; diff --git a/src/include/firebird/Message.h b/src/include/firebird/Message.h index c152648417..82fbf58649 100644 --- a/src/include/firebird/Message.h +++ b/src/include/firebird/Message.h @@ -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 diff --git a/src/include/types_pub.h b/src/include/types_pub.h index 3b0bcbd48f..a3adda32e6 100644 --- a/src/include/types_pub.h +++ b/src/include/types_pub.h @@ -178,12 +178,7 @@ struct FB_DEC34_t { ISC_UINT64 fb_data[2]; }; -struct FB_DEC_FIXED_t { - ISC_UINT64 fb_data[2]; -}; - typedef struct FB_DEC16_t FB_DEC16; typedef struct FB_DEC34_t FB_DEC34; -typedef struct FB_DEC_FIXED_t FB_DEC_FIXED; #endif /* INCLUDE_TYPES_PUB_H */ diff --git a/src/isql/isql.epp b/src/isql/isql.epp index e51b6e06bc..6d6d3b1563 100644 --- a/src/isql/isql.epp +++ b/src/isql/isql.epp @@ -317,7 +317,6 @@ IsqlGlobals::IsqlGlobals() df16 = Firebird::UtilInterfacePtr()->getDecFloat16(&statusWrapper); df34 = Firebird::UtilInterfacePtr()->getDecFloat34(&statusWrapper); - dfix = Firebird::UtilInterfacePtr()->getDecFixed(&statusWrapper); } // I s q l G l o b a l s : : p r i n t f @@ -2286,7 +2285,6 @@ static processing_state add_row(TEXT* tabname) double* dvalue; FB_DEC16* d64value; FB_DEC34* d128value; - FB_DEC_FIXED* dfixvalue; UCHAR* boolean; ISC_QUAD* blobid; vary* avary; @@ -2364,6 +2362,7 @@ static processing_state add_row(TEXT* tabname) } break; + case SQL_DEC_FIXED: case SQL_DEC34: d128value = (FB_DEC34*) datap; if (isqlGlob.df34) @@ -2375,23 +2374,6 @@ static processing_state add_row(TEXT* tabname) } break; - case SQL_DEC_FIXED: - scale = msg->getScale(fbStatus, i); - if (ISQL_errmsg(fbStatus)) - return (SKIP); - - dfixvalue = (FB_DEC_FIXED*) datap; - - if (isqlGlob.dfix) - isqlGlob.dfix->fromString(fbStatus, lastInputLine, scale, dfixvalue); - - if ((!isqlGlob.dfix) || (fbStatus->getState() & Firebird::IStatus::STATE_ERRORS)) - { - STDERROUT("Input parsing problem"); - done = true; - } - break; - case SQL_TYPE_DATE: if (3 != sscanf(lastInputLine, "%d/%d/%d", ×.tm_year, ×.tm_mon, ×.tm_mday) || @@ -3083,7 +3065,6 @@ static processing_state bulk_insert_hack(const char* command) tm times; FB_DEC16* d64value; FB_DEC34* d128value; - FB_DEC_FIXED* dfixvalue; // Initialize the time structure. memset(×, 0, sizeof(times)); char msec_str[5] = ""; @@ -3155,6 +3136,7 @@ static processing_state bulk_insert_hack(const char* command) break; case SQL_DEC34: + case SQL_DEC_FIXED: d128value = (FB_DEC34*) datap; if (isqlGlob.df34) isqlGlob.df34->fromString(fbStatus, get_numeric_value(lastPos).c_str(), d128value); @@ -3165,22 +3147,6 @@ static processing_state bulk_insert_hack(const char* command) } break; - case SQL_DEC_FIXED: - scale = message->getScale(fbStatus, i); - if (ISQL_errmsg(fbStatus)) - return (SKIP); - - dfixvalue = (FB_DEC_FIXED*) datap; - if (isqlGlob.dfix) - isqlGlob.dfix->fromString(fbStatus, get_numeric_value(lastPos).c_str(), scale, dfixvalue); - - if ((!isqlGlob.dfix) || (fbStatus->getState() & Firebird::IStatus::STATE_ERRORS)) - { - STDERROUT("Input parsing problem"); - done = true; - } - break; - case SQL_TYPE_DATE: if (3 != sscanf(lastPos, "%d-%d-%d", ×.tm_year, ×.tm_mon, ×.tm_mday) || @@ -7338,6 +7304,7 @@ static unsigned print_item(TEXT** s, const IsqlVar* var, const unsigned length) break; case SQL_DEC34: + case SQL_DEC_FIXED: { char decStr[Firebird::IDecFloat34::STRING_SIZE]; if (isqlGlob.df34) @@ -7356,25 +7323,6 @@ static unsigned print_item(TEXT** s, const IsqlVar* var, const unsigned length) } break; - case SQL_DEC_FIXED: - { - char decStr[Firebird::IDecFixed::STRING_SIZE]; - if (isqlGlob.dfix) - { - isqlGlob.dfix->toString(fbStatus, var->value.asDecFixed, dscale, sizeof(decStr), decStr); - if (ISQL_errmsg(fbStatus)) - strcpy(decStr, convErr); - } - else - strcpy(decStr, convErr); - - if (setValues.List) - isqlGlob.printf("%*.*s%s", sizeof(decStr) - 1, sizeof(decStr) - 1, decStr, NEWLINE); - else - sprintf(p, "%*.*s ", sizeof(decStr) - 1, sizeof(decStr) - 1, decStr); - } - break; - case SQL_TEXT: str2 = var->value.asChar; // See if it is character set OCTETS @@ -8154,12 +8102,10 @@ static unsigned process_message_display(Firebird::IMessageMetadata* message, uns case SQL_DEC16: disp_length = Firebird::IDecFloat16::STRING_SIZE - 1; break; + case SQL_DEC_FIXED: case SQL_DEC34: disp_length = Firebird::IDecFloat34::STRING_SIZE - 1; break; - case SQL_DEC_FIXED: - disp_length = Firebird::IDecFixed::STRING_SIZE - 1; - break; case SQL_TEXT: alignment = 1; data_length++; diff --git a/src/isql/isql.h b/src/isql/isql.h index e99d09f854..7311381ab6 100644 --- a/src/isql/isql.h +++ b/src/isql/isql.h @@ -406,7 +406,6 @@ public: USHORT att_charset; Firebird::IDecFloat16* df16; Firebird::IDecFloat34* df34; - Firebird::IDecFixed* dfix; void printf(const char* buffer, ...); void prints(const char* buffer); @@ -466,7 +465,6 @@ struct IsqlVar char* asChar; FB_DEC16* asDec16; FB_DEC34* asDec34; - FB_DEC_FIXED* asDecFixed; void* setPtr; }; TypeMix value; diff --git a/src/jrd/ExtEngineManager.cpp b/src/jrd/ExtEngineManager.cpp index eba14a14f9..adad29f6e5 100644 --- a/src/jrd/ExtEngineManager.cpp +++ b/src/jrd/ExtEngineManager.cpp @@ -1076,8 +1076,8 @@ void ExtEngineManager::makeFunction(thread_db* tdbb, CompilerScratch* csb, Jrd:: metadata->name = udf->getName().identifier; metadata->entryPoint = entryPointTrimmed; metadata->body = body; - metadata->inputParameters = Routine::createMetadata(udf->getInputFields()); - metadata->outputParameters = Routine::createMetadata(udf->getOutputFields()); + metadata->inputParameters = Routine::createMetadata(udf->getInputFields(), true); + metadata->outputParameters = Routine::createMetadata(udf->getOutputFields(), true); FbLocalStatus status; @@ -1200,8 +1200,8 @@ void ExtEngineManager::makeProcedure(thread_db* tdbb, CompilerScratch* csb, jrd_ metadata->name = prc->getName().identifier; metadata->entryPoint = entryPointTrimmed; metadata->body = body; - metadata->inputParameters = Routine::createMetadata(prc->getInputFields()); - metadata->outputParameters = Routine::createMetadata(prc->getOutputFields()); + metadata->inputParameters = Routine::createMetadata(prc->getInputFields(), true); + metadata->outputParameters = Routine::createMetadata(prc->getOutputFields(), true); FbLocalStatus status; @@ -1346,7 +1346,13 @@ void ExtEngineManager::makeTrigger(thread_db* tdbb, CompilerScratch* csb, Jrd::T { jrd_fld* field = (*relation->rel_fields)[i]; if (field) - fieldsMsg->addItem(field->fld_name, !field->fld_not_null, relFormat->fmt_desc[i]); + { + dsc d(relFormat->fmt_desc[i]); + if (d.dsc_dtype == dtype_dec_fixed) + d.dsc_dtype = dtype_dec128; + + fieldsMsg->addItem(field->fld_name, !field->fld_not_null, d); + } } } diff --git a/src/jrd/Function.epp b/src/jrd/Function.epp index 357ee9ecf6..2a815171c8 100644 --- a/src/jrd/Function.epp +++ b/src/jrd/Function.epp @@ -460,10 +460,10 @@ Function* Function::loadMetadata(thread_db* tdbb, USHORT id, bool noscan, USHORT } else { - RefPtr inputMetadata(REF_NO_INCR, createMetadata(function->getInputFields())); + RefPtr inputMetadata(REF_NO_INCR, createMetadata(function->getInputFields(), false)); function->setInputFormat(createFormat(function->getPool(), inputMetadata, false)); - RefPtr outputMetadata(REF_NO_INCR, createMetadata(function->getOutputFields())); + RefPtr outputMetadata(REF_NO_INCR, createMetadata(function->getOutputFields(), false)); function->setOutputFormat(createFormat(function->getPool(), outputMetadata, true)); function->setImplemented(false); diff --git a/src/jrd/Routine.cpp b/src/jrd/Routine.cpp index 0d28a2a013..e0f8b5602e 100644 --- a/src/jrd/Routine.cpp +++ b/src/jrd/Routine.cpp @@ -35,7 +35,7 @@ namespace Jrd { // Create a MsgMetadata from a parameters array. -MsgMetadata* Routine::createMetadata(const Array >& parameters) +MsgMetadata* Routine::createMetadata(const Array >& parameters, bool isExtern) { RefPtr metadata(FB_NEW MsgMetadata); @@ -43,7 +43,10 @@ MsgMetadata* Routine::createMetadata(const Array >& paramet i != parameters.end(); ++i) { - metadata->addItem((*i)->prm_name, (*i)->prm_nullable, (*i)->prm_desc); + dsc d((*i)->prm_desc); + if (isExtern && d.dsc_dtype == dtype_dec_fixed) + d.dsc_dtype = dtype_dec128; + metadata->addItem((*i)->prm_name, (*i)->prm_nullable, d); } metadata->makeOffsets(); diff --git a/src/jrd/Routine.h b/src/jrd/Routine.h index 7bf0c8ca00..2948910c5e 100644 --- a/src/jrd/Routine.h +++ b/src/jrd/Routine.h @@ -83,7 +83,7 @@ namespace Jrd static const USHORT MAX_ALTER_COUNT = 64; // Number of times an in-cache routine can be altered static Firebird::MsgMetadata* createMetadata( - const Firebird::Array >& parameters); + const Firebird::Array >& parameters, bool isExtern); static Format* createFormat(MemoryPool& pool, Firebird::IMessageMetadata* params, bool addEof); public: diff --git a/src/jrd/met.epp b/src/jrd/met.epp index 6a649a177d..2e46fe62b6 100644 --- a/src/jrd/met.epp +++ b/src/jrd/met.epp @@ -3512,12 +3512,12 @@ jrd_prc* MET_procedure(thread_db* tdbb, USHORT id, bool noscan, USHORT flags) else { RefPtr inputMetadata(REF_NO_INCR, - Routine::createMetadata(procedure->getInputFields())); + Routine::createMetadata(procedure->getInputFields(), false)); procedure->setInputFormat( Routine::createFormat(procedure->getPool(), inputMetadata, false)); RefPtr outputMetadata(REF_NO_INCR, - Routine::createMetadata(procedure->getOutputFields())); + Routine::createMetadata(procedure->getOutputFields(), false)); procedure->setOutputFormat( Routine::createFormat(procedure->getPool(), outputMetadata, true)); diff --git a/src/jrd/mov.cpp b/src/jrd/mov.cpp index 75a865e512..9e87e1440f 100644 --- a/src/jrd/mov.cpp +++ b/src/jrd/mov.cpp @@ -416,6 +416,42 @@ void MOV_move(Jrd::thread_db* tdbb, /*const*/ dsc* from, dsc* to) } +void MOV_move_ext(Jrd::thread_db* tdbb, /*const*/ dsc* from, dsc* to, bool toExtern) +{ +/************************************** + * + * M O V _ m o v e _ e x t + * + ************************************** + * + * Functional description + * Move data to/from outer world. + * + **************************************/ + + MOV_move(tdbb, from, to); + + switch(to->dsc_dtype) + { + case dtype_dec_fixed: + if (toExtern) + { + ((Decimal128*)(to->dsc_address))->setScale(tdbb->getAttachment()->att_dec_status, + to->dsc_scale); + } + else + { + ((DecimalFixed*)(to->dsc_address))->exactInt(tdbb->getAttachment()->att_dec_status, + to->dsc_scale); + } + break; + + default: + break; + } +} + + Decimal64 MOV_get_dec64(Jrd::thread_db* tdbb, const dsc* desc) { /************************************** diff --git a/src/jrd/mov_proto.h b/src/jrd/mov_proto.h index 508d39094c..02f404a73e 100644 --- a/src/jrd/mov_proto.h +++ b/src/jrd/mov_proto.h @@ -50,6 +50,7 @@ int MOV_make_string2(Jrd::thread_db*, const dsc*, USHORT, UCHAR**, Jrd::MoveBuf Firebird::string MOV_make_string2(Jrd::thread_db* tdbb, const dsc* desc, USHORT ttype, bool limit = true); void MOV_move(Jrd::thread_db*, /*const*/ dsc*, dsc*); +void MOV_move_ext(Jrd::thread_db* tdbb, /*const*/ dsc* from, dsc* to, bool toExtern); Firebird::Decimal64 MOV_get_dec64(Jrd::thread_db*, const dsc*); Firebird::Decimal128 MOV_get_dec128(Jrd::thread_db*, const dsc*); Firebird::DecimalFixed MOV_get_dec_fixed(Jrd::thread_db*, const dsc*, SSHORT); diff --git a/src/yvalve/YObjects.h b/src/yvalve/YObjects.h index ba10480527..0f32dadd0f 100644 --- a/src/yvalve/YObjects.h +++ b/src/yvalve/YObjects.h @@ -623,7 +623,6 @@ public: Firebird::IEventBlock* createEventBlock(Firebird::CheckStatusWrapper* status, const char** events); Firebird::IDecFloat16* getDecFloat16(Firebird::CheckStatusWrapper* status); Firebird::IDecFloat34* getDecFloat34(Firebird::CheckStatusWrapper* status); - Firebird::IDecFixed* getDecFixed(Firebird::CheckStatusWrapper* status); }; } // namespace Why diff --git a/src/yvalve/utl.cpp b/src/yvalve/utl.cpp index 83dc1eeb79..912210e649 100644 --- a/src/yvalve/utl.cpp +++ b/src/yvalve/utl.cpp @@ -1187,56 +1187,6 @@ IDecFloat34* UtilInterface::getDecFloat34(CheckStatusWrapper* status) return &decFloat34; } -class DecFixed FB_FINAL : public AutoIface > -{ -public: - // IDecFixed implementation - void toBcd(const FB_DEC_FIXED* from, int* sign, unsigned char* bcd) - { - int exp = 0; - *sign = decQuadToBCD(reinterpret_cast(from), &exp, bcd); - fb_assert(exp == 0); - } - - void toString(CheckStatusWrapper* status, const FB_DEC_FIXED* from, int scale, unsigned bufSize, char* buffer) - { - try - { - DecimalStatus decSt(FB_DEC_Errors); - reinterpret_cast(from)->toString(decSt, scale, bufSize, buffer); - } - catch (const Exception& ex) - { - ex.stuffException(status); - } - } - - void fromBcd(int sign, const unsigned char* bcd, FB_DEC_FIXED* to) - { - decQuadFromBCD(reinterpret_cast(to), 0, bcd, sign ? DECFLOAT_Sign : 0); - } - - void fromString(CheckStatusWrapper* status, const char* from, int scale, FB_DEC_FIXED* to) - { - try - { - DecimalStatus decSt(FB_DEC_Errors); - DecimalFixed* val = reinterpret_cast(to); - val->set(from, scale, decSt); - } - catch (const Exception& ex) - { - ex.stuffException(status); - } - } -}; - -IDecFixed* UtilInterface::getDecFixed(CheckStatusWrapper* /*status*/) -{ - static DecFixed decFixed; - return &decFixed; -} - unsigned UtilInterface::setOffsets(CheckStatusWrapper* status, IMessageMetadata* metadata, IOffsetsCallback* callback) { From 3de8bd66b03f50a68f7e15b65eed0ec3331c5a57 Mon Sep 17 00:00:00 2001 From: firebirds <> Date: Thu, 8 Mar 2018 00:04:29 +0000 Subject: [PATCH 056/171] increment build number --- src/jrd/build_no.h | 12 ++++++------ src/misc/writeBuildNum.sh | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/jrd/build_no.h b/src/jrd/build_no.h index 0430d5aba1..bdbee3925d 100644 --- a/src/jrd/build_no.h +++ b/src/jrd/build_no.h @@ -3,16 +3,16 @@ *** DO NOT EDIT *** TO CHANGE ANY INFORMATION IN HERE PLEASE EDIT src/misc/writeBuildNum.sh - FORMAL BUILD NUMBER:916 + FORMAL BUILD NUMBER:918 */ -#define PRODUCT_VER_STRING "4.0.0.916" -#define FILE_VER_STRING "WI-T4.0.0.916" -#define LICENSE_VER_STRING "WI-T4.0.0.916" -#define FILE_VER_NUMBER 4, 0, 0, 916 +#define PRODUCT_VER_STRING "4.0.0.918" +#define FILE_VER_STRING "WI-T4.0.0.918" +#define LICENSE_VER_STRING "WI-T4.0.0.918" +#define FILE_VER_NUMBER 4, 0, 0, 918 #define FB_MAJOR_VER "4" #define FB_MINOR_VER "0" #define FB_REV_NO "0" -#define FB_BUILD_NO "916" +#define FB_BUILD_NO "918" #define FB_BUILD_TYPE "T" #define FB_BUILD_SUFFIX "Firebird 4.0 Alpha 1" diff --git a/src/misc/writeBuildNum.sh b/src/misc/writeBuildNum.sh index f1bda4abf4..f67b906658 100755 --- a/src/misc/writeBuildNum.sh +++ b/src/misc/writeBuildNum.sh @@ -9,7 +9,7 @@ BuildType=T MajorVer=4 MinorVer=0 RevNo=0 -BuildNum=916 +BuildNum=918 NowAt=`pwd` cd `dirname $0` From de1c8e4aad1d111eda37ed991e5c9cf9e805fdf6 Mon Sep 17 00:00:00 2001 From: Adriano dos Santos Fernandes Date: Fri, 9 Mar 2018 00:07:14 -0300 Subject: [PATCH 057/171] Misc. --- examples/udr/Functions.cpp | 13 +++++++++---- src/jrd/mov.cpp | 6 +++--- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/examples/udr/Functions.cpp b/examples/udr/Functions.cpp index 749861c434..ecbbc7d2dd 100644 --- a/examples/udr/Functions.cpp +++ b/examples/udr/Functions.cpp @@ -186,14 +186,14 @@ FB_UDR_BEGIN_FUNCTION(mult) unsigned char bcd[IDecFloat34::BCD_SIZE]; int sign, exp; - void load(void *from, IDecFloat34* df34) + void load(void* from, IDecFloat34* df34) { - df34->toBcd((FB_DEC34*)from, &sign, bcd, &exp); + df34->toBcd((FB_DEC34*) from, &sign, bcd, &exp); } - void store(void *to, IDecFloat34* df34) const + void store(void* to, IDecFloat34* df34) const { - df34->fromBcd(sign, bcd, exp, (FB_DEC34*)to); + df34->fromBcd(sign, bcd, exp, (FB_DEC34*) to); } }; @@ -204,8 +204,10 @@ FB_UDR_BEGIN_FUNCTION(mult) // 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--;) @@ -215,12 +217,15 @@ FB_UDR_BEGIN_FUNCTION(mult) 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); diff --git a/src/jrd/mov.cpp b/src/jrd/mov.cpp index 9e87e1440f..5f600083c5 100644 --- a/src/jrd/mov.cpp +++ b/src/jrd/mov.cpp @@ -431,17 +431,17 @@ void MOV_move_ext(Jrd::thread_db* tdbb, /*const*/ dsc* from, dsc* to, bool toExt MOV_move(tdbb, from, to); - switch(to->dsc_dtype) + switch (to->dsc_dtype) { case dtype_dec_fixed: if (toExtern) { - ((Decimal128*)(to->dsc_address))->setScale(tdbb->getAttachment()->att_dec_status, + ((Decimal128*) to->dsc_address)->setScale(tdbb->getAttachment()->att_dec_status, to->dsc_scale); } else { - ((DecimalFixed*)(to->dsc_address))->exactInt(tdbb->getAttachment()->att_dec_status, + ((DecimalFixed*) to->dsc_address)->exactInt(tdbb->getAttachment()->att_dec_status, to->dsc_scale); } break; From e81ecc60e8e5e0c1bab6688e885ec0467d3de59c Mon Sep 17 00:00:00 2001 From: AlexPeshkoff Date: Fri, 9 Mar 2018 21:54:28 +0300 Subject: [PATCH 058/171] Fixed CORE-5765: Missing directives in Firebird.pas --- extern/cloop/src/cloop/Generator.cpp | 2 ++ extern/cloop/src/tests/test1/CalcPascalApi.pas | 5 +++++ 2 files changed, 7 insertions(+) diff --git a/extern/cloop/src/cloop/Generator.cpp b/extern/cloop/src/cloop/Generator.cpp index db906e72b6..202c98c096 100644 --- a/extern/cloop/src/cloop/Generator.cpp +++ b/extern/cloop/src/cloop/Generator.cpp @@ -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"); diff --git a/extern/cloop/src/tests/test1/CalcPascalApi.pas b/extern/cloop/src/tests/test1/CalcPascalApi.pas index 62fdfbb238..5c66adde2a 100644 --- a/extern/cloop/src/tests/test1/CalcPascalApi.pas +++ b/extern/cloop/src/tests/test1/CalcPascalApi.pas @@ -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 From dadab0aec317705759bdfefba39728dbb079ccfa Mon Sep 17 00:00:00 2001 From: firebirds <> Date: Sat, 10 Mar 2018 00:04:06 +0000 Subject: [PATCH 059/171] increment build number --- src/jrd/build_no.h | 12 ++++++------ src/misc/writeBuildNum.sh | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/jrd/build_no.h b/src/jrd/build_no.h index bdbee3925d..be0064f931 100644 --- a/src/jrd/build_no.h +++ b/src/jrd/build_no.h @@ -3,16 +3,16 @@ *** DO NOT EDIT *** TO CHANGE ANY INFORMATION IN HERE PLEASE EDIT src/misc/writeBuildNum.sh - FORMAL BUILD NUMBER:918 + FORMAL BUILD NUMBER:920 */ -#define PRODUCT_VER_STRING "4.0.0.918" -#define FILE_VER_STRING "WI-T4.0.0.918" -#define LICENSE_VER_STRING "WI-T4.0.0.918" -#define FILE_VER_NUMBER 4, 0, 0, 918 +#define PRODUCT_VER_STRING "4.0.0.920" +#define FILE_VER_STRING "WI-T4.0.0.920" +#define LICENSE_VER_STRING "WI-T4.0.0.920" +#define FILE_VER_NUMBER 4, 0, 0, 920 #define FB_MAJOR_VER "4" #define FB_MINOR_VER "0" #define FB_REV_NO "0" -#define FB_BUILD_NO "918" +#define FB_BUILD_NO "920" #define FB_BUILD_TYPE "T" #define FB_BUILD_SUFFIX "Firebird 4.0 Alpha 1" diff --git a/src/misc/writeBuildNum.sh b/src/misc/writeBuildNum.sh index f67b906658..4b0ab1fa36 100755 --- a/src/misc/writeBuildNum.sh +++ b/src/misc/writeBuildNum.sh @@ -9,7 +9,7 @@ BuildType=T MajorVer=4 MinorVer=0 RevNo=0 -BuildNum=918 +BuildNum=920 NowAt=`pwd` cd `dirname $0` From 45b0e523136b690eba2f879c230900fdc21a3916 Mon Sep 17 00:00:00 2001 From: AlexPeshkoff Date: Sun, 11 Mar 2018 14:14:33 +0300 Subject: [PATCH 060/171] Fixed CORE-5769: Database crypt plugin sample on Pascal is broken --- examples/dbcrypt/cryptDb.pas | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/examples/dbcrypt/cryptDb.pas b/examples/dbcrypt/cryptDb.pas index 69a85f3287..a092919cdf 100644 --- a/examples/dbcrypt/cryptDb.pas +++ b/examples/dbcrypt/cryptDb.pas @@ -71,6 +71,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); @@ -179,6 +180,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; From a48f18f01951ec777547361f33615ff9fc6ed17f Mon Sep 17 00:00:00 2001 From: Adriano dos Santos Fernandes Date: Sun, 11 Mar 2018 11:52:11 -0300 Subject: [PATCH 061/171] Fixed CORE-5771 - Restore (without replace) when database already exists crashes gbak or Firebird (when run through service manager). --- src/burp/burp.cpp | 41 +++++++++++++++++++++++++++++++---------- 1 file changed, 31 insertions(+), 10 deletions(-) diff --git a/src/burp/burp.cpp b/src/burp/burp.cpp index 7a2c83f131..baec34964b 100644 --- a/src/burp/burp.cpp +++ b/src/burp/burp.cpp @@ -1316,15 +1316,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); + 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 @@ -1822,15 +1824,20 @@ static gbak_action open_files(const TEXT* file1, { tdgbl->db_handle = Firebird::DispatcherPtr()->attachDatabase(status_vector, file1, dpb.getBufferLength(), dpb.getBuffer()); - if (!status_vector->hasData()) + + 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); tdgbl->db_handle->detach(status_vector); - if (status_vector->hasData()) + + 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) @@ -1968,8 +1975,11 @@ static gbak_action open_files(const TEXT* file1, else { tdgbl->db_handle->detach(status_vector); - if (status_vector->hasData()) + + if (status_vector->getState() & Firebird::IStatus::STATE_ERRORS) BURP_print_status(true, status_vector); + else + tdgbl->db_handle = NULL; } return flag; @@ -2144,29 +2154,40 @@ static gbak_action open_files(const TEXT* file1, { tdgbl->db_handle = Firebird::DispatcherPtr()->attachDatabase(status_vector, *file2, dpb.getBufferLength(), dpb.getBuffer()); - if (status_vector->isEmpty()) + + if (!(status_vector->getState() & Firebird::IStatus::STATE_ERRORS)) { if (sw_replace == IN_SW_BURP_C) { tdgbl->db_handle->detach(status_vector); - if (status_vector->hasData()) + + 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->hasData()) + + if (status_vector->getState() & Firebird::IStatus::STATE_ERRORS) { Firebird::FbLocalStatus status2; tdgbl->db_handle->detach(&status2); - if (!status2.isSuccess()) + + 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) From e6a89afd3bc0b7e73faac0ab6b51b6e2aab7e633 Mon Sep 17 00:00:00 2001 From: AlexPeshkoff Date: Sun, 11 Mar 2018 19:44:04 +0300 Subject: [PATCH 062/171] Fixed CORE-5770: User who is allowed to manage other users must have this ability WITHOUT need to grant him RDB$ADMIN role (which is related to admin tasks in "main" database rather than in security_db) --- src/auth/SecureRemotePassword/manage/SrpManagement.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/auth/SecureRemotePassword/manage/SrpManagement.cpp b/src/auth/SecureRemotePassword/manage/SrpManagement.cpp index b0b01da4fa..ae1fac37e4 100644 --- a/src/auth/SecureRemotePassword/manage/SrpManagement.cpp +++ b/src/auth/SecureRemotePassword/manage/SrpManagement.cpp @@ -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(), From 40eb153afbaed70f5ae55825526238ff872adb93 Mon Sep 17 00:00:00 2001 From: firebirds <> Date: Mon, 12 Mar 2018 00:04:13 +0000 Subject: [PATCH 063/171] increment build number --- src/jrd/build_no.h | 12 ++++++------ src/misc/writeBuildNum.sh | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/jrd/build_no.h b/src/jrd/build_no.h index be0064f931..b95f6426ce 100644 --- a/src/jrd/build_no.h +++ b/src/jrd/build_no.h @@ -3,16 +3,16 @@ *** DO NOT EDIT *** TO CHANGE ANY INFORMATION IN HERE PLEASE EDIT src/misc/writeBuildNum.sh - FORMAL BUILD NUMBER:920 + FORMAL BUILD NUMBER:923 */ -#define PRODUCT_VER_STRING "4.0.0.920" -#define FILE_VER_STRING "WI-T4.0.0.920" -#define LICENSE_VER_STRING "WI-T4.0.0.920" -#define FILE_VER_NUMBER 4, 0, 0, 920 +#define PRODUCT_VER_STRING "4.0.0.923" +#define FILE_VER_STRING "WI-T4.0.0.923" +#define LICENSE_VER_STRING "WI-T4.0.0.923" +#define FILE_VER_NUMBER 4, 0, 0, 923 #define FB_MAJOR_VER "4" #define FB_MINOR_VER "0" #define FB_REV_NO "0" -#define FB_BUILD_NO "920" +#define FB_BUILD_NO "923" #define FB_BUILD_TYPE "T" #define FB_BUILD_SUFFIX "Firebird 4.0 Alpha 1" diff --git a/src/misc/writeBuildNum.sh b/src/misc/writeBuildNum.sh index 4b0ab1fa36..0238fbc015 100755 --- a/src/misc/writeBuildNum.sh +++ b/src/misc/writeBuildNum.sh @@ -9,7 +9,7 @@ BuildType=T MajorVer=4 MinorVer=0 RevNo=0 -BuildNum=920 +BuildNum=923 NowAt=`pwd` cd `dirname $0` From cc2b19e3bf5ede3016762821cf45578a9960e29d Mon Sep 17 00:00:00 2001 From: hvlad Date: Thu, 15 Mar 2018 11:32:15 +0200 Subject: [PATCH 064/171] Fixed bug CORE-5776 : "Input parameter mismatch" error after altering external function into PSQL function --- src/dsql/DdlNodes.epp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/dsql/DdlNodes.epp b/src/dsql/DdlNodes.epp index c2ff7f35a5..0b2e189c46 100644 --- a/src/dsql/DdlNodes.epp +++ b/src/dsql/DdlNodes.epp @@ -1792,6 +1792,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) { From 44c6463d07eca4d164fcac43f42bfe2c7585822b Mon Sep 17 00:00:00 2001 From: AlexPeshkoff Date: Thu, 15 Mar 2018 14:44:09 +0300 Subject: [PATCH 065/171] Fixed CORE-5772: Client hangs when working with events under high load --- src/common/ThreadStart.cpp | 10 ++++ src/common/ThreadStart.h | 1 + src/remote/client/interface.cpp | 16 ++---- src/remote/inet.cpp | 5 +- src/remote/remote.cpp | 5 -- src/remote/remote.h | 86 ++++++++++++++++++++++++++++++++- 6 files changed, 102 insertions(+), 21 deletions(-) diff --git a/src/common/ThreadStart.cpp b/src/common/ThreadStart.cpp index d2df46f74f..3a1e4545cc 100644 --- a/src/common/ThreadStart.cpp +++ b/src/common/ThreadStart.cpp @@ -208,6 +208,11 @@ ThreadId Thread::getId() #endif } +bool Thread::isCurrent(Handle& thread) +{ + return pthread_self() == thread; +} + void Thread::sleep(unsigned milliseconds) { #if defined(HAVE_NANOSLEEP) @@ -342,6 +347,11 @@ ThreadId Thread::getId() return GetCurrentThreadId(); } +bool Thread::isCurrent(Handle& thread) +{ + return GetCurrentThreadId() == GetThreadId(thread); +} + void Thread::sleep(unsigned milliseconds) { SleepEx(milliseconds, FALSE); diff --git a/src/common/ThreadStart.h b/src/common/ThreadStart.h index 5af2aff963..3fde12a7bd 100644 --- a/src/common/ThreadStart.h +++ b/src/common/ThreadStart.h @@ -78,6 +78,7 @@ public: static void 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(Handle& handle); static ThreadId getId(); diff --git a/src/remote/client/interface.cpp b/src/remote/client/interface.cpp index b69b3bc657..ddc22d0961 100644 --- a/src/remote/client/interface.cpp +++ b/src/remote/client/interface.cpp @@ -1859,7 +1859,7 @@ void Attachment::freeClientData(CheckStatusWrapper* status, bool force) { CHECK_HANDLE(rdb, isc_bad_db_handle); rem_port* port = rdb->rdb_port; - RefMutexGuard portGuard(*port->port_sync, FB_FUNCTION); + RemotePortGuard portGuard(port, FB_FUNCTION); try { @@ -1954,7 +1954,7 @@ void Attachment::dropDatabase(CheckStatusWrapper* status) CHECK_HANDLE(rdb, isc_bad_db_handle); rem_port* port = rdb->rdb_port; - RefMutexGuard portGuard(*port->port_sync, FB_FUNCTION); + RemotePortGuard portGuard(port, FB_FUNCTION); try { @@ -4974,15 +4974,6 @@ void Attachment::putSlice(CheckStatusWrapper* status, ITransaction* apiTra, ISC_ } -namespace { - void portEventsShutdown(rem_port* port) - { - if (port->port_events_thread) - Thread::waitForCompletion(port->port_events_thread); - } -} - - Firebird::IEvents* Attachment::queEvents(CheckStatusWrapper* status, Firebird::IEventCallback* callback, unsigned int length, const unsigned char* events) { @@ -5024,7 +5015,6 @@ Firebird::IEvents* Attachment::queEvents(CheckStatusWrapper* status, Firebird::I Thread::start(event_thread, port->port_async, THREAD_high, &port->port_async->port_events_thread); - port->port_async->port_events_shutdown = portEventsShutdown; port->port_async->port_context = rdb; } @@ -5754,7 +5744,7 @@ void Service::freeClientData(CheckStatusWrapper* status, bool force) CHECK_HANDLE(rdb, isc_bad_svc_handle); rem_port* port = rdb->rdb_port; - RefMutexGuard portGuard(*port->port_sync, FB_FUNCTION); + RemotePortGuard portGuard(port, FB_FUNCTION); try { diff --git a/src/remote/inet.cpp b/src/remote/inet.cpp index f7d0e04b4c..7a421d63b9 100644 --- a/src/remote/inet.cpp +++ b/src/remote/inet.cpp @@ -1695,7 +1695,10 @@ static void disconnect(rem_port* const port) SOCLOSE(port->port_channel); } - port->release(); + if (port->port_thread_guard && port->port_events_thread && !Thread::isCurrent(port->port_events_thread)) + port->port_thread_guard->setWait(port->port_events_thread); + else + port->release(); #ifdef DEBUG if (INET_trace & TRACE_summary) diff --git a/src/remote/remote.cpp b/src/remote/remote.cpp index 9ca6e3da74..97cd913d52 100644 --- a/src/remote/remote.cpp +++ b/src/remote/remote.cpp @@ -1381,11 +1381,6 @@ namespace { rem_port::~rem_port() { - if (port_events_shutdown) - { - port_events_shutdown(this); - } - delete port_srv_auth; delete port_srv_auth_block; delete port_version; diff --git a/src/remote/remote.h b/src/remote/remote.h index 1c18a3a86a..30828b1ee5 100644 --- a/src/remote/remote.h +++ b/src/remote/remote.h @@ -41,6 +41,7 @@ #include "../common/StatusHolder.h" #include "../common/classes/RefCounted.h" #include "../common/classes/GetPlugins.h" +#include "../common/classes/RefMutex.h" #include "firebird/Interface.h" @@ -915,6 +916,9 @@ const USHORT PORT_connecting = 0x0400; // Aux connection waits for a channel to const USHORT PORT_z_data = 0x0800; // Zlib incoming buffer has data left after decompression const USHORT PORT_compressed = 0x1000; // Compress outgoing stream (does not affect incoming) +// forward decl +class RemotePortGuard; + // Port itself typedef rem_port* (*t_port_connect)(rem_port*, PACKET*); @@ -973,7 +977,7 @@ struct rem_port : public Firebird::GlobalStorage, public Firebird::RefCounted struct linger port_linger; // linger value as defined by SO_LINGER Rdb* port_context; Thread::Handle port_events_thread; // handle of thread, handling incoming events - void (*port_events_shutdown)(rem_port*); // hack - avoid changing API at beta stage + RemotePortGuard* port_thread_guard; // will close port_events_thread in safe way #ifdef WIN_NT HANDLE port_pipe; // port pipe handle HANDLE port_event; // event associated with a port @@ -1040,7 +1044,7 @@ public: port_server(0), port_server_flags(0), port_protocol(0), port_buff_size(rpt / 2), port_flags(0), port_connect_timeout(0), port_dummy_packet_interval(0), port_dummy_timeout(0), port_handle(INVALID_SOCKET), port_channel(INVALID_SOCKET), port_context(0), - port_events_thread(0), port_events_shutdown(0), + port_events_thread(0), port_thread_guard(0), #ifdef WIN_NT port_pipe(INVALID_HANDLE_VALUE), port_event(INVALID_HANDLE_VALUE), #endif @@ -1271,6 +1275,84 @@ private: }; +// Port guard is needed to close events delivery thread in safe way +class RemotePortGuard +{ +private: + class WaitThread + { + public: + WaitThread(rem_port* async) + : asyncPort(async), + waitFlag(false) + { } + + ~WaitThread() + { + if (waitFlag) + { + //printf("waitForCompletion %p\n", waitHandle); + Thread::waitForCompletion(waitHandle); + fb_assert(asyncPort); + if (asyncPort) + { + // printf(" release asyncPort %p\n", asyncPort); + asyncPort->release(); + } + //printf(" done\n"); + } + else if (asyncPort) + asyncPort->port_thread_guard = nullptr; + } + + rem_port* asyncPort; + Thread::Handle waitHandle; + bool waitFlag; + }; + +public: + RemotePortGuard(rem_port* port, const char* f) + : wThr(port->port_async), + guard(*port->port_sync, f) + { + if (wThr.asyncPort) + wThr.asyncPort->port_thread_guard = this; + } + + void setWait(Thread::Handle& handle) + { + wThr.waitHandle = handle; + wThr.waitFlag = true; + fb_assert(wThr.asyncPort); + wThr.asyncPort->port_thread_guard = nullptr; + } + +/* ~RemotePortGuard() + { + if (waitFlag) + { + printf("waitForCompletion %p\n", waitHandle); + Thread::waitForCompletion(waitHandle); + } + + if (asyncPort) + { + if (asyncPort->port_thread_guard) + asyncPort->port_thread_guard = nullptr; + else + { + asyncPort->release(); + printf("release asyncPort %p\n", asyncPort); + } + } + } +*/ +private: + WaitThread wThr; + Firebird::RefMutexGuard guard; +}; + + // Queuing structure for Client batch fetches typedef void (*t_rmtque_fn)(rem_port*, rmtque*, USHORT); From 42dd67631d7df71ccfa1a4d2488d93f86c42bc41 Mon Sep 17 00:00:00 2001 From: AlexPeshkoff Date: Thu, 15 Mar 2018 15:59:52 +0300 Subject: [PATCH 066/171] Postfix for CORE-5772 --- src/remote/remote.h | 25 ------------------------- 1 file changed, 25 deletions(-) diff --git a/src/remote/remote.h b/src/remote/remote.h index 30828b1ee5..f6c1ca70a6 100644 --- a/src/remote/remote.h +++ b/src/remote/remote.h @@ -1291,15 +1291,10 @@ private: { if (waitFlag) { - //printf("waitForCompletion %p\n", waitHandle); Thread::waitForCompletion(waitHandle); fb_assert(asyncPort); if (asyncPort) - { - // printf(" release asyncPort %p\n", asyncPort); asyncPort->release(); - } - //printf(" done\n"); } else if (asyncPort) asyncPort->port_thread_guard = nullptr; @@ -1327,26 +1322,6 @@ public: wThr.asyncPort->port_thread_guard = nullptr; } -/* ~RemotePortGuard() - { - if (waitFlag) - { - printf("waitForCompletion %p\n", waitHandle); - Thread::waitForCompletion(waitHandle); - } - - if (asyncPort) - { - if (asyncPort->port_thread_guard) - asyncPort->port_thread_guard = nullptr; - else - { - asyncPort->release(); - printf("release asyncPort %p\n", asyncPort); - } - } - } -*/ private: WaitThread wThr; Firebird::RefMutexGuard guard; From 5006cd038b63438219bd4992b79151c798c36711 Mon Sep 17 00:00:00 2001 From: firebirds <> Date: Fri, 16 Mar 2018 00:04:15 +0000 Subject: [PATCH 067/171] increment build number --- src/jrd/build_no.h | 12 ++++++------ src/misc/writeBuildNum.sh | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/jrd/build_no.h b/src/jrd/build_no.h index b95f6426ce..7c60a3b036 100644 --- a/src/jrd/build_no.h +++ b/src/jrd/build_no.h @@ -3,16 +3,16 @@ *** DO NOT EDIT *** TO CHANGE ANY INFORMATION IN HERE PLEASE EDIT src/misc/writeBuildNum.sh - FORMAL BUILD NUMBER:923 + FORMAL BUILD NUMBER:926 */ -#define PRODUCT_VER_STRING "4.0.0.923" -#define FILE_VER_STRING "WI-T4.0.0.923" -#define LICENSE_VER_STRING "WI-T4.0.0.923" -#define FILE_VER_NUMBER 4, 0, 0, 923 +#define PRODUCT_VER_STRING "4.0.0.926" +#define FILE_VER_STRING "WI-T4.0.0.926" +#define LICENSE_VER_STRING "WI-T4.0.0.926" +#define FILE_VER_NUMBER 4, 0, 0, 926 #define FB_MAJOR_VER "4" #define FB_MINOR_VER "0" #define FB_REV_NO "0" -#define FB_BUILD_NO "923" +#define FB_BUILD_NO "926" #define FB_BUILD_TYPE "T" #define FB_BUILD_SUFFIX "Firebird 4.0 Alpha 1" diff --git a/src/misc/writeBuildNum.sh b/src/misc/writeBuildNum.sh index 0238fbc015..1e5db4b9d4 100755 --- a/src/misc/writeBuildNum.sh +++ b/src/misc/writeBuildNum.sh @@ -9,7 +9,7 @@ BuildType=T MajorVer=4 MinorVer=0 RevNo=0 -BuildNum=923 +BuildNum=926 NowAt=`pwd` cd `dirname $0` From a16249fcfca5148766fcef99f5e298f5c38bb90c Mon Sep 17 00:00:00 2001 From: hvlad Date: Fri, 16 Mar 2018 15:16:07 +0200 Subject: [PATCH 068/171] Fixed bug CORE-405 : Garbage vs indices/constraints --- src/jrd/idx.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/jrd/idx.cpp b/src/jrd/idx.cpp index f95fedfb0b..7775a252b2 100644 --- a/src/jrd/idx.cpp +++ b/src/jrd/idx.cpp @@ -367,7 +367,9 @@ void IDX_create_index(thread_db* tdbb, if (!VIO_garbage_collect(tdbb, &primary, transaction)) continue; - if (primary.rpb_flags & rpb_deleted) + const bool deleted = primary.rpb_flags & rpb_deleted; + + if (deleted) CCH_RELEASE(tdbb, &primary.getWindow(tdbb)); else { @@ -484,7 +486,7 @@ void IDX_create_index(thread_db* tdbb, index_sort_record* isr = (index_sort_record*) p; isr->isr_record_number = primary.rpb_number.getValue(); isr->isr_key_length = key.key_length; - isr->isr_flags = (stack.hasData() ? ISR_secondary : 0) | (key_is_null ? ISR_null : 0); + isr->isr_flags = ((stack.hasData() || deleted) ? ISR_secondary : 0) | (key_is_null ? ISR_null : 0); if (record != gc_record) delete record; } From 15d37fc989a8bd92bcdf51c390159ac2ad0ee619 Mon Sep 17 00:00:00 2001 From: firebirds <> Date: Sat, 17 Mar 2018 00:03:59 +0000 Subject: [PATCH 069/171] increment build number --- src/jrd/build_no.h | 12 ++++++------ src/misc/writeBuildNum.sh | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/jrd/build_no.h b/src/jrd/build_no.h index 7c60a3b036..0594197d50 100644 --- a/src/jrd/build_no.h +++ b/src/jrd/build_no.h @@ -3,16 +3,16 @@ *** DO NOT EDIT *** TO CHANGE ANY INFORMATION IN HERE PLEASE EDIT src/misc/writeBuildNum.sh - FORMAL BUILD NUMBER:926 + FORMAL BUILD NUMBER:927 */ -#define PRODUCT_VER_STRING "4.0.0.926" -#define FILE_VER_STRING "WI-T4.0.0.926" -#define LICENSE_VER_STRING "WI-T4.0.0.926" -#define FILE_VER_NUMBER 4, 0, 0, 926 +#define PRODUCT_VER_STRING "4.0.0.927" +#define FILE_VER_STRING "WI-T4.0.0.927" +#define LICENSE_VER_STRING "WI-T4.0.0.927" +#define FILE_VER_NUMBER 4, 0, 0, 927 #define FB_MAJOR_VER "4" #define FB_MINOR_VER "0" #define FB_REV_NO "0" -#define FB_BUILD_NO "926" +#define FB_BUILD_NO "927" #define FB_BUILD_TYPE "T" #define FB_BUILD_SUFFIX "Firebird 4.0 Alpha 1" diff --git a/src/misc/writeBuildNum.sh b/src/misc/writeBuildNum.sh index 1e5db4b9d4..3416325d63 100755 --- a/src/misc/writeBuildNum.sh +++ b/src/misc/writeBuildNum.sh @@ -9,7 +9,7 @@ BuildType=T MajorVer=4 MinorVer=0 RevNo=0 -BuildNum=926 +BuildNum=927 NowAt=`pwd` cd `dirname $0` From ccfea1c1928ddb24a5a60ad6c77869081be5f62f Mon Sep 17 00:00:00 2001 From: hvlad Date: Sun, 18 Mar 2018 15:47:01 +0200 Subject: [PATCH 070/171] Avoid GetThreadId() which is not present in WinXP (see CORE-5772) --- src/common/ThreadStart.cpp | 20 ++++++++++++-------- src/common/ThreadStart.h | 4 ++-- src/remote/client/interface.cpp | 7 ++++--- src/remote/inet.cpp | 2 +- src/remote/remote.h | 3 ++- 5 files changed, 21 insertions(+), 15 deletions(-) diff --git a/src/common/ThreadStart.cpp b/src/common/ThreadStart.cpp index 3a1e4545cc..7997325e17 100644 --- a/src/common/ThreadStart.cpp +++ b/src/common/ThreadStart.cpp @@ -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,7 @@ void Thread::start(ThreadEntryPoint* routine, void* arg, int priority_arg, Handl #endif *p_handle = thread; } + return getId(); } void Thread::waitForCompletion(Handle& thread) @@ -208,9 +209,9 @@ ThreadId Thread::getId() #endif } -bool Thread::isCurrent(Handle& thread) +bool Thread::isCurrent(const ThreadId threadId) { - return pthread_self() == thread; + return getId() == threadId; } void Thread::sleep(unsigned milliseconds) @@ -257,7 +258,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) { /************************************** * @@ -321,6 +322,8 @@ void Thread::start(ThreadEntryPoint* routine, void* arg, int priority_arg, Handl { CloseHandle(handle); } + + return thread_id; } void Thread::waitForCompletion(Handle& handle) @@ -347,9 +350,9 @@ ThreadId Thread::getId() return GetCurrentThreadId(); } -bool Thread::isCurrent(Handle& thread) +bool Thread::isCurrent(const ThreadId threadId) { - return GetCurrentThreadId() == GetThreadId(thread); + return GetCurrentThreadId() == threadId; } void Thread::sleep(unsigned milliseconds) @@ -366,7 +369,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) { /************************************** * @@ -378,7 +381,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&) diff --git a/src/common/ThreadStart.h b/src/common/ThreadStart.h index 3fde12a7bd..231e5eb380 100644 --- a/src/common/ThreadStart.h +++ b/src/common/ThreadStart.h @@ -75,10 +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(Handle& handle); + static bool isCurrent(const ThreadId threadId); static ThreadId getId(); diff --git a/src/remote/client/interface.cpp b/src/remote/client/interface.cpp index ddc22d0961..581c3b1bd9 100644 --- a/src/remote/client/interface.cpp +++ b/src/remote/client/interface.cpp @@ -5013,10 +5013,11 @@ Firebird::IEvents* Attachment::queEvents(CheckStatusWrapper* status, Firebird::I receive_response(status, rdb, packet); port->connect(packet); - Thread::start(event_thread, port->port_async, THREAD_high, - &port->port_async->port_events_thread); + rem_port* port_async = port->port_async; + port_async->port_events_threadId = + Thread::start(event_thread, port_async, THREAD_high, &port_async->port_events_thread); - port->port_async->port_context = rdb; + port_async->port_context = rdb; } // Add event block to port's list of active remote events diff --git a/src/remote/inet.cpp b/src/remote/inet.cpp index 7a421d63b9..d895049a23 100644 --- a/src/remote/inet.cpp +++ b/src/remote/inet.cpp @@ -1695,7 +1695,7 @@ static void disconnect(rem_port* const port) SOCLOSE(port->port_channel); } - if (port->port_thread_guard && port->port_events_thread && !Thread::isCurrent(port->port_events_thread)) + if (port->port_thread_guard && port->port_events_thread && !Thread::isCurrent(port->port_events_threadId)) port->port_thread_guard->setWait(port->port_events_thread); else port->release(); diff --git a/src/remote/remote.h b/src/remote/remote.h index f6c1ca70a6..ea0d900e11 100644 --- a/src/remote/remote.h +++ b/src/remote/remote.h @@ -977,6 +977,7 @@ struct rem_port : public Firebird::GlobalStorage, public Firebird::RefCounted struct linger port_linger; // linger value as defined by SO_LINGER Rdb* port_context; Thread::Handle port_events_thread; // handle of thread, handling incoming events + ThreadId port_events_threadId; RemotePortGuard* port_thread_guard; // will close port_events_thread in safe way #ifdef WIN_NT HANDLE port_pipe; // port pipe handle @@ -1044,7 +1045,7 @@ public: port_server(0), port_server_flags(0), port_protocol(0), port_buff_size(rpt / 2), port_flags(0), port_connect_timeout(0), port_dummy_packet_interval(0), port_dummy_timeout(0), port_handle(INVALID_SOCKET), port_channel(INVALID_SOCKET), port_context(0), - port_events_thread(0), port_thread_guard(0), + port_events_thread(0), port_events_threadId(0), port_thread_guard(0), #ifdef WIN_NT port_pipe(INVALID_HANDLE_VALUE), port_event(INVALID_HANDLE_VALUE), #endif From 9422df896c440f69252bf5e33acc945d38fcde33 Mon Sep 17 00:00:00 2001 From: hvlad Date: Mon, 19 Mar 2018 15:58:02 +0200 Subject: [PATCH 071/171] Fix thread priority for attachmentShutdownThread (it was run at lowest priority) --- src/jrd/jrd.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/jrd/jrd.cpp b/src/jrd/jrd.cpp index 27d335ba12..3b3b80f54f 100644 --- a/src/jrd/jrd.cpp +++ b/src/jrd/jrd.cpp @@ -8760,7 +8760,7 @@ void JRD_shutdown_attachment(Attachment* attachment) attachment->getStable()->addRef(); queue->add(attachment->getStable()); - Thread::start(attachmentShutdownThread, queue, 0); + Thread::start(attachmentShutdownThread, queue, THREAD_high); } catch (const Exception&) {} // no-op @@ -8805,7 +8805,7 @@ void JRD_shutdown_attachments(Database* dbb) } if (queue.hasData()) - Thread::start(attachmentShutdownThread, queue.release(), 0); + Thread::start(attachmentShutdownThread, queue.release(), THREAD_high); } catch (const Exception&) {} // no-op From e5ec4f534b2289676c55ce47ec4ab110997549e1 Mon Sep 17 00:00:00 2001 From: AlexPeshkoff Date: Mon, 19 Mar 2018 18:17:22 +0300 Subject: [PATCH 072/171] Fixed CORE-5780: Server hangs when client tries to send too long DB encryption key(s) --- src/remote/server/server.cpp | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/src/remote/server/server.cpp b/src/remote/server/server.cpp index 089127cf96..ad300c9764 100644 --- a/src/remote/server/server.cpp +++ b/src/remote/server/server.cpp @@ -145,9 +145,15 @@ public: { if (replyLength > wakeLength) replyLength = wakeLength; - memcpy(replyData, wakeData, replyLength); - wake = true; + if (wakeData) + { + memcpy(replyData, wakeData, replyLength); + wake = true; + } + else + stop(); + sem.release(); } @@ -198,7 +204,7 @@ public: loadClientKey(); unsigned rc = keyCallback ? keyCallback->callback(dataLength, data, bufferLength, buffer) : - // use legacy behavior if holders to do wish to accept keys from client + // use legacy behavior if holders do wish to accept keys from client networkCallback.callback(dataLength, data, bufferLength, buffer); return rc; @@ -6393,7 +6399,8 @@ SSHORT rem_port::asyncReceive(PACKET* asyncPacket, const UCHAR* buffer, SSHORT d return 0; } - switch (xdr_peek_long(&port_async_receive->port_receive, buffer, dataSize)) + SLONG original_op = xdr_peek_long(&port_async_receive->port_receive, buffer, dataSize); + switch (original_op) { case op_cancel: case op_abort_aux_connection: @@ -6427,14 +6434,16 @@ SSHORT rem_port::asyncReceive(PACKET* asyncPacket, const UCHAR* buffer, SSHORT d break; case op_abort_aux_connection: if (port_async && (port_async->port_flags & PORT_connecting)) - { port_async->abort_aux_connection(); - } break; case op_crypt_key_callback: port_server_crypt_callback->wakeup(asyncPacket->p_cc.p_cc_data.cstr_length, asyncPacket->p_cc.p_cc_data.cstr_address); break; + case op_partial: + if (original_op == op_crypt_key_callback) + port_server_crypt_callback->wakeup(0, NULL); + break; default: fb_assert(false); return 0; From 17ced5071fb13ec992be9d8152029ce05f4e7680 Mon Sep 17 00:00:00 2001 From: firebirds <> Date: Tue, 20 Mar 2018 00:04:23 +0000 Subject: [PATCH 073/171] increment build number --- src/jrd/build_no.h | 12 ++++++------ src/misc/writeBuildNum.sh | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/jrd/build_no.h b/src/jrd/build_no.h index 0594197d50..63d2830871 100644 --- a/src/jrd/build_no.h +++ b/src/jrd/build_no.h @@ -3,16 +3,16 @@ *** DO NOT EDIT *** TO CHANGE ANY INFORMATION IN HERE PLEASE EDIT src/misc/writeBuildNum.sh - FORMAL BUILD NUMBER:927 + FORMAL BUILD NUMBER:930 */ -#define PRODUCT_VER_STRING "4.0.0.927" -#define FILE_VER_STRING "WI-T4.0.0.927" -#define LICENSE_VER_STRING "WI-T4.0.0.927" -#define FILE_VER_NUMBER 4, 0, 0, 927 +#define PRODUCT_VER_STRING "4.0.0.930" +#define FILE_VER_STRING "WI-T4.0.0.930" +#define LICENSE_VER_STRING "WI-T4.0.0.930" +#define FILE_VER_NUMBER 4, 0, 0, 930 #define FB_MAJOR_VER "4" #define FB_MINOR_VER "0" #define FB_REV_NO "0" -#define FB_BUILD_NO "927" +#define FB_BUILD_NO "930" #define FB_BUILD_TYPE "T" #define FB_BUILD_SUFFIX "Firebird 4.0 Alpha 1" diff --git a/src/misc/writeBuildNum.sh b/src/misc/writeBuildNum.sh index 3416325d63..f41850e52b 100755 --- a/src/misc/writeBuildNum.sh +++ b/src/misc/writeBuildNum.sh @@ -9,7 +9,7 @@ BuildType=T MajorVer=4 MinorVer=0 RevNo=0 -BuildNum=927 +BuildNum=930 NowAt=`pwd` cd `dirname $0` From 690b0576bfb697f565828599c19588a95e3c8996 Mon Sep 17 00:00:00 2001 From: hvlad Date: Tue, 20 Mar 2018 09:11:15 +0200 Subject: [PATCH 074/171] Fixed bug CORE-5773 : PSQL cursor doesn't see inserted record --- src/dsql/StmtNodes.cpp | 9 ++++++++- src/jrd/JrdStatement.cpp | 3 +++ src/jrd/exe.h | 1 + src/jrd/req.h | 1 + src/jrd/vio.cpp | 3 +++ 5 files changed, 16 insertions(+), 1 deletion(-) diff --git a/src/dsql/StmtNodes.cpp b/src/dsql/StmtNodes.cpp index e26d67028a..5d0632422a 100644 --- a/src/dsql/StmtNodes.cpp +++ b/src/dsql/StmtNodes.cpp @@ -1241,10 +1241,14 @@ const StmtNode* CursorStmtNode::execute(thread_db* tdbb, jrd_req* request, ExeSt static RegisterNode 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 . 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; diff --git a/src/jrd/JrdStatement.cpp b/src/jrd/JrdStatement.cpp index dd5ce229fc..cf702e7632 100644 --- a/src/jrd/JrdStatement.cpp +++ b/src/jrd/JrdStatement.cpp @@ -162,6 +162,9 @@ JrdStatement::JrdStatement(thread_db* tdbb, MemoryPool* p, CompilerScratch* csb) if (!tail->csb_fields && !(tail->csb_flags & csb_update)) rpb->rpb_stream_flags |= RPB_s_no_data; + if (tail->csb_flags & csb_unstable) + rpb->rpb_stream_flags |= RPB_s_unstable; + rpb->rpb_relation = tail->csb_relation; delete tail->csb_fields; diff --git a/src/jrd/exe.h b/src/jrd/exe.h index 206dd70b53..4d9bcdf7a3 100644 --- a/src/jrd/exe.h +++ b/src/jrd/exe.h @@ -619,6 +619,7 @@ const int csb_sub_stream = 128; // a sub-stream of the RSE being processed const int csb_erase = 256; // we are processing an erase const int csb_unmatched = 512; // stream has conjuncts unmatched by any index const int csb_update = 1024; // erase or modify for relation +const int csb_unstable = 2048; // unstable explicit cursor inline void CompilerScratch::csb_repeat::activate() { diff --git a/src/jrd/req.h b/src/jrd/req.h index 9678bfa55d..23c9fe2124 100644 --- a/src/jrd/req.h +++ b/src/jrd/req.h @@ -123,6 +123,7 @@ const USHORT rpb_long_tranum = 1024; // transaction number is 64-bit const USHORT RPB_s_update = 0x01; // input stream fetched for update const USHORT RPB_s_no_data = 0x02; // nobody is going to access the data const USHORT RPB_s_sweeper = 0x04; // garbage collector - skip swept pages +const USHORT RPB_s_unstable = 0x08; // don't use undo log, used with unstable explicit cursors // Runtime flags diff --git a/src/jrd/vio.cpp b/src/jrd/vio.cpp index 1528172406..2d8ff88150 100644 --- a/src/jrd/vio.cpp +++ b/src/jrd/vio.cpp @@ -724,6 +724,9 @@ bool VIO_chase_record_version(thread_db* tdbb, record_param* rpb, rpb->rpb_runtime_flags &= ~RPB_UNDO_FLAGS; int forceBack = 0; + if (rpb->rpb_stream_flags & RPB_s_unstable) + noundo = true; + if (state == tra_us && !noundo && !(transaction->tra_flags & TRA_system)) { switch (get_undo_data(tdbb, transaction, rpb, pool)) From a27f4b8a5f66430ee01b6ad1e8dd065b93764fdf Mon Sep 17 00:00:00 2001 From: AlexPeshkoff Date: Tue, 20 Mar 2018 18:37:38 +0300 Subject: [PATCH 075/171] Fixed CORE-5778: install.sh fails if -path argument contains "firebird" --- builds/install/posix-common/posixLibrary.sh.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/builds/install/posix-common/posixLibrary.sh.in b/builds/install/posix-common/posixLibrary.sh.in index 270c0659a6..3ad7efa2a2 100644 --- a/builds/install/posix-common/posixLibrary.sh.in +++ b/builds/install/posix-common/posixLibrary.sh.in @@ -239,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' } From f89ca3cfbeaff0cebaac93f261d15b595310325c Mon Sep 17 00:00:00 2001 From: AlexPeshkoff Date: Tue, 20 Mar 2018 19:55:08 +0300 Subject: [PATCH 076/171] Syntax --- src/msgs/messages2.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/msgs/messages2.sql b/src/msgs/messages2.sql index 9c54081a41..595ed870d4 100644 --- a/src/msgs/messages2.sql +++ b/src/msgs/messages2.sql @@ -896,7 +896,7 @@ Data source : @4', NULL, NULL) ('login_error', NULL, 'server.cpp', NULL, 0, 786, NULL, 'Error occurred during login, please check server firebird.log for details', NULL, NULL); ('already_opened', 'lockDatabaseFile', 'unix.cpp', NULL, 0, 787, NULL, 'Database already opened with engine instance, incompatible with current', NULL, NULL); ('bad_crypt_key', NULL, 'CryptoManager.cpp', NULL, 0, 788, NULL, 'Invalid crypt key @1', NULL, NULL); -('encrypt_error', NULL, 'CryptoManager.cpp', NULL, 0, 789, NULL, 'Page requires encyption but crypt plugin is missing', NULL, NULL); +('encrypt_error', NULL, 'CryptoManager.cpp', NULL, 0, 789, NULL, 'Page requires encryption but crypt plugin is missing', NULL, NULL); ('max_idx_depth', NULL, 'btr.cpp', NULL, 0, 790, NULL, 'Maximum index depth (@1 levels) is reached', NULL, NULL); ('wrong_prvlg', 'SCL_convert_privilege', 'scl.epp', NULL, 0, 791, NULL, 'System privilege @1 does not exist', NULL, NULL); ('miss_prvlg', 'validateAccess', 'jrd.cpp', NULL, 0, 792, NULL, 'System privilege @1 is missing', NULL, NULL); From 1dc40bee495f9939d7a0ef857cd594211d38405f Mon Sep 17 00:00:00 2001 From: firebirds <> Date: Wed, 21 Mar 2018 00:04:32 +0000 Subject: [PATCH 077/171] increment build number --- src/jrd/build_no.h | 12 ++++++------ src/misc/writeBuildNum.sh | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/jrd/build_no.h b/src/jrd/build_no.h index 63d2830871..2b0d573f5a 100644 --- a/src/jrd/build_no.h +++ b/src/jrd/build_no.h @@ -3,16 +3,16 @@ *** DO NOT EDIT *** TO CHANGE ANY INFORMATION IN HERE PLEASE EDIT src/misc/writeBuildNum.sh - FORMAL BUILD NUMBER:930 + FORMAL BUILD NUMBER:933 */ -#define PRODUCT_VER_STRING "4.0.0.930" -#define FILE_VER_STRING "WI-T4.0.0.930" -#define LICENSE_VER_STRING "WI-T4.0.0.930" -#define FILE_VER_NUMBER 4, 0, 0, 930 +#define PRODUCT_VER_STRING "4.0.0.933" +#define FILE_VER_STRING "WI-T4.0.0.933" +#define LICENSE_VER_STRING "WI-T4.0.0.933" +#define FILE_VER_NUMBER 4, 0, 0, 933 #define FB_MAJOR_VER "4" #define FB_MINOR_VER "0" #define FB_REV_NO "0" -#define FB_BUILD_NO "930" +#define FB_BUILD_NO "933" #define FB_BUILD_TYPE "T" #define FB_BUILD_SUFFIX "Firebird 4.0 Alpha 1" diff --git a/src/misc/writeBuildNum.sh b/src/misc/writeBuildNum.sh index f41850e52b..71ad5edc57 100755 --- a/src/misc/writeBuildNum.sh +++ b/src/misc/writeBuildNum.sh @@ -9,7 +9,7 @@ BuildType=T MajorVer=4 MinorVer=0 RevNo=0 -BuildNum=930 +BuildNum=933 NowAt=`pwd` cd `dirname $0` From 21b42b2e8f9e8af3b299ab8cfaf2fde09dc6acc2 Mon Sep 17 00:00:00 2001 From: Artyom Smirnov Date: Wed, 21 Mar 2018 14:47:20 +0300 Subject: [PATCH 078/171] Allow to redirect server's stdout and stderr to file (#143) Before these changes guardian and server binary closed stdin/stdout/stderr/... and server can reuse those descriptors when opening files or using shmem for example. So some stray stdout can introduce unwanted data or even crash server. Server do not emit any stdout/stderr in release build but UDRs or external libraries can print to stdout. After these changes stdout/stderr will be kept opened and user have options to redirect it to /dev/null (by default) or other file by choise or just allow server to print. New config option OutputRedirectionFile was introduced to allow user control server behavior. --- builds/install/misc/firebird.conf.in | 11 ++++++++ src/common/config/config.cpp | 16 +++++++++++- src/common/config/config.h | 3 +++ src/remote/server/os/posix/inet_server.cpp | 30 +++++++++++++++++++++- src/utilities/guard/guard.cpp | 7 ++++- 5 files changed, 64 insertions(+), 3 deletions(-) diff --git a/builds/install/misc/firebird.conf.in b/builds/install/misc/firebird.conf.in index 6230564e6b..8d47540609 100644 --- a/builds/install/misc/firebird.conf.in +++ b/builds/install/misc/firebird.conf.in @@ -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 diff --git a/src/common/config/config.cpp b/src/common/config/config.cpp index e970f4dfe3..6aa616ba67 100644 --- a/src/common/config/config.cpp +++ b/src/common/config/config.cpp @@ -202,7 +202,16 @@ const Config::ConfigEntry Config::entries[MAX_CONFIG_KEY] = {TYPE_BOOLEAN, "AllowEncryptedSecurityDatabase", (ConfigValue) false}, {TYPE_INTEGER, "StatementTimeout", (ConfigValue) 0}, {TYPE_INTEGER, "ConnectionIdleTimeout", (ConfigValue) 0}, - {TYPE_INTEGER, "ClientBatchBuffer", (ConfigValue) (128 * 1024)} + {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 }; /****************************************************************************** @@ -839,3 +848,8 @@ unsigned int Config::getClientBatchBuffer() const return get(KEY_CLIENT_BATCH_BUFFER); } +const char* Config::getOutputRedirectionFile() +{ + const char* file = (const char*) (getDefaultConfig()->values[KEY_OUTPUT_REDIRECTION_FILE]); + return file; +} diff --git a/src/common/config/config.h b/src/common/config/config.h index 9fecce5e65..589358b63d 100644 --- a/src/common/config/config.h +++ b/src/common/config/config.h @@ -146,6 +146,7 @@ public: KEY_STMT_TIMEOUT, KEY_CONN_IDLE_TIMEOUT, KEY_CLIENT_BATCH_BUFFER, + KEY_OUTPUT_REDIRECTION_FILE, MAX_CONFIG_KEY // keep it last }; @@ -362,6 +363,8 @@ public: unsigned int getConnIdleTimeout() const; unsigned int getClientBatchBuffer() const; + + static const char* getOutputRedirectionFile(); }; // Implementation of interface to access master configuration file diff --git a/src/remote/server/os/posix/inet_server.cpp b/src/remote/server/os/posix/inet_server.cpp index 56f6a1ff9b..6aea08b6eb 100644 --- a/src/remote/server/os/posix/inet_server.cpp +++ b/src/remote/server/os/posix/inet_server.cpp @@ -345,8 +345,10 @@ int CLIB_ROUTINE main( int argc, char** argv) if (!(debug || classic)) { + //Keep stdout and stderr openened always. We decide allow output + //from binary or redirect it according to config int mask = 0; // FD_ZERO(&mask); - mask |= 1 << 2; // FD_SET(2, &mask); + mask |= (1 << 1 | 1 << 2); // FD_SET(1, &mask); FD_SET(2, &mask); divorce_terminal(mask); } @@ -357,6 +359,32 @@ int CLIB_ROUTINE main( int argc, char** argv) exit(STARTUP_ERROR); } + if (!debug) + { + const char* redirection_file = Config::getOutputRedirectionFile(); + if (redirection_file && strcmp(redirection_file, "-") != 0) + { + int f = open(redirection_file, O_CREAT|O_APPEND|O_WRONLY, 0644); + if (f >= 0) + { + int stdout_no = fileno(stdout); + int stderr_no = fileno(stderr); + + if (f != stdout_no) + dup2(f, stdout_no); + if (f != stderr_no) + dup2(f, stderr_no); + + if (f != stdout_no && f != stderr_no) + close(f); + } + else + { + gds__log("Unable to open file %s for output redirection", redirection_file); + } + } + } + if (super || standaloneClassic) { try diff --git a/src/utilities/guard/guard.cpp b/src/utilities/guard/guard.cpp index 67cf895017..cb78fdbb42 100644 --- a/src/utilities/guard/guard.cpp +++ b/src/utilities/guard/guard.cpp @@ -167,7 +167,12 @@ int CLIB_ROUTINE main( int argc, char **argv) if (daemon && fork()) { exit(0); } - divorce_terminal(0); + + //Keep stdout and stderr opened and let server emit output + //or redirect stdout/stderr to /dev/null or file by user choice + int mask = 0; // FD_ZERO(&mask); + mask |= (1 << 1 | 1 << 2); // FD_SET(1, &mask); FD_SET(2, &mask); + divorce_terminal(mask); time_t timer = 0; From 1e8e7858db84750a77006d307bf28e9686f9414e Mon Sep 17 00:00:00 2001 From: AlexPeshkoff Date: Wed, 21 Mar 2018 15:19:20 +0300 Subject: [PATCH 079/171] Patch for CORE-5779: support for riscv64, also some code fixes related with prior ports --- configure.ac | 12 ++++++++++ src/common/classes/DbImplementation.cpp | 29 ++++++++++++++----------- src/common/common.h | 4 ++++ src/include/gen/msgs.h | 2 +- src/jrd/inf_pub.h | 2 +- 5 files changed, 34 insertions(+), 15 deletions(-) diff --git a/configure.ac b/configure.ac index ee114415b6..235dc373d4 100644 --- a/configure.ac +++ b/configure.ac @@ -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 diff --git a/src/common/classes/DbImplementation.cpp b/src/common/classes/DbImplementation.cpp index f948bddbc3..95b1e33299 100644 --- a/src/common/classes/DbImplementation.cpp +++ b/src/common/classes/DbImplementation.cpp @@ -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 diff --git a/src/common/common.h b/src/common/common.h index 9f2c8c067f..7d67bf5845 100644 --- a/src/common/common.h +++ b/src/common/common.h @@ -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 diff --git a/src/include/gen/msgs.h b/src/include/gen/msgs.h index 001cceacb9..eef9a446f5 100644 --- a/src/include/gen/msgs.h +++ b/src/include/gen/msgs.h @@ -813,7 +813,7 @@ Data source : @4"}, /* eds_statement */ {335545106, "Error occurred during login, please check server firebird.log for details"}, /* login_error */ {335545107, "Database already opened with engine instance, incompatible with current"}, /* already_opened */ {335545108, "Invalid crypt key @1"}, /* bad_crypt_key */ - {335545109, "Page requires encyption but crypt plugin is missing"}, /* encrypt_error */ + {335545109, "Page requires encryption but crypt plugin is missing"}, /* encrypt_error */ {335545110, "Maximum index depth (@1 levels) is reached"}, /* max_idx_depth */ {335545111, "System privilege @1 does not exist"}, /* wrong_prvlg */ {335545112, "System privilege @1 is missing"}, /* miss_prvlg */ diff --git a/src/jrd/inf_pub.h b/src/jrd/inf_pub.h index a3513f98be..df61e9c498 100644 --- a/src/jrd/inf_pub.h +++ b/src/jrd/inf_pub.h @@ -256,7 +256,7 @@ enum info_db_implementations isc_info_db_impl_linux_ppc64el = 85, isc_info_db_impl_linux_ppc64 = 86, isc_info_db_impl_linux_m68k = 87, - + isc_info_db_impl_linux_riscv64 = 88, isc_info_db_impl_last_value // Leave this LAST! }; From 63f4e450eb6eedc8430b800bae5e0c92cfb7b068 Mon Sep 17 00:00:00 2001 From: AlexPeshkoff Date: Wed, 21 Mar 2018 20:05:29 +0300 Subject: [PATCH 080/171] An attempt to fix CORE-5764, need feedback on snapshot build --- src/common/unicode_util.cpp | 72 +++++++++++++++++-------------------- 1 file changed, 33 insertions(+), 39 deletions(-) diff --git a/src/common/unicode_util.cpp b/src/common/unicode_util.cpp index e82e720d8a..c6ef8bea2d 100644 --- a/src/common/unicode_util.cpp +++ b/src/common/unicode_util.cpp @@ -50,9 +50,6 @@ # include #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 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); 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); 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); From 40ab6c5db09a7038ecc12c8e089e60855799e1a7 Mon Sep 17 00:00:00 2001 From: firebirds <> Date: Thu, 22 Mar 2018 00:04:13 +0000 Subject: [PATCH 081/171] increment build number --- src/jrd/build_no.h | 12 ++++++------ src/misc/writeBuildNum.sh | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/jrd/build_no.h b/src/jrd/build_no.h index 2b0d573f5a..d8fedd6c5e 100644 --- a/src/jrd/build_no.h +++ b/src/jrd/build_no.h @@ -3,16 +3,16 @@ *** DO NOT EDIT *** TO CHANGE ANY INFORMATION IN HERE PLEASE EDIT src/misc/writeBuildNum.sh - FORMAL BUILD NUMBER:933 + FORMAL BUILD NUMBER:936 */ -#define PRODUCT_VER_STRING "4.0.0.933" -#define FILE_VER_STRING "WI-T4.0.0.933" -#define LICENSE_VER_STRING "WI-T4.0.0.933" -#define FILE_VER_NUMBER 4, 0, 0, 933 +#define PRODUCT_VER_STRING "4.0.0.936" +#define FILE_VER_STRING "WI-T4.0.0.936" +#define LICENSE_VER_STRING "WI-T4.0.0.936" +#define FILE_VER_NUMBER 4, 0, 0, 936 #define FB_MAJOR_VER "4" #define FB_MINOR_VER "0" #define FB_REV_NO "0" -#define FB_BUILD_NO "933" +#define FB_BUILD_NO "936" #define FB_BUILD_TYPE "T" #define FB_BUILD_SUFFIX "Firebird 4.0 Alpha 1" diff --git a/src/misc/writeBuildNum.sh b/src/misc/writeBuildNum.sh index 71ad5edc57..3ca7c49f7e 100755 --- a/src/misc/writeBuildNum.sh +++ b/src/misc/writeBuildNum.sh @@ -9,7 +9,7 @@ BuildType=T MajorVer=4 MinorVer=0 RevNo=0 -BuildNum=933 +BuildNum=936 NowAt=`pwd` cd `dirname $0` From 885f2e4457362800ca62551122c0060ce25e152f Mon Sep 17 00:00:00 2001 From: AlexPeshkoff Date: Thu, 22 Mar 2018 12:29:38 +0300 Subject: [PATCH 082/171] Fixed a code somewhy accepted by gcc6 --- src/common/unicode_util.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/common/unicode_util.cpp b/src/common/unicode_util.cpp index c6ef8bea2d..b1605491ea 100644 --- a/src/common/unicode_util.cpp +++ b/src/common/unicode_util.cpp @@ -999,7 +999,7 @@ UnicodeUtil::ICU* UnicodeUtil::loadICU(const string& icuVersion, const string& c icu->ucModule = formatAndLoad(ucTemplate, majorVersion, minorVersion); if (!icu->ucModule) { - gds__log("failed to load UC icu module version %s", configVersion); + gds__log("failed to load UC icu module version %s", configVersion.c_str()); delete icu; continue; } @@ -1007,7 +1007,7 @@ UnicodeUtil::ICU* UnicodeUtil::loadICU(const string& icuVersion, const string& c icu->inModule = formatAndLoad(inTemplate, majorVersion, minorVersion); if (!icu->inModule) { - gds__log("failed to load IN icu module version %s", configVersion); + gds__log("failed to load IN icu module version %s", configVersion.c_str()); delete icu; continue; } From 3bdee64445d2b84ae5a7d5074427ae6941c52036 Mon Sep 17 00:00:00 2001 From: paulbeach Date: Fri, 30 Jun 2017 13:16:21 +0200 Subject: [PATCH 083/171] Add inet6 protocol support for MacOS --- src/remote/SockAddr.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/remote/SockAddr.h b/src/remote/SockAddr.h index 996cc1ec47..22066a8c8f 100644 --- a/src/remote/SockAddr.h +++ b/src/remote/SockAddr.h @@ -85,11 +85,12 @@ public: void unmapV4(); }; -// Definitions below taken from sources at correspondent operating systems. +// Definitions below taken from sources (socket.h) on the correspondent operating systems. // If something else arrives, it should be added here and into checkAndFixFamily() also. #define AF_INET6_POSIX 10 #define AF_INET6_WINDOWS 23 +#define AF_INET6_DARWIN 30 inline void SockAddr::checkAndFixFamily() { @@ -97,6 +98,8 @@ inline void SockAddr::checkAndFixFamily() if (data.sock.sa_family == AF_INET6_WINDOWS) #elif AF_INET6 == AF_INET6_WINDOWS if (data.sock.sa_family == AF_INET6_POSIX) +#elif AF_INET6 == AF_INET6_DARWIN + if (data.sock.sa_family == AF_INET6_DARWIN) #else #error Unknown value of AF_INET6 ! #endif From 3b65d2d9a99f2236d364df5692a66e8374c71029 Mon Sep 17 00:00:00 2001 From: firebirds <> Date: Fri, 23 Mar 2018 00:04:09 +0000 Subject: [PATCH 084/171] increment build number --- src/jrd/build_no.h | 12 ++++++------ src/misc/writeBuildNum.sh | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/jrd/build_no.h b/src/jrd/build_no.h index d8fedd6c5e..fa1b12ef80 100644 --- a/src/jrd/build_no.h +++ b/src/jrd/build_no.h @@ -3,16 +3,16 @@ *** DO NOT EDIT *** TO CHANGE ANY INFORMATION IN HERE PLEASE EDIT src/misc/writeBuildNum.sh - FORMAL BUILD NUMBER:936 + FORMAL BUILD NUMBER:938 */ -#define PRODUCT_VER_STRING "4.0.0.936" -#define FILE_VER_STRING "WI-T4.0.0.936" -#define LICENSE_VER_STRING "WI-T4.0.0.936" -#define FILE_VER_NUMBER 4, 0, 0, 936 +#define PRODUCT_VER_STRING "4.0.0.938" +#define FILE_VER_STRING "WI-T4.0.0.938" +#define LICENSE_VER_STRING "WI-T4.0.0.938" +#define FILE_VER_NUMBER 4, 0, 0, 938 #define FB_MAJOR_VER "4" #define FB_MINOR_VER "0" #define FB_REV_NO "0" -#define FB_BUILD_NO "936" +#define FB_BUILD_NO "938" #define FB_BUILD_TYPE "T" #define FB_BUILD_SUFFIX "Firebird 4.0 Alpha 1" diff --git a/src/misc/writeBuildNum.sh b/src/misc/writeBuildNum.sh index 3ca7c49f7e..5ffcd186a3 100755 --- a/src/misc/writeBuildNum.sh +++ b/src/misc/writeBuildNum.sh @@ -9,7 +9,7 @@ BuildType=T MajorVer=4 MinorVer=0 RevNo=0 -BuildNum=936 +BuildNum=938 NowAt=`pwd` cd `dirname $0` From d0d92de6b2a0ef515712c1060c53d96f2987dfbd Mon Sep 17 00:00:00 2001 From: AlexPeshkoff Date: Fri, 23 Mar 2018 20:10:14 +0300 Subject: [PATCH 085/171] Fixed CORE-5699: DECFLOAT should not through exceptions when +/-NaN, +/-sNaN and +/-Infinity is used in comparisons --- src/common/DecFloat.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/common/DecFloat.cpp b/src/common/DecFloat.cpp index ead909827b..0e5292bed8 100644 --- a/src/common/DecFloat.cpp +++ b/src/common/DecFloat.cpp @@ -359,7 +359,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); From dce2f1052ca6d281e6729e6377f4cb5e6ba3b43c Mon Sep 17 00:00:00 2001 From: AlexPeshkoff Date: Fri, 23 Mar 2018 20:31:52 +0300 Subject: [PATCH 086/171] Fixed CORE-5705: Store precision of DECFLOAT in RDB$FIELDS --- src/dsql/DdlNodes.epp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/dsql/DdlNodes.epp b/src/dsql/DdlNodes.epp index 0b2e189c46..5215000c25 100644 --- a/src/dsql/DdlNodes.epp +++ b/src/dsql/DdlNodes.epp @@ -848,6 +848,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) From a68927e2973f0cc14c299a6377116201479df590 Mon Sep 17 00:00:00 2001 From: firebirds <> Date: Sat, 24 Mar 2018 00:06:03 +0000 Subject: [PATCH 087/171] increment build number --- src/jrd/build_no.h | 12 ++++++------ src/misc/writeBuildNum.sh | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/jrd/build_no.h b/src/jrd/build_no.h index fa1b12ef80..0a71f3ad0a 100644 --- a/src/jrd/build_no.h +++ b/src/jrd/build_no.h @@ -3,16 +3,16 @@ *** DO NOT EDIT *** TO CHANGE ANY INFORMATION IN HERE PLEASE EDIT src/misc/writeBuildNum.sh - FORMAL BUILD NUMBER:938 + FORMAL BUILD NUMBER:940 */ -#define PRODUCT_VER_STRING "4.0.0.938" -#define FILE_VER_STRING "WI-T4.0.0.938" -#define LICENSE_VER_STRING "WI-T4.0.0.938" -#define FILE_VER_NUMBER 4, 0, 0, 938 +#define PRODUCT_VER_STRING "4.0.0.940" +#define FILE_VER_STRING "WI-T4.0.0.940" +#define LICENSE_VER_STRING "WI-T4.0.0.940" +#define FILE_VER_NUMBER 4, 0, 0, 940 #define FB_MAJOR_VER "4" #define FB_MINOR_VER "0" #define FB_REV_NO "0" -#define FB_BUILD_NO "938" +#define FB_BUILD_NO "940" #define FB_BUILD_TYPE "T" #define FB_BUILD_SUFFIX "Firebird 4.0 Alpha 1" diff --git a/src/misc/writeBuildNum.sh b/src/misc/writeBuildNum.sh index 5ffcd186a3..51caf505b2 100755 --- a/src/misc/writeBuildNum.sh +++ b/src/misc/writeBuildNum.sh @@ -9,7 +9,7 @@ BuildType=T MajorVer=4 MinorVer=0 RevNo=0 -BuildNum=938 +BuildNum=940 NowAt=`pwd` cd `dirname $0` From 4566623ec9c895e310d84bb2670e2ede362893ee Mon Sep 17 00:00:00 2001 From: Mark Rotteveel Date: Mon, 26 Mar 2018 16:31:11 +0200 Subject: [PATCH 088/171] CORE-5710 make precision optional for DECFLOAT (#150) * CORE-5710 make precision optional for DECFLOAT * Make DECFLOAT a reserved word * Add DECFLOAT to keyword_or_column --- doc/sql.extensions/README.data_types | 12 +++++++----- src/dsql/parse.y | 22 ++++++++++++++-------- src/yvalve/keywords.cpp | 2 +- 3 files changed, 22 insertions(+), 14 deletions(-) diff --git a/doc/sql.extensions/README.data_types b/doc/sql.extensions/README.data_types index a3119f4827..c755198148 100644 --- a/doc/sql.extensions/README.data_types +++ b/doc/sql.extensions/README.data_types @@ -116,23 +116,25 @@ DECFLOAT (FB 4.0) Alex Peshkoff 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,7 +157,7 @@ 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 - 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 @@ -180,7 +182,7 @@ DECFLOAT (FB 4.0) 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. - 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. diff --git a/src/dsql/parse.y b/src/dsql/parse.y index f79d8e364e..4595d49fad 100644 --- a/src/dsql/parse.y +++ b/src/dsql/parse.y @@ -4135,7 +4135,8 @@ keyword_or_column | UPDATING | VAR_SAMP | VAR_POP - | UNBOUNDED // added in FB 4.0 + | DECFLOAT // added in FB 4.0 + | UNBOUNDED | WINDOW ; @@ -4799,15 +4800,15 @@ varbinary_character_keyword %type 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. + if ($2 != 0 && $2 != 16 && $2 != 34) + yyabandon(YYPOSNARG(2), -842, isc_decprecision_err); // DecFloat precision must be 16 or 34. $$ = newNode(); - $$->precision = $3; - $$->dtype = $3 == 16 ? dtype_dec64 : dtype_dec128; - $$->length = $3 == 16 ? sizeof(Decimal64) : sizeof(Decimal128); + $$->precision = $2 == 0 ? 34 : (USHORT) $2; + $$->dtype = $2 == 16 ? dtype_dec64 : dtype_dec128; + $$->length = $2 == 16 ? sizeof(Decimal64) : sizeof(Decimal128); } ; @@ -5009,6 +5010,12 @@ precision_opt | '(' nonneg_short_integer ')' { $$ = $2; } ; +// alternative to precision_opt that does not allow zero +%type precision_opt_nz +precision_opt_nz + : /* nothing */ { $$ = 0; } + | '(' pos_short_integer ')' { $$ = $2; } + ; // transaction statements @@ -8482,7 +8489,6 @@ non_reserved_word | BIND // added in FB 4.0 | COMPARE_DECFLOAT | CUME_DIST - | DECFLOAT | DEFINER | EXCLUDE | FIRST_DAY diff --git a/src/yvalve/keywords.cpp b/src/yvalve/keywords.cpp index a67b5a3db6..c8d6c48ff3 100644 --- a/src/yvalve/keywords.cpp +++ b/src/yvalve/keywords.cpp @@ -160,7 +160,7 @@ static const TOK tokens[] = {TOK_DAY, "DAY", false}, {TOK_DDL, "DDL", true}, {TOK_DEC, "DEC", false}, - {TOK_DECFLOAT, "DECFLOAT", true}, + {TOK_DECFLOAT, "DECFLOAT", false}, {TOK_DECIMAL, "DECIMAL", false}, {TOK_DECLARE, "DECLARE", false}, {TOK_DECODE, "DECODE", true}, From 6feecfd1e98ae8cb33ad8feba76b288613eed56d Mon Sep 17 00:00:00 2001 From: AlexPeshkoff Date: Mon, 26 Mar 2018 17:40:07 +0300 Subject: [PATCH 089/171] Fixed CORE-5728: Field subtype of DEC_FIXED columns not returned by isc_info_sql_sub_type --- src/common/dsc.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/common/dsc.cpp b/src/common/dsc.cpp index fcab542b56..b04dc56cde 100644 --- a/src/common/dsc.cpp +++ b/src/common/dsc.cpp @@ -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: From 0c75917d38016ab8674889534bf859af475a3ec9 Mon Sep 17 00:00:00 2001 From: firebirds <> Date: Tue, 27 Mar 2018 00:04:02 +0000 Subject: [PATCH 090/171] increment build number --- src/jrd/build_no.h | 12 ++++++------ src/misc/writeBuildNum.sh | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/jrd/build_no.h b/src/jrd/build_no.h index 0a71f3ad0a..878f970ffc 100644 --- a/src/jrd/build_no.h +++ b/src/jrd/build_no.h @@ -3,16 +3,16 @@ *** DO NOT EDIT *** TO CHANGE ANY INFORMATION IN HERE PLEASE EDIT src/misc/writeBuildNum.sh - FORMAL BUILD NUMBER:940 + FORMAL BUILD NUMBER:942 */ -#define PRODUCT_VER_STRING "4.0.0.940" -#define FILE_VER_STRING "WI-T4.0.0.940" -#define LICENSE_VER_STRING "WI-T4.0.0.940" -#define FILE_VER_NUMBER 4, 0, 0, 940 +#define PRODUCT_VER_STRING "4.0.0.942" +#define FILE_VER_STRING "WI-T4.0.0.942" +#define LICENSE_VER_STRING "WI-T4.0.0.942" +#define FILE_VER_NUMBER 4, 0, 0, 942 #define FB_MAJOR_VER "4" #define FB_MINOR_VER "0" #define FB_REV_NO "0" -#define FB_BUILD_NO "940" +#define FB_BUILD_NO "942" #define FB_BUILD_TYPE "T" #define FB_BUILD_SUFFIX "Firebird 4.0 Alpha 1" diff --git a/src/misc/writeBuildNum.sh b/src/misc/writeBuildNum.sh index 51caf505b2..795025a32c 100755 --- a/src/misc/writeBuildNum.sh +++ b/src/misc/writeBuildNum.sh @@ -9,7 +9,7 @@ BuildType=T MajorVer=4 MinorVer=0 RevNo=0 -BuildNum=940 +BuildNum=942 NowAt=`pwd` cd `dirname $0` From d63ac10b21e207478e3a31f1f875118c90d3f200 Mon Sep 17 00:00:00 2001 From: Artyom Smirnov Date: Wed, 28 Mar 2018 18:57:23 +0300 Subject: [PATCH 091/171] If guard starts in daemon mode then close all fds to properly daemonize (#152) Also in server detect if stdout/stderr fds were closed by guard and reopen with redirecting to file or /dev/null --- src/remote/server/os/posix/inet_server.cpp | 24 +++++++++++++++++++--- src/utilities/guard/guard.cpp | 3 ++- 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/src/remote/server/os/posix/inet_server.cpp b/src/remote/server/os/posix/inet_server.cpp index 6aea08b6eb..12c890a93f 100644 --- a/src/remote/server/os/posix/inet_server.cpp +++ b/src/remote/server/os/posix/inet_server.cpp @@ -151,6 +151,11 @@ static int closePort(const int reason, const int, void* arg) return 0; } +bool check_fd(int fd) +{ + return fcntl(fd, F_GETFL) != -1 || errno != EBADF; +} + extern "C" { int CLIB_ROUTINE main( int argc, char** argv) @@ -362,13 +367,26 @@ int CLIB_ROUTINE main( int argc, char** argv) if (!debug) { const char* redirection_file = Config::getOutputRedirectionFile(); - if (redirection_file && strcmp(redirection_file, "-") != 0) + + int stdout_no = fileno(stdout); + int stderr_no = fileno(stderr); + const char* dev_null_file = "/dev/null"; + bool keep_as_is = !redirection_file || redirection_file && (strcmp(redirection_file, "-") == 0 || strcmp(redirection_file, "") == 0); + + //guard close all fds to properly demonize. Detect this case + //and if we spawned from daemon we reopen stdout and stderr + //and redirect it to /dev/null if user want us to print to stdout + if ((!check_fd(stdout_no) || !check_fd(stderr_no)) && keep_as_is) + { + redirection_file = dev_null_file; + keep_as_is = false; + } + + if (!keep_as_is) { int f = open(redirection_file, O_CREAT|O_APPEND|O_WRONLY, 0644); if (f >= 0) { - int stdout_no = fileno(stdout); - int stderr_no = fileno(stderr); if (f != stdout_no) dup2(f, stdout_no); diff --git a/src/utilities/guard/guard.cpp b/src/utilities/guard/guard.cpp index cb78fdbb42..b6364273ff 100644 --- a/src/utilities/guard/guard.cpp +++ b/src/utilities/guard/guard.cpp @@ -170,8 +170,9 @@ int CLIB_ROUTINE main( int argc, char **argv) //Keep stdout and stderr opened and let server emit output //or redirect stdout/stderr to /dev/null or file by user choice + //If we want to daemonize - close all fds and let child to reopen it. int mask = 0; // FD_ZERO(&mask); - mask |= (1 << 1 | 1 << 2); // FD_SET(1, &mask); FD_SET(2, &mask); + mask |= daemon ? 0 : (1 << 1 | 1 << 2); // FD_SET(1, &mask); FD_SET(2, &mask); divorce_terminal(mask); time_t timer = 0; From eaee6a6fdfdbcf6299ad9a50721324e48b7f7475 Mon Sep 17 00:00:00 2001 From: firebirds <> Date: Thu, 29 Mar 2018 00:04:09 +0000 Subject: [PATCH 092/171] increment build number --- src/jrd/build_no.h | 12 ++++++------ src/misc/writeBuildNum.sh | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/jrd/build_no.h b/src/jrd/build_no.h index 878f970ffc..cd3d5663c6 100644 --- a/src/jrd/build_no.h +++ b/src/jrd/build_no.h @@ -3,16 +3,16 @@ *** DO NOT EDIT *** TO CHANGE ANY INFORMATION IN HERE PLEASE EDIT src/misc/writeBuildNum.sh - FORMAL BUILD NUMBER:942 + FORMAL BUILD NUMBER:943 */ -#define PRODUCT_VER_STRING "4.0.0.942" -#define FILE_VER_STRING "WI-T4.0.0.942" -#define LICENSE_VER_STRING "WI-T4.0.0.942" -#define FILE_VER_NUMBER 4, 0, 0, 942 +#define PRODUCT_VER_STRING "4.0.0.943" +#define FILE_VER_STRING "WI-T4.0.0.943" +#define LICENSE_VER_STRING "WI-T4.0.0.943" +#define FILE_VER_NUMBER 4, 0, 0, 943 #define FB_MAJOR_VER "4" #define FB_MINOR_VER "0" #define FB_REV_NO "0" -#define FB_BUILD_NO "942" +#define FB_BUILD_NO "943" #define FB_BUILD_TYPE "T" #define FB_BUILD_SUFFIX "Firebird 4.0 Alpha 1" diff --git a/src/misc/writeBuildNum.sh b/src/misc/writeBuildNum.sh index 795025a32c..fa0fcb4158 100755 --- a/src/misc/writeBuildNum.sh +++ b/src/misc/writeBuildNum.sh @@ -9,7 +9,7 @@ BuildType=T MajorVer=4 MinorVer=0 RevNo=0 -BuildNum=942 +BuildNum=943 NowAt=`pwd` cd `dirname $0` From 57f2f6926838e81499a9f6dbbd4cd3f13755740c Mon Sep 17 00:00:00 2001 From: hvlad Date: Sat, 31 Mar 2018 00:38:41 +0300 Subject: [PATCH 093/171] Let SQL parser handle '\r', '\n' and '\r\n' as end of line. --- src/dsql/Parser.cpp | 55 +++++++++++++++++++++++++++++---------------- src/dsql/Parser.h | 1 + 2 files changed, 37 insertions(+), 19 deletions(-) diff --git a/src/dsql/Parser.cpp b/src/dsql/Parser.cpp index 0686329fb0..e1729b7376 100644 --- a/src/dsql/Parser.cpp +++ b/src/dsql/Parser.cpp @@ -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. + lex.ptr++; + if (yylexSkipEol()) break; - } } 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,34 @@ 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(); diff --git a/src/dsql/Parser.h b/src/dsql/Parser.h index 2422f2f61a..f74235a52e 100644 --- a/src/dsql/Parser.h +++ b/src/dsql/Parser.h @@ -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); From 606d91fd2904f283f0deb4a1ed6b327a5adac775 Mon Sep 17 00:00:00 2001 From: hvlad Date: Sat, 31 Mar 2018 00:39:34 +0300 Subject: [PATCH 094/171] Let ExtDS preprocessor handle '\r', '\n' and '\r\n' as end of line. --- src/jrd/extds/ExtDS.cpp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/jrd/extds/ExtDS.cpp b/src/jrd/extds/ExtDS.cpp index b97caccec6..5f90961272 100644 --- a/src/jrd/extds/ExtDS.cpp +++ b/src/jrd/extds/ExtDS.cpp @@ -1074,15 +1074,19 @@ static TokenType getToken(const char** begin, const char* end) case '-': if (p < end && *p == '-') { - while (p < end) + while (++p < end) { - if (*p++ == '\n') + if (*p == '\r') { - p--; - ret = ttComment; + p++; + if (p < end && *p == '\n') + p++; break; } + else if (*p == '\n') + break; } + ret = ttComment; } else { ret = ttOther; From 19deaaaf0508cd469f737c525aae2b57d27864d8 Mon Sep 17 00:00:00 2001 From: firebirds <> Date: Sat, 31 Mar 2018 00:03:58 +0000 Subject: [PATCH 095/171] increment build number --- src/jrd/build_no.h | 12 ++++++------ src/misc/writeBuildNum.sh | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/jrd/build_no.h b/src/jrd/build_no.h index cd3d5663c6..1674f1073b 100644 --- a/src/jrd/build_no.h +++ b/src/jrd/build_no.h @@ -3,16 +3,16 @@ *** DO NOT EDIT *** TO CHANGE ANY INFORMATION IN HERE PLEASE EDIT src/misc/writeBuildNum.sh - FORMAL BUILD NUMBER:943 + FORMAL BUILD NUMBER:945 */ -#define PRODUCT_VER_STRING "4.0.0.943" -#define FILE_VER_STRING "WI-T4.0.0.943" -#define LICENSE_VER_STRING "WI-T4.0.0.943" -#define FILE_VER_NUMBER 4, 0, 0, 943 +#define PRODUCT_VER_STRING "4.0.0.945" +#define FILE_VER_STRING "WI-T4.0.0.945" +#define LICENSE_VER_STRING "WI-T4.0.0.945" +#define FILE_VER_NUMBER 4, 0, 0, 945 #define FB_MAJOR_VER "4" #define FB_MINOR_VER "0" #define FB_REV_NO "0" -#define FB_BUILD_NO "943" +#define FB_BUILD_NO "945" #define FB_BUILD_TYPE "T" #define FB_BUILD_SUFFIX "Firebird 4.0 Alpha 1" diff --git a/src/misc/writeBuildNum.sh b/src/misc/writeBuildNum.sh index fa0fcb4158..5f0d9cd87b 100755 --- a/src/misc/writeBuildNum.sh +++ b/src/misc/writeBuildNum.sh @@ -9,7 +9,7 @@ BuildType=T MajorVer=4 MinorVer=0 RevNo=0 -BuildNum=943 +BuildNum=945 NowAt=`pwd` cd `dirname $0` From d22a07090cd0bd2815439b97ca89431d7e23ae31 Mon Sep 17 00:00:00 2001 From: Mark Rotteveel Date: Mon, 2 Apr 2018 19:18:20 +0200 Subject: [PATCH 096/171] Update keywords for FB4 and check against SQL:2016 (#154) --- doc/sql.extensions/README.keywords | 159 +++++++++++++++++------------ 1 file changed, 92 insertions(+), 67 deletions(-) diff --git a/doc/sql.extensions/README.keywords b/doc/sql.extensions/README.keywords index a5d1bb9a92..61dafd1a7b 100644 --- a/doc/sql.extensions/README.keywords +++ b/doc/sql.extensions/README.keywords @@ -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,71 @@ 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) + SECURITY + SESSION + SQL (1) + SYSTEM (1) TIES + TOTALORDER * + TRAPS * From 191a3b6f920a24eb0a7f01e7edc8b2b12ba6396f Mon Sep 17 00:00:00 2001 From: abzalov Date: Mon, 2 Apr 2018 22:54:47 +0300 Subject: [PATCH 097/171] =?UTF-8?q?CORE-5746:=20Remove=20the=20restriction?= =?UTF-8?q?=20on=20create/delete,=20enable/disable=20th=E2=80=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/dsql/DdlNodes.epp | 25 ++++++++++++++++--------- src/jrd/vio.cpp | 6 ++++-- 2 files changed, 20 insertions(+), 11 deletions(-) diff --git a/src/dsql/DdlNodes.epp b/src/dsql/DdlNodes.epp index 5215000c25..8384e05d8b 100644 --- a/src/dsql/DdlNodes.epp +++ b/src/dsql/DdlNodes.epp @@ -89,7 +89,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); @@ -538,14 +538,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 @@ -1286,9 +1289,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: @@ -9668,12 +9672,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; } @@ -9730,7 +9735,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()); @@ -9811,12 +9817,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; } diff --git a/src/jrd/vio.cpp b/src/jrd/vio.cpp index 2d8ff88150..61ddf1b87a 100644 --- a/src/jrd/vio.cpp +++ b/src/jrd/vio.cpp @@ -1612,7 +1612,8 @@ void VIO_erase(thread_db* tdbb, record_param* rpb, jrd_tra* transaction) case rel_indices: protect_system_table_delupd(tdbb, relation, "DELETE"); EVL_field(0, rpb->rpb_record, f_idx_relation, &desc); - SCL_check_relation(tdbb, &desc, SCL_control); + EVL_field(0, rpb->rpb_record, f_idx_sys_flag, &desc2); + SCL_check_relation(tdbb, &desc, SCL_control, MOV_get_long(tdbb, &desc2, 0) == 1); EVL_field(0, rpb->rpb_record, f_idx_id, &desc2); if ( (id = MOV_get_long(tdbb, &desc2, 0)) ) { @@ -3253,7 +3254,8 @@ void VIO_store(thread_db* tdbb, record_param* rpb, jrd_tra* transaction) case rel_indices: protect_system_table_insert(tdbb, request, relation); EVL_field(0, rpb->rpb_record, f_idx_relation, &desc); - SCL_check_relation(tdbb, &desc, SCL_control); + EVL_field(0, rpb->rpb_record, f_idx_sys_flag, &desc2); + SCL_check_relation(tdbb, &desc, SCL_control, MOV_get_long(tdbb, &desc2, 0) == 1); EVL_field(0, rpb->rpb_record, f_idx_name, &desc); if (EVL_field(0, rpb->rpb_record, f_idx_exp_blr, &desc2)) { From 64b6de01e420551cbddae948c48e3e6a70ef93d4 Mon Sep 17 00:00:00 2001 From: hvlad Date: Tue, 3 Apr 2018 01:01:52 +0300 Subject: [PATCH 098/171] Additional fix for bug CORE-5702 : Firebird Handle Leak Windows --- src/jrd/jrd.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/jrd/jrd.cpp b/src/jrd/jrd.cpp index 3b3b80f54f..8f4d88fa8c 100644 --- a/src/jrd/jrd.cpp +++ b/src/jrd/jrd.cpp @@ -384,6 +384,8 @@ int JProvider::release() static void shutdownBeforeUnload() { + ThreadSync thread(FB_FUNCTION); + LocalStatus status; CheckStatusWrapper statusWrapper(&status); From 681caa599594e569e36393df8008f855ffeff0d6 Mon Sep 17 00:00:00 2001 From: firebirds <> Date: Tue, 3 Apr 2018 00:04:05 +0000 Subject: [PATCH 099/171] increment build number --- src/jrd/build_no.h | 12 ++++++------ src/misc/writeBuildNum.sh | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/jrd/build_no.h b/src/jrd/build_no.h index 1674f1073b..9bcb400cad 100644 --- a/src/jrd/build_no.h +++ b/src/jrd/build_no.h @@ -3,16 +3,16 @@ *** DO NOT EDIT *** TO CHANGE ANY INFORMATION IN HERE PLEASE EDIT src/misc/writeBuildNum.sh - FORMAL BUILD NUMBER:945 + FORMAL BUILD NUMBER:947 */ -#define PRODUCT_VER_STRING "4.0.0.945" -#define FILE_VER_STRING "WI-T4.0.0.945" -#define LICENSE_VER_STRING "WI-T4.0.0.945" -#define FILE_VER_NUMBER 4, 0, 0, 945 +#define PRODUCT_VER_STRING "4.0.0.947" +#define FILE_VER_STRING "WI-T4.0.0.947" +#define LICENSE_VER_STRING "WI-T4.0.0.947" +#define FILE_VER_NUMBER 4, 0, 0, 947 #define FB_MAJOR_VER "4" #define FB_MINOR_VER "0" #define FB_REV_NO "0" -#define FB_BUILD_NO "945" +#define FB_BUILD_NO "947" #define FB_BUILD_TYPE "T" #define FB_BUILD_SUFFIX "Firebird 4.0 Alpha 1" diff --git a/src/misc/writeBuildNum.sh b/src/misc/writeBuildNum.sh index 5f0d9cd87b..1498386645 100755 --- a/src/misc/writeBuildNum.sh +++ b/src/misc/writeBuildNum.sh @@ -9,7 +9,7 @@ BuildType=T MajorVer=4 MinorVer=0 RevNo=0 -BuildNum=945 +BuildNum=947 NowAt=`pwd` cd `dirname $0` From 0cc3d04c9aaeb5b32762d2d23d932cf8122827a3 Mon Sep 17 00:00:00 2001 From: hvlad Date: Thu, 5 Apr 2018 00:37:45 +0300 Subject: [PATCH 100/171] Corrected additional fix for bug CORE-5702 : Firebird Handle Leak Windows --- src/jrd/jrd.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/jrd/jrd.cpp b/src/jrd/jrd.cpp index 8f4d88fa8c..ed9b39e63e 100644 --- a/src/jrd/jrd.cpp +++ b/src/jrd/jrd.cpp @@ -382,14 +382,19 @@ int JProvider::release() return 1; } +static void threadDetach() +{ + ThreadSync* thd = ThreadSync::findThread(); + delete thd; +} + static void shutdownBeforeUnload() { - ThreadSync thread(FB_FUNCTION); - LocalStatus status; CheckStatusWrapper statusWrapper(&status); JProvider::getInstance()->shutdown(&statusWrapper, 0, fb_shutrsn_exit_called); + threadDetach(); }; class EngineFactory : public AutoIface > From c2ba6a8979c0d75086b03c3dd28f0b2f8c08beea Mon Sep 17 00:00:00 2001 From: firebirds <> Date: Thu, 5 Apr 2018 00:04:10 +0000 Subject: [PATCH 101/171] increment build number --- src/jrd/build_no.h | 12 ++++++------ src/misc/writeBuildNum.sh | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/jrd/build_no.h b/src/jrd/build_no.h index 9bcb400cad..f397d21708 100644 --- a/src/jrd/build_no.h +++ b/src/jrd/build_no.h @@ -3,16 +3,16 @@ *** DO NOT EDIT *** TO CHANGE ANY INFORMATION IN HERE PLEASE EDIT src/misc/writeBuildNum.sh - FORMAL BUILD NUMBER:947 + FORMAL BUILD NUMBER:948 */ -#define PRODUCT_VER_STRING "4.0.0.947" -#define FILE_VER_STRING "WI-T4.0.0.947" -#define LICENSE_VER_STRING "WI-T4.0.0.947" -#define FILE_VER_NUMBER 4, 0, 0, 947 +#define PRODUCT_VER_STRING "4.0.0.948" +#define FILE_VER_STRING "WI-T4.0.0.948" +#define LICENSE_VER_STRING "WI-T4.0.0.948" +#define FILE_VER_NUMBER 4, 0, 0, 948 #define FB_MAJOR_VER "4" #define FB_MINOR_VER "0" #define FB_REV_NO "0" -#define FB_BUILD_NO "947" +#define FB_BUILD_NO "948" #define FB_BUILD_TYPE "T" #define FB_BUILD_SUFFIX "Firebird 4.0 Alpha 1" diff --git a/src/misc/writeBuildNum.sh b/src/misc/writeBuildNum.sh index 1498386645..bb568b7f44 100755 --- a/src/misc/writeBuildNum.sh +++ b/src/misc/writeBuildNum.sh @@ -9,7 +9,7 @@ BuildType=T MajorVer=4 MinorVer=0 RevNo=0 -BuildNum=947 +BuildNum=948 NowAt=`pwd` cd `dirname $0` From 7f044bccf9ebe15a3ffe355146f83cdb90b30e05 Mon Sep 17 00:00:00 2001 From: Adriano dos Santos Fernandes Date: Thu, 5 Apr 2018 12:41:40 -0300 Subject: [PATCH 102/171] Misc. --- src/common/ThreadStart.cpp | 1 + src/dsql/Parser.cpp | 1 + src/dsql/parse.y | 10 ++++++---- src/jrd/extds/ExtDS.cpp | 4 ++-- src/remote/client/interface.cpp | 2 +- src/remote/remote.h | 2 ++ src/remote/server/os/posix/inet_server.cpp | 17 +++++++++-------- src/remote/server/server.cpp | 1 + src/utilities/guard/guard.cpp | 6 +++--- 9 files changed, 26 insertions(+), 18 deletions(-) diff --git a/src/common/ThreadStart.cpp b/src/common/ThreadStart.cpp index 7997325e17..1e585c66b8 100644 --- a/src/common/ThreadStart.cpp +++ b/src/common/ThreadStart.cpp @@ -180,6 +180,7 @@ ThreadId Thread::start(ThreadEntryPoint* routine, void* arg, int priority_arg, H #endif *p_handle = thread; } + return getId(); } diff --git a/src/dsql/Parser.cpp b/src/dsql/Parser.cpp index e1729b7376..e36eeb9a77 100644 --- a/src/dsql/Parser.cpp +++ b/src/dsql/Parser.cpp @@ -394,6 +394,7 @@ bool Parser::yylexSkipEol() { bool eol = false; const TEXT c = *lex.ptr; + if (c == '\r') { lex.ptr++; diff --git a/src/dsql/parse.y b/src/dsql/parse.y index 4595d49fad..ea39da7c08 100644 --- a/src/dsql/parse.y +++ b/src/dsql/parse.y @@ -4802,13 +4802,15 @@ varbinary_character_keyword decfloat_type : DECFLOAT precision_opt_nz { - if ($2 != 0 && $2 != 16 && $2 != 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(); - $$->precision = $2 == 0 ? 34 : (USHORT) $2; - $$->dtype = $2 == 16 ? dtype_dec64 : dtype_dec128; - $$->length = $2 == 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); } ; diff --git a/src/jrd/extds/ExtDS.cpp b/src/jrd/extds/ExtDS.cpp index 5f90961272..11a4c9de1c 100644 --- a/src/jrd/extds/ExtDS.cpp +++ b/src/jrd/extds/ExtDS.cpp @@ -1086,11 +1086,11 @@ static TokenType getToken(const char** begin, const char* end) else if (*p == '\n') break; } + ret = ttComment; } - else { + else ret = ttOther; - } break; default: diff --git a/src/remote/client/interface.cpp b/src/remote/client/interface.cpp index 581c3b1bd9..3d55191f4f 100644 --- a/src/remote/client/interface.cpp +++ b/src/remote/client/interface.cpp @@ -5014,7 +5014,7 @@ Firebird::IEvents* Attachment::queEvents(CheckStatusWrapper* status, Firebird::I port->connect(packet); rem_port* port_async = port->port_async; - port_async->port_events_threadId = + port_async->port_events_threadId = Thread::start(event_thread, port_async, THREAD_high, &port_async->port_events_thread); port_async->port_context = rdb; diff --git a/src/remote/remote.h b/src/remote/remote.h index ea0d900e11..515b70f074 100644 --- a/src/remote/remote.h +++ b/src/remote/remote.h @@ -1293,7 +1293,9 @@ private: if (waitFlag) { Thread::waitForCompletion(waitHandle); + fb_assert(asyncPort); + if (asyncPort) asyncPort->release(); } diff --git a/src/remote/server/os/posix/inet_server.cpp b/src/remote/server/os/posix/inet_server.cpp index 12c890a93f..18053380e5 100644 --- a/src/remote/server/os/posix/inet_server.cpp +++ b/src/remote/server/os/posix/inet_server.cpp @@ -350,8 +350,8 @@ int CLIB_ROUTINE main( int argc, char** argv) if (!(debug || classic)) { - //Keep stdout and stderr openened always. We decide allow output - //from binary or redirect it according to config + // Keep stdout and stderr openened always. We decide allow output + // from binary or redirect it according to config int mask = 0; // FD_ZERO(&mask); mask |= (1 << 1 | 1 << 2); // FD_SET(1, &mask); FD_SET(2, &mask); divorce_terminal(mask); @@ -371,11 +371,12 @@ int CLIB_ROUTINE main( int argc, char** argv) int stdout_no = fileno(stdout); int stderr_no = fileno(stderr); const char* dev_null_file = "/dev/null"; - bool keep_as_is = !redirection_file || redirection_file && (strcmp(redirection_file, "-") == 0 || strcmp(redirection_file, "") == 0); + bool keep_as_is = !redirection_file || redirection_file && + (strcmp(redirection_file, "-") == 0 || strcmp(redirection_file, "") == 0); - //guard close all fds to properly demonize. Detect this case - //and if we spawned from daemon we reopen stdout and stderr - //and redirect it to /dev/null if user want us to print to stdout + // guard close all fds to properly demonize. Detect this case + // and if we spawned from daemon we reopen stdout and stderr + // and redirect it to /dev/null if user want us to print to stdout if ((!check_fd(stdout_no) || !check_fd(stderr_no)) && keep_as_is) { redirection_file = dev_null_file; @@ -385,11 +386,13 @@ int CLIB_ROUTINE main( int argc, char** argv) if (!keep_as_is) { int f = open(redirection_file, O_CREAT|O_APPEND|O_WRONLY, 0644); + if (f >= 0) { if (f != stdout_no) dup2(f, stdout_no); + if (f != stderr_no) dup2(f, stderr_no); @@ -397,9 +400,7 @@ int CLIB_ROUTINE main( int argc, char** argv) close(f); } else - { gds__log("Unable to open file %s for output redirection", redirection_file); - } } } diff --git a/src/remote/server/server.cpp b/src/remote/server/server.cpp index ad300c9764..fc845fe2aa 100644 --- a/src/remote/server/server.cpp +++ b/src/remote/server/server.cpp @@ -6400,6 +6400,7 @@ SSHORT rem_port::asyncReceive(PACKET* asyncPacket, const UCHAR* buffer, SSHORT d } SLONG original_op = xdr_peek_long(&port_async_receive->port_receive, buffer, dataSize); + switch (original_op) { case op_cancel: diff --git a/src/utilities/guard/guard.cpp b/src/utilities/guard/guard.cpp index b6364273ff..f65a6167e8 100644 --- a/src/utilities/guard/guard.cpp +++ b/src/utilities/guard/guard.cpp @@ -168,9 +168,9 @@ int CLIB_ROUTINE main( int argc, char **argv) exit(0); } - //Keep stdout and stderr opened and let server emit output - //or redirect stdout/stderr to /dev/null or file by user choice - //If we want to daemonize - close all fds and let child to reopen it. + // Keep stdout and stderr opened and let server emit output + // or redirect stdout/stderr to /dev/null or file by user choice + // If we want to daemonize - close all fds and let child to reopen it. int mask = 0; // FD_ZERO(&mask); mask |= daemon ? 0 : (1 << 1 | 1 << 2); // FD_SET(1, &mask); FD_SET(2, &mask); divorce_terminal(mask); From ec86419d25c1a209def9ccebab4644e99e9e8127 Mon Sep 17 00:00:00 2001 From: hvlad Date: Thu, 5 Apr 2018 21:02:32 +0300 Subject: [PATCH 103/171] Missed piece for fix of CORE-5746: Remove the restriction on create/delete, enable/disable user indexes in the system tables --- src/dsql/DdlNodes.epp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dsql/DdlNodes.epp b/src/dsql/DdlNodes.epp index 8384e05d8b..abd7247aec 100644 --- a/src/dsql/DdlNodes.epp +++ b/src/dsql/DdlNodes.epp @@ -9604,7 +9604,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; } From 476af424ac6b34824fa85f75521bd879cd6c5cb0 Mon Sep 17 00:00:00 2001 From: firebirds <> Date: Fri, 6 Apr 2018 00:04:16 +0000 Subject: [PATCH 104/171] increment build number --- src/jrd/build_no.h | 12 ++++++------ src/misc/writeBuildNum.sh | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/jrd/build_no.h b/src/jrd/build_no.h index f397d21708..52ff00d20d 100644 --- a/src/jrd/build_no.h +++ b/src/jrd/build_no.h @@ -3,16 +3,16 @@ *** DO NOT EDIT *** TO CHANGE ANY INFORMATION IN HERE PLEASE EDIT src/misc/writeBuildNum.sh - FORMAL BUILD NUMBER:948 + FORMAL BUILD NUMBER:952 */ -#define PRODUCT_VER_STRING "4.0.0.948" -#define FILE_VER_STRING "WI-T4.0.0.948" -#define LICENSE_VER_STRING "WI-T4.0.0.948" -#define FILE_VER_NUMBER 4, 0, 0, 948 +#define PRODUCT_VER_STRING "4.0.0.952" +#define FILE_VER_STRING "WI-T4.0.0.952" +#define LICENSE_VER_STRING "WI-T4.0.0.952" +#define FILE_VER_NUMBER 4, 0, 0, 952 #define FB_MAJOR_VER "4" #define FB_MINOR_VER "0" #define FB_REV_NO "0" -#define FB_BUILD_NO "948" +#define FB_BUILD_NO "952" #define FB_BUILD_TYPE "T" #define FB_BUILD_SUFFIX "Firebird 4.0 Alpha 1" diff --git a/src/misc/writeBuildNum.sh b/src/misc/writeBuildNum.sh index bb568b7f44..4e3696c319 100755 --- a/src/misc/writeBuildNum.sh +++ b/src/misc/writeBuildNum.sh @@ -9,7 +9,7 @@ BuildType=T MajorVer=4 MinorVer=0 RevNo=0 -BuildNum=948 +BuildNum=952 NowAt=`pwd` cd `dirname $0` From 946e4fddabab7cb19c9d994299b415de5ec98901 Mon Sep 17 00:00:00 2001 From: Egor Pugin Date: Thu, 5 Apr 2018 19:50:41 +0300 Subject: [PATCH 105/171] Reflect build changes in cmake build. Fix VS15.6 build. --- src/CMakeLists.txt | 22 +++++++++++----------- src/common/os/win32/mod_loader.cpp | 2 +- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index f5b974c8fd..d09f102a5b 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -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 diff --git a/src/common/os/win32/mod_loader.cpp b/src/common/os/win32/mod_loader.cpp index 49c6f2a326..68ebaecadc 100644 --- a/src/common/os/win32/mod_loader.cpp +++ b/src/common/os/win32/mod_loader.cpp @@ -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 ! From 1704e3d5ffa6f0195e4a162606fc088aefbb6d28 Mon Sep 17 00:00:00 2001 From: firebirds <> Date: Sat, 7 Apr 2018 00:04:12 +0000 Subject: [PATCH 106/171] increment build number --- src/jrd/build_no.h | 12 ++++++------ src/misc/writeBuildNum.sh | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/jrd/build_no.h b/src/jrd/build_no.h index 52ff00d20d..0e53ac59e3 100644 --- a/src/jrd/build_no.h +++ b/src/jrd/build_no.h @@ -3,16 +3,16 @@ *** DO NOT EDIT *** TO CHANGE ANY INFORMATION IN HERE PLEASE EDIT src/misc/writeBuildNum.sh - FORMAL BUILD NUMBER:952 + FORMAL BUILD NUMBER:953 */ -#define PRODUCT_VER_STRING "4.0.0.952" -#define FILE_VER_STRING "WI-T4.0.0.952" -#define LICENSE_VER_STRING "WI-T4.0.0.952" -#define FILE_VER_NUMBER 4, 0, 0, 952 +#define PRODUCT_VER_STRING "4.0.0.953" +#define FILE_VER_STRING "WI-T4.0.0.953" +#define LICENSE_VER_STRING "WI-T4.0.0.953" +#define FILE_VER_NUMBER 4, 0, 0, 953 #define FB_MAJOR_VER "4" #define FB_MINOR_VER "0" #define FB_REV_NO "0" -#define FB_BUILD_NO "952" +#define FB_BUILD_NO "953" #define FB_BUILD_TYPE "T" #define FB_BUILD_SUFFIX "Firebird 4.0 Alpha 1" diff --git a/src/misc/writeBuildNum.sh b/src/misc/writeBuildNum.sh index 4e3696c319..ba9e42f634 100755 --- a/src/misc/writeBuildNum.sh +++ b/src/misc/writeBuildNum.sh @@ -9,7 +9,7 @@ BuildType=T MajorVer=4 MinorVer=0 RevNo=0 -BuildNum=952 +BuildNum=953 NowAt=`pwd` cd `dirname $0` From 300566d9ba739b96b994b7f56fb2750e5ff12033 Mon Sep 17 00:00:00 2001 From: Roman Simakov Date: Mon, 9 Apr 2018 17:25:44 +0300 Subject: [PATCH 107/171] Fixed CORE-5790 - User with DROP DATABASE privilege can't drop database --- src/jrd/jrd.cpp | 7 +------ src/jrd/scl.epp | 3 +++ 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/src/jrd/jrd.cpp b/src/jrd/jrd.cpp index ed9b39e63e..7a936a1958 100644 --- a/src/jrd/jrd.cpp +++ b/src/jrd/jrd.cpp @@ -3043,12 +3043,7 @@ void JAttachment::dropDatabase(CheckStatusWrapper* user_status) const PathName& file_name = attachment->att_filename; - if (!attachment->locksmith(tdbb, DROP_DATABASE)) - { - ERR_post(Arg::Gds(isc_no_priv) << Arg::Str("drop") << - Arg::Str("database") << - Arg::Str(file_name)); - } + SCL_check_database(tdbb, SCL_drop); if (attachment->att_flags & ATT_shutdown) { diff --git a/src/jrd/scl.epp b/src/jrd/scl.epp index 466c401c17..9da863c841 100644 --- a/src/jrd/scl.epp +++ b/src/jrd/scl.epp @@ -372,6 +372,9 @@ void SCL_check_database(thread_db* tdbb, SecurityClass::flags_t mask) if (mask == SCL_alter && attachment->locksmith(tdbb, USE_NBACKUP_UTILITY)) return; + if (mask == SCL_drop && attachment->locksmith(tdbb, DROP_DATABASE)) + return; + const P_NAMES* names; for (names = p_names; names->p_names_priv; names++) { From a85437ae428b62e5068a16747dc269c949dbb5fe Mon Sep 17 00:00:00 2001 From: firebirds <> Date: Tue, 10 Apr 2018 00:04:12 +0000 Subject: [PATCH 108/171] increment build number --- src/jrd/build_no.h | 12 ++++++------ src/misc/writeBuildNum.sh | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/jrd/build_no.h b/src/jrd/build_no.h index 0e53ac59e3..17914a307a 100644 --- a/src/jrd/build_no.h +++ b/src/jrd/build_no.h @@ -3,16 +3,16 @@ *** DO NOT EDIT *** TO CHANGE ANY INFORMATION IN HERE PLEASE EDIT src/misc/writeBuildNum.sh - FORMAL BUILD NUMBER:953 + FORMAL BUILD NUMBER:954 */ -#define PRODUCT_VER_STRING "4.0.0.953" -#define FILE_VER_STRING "WI-T4.0.0.953" -#define LICENSE_VER_STRING "WI-T4.0.0.953" -#define FILE_VER_NUMBER 4, 0, 0, 953 +#define PRODUCT_VER_STRING "4.0.0.954" +#define FILE_VER_STRING "WI-T4.0.0.954" +#define LICENSE_VER_STRING "WI-T4.0.0.954" +#define FILE_VER_NUMBER 4, 0, 0, 954 #define FB_MAJOR_VER "4" #define FB_MINOR_VER "0" #define FB_REV_NO "0" -#define FB_BUILD_NO "953" +#define FB_BUILD_NO "954" #define FB_BUILD_TYPE "T" #define FB_BUILD_SUFFIX "Firebird 4.0 Alpha 1" diff --git a/src/misc/writeBuildNum.sh b/src/misc/writeBuildNum.sh index ba9e42f634..99569c9696 100755 --- a/src/misc/writeBuildNum.sh +++ b/src/misc/writeBuildNum.sh @@ -9,7 +9,7 @@ BuildType=T MajorVer=4 MinorVer=0 RevNo=0 -BuildNum=953 +BuildNum=954 NowAt=`pwd` cd `dirname $0` From 1f4d06a1d52261117d8ca87d773308588adc20c7 Mon Sep 17 00:00:00 2001 From: hvlad Date: Tue, 10 Apr 2018 17:26:52 +0300 Subject: [PATCH 109/171] Fixed my error (case when eol follows immediately after '--') --- src/dsql/Parser.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dsql/Parser.cpp b/src/dsql/Parser.cpp index e36eeb9a77..d0b51832cb 100644 --- a/src/dsql/Parser.cpp +++ b/src/dsql/Parser.cpp @@ -342,9 +342,9 @@ bool Parser::yylexSkipSpaces() lex.ptr++; while (lex.ptr < lex.end) { - lex.ptr++; if (yylexSkipEol()) break; + lex.ptr++; } if (lex.ptr >= lex.end) return false; From 943b9407e831e576e97191f6a7687c38acd47831 Mon Sep 17 00:00:00 2001 From: firebirds <> Date: Wed, 11 Apr 2018 00:04:11 +0000 Subject: [PATCH 110/171] increment build number --- src/jrd/build_no.h | 12 ++++++------ src/misc/writeBuildNum.sh | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/jrd/build_no.h b/src/jrd/build_no.h index 17914a307a..6cd72ad022 100644 --- a/src/jrd/build_no.h +++ b/src/jrd/build_no.h @@ -3,16 +3,16 @@ *** DO NOT EDIT *** TO CHANGE ANY INFORMATION IN HERE PLEASE EDIT src/misc/writeBuildNum.sh - FORMAL BUILD NUMBER:954 + FORMAL BUILD NUMBER:955 */ -#define PRODUCT_VER_STRING "4.0.0.954" -#define FILE_VER_STRING "WI-T4.0.0.954" -#define LICENSE_VER_STRING "WI-T4.0.0.954" -#define FILE_VER_NUMBER 4, 0, 0, 954 +#define PRODUCT_VER_STRING "4.0.0.955" +#define FILE_VER_STRING "WI-T4.0.0.955" +#define LICENSE_VER_STRING "WI-T4.0.0.955" +#define FILE_VER_NUMBER 4, 0, 0, 955 #define FB_MAJOR_VER "4" #define FB_MINOR_VER "0" #define FB_REV_NO "0" -#define FB_BUILD_NO "954" +#define FB_BUILD_NO "955" #define FB_BUILD_TYPE "T" #define FB_BUILD_SUFFIX "Firebird 4.0 Alpha 1" diff --git a/src/misc/writeBuildNum.sh b/src/misc/writeBuildNum.sh index 99569c9696..53c48ee7ac 100755 --- a/src/misc/writeBuildNum.sh +++ b/src/misc/writeBuildNum.sh @@ -9,7 +9,7 @@ BuildType=T MajorVer=4 MinorVer=0 RevNo=0 -BuildNum=954 +BuildNum=955 NowAt=`pwd` cd `dirname $0` From affb39894b51a82c0d2608a7876d6eddbdd08c1d Mon Sep 17 00:00:00 2001 From: AlexPeshkoff Date: Wed, 11 Apr 2018 20:17:28 +0300 Subject: [PATCH 111/171] Fixed CORE-5791: ODS for windows builds and linux-x64 (on the one side) and linux-x86 (on the other side) does not match --- builds/posix/Makefile.in | 25 +++- src/common/classes/DbImplementation.h | 1 - src/jrd/ods.cpp | 4 +- src/jrd/ods.h | 15 +++ src/jrd/ods_proto.h | 2 +- src/jrd/os/posix/unix.cpp | 2 +- src/jrd/pag.cpp | 2 +- src/misc/ods.awk | 112 ++++++++++++++++ src/misc/ods.txt | 185 ++++++++++++++++++++++++++ src/utilities/gstat/dba.epp | 2 +- src/utilities/nbackup/nbackup.cpp | 2 +- 11 files changed, 343 insertions(+), 9 deletions(-) create mode 100644 src/misc/ods.awk create mode 100644 src/misc/ods.txt diff --git a/builds/posix/Makefile.in b/builds/posix/Makefile.in index 8f724d3cf3..ffe02f7999 100644 --- a/builds/posix/Makefile.in +++ b/builds/posix/Makefile.in @@ -204,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 @@ -215,6 +215,7 @@ master_process: $(MAKE) export_lists $(MAKE) external $(MAKE) updateCloopInterfaces + $(MAKE) preliminaryCheck $(MAKE) boot $(MAKE) yvalve ifeq ($(IsDeveloper), Y) @@ -285,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) + gawk -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 # diff --git a/src/common/classes/DbImplementation.h b/src/common/classes/DbImplementation.h index cacf0e0188..5d2a496359 100644 --- a/src/common/classes/DbImplementation.h +++ b/src/common/classes/DbImplementation.h @@ -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: diff --git a/src/jrd/ods.cpp b/src/jrd/ods.cpp index 9282c69877..edc1cecb15 100644 --- a/src/jrd/ods.cpp +++ b/src/jrd/ods.cpp @@ -36,8 +36,10 @@ namespace namespace Ods { -bool isSupported(USHORT majorVersion, USHORT minorVersion) +bool isSupported(const header_page* hdr) { + USHORT majorVersion = hdr->hdr_ods_version; + USHORT minorVersion = hdr->hdr_ods_minor; const bool isFirebird = (majorVersion & ODS_FIREBIRD_FLAG); majorVersion &= ~ODS_FIREBIRD_FLAG; diff --git a/src/jrd/ods.h b/src/jrd/ods.h index 56d3cf287f..78e98e7606 100644 --- a/src/jrd/ods.h +++ b/src/jrd/ods.h @@ -33,8 +33,10 @@ #ifndef JRD_ODS_H #define JRD_ODS_H +#ifndef ODS_TESTING #include "../jrd/RecordNumber.h" #include "../common/classes/fb_string.h" +#endif //ODS_TESTING // This macro enables the ability of the engine to connect to databases // from ODS 8 up to the latest. If this macro is undefined, the engine @@ -316,7 +318,9 @@ struct index_root_page USHORT irt_count; // Number of indices struct irt_repeat { +#ifndef ODS_TESTING private: +#endif //ODS_TESTING ULONG irt_root; // page number of index root if irt_in_progress is NOT set, or // highest 32 bit of transaction if irt_in_progress is set ULONG irt_transaction; // transaction in progress (lowest 32 bits) @@ -325,6 +329,7 @@ struct index_root_page UCHAR irt_keys; // number of keys in index UCHAR irt_flags; +#ifndef ODS_TESTING ULONG getRoot() const; void setRoot(ULONG root_page); @@ -332,6 +337,7 @@ struct index_root_page void setTransaction(TraNumber traNumber); bool isUsed() const; +#endif //ODS_TESTING } irt_rpt[1]; }; @@ -352,6 +358,7 @@ const USHORT irt_foreign = 8; const USHORT irt_primary = 16; const USHORT irt_expression = 32; +#ifndef ODS_TESTING inline ULONG index_root_page::irt_repeat::getRoot() const { return (irt_flags & irt_in_progress) ? 0 : irt_root; @@ -379,6 +386,7 @@ inline bool index_root_page::irt_repeat::isUsed() const { return (irt_flags & irt_in_progress) || (irt_root != 0); } +#endif //ODS_TESTING const int STUFF_COUNT = 4; @@ -567,6 +575,7 @@ struct generator_page { pag gpg_header; ULONG gpg_sequence; // Sequence number + ULONG gpg_dummy1; // Alignment enforced SINT64 gpg_values[1]; // Generator vector }; @@ -631,9 +640,11 @@ struct blh ULONG blh_length; // Total length of data USHORT blh_sub_type; // Blob sub-type UCHAR blh_charset; // Blob charset (since ODS 11.1) +#ifndef ODS_TESTING #ifdef CHECK_BLOB_FIELD_ACCESS_FOR_SELECT USHORT blh_fld_id; // Field ID #endif +#endif //ODS_TESTING UCHAR blh_unused; ULONG blh_page[1]; // Page vector for blob pages }; @@ -705,10 +716,13 @@ inline int IAD_LEN(int count) #define IAD_LEN(count) (sizeof (Ods::InternalArrayDesc) + \ (count ? count - 1: count) * sizeof (Ods::InternalArrayDesc::iad_repeat)) +#ifndef ODS_TESTING Firebird::string pagtype(UCHAR type); +#endif //ODS_TESTING } //namespace Ods +#ifndef ODS_TESTING // alignment for raw page access const USHORT PAGE_ALIGNMENT = 1024; @@ -720,5 +734,6 @@ const int MAX_TABLE_VERSIONS = 255; // max number of view formats (aka versions), limited by "SSHORT RDB$FORMAT" const int MAX_VIEW_VERSIONS = MAX_SSHORT; +#endif //ODS_TESTING #endif // JRD_ODS_H diff --git a/src/jrd/ods_proto.h b/src/jrd/ods_proto.h index b84cc1bd7c..779ff7e345 100644 --- a/src/jrd/ods_proto.h +++ b/src/jrd/ods_proto.h @@ -25,7 +25,7 @@ namespace Ods { - bool isSupported(USHORT, USHORT); + bool isSupported(const header_page* hdr); // NS: ODS code logic should never depend on host platform pointer size. // this is why data type for these things is ULONG (32-bit unsigned integer) diff --git a/src/jrd/os/posix/unix.cpp b/src/jrd/os/posix/unix.cpp index 2c9582f5b9..47631b113e 100644 --- a/src/jrd/os/posix/unix.cpp +++ b/src/jrd/os/posix/unix.cpp @@ -1230,7 +1230,7 @@ static bool raw_devices_validate_database(int desc, const PathName& file_name) if (hp->hdr_header.pag_type != pag_header /*|| hp->hdr_sequence*/) goto quit; - if (!Ods::isSupported(hp->hdr_ods_version, hp->hdr_ods_minor)) + if (!Ods::isSupported(hp)) goto quit; if (hp->hdr_page_size < MIN_PAGE_SIZE || hp->hdr_page_size > MAX_PAGE_SIZE) diff --git a/src/jrd/pag.cpp b/src/jrd/pag.cpp index 5018c8e5c9..b84c8e2b34 100644 --- a/src/jrd/pag.cpp +++ b/src/jrd/pag.cpp @@ -1264,7 +1264,7 @@ void PAG_header_init(thread_db* tdbb) const USHORT ods_version = header->hdr_ods_version & ~ODS_FIREBIRD_FLAG; - if (!Ods::isSupported(header->hdr_ods_version, header->hdr_ods_minor)) + if (!Ods::isSupported(header)) { ERR_post(Arg::Gds(isc_wrong_ods) << Arg::Str(attachment->att_filename) << Arg::Num(ods_version) << diff --git a/src/misc/ods.awk b/src/misc/ods.awk new file mode 100644 index 0000000000..53b6bb6451 --- /dev/null +++ b/src/misc/ods.awk @@ -0,0 +1,112 @@ +# +# PROGRAM: ODS sizes and offsets validation +# MODULE: ods.awk +# DESCRIPTION: Generates c++ code printing reference sample for ODS strctures +# +# 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.firebirdsql.org/en/initial-developer-s-public-license-version-1-0/ +# +# 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 Alexander Peshkoff +# for the Firebird Open Source RDBMS project. +# +# Copyright (c) 2018 Alexander Peshkoff +# and all contributors signed below. +# +# All Rights Reserved. +# Contributor(s): ______________________________________. +# + +BEGIN { + st = 0; + nm = ""; + nm2 = ""; + v2 = ""; + skip = 0; + + print "#include " + print "#ifdef _MSC_VER" + print "#include \"gen/autoconfig_msvc.h\"" + print "#else" + print "#include \"gen/autoconfig.h\"" + print "#endif" + print "" + print "#if SIZEOF_VOID_P == 8" + print "#define FMT \"l\"" + print "#else" + print "#define FMT \"\"" + print "#endif" + print "" + print "#include \"fb_types.h\"" + print "#define ODS_TESTING" + print "#include \"../jrd/ods.h\"" + print "" + print "using namespace Ods;" + print "" + print "int main() {" +} + +($1 == "struct") { + ++st; + if (st <= 2) + { + if (st == 1) + { + nm = $2; + nm2 = nm; + } + else + { + nm2 = nm "::" $2; + } + v2 = $2 "_"; + + print "\tprintf(\"\\n *** " $0 " %\" FMT \"u\\n\", sizeof(" nm2 "));"; + print "\t" nm2 " " v2 ";"; + } +} + + +($1 == "};") { + if (st > 1) + { + v2 = nm "_"; + } + st--; +} + +($1 == "}") { + if (st > 1) + { + st--; + v2 = nm "_"; + } +} + +($2 == "ODS_TESTING") { skip = 1; } + +(st > 0 && substr($1, 1, 1) != "#" && $1 != "struct" && skip == 0 && $1 != "//") { + m = $2; + i = index(m, "["); + if (i == 0) + i = index(m, ";"); + if (i > 0) + m = substr(m, 1, i - 1); + + if (length(m) > 0) + print "\tprintf(\"" m " %\" FMT \"d\\n\", (char*)&" v2 "." m " - (char*)&" v2 ");" +} + +($2 == "//ODS_TESTING") { skip = 0; } + +END { + print "}" +} + diff --git a/src/misc/ods.txt b/src/misc/ods.txt new file mode 100644 index 0000000000..101bde4278 --- /dev/null +++ b/src/misc/ods.txt @@ -0,0 +1,185 @@ + + *** struct pag 16 +pag_type 0 +pag_flags 1 +pag_reserved 2 +pag_generation 4 +pag_scn 8 +pag_pageno 12 + + *** struct blob_page 32 +blp_header 0 +blp_lead_page 16 +blp_sequence 20 +blp_length 24 +blp_pad 26 +blp_page 28 + + *** struct btree_page 40 +btr_header 0 +btr_sibling 16 +btr_left_sibling 20 +btr_prefix_total 24 +btr_relation 28 +btr_length 30 +btr_id 32 +btr_level 33 +btr_jump_interval 34 +btr_jump_size 36 +btr_jump_count 38 +btr_nodes 39 + + *** struct data_page 28 +dpg_header 0 +dpg_sequence 16 +dpg_relation 20 +dpg_count 22 + + *** struct dpg_repeat 4 +dpg_offset 0 +dpg_length 2 +dpg_rpt 24 + + *** struct index_root_page 32 +irt_header 0 +irt_relation 16 +irt_count 18 + + *** struct irt_repeat 12 +irt_root 0 +irt_transaction 4 +irt_desc 8 +irt_keys 10 +irt_flags 11 +irt_rpt 20 + + *** struct irtd 8 +irtd_field 0 +irtd_itype 2 +irtd_selectivity 4 + + *** struct header_page 132 +hdr_header 0 +hdr_page_size 16 +hdr_ods_version 18 +hdr_PAGES 20 +hdr_next_page 24 +hdr_oldest_transaction 28 +hdr_oldest_active 32 +hdr_next_transaction 36 +hdr_sequence 40 +hdr_flags 42 +hdr_creation_date 44 +hdr_attachment_id 52 +hdr_shadow_count 56 +hdr_cpu 60 +hdr_os 61 +hdr_cc 62 +hdr_compatibility_flags 63 +hdr_ods_minor 64 +hdr_end 66 +hdr_page_buffers 68 +hdr_oldest_snapshot 72 +hdr_backup_pages 76 +hdr_crypt_page 80 +hdr_crypt_plugin 84 +hdr_att_high 116 +hdr_tra_high 120 +hdr_data 128 + + *** struct page_inv_page 32 +pip_header 0 +pip_min 16 +pip_extent 20 +pip_used 24 +pip_bits 28 + + *** struct scns_page 24 +scn_header 0 +scn_sequence 16 +scn_pages 20 + + *** struct pointer_page 36 +ppg_header 0 +ppg_sequence 16 +ppg_next 20 +ppg_count 24 +ppg_relation 26 +ppg_min_space 28 +ppg_page 32 + + *** struct tx_inv_page 24 +tip_header 0 +tip_next 16 +tip_transactions 20 + + *** struct generator_page 32 +gpg_header 0 +gpg_sequence 16 +gpg_dummy1 20 +gpg_values 24 + + *** struct rhd 16 +rhd_transaction 0 +rhd_b_page 4 +rhd_b_line 8 +rhd_flags 10 +rhd_format 12 +rhd_data 13 + + *** struct rhde 20 +rhde_transaction 0 +rhde_b_page 4 +rhde_b_line 8 +rhde_flags 10 +rhde_format 12 +rhde_tra_high 14 +rhde_data 16 + + *** struct rhdf 24 +rhdf_transaction 0 +rhdf_b_page 4 +rhdf_b_line 8 +rhdf_flags 10 +rhdf_format 12 +rhdf_tra_high 14 +rhdf_f_page 16 +rhdf_f_line 20 +rhdf_data 22 + + *** struct blh 32 +blh_lead_page 0 +blh_max_sequence 4 +blh_max_segment 8 +blh_flags 10 +blh_level 12 +blh_count 16 +blh_length 20 +blh_sub_type 24 +blh_charset 26 +blh_unused 27 +blh_page 28 + + *** struct Descriptor 12 +dsc_dtype 0 +dsc_scale 1 +dsc_length 2 +dsc_sub_type 4 +dsc_flags 6 +dsc_offset 8 + + *** struct InternalArrayDesc 40 +iad_version 0 +iad_dimensions 1 +iad_struct_count 2 +iad_element_length 4 +iad_length 6 +iad_count 8 +iad_total_length 12 + + *** struct iad_repeat 24 +iad_desc 0 +iad_length 12 +iad_lower 16 +iad_upper 20 +iad_rpt 16 diff --git a/src/utilities/gstat/dba.epp b/src/utilities/gstat/dba.epp index 897e4b05d0..9151bf1274 100644 --- a/src/utilities/gstat/dba.epp +++ b/src/utilities/gstat/dba.epp @@ -620,7 +620,7 @@ int gstat(Firebird::UtilSvc* uSvc) uSvc->started(); - if (!Ods::isSupported(header->hdr_ods_version, header->hdr_ods_minor)) + if (!Ods::isSupported(header)) { const int oversion = (header->hdr_ods_version & ~ODS_FIREBIRD_FLAG); dba_error(3, SafeArg() << ODS_VERSION << oversion); diff --git a/src/utilities/nbackup/nbackup.cpp b/src/utilities/nbackup/nbackup.cpp index bbb631906b..ea0ed412ed 100644 --- a/src/utilities/nbackup/nbackup.cpp +++ b/src/utilities/nbackup/nbackup.cpp @@ -1089,7 +1089,7 @@ void NBackup::backup_database(int level, Guid& guid, const PathName& fname) if (read_file(dbase, header, SECTOR_ALIGNMENT/*sizeof(*header)*/) != SECTOR_ALIGNMENT/*sizeof(*header)*/) status_exception::raise(Arg::Gds(isc_nbackup_err_eofhdrdb) << dbname.c_str() << Arg::Num(1)); - if (!Ods::isSupported(header->hdr_ods_version, header->hdr_ods_minor)) + if (!Ods::isSupported(header)) { const USHORT ods_version = header->hdr_ods_version & ~ODS_FIREBIRD_FLAG; status_exception::raise(Arg::Gds(isc_wrong_ods) << Arg::Str(database.c_str()) << From 0bf40a845309abe7bfc5c685ba87096a90ad3567 Mon Sep 17 00:00:00 2001 From: AlexPeshkoff Date: Wed, 11 Apr 2018 20:43:06 +0300 Subject: [PATCH 112/171] Comments --- src/jrd/CryptoManager.cpp | 2 +- src/remote/protocol.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/jrd/CryptoManager.cpp b/src/jrd/CryptoManager.cpp index 25ee955f6a..ad88959653 100644 --- a/src/jrd/CryptoManager.cpp +++ b/src/jrd/CryptoManager.cpp @@ -1135,7 +1135,7 @@ namespace Jrd { } // Slow IO - we need exclusive lock on crypto manager. - // That may happen only when another process changed DB encyption. + // That may happen only when another process changed DB encryption. BarSync::LockGuard lockGuard(tdbb, sync); lockGuard.lock(); for (SINT64 previous = slowIO; ; previous = slowIO) diff --git a/src/remote/protocol.h b/src/remote/protocol.h index 0e6403aa5b..78fe694a8c 100644 --- a/src/remote/protocol.h +++ b/src/remote/protocol.h @@ -380,7 +380,7 @@ const UCHAR CNCT_specific_data = 7; // Some data, needed for user verification const UCHAR CNCT_plugin_name = 8; // Name of plugin, which generated that data const UCHAR CNCT_login = 9; // Same data as isc_dpb_user_name const UCHAR CNCT_plugin_list = 10; // List of plugins, available on client -const UCHAR CNCT_client_crypt = 11; // Client encyption level (DISABLED/ENABLED/REQUIRED) +const UCHAR CNCT_client_crypt = 11; // Client encryption level (DISABLED/ENABLED/REQUIRED) // Accept Block (Server response to connect block) From d097b4275c6748d4edbd00d35befcc21e9112026 Mon Sep 17 00:00:00 2001 From: firebirds <> Date: Thu, 12 Apr 2018 00:04:10 +0000 Subject: [PATCH 113/171] increment build number --- src/jrd/build_no.h | 12 ++++++------ src/misc/writeBuildNum.sh | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/jrd/build_no.h b/src/jrd/build_no.h index 6cd72ad022..346a8a1f44 100644 --- a/src/jrd/build_no.h +++ b/src/jrd/build_no.h @@ -3,16 +3,16 @@ *** DO NOT EDIT *** TO CHANGE ANY INFORMATION IN HERE PLEASE EDIT src/misc/writeBuildNum.sh - FORMAL BUILD NUMBER:955 + FORMAL BUILD NUMBER:957 */ -#define PRODUCT_VER_STRING "4.0.0.955" -#define FILE_VER_STRING "WI-T4.0.0.955" -#define LICENSE_VER_STRING "WI-T4.0.0.955" -#define FILE_VER_NUMBER 4, 0, 0, 955 +#define PRODUCT_VER_STRING "4.0.0.957" +#define FILE_VER_STRING "WI-T4.0.0.957" +#define LICENSE_VER_STRING "WI-T4.0.0.957" +#define FILE_VER_NUMBER 4, 0, 0, 957 #define FB_MAJOR_VER "4" #define FB_MINOR_VER "0" #define FB_REV_NO "0" -#define FB_BUILD_NO "955" +#define FB_BUILD_NO "957" #define FB_BUILD_TYPE "T" #define FB_BUILD_SUFFIX "Firebird 4.0 Alpha 1" diff --git a/src/misc/writeBuildNum.sh b/src/misc/writeBuildNum.sh index 53c48ee7ac..cc2d049eba 100755 --- a/src/misc/writeBuildNum.sh +++ b/src/misc/writeBuildNum.sh @@ -9,7 +9,7 @@ BuildType=T MajorVer=4 MinorVer=0 RevNo=0 -BuildNum=955 +BuildNum=957 NowAt=`pwd` cd `dirname $0` From a545b78c360c92c35e27a7ea21a1dd9c9c8d4e16 Mon Sep 17 00:00:00 2001 From: AlexPeshkoff Date: Thu, 12 Apr 2018 16:28:13 +0300 Subject: [PATCH 114/171] Postfix for CORE-5791 - no GNU extensions in awk are actually needed --- builds/posix/Makefile.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/builds/posix/Makefile.in b/builds/posix/Makefile.in index ffe02f7999..8b4546c1af 100644 --- a/builds/posix/Makefile.in +++ b/builds/posix/Makefile.in @@ -302,7 +302,7 @@ preliminaryCheck: $(STD_SIZES) $(RUN_SIZES) diff -u $^ $(RUN_SIZES): $(ODS_H) $(ODS_AWK) - gawk -f $(ODS_AWK) <$(ODS_H) >$(ODS_TEST_CPP) + awk -f $(ODS_AWK) <$(ODS_H) >$(ODS_TEST_CPP) $(CXX) -o $(ODS_TEST) $(WCXXFLAGS) $(ODS_TEST_CPP) $(ODS_TEST) >$(RUN_SIZES) From d5fa522646fe4ce07877a1206c54fddcec640546 Mon Sep 17 00:00:00 2001 From: hvlad Date: Thu, 12 Apr 2018 23:24:31 +0300 Subject: [PATCH 115/171] Create MonitoringData early to avoid races later. It fixed leakage of MonitoringData instance (and few related handles) when many connections created simultaneously. See also CORE-5702. --- src/jrd/jrd.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/jrd/jrd.cpp b/src/jrd/jrd.cpp index 7a936a1958..85175bfcba 100644 --- a/src/jrd/jrd.cpp +++ b/src/jrd/jrd.cpp @@ -1580,6 +1580,7 @@ JAttachment* JProvider::internalAttach(CheckStatusWrapper* user_status, const ch dbb, Ods::hdr_nbak_unknown); dbb->dbb_backup_manager->initializeAlloc(tdbb); dbb->dbb_crypto_manager = FB_NEW_POOL(*dbb->dbb_permanent) CryptoManager(tdbb); + dbb->dbb_monitoring_data = FB_NEW_POOL(*dbb->dbb_permanent) MonitoringData(dbb); PAG_init2(tdbb, 0); PAG_header(tdbb, false); From d1e90e035eac0a355df6cd89405d8132f7cba3ed Mon Sep 17 00:00:00 2001 From: firebirds <> Date: Fri, 13 Apr 2018 00:04:06 +0000 Subject: [PATCH 116/171] increment build number --- src/jrd/build_no.h | 12 ++++++------ src/misc/writeBuildNum.sh | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/jrd/build_no.h b/src/jrd/build_no.h index 346a8a1f44..17af195f24 100644 --- a/src/jrd/build_no.h +++ b/src/jrd/build_no.h @@ -3,16 +3,16 @@ *** DO NOT EDIT *** TO CHANGE ANY INFORMATION IN HERE PLEASE EDIT src/misc/writeBuildNum.sh - FORMAL BUILD NUMBER:957 + FORMAL BUILD NUMBER:959 */ -#define PRODUCT_VER_STRING "4.0.0.957" -#define FILE_VER_STRING "WI-T4.0.0.957" -#define LICENSE_VER_STRING "WI-T4.0.0.957" -#define FILE_VER_NUMBER 4, 0, 0, 957 +#define PRODUCT_VER_STRING "4.0.0.959" +#define FILE_VER_STRING "WI-T4.0.0.959" +#define LICENSE_VER_STRING "WI-T4.0.0.959" +#define FILE_VER_NUMBER 4, 0, 0, 959 #define FB_MAJOR_VER "4" #define FB_MINOR_VER "0" #define FB_REV_NO "0" -#define FB_BUILD_NO "957" +#define FB_BUILD_NO "959" #define FB_BUILD_TYPE "T" #define FB_BUILD_SUFFIX "Firebird 4.0 Alpha 1" diff --git a/src/misc/writeBuildNum.sh b/src/misc/writeBuildNum.sh index cc2d049eba..8a9b27907c 100755 --- a/src/misc/writeBuildNum.sh +++ b/src/misc/writeBuildNum.sh @@ -9,7 +9,7 @@ BuildType=T MajorVer=4 MinorVer=0 RevNo=0 -BuildNum=957 +BuildNum=959 NowAt=`pwd` cd `dirname $0` From 0d8cde9252e103da8e4ec86532a9fa980f392c48 Mon Sep 17 00:00:00 2001 From: Dmitry Yemanov Date: Fri, 13 Apr 2018 10:18:00 +0300 Subject: [PATCH 117/171] More complete solution for early monitoring initialization --- src/jrd/Monitoring.cpp | 12 +++++++----- src/jrd/jrd.cpp | 1 + 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/jrd/Monitoring.cpp b/src/jrd/Monitoring.cpp index 304294aaf5..fcc0065e31 100644 --- a/src/jrd/Monitoring.cpp +++ b/src/jrd/Monitoring.cpp @@ -1134,6 +1134,7 @@ void Monitoring::putCall(SnapshotData::DumpRecord& record, const jrd_req* reques putMemoryUsage(record, request->req_memory_stats, stat_id, stat_call); } + void Monitoring::putStatistics(SnapshotData::DumpRecord& record, const RuntimeStatistics& statistics, int stat_id, int stat_group) { @@ -1204,6 +1205,7 @@ void Monitoring::putStatistics(SnapshotData::DumpRecord& record, const RuntimeSt } } + void Monitoring::putContextVars(SnapshotData::DumpRecord& record, const StringMap& variables, SINT64 object_id, bool is_attachment) { @@ -1223,6 +1225,7 @@ void Monitoring::putContextVars(SnapshotData::DumpRecord& record, const StringMa } } + void Monitoring::putMemoryUsage(SnapshotData::DumpRecord& record, const MemoryStats& stats, int stat_id, int stat_group) { @@ -1270,8 +1273,7 @@ void Monitoring::dumpAttachment(thread_db* tdbb, Attachment* attachment) const AttNumber att_id = attachment->att_attachment_id; const MetaName& user_name = attachment->att_user->getUserName(); - if (!dbb->dbb_monitoring_data) - dbb->dbb_monitoring_data = FB_NEW_POOL(pool) MonitoringData(dbb); + fb_assert(dbb->dbb_monitoring_data); MonitoringData::Guard guard(dbb->dbb_monitoring_data); dbb->dbb_monitoring_data->cleanup(att_id); @@ -1334,15 +1336,15 @@ void Monitoring::publishAttachment(thread_db* tdbb) Database* const dbb = tdbb->getDatabase(); Attachment* const attachment = tdbb->getAttachment(); - if (!dbb->dbb_monitoring_data) - dbb->dbb_monitoring_data = FB_NEW_POOL(*dbb->dbb_permanent) MonitoringData(dbb); - const char* user_name = attachment->att_user ? attachment->att_user->getUserName().c_str() : ""; + fb_assert(dbb->dbb_monitoring_data); + MonitoringData::Guard guard(dbb->dbb_monitoring_data); dbb->dbb_monitoring_data->setup(attachment->att_attachment_id, user_name); } + void Monitoring::cleanupAttachment(thread_db* tdbb) { Database* const dbb = tdbb->getDatabase(); diff --git a/src/jrd/jrd.cpp b/src/jrd/jrd.cpp index 85175bfcba..00f2088dcb 100644 --- a/src/jrd/jrd.cpp +++ b/src/jrd/jrd.cpp @@ -2755,6 +2755,7 @@ JAttachment* JProvider::createDatabase(CheckStatusWrapper* user_status, const ch dbb, Ods::hdr_nbak_normal); dbb->dbb_backup_manager->dbCreating = true; dbb->dbb_crypto_manager = FB_NEW_POOL(*dbb->dbb_permanent) CryptoManager(tdbb); + dbb->dbb_monitoring_data = FB_NEW_POOL(*dbb->dbb_permanent) MonitoringData(dbb); PAG_format_header(tdbb); INI_init2(tdbb); From ce3937b5134a9dc38564e463beaffb58322c9176 Mon Sep 17 00:00:00 2001 From: firebirds <> Date: Sat, 14 Apr 2018 00:08:23 +0000 Subject: [PATCH 118/171] increment build number --- src/jrd/build_no.h | 12 ++++++------ src/misc/writeBuildNum.sh | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/jrd/build_no.h b/src/jrd/build_no.h index 17af195f24..efa7b449bb 100644 --- a/src/jrd/build_no.h +++ b/src/jrd/build_no.h @@ -3,16 +3,16 @@ *** DO NOT EDIT *** TO CHANGE ANY INFORMATION IN HERE PLEASE EDIT src/misc/writeBuildNum.sh - FORMAL BUILD NUMBER:959 + FORMAL BUILD NUMBER:960 */ -#define PRODUCT_VER_STRING "4.0.0.959" -#define FILE_VER_STRING "WI-T4.0.0.959" -#define LICENSE_VER_STRING "WI-T4.0.0.959" -#define FILE_VER_NUMBER 4, 0, 0, 959 +#define PRODUCT_VER_STRING "4.0.0.960" +#define FILE_VER_STRING "WI-T4.0.0.960" +#define LICENSE_VER_STRING "WI-T4.0.0.960" +#define FILE_VER_NUMBER 4, 0, 0, 960 #define FB_MAJOR_VER "4" #define FB_MINOR_VER "0" #define FB_REV_NO "0" -#define FB_BUILD_NO "959" +#define FB_BUILD_NO "960" #define FB_BUILD_TYPE "T" #define FB_BUILD_SUFFIX "Firebird 4.0 Alpha 1" diff --git a/src/misc/writeBuildNum.sh b/src/misc/writeBuildNum.sh index 8a9b27907c..46468cb16f 100755 --- a/src/misc/writeBuildNum.sh +++ b/src/misc/writeBuildNum.sh @@ -9,7 +9,7 @@ BuildType=T MajorVer=4 MinorVer=0 RevNo=0 -BuildNum=959 +BuildNum=960 NowAt=`pwd` cd `dirname $0` From 9346d75bb9752ffab68cf9d7585f1d71b84490c1 Mon Sep 17 00:00:00 2001 From: AlexPeshkoff Date: Wed, 18 Apr 2018 19:49:45 +0300 Subject: [PATCH 119/171] Fixed CORE-5796: gstat may produce faulty report about presence of some none-encrypted pages in database --- src/msgs/facilities2.sql | 2 +- src/msgs/messages2.sql | 1 + src/utilities/gstat/dba.epp | 57 ++++++++++++++++++++++++++++++++++++- 3 files changed, 58 insertions(+), 2 deletions(-) diff --git a/src/msgs/facilities2.sql b/src/msgs/facilities2.sql index 5f810973aa..fff966edf2 100644 --- a/src/msgs/facilities2.sql +++ b/src/msgs/facilities2.sql @@ -15,7 +15,7 @@ set bulk_insert INSERT INTO FACILITIES (LAST_CHANGE, FACILITY, FAC_CODE, MAX_NUM ('2018-02-27 14:50:31', 'JRD_BUGCHK', 15, 308) ('2016-05-26 13:53:45', 'ISQL', 17, 196) ('2010-07-10 10:50:30', 'GSEC', 18, 105) -('2017-03-09 21:51:33', 'GSTAT', 21, 61) +('2018-04-18 18:52:29', 'GSTAT', 21, 62) ('2013-12-19 17:31:31', 'FBSVCMGR', 22, 58) ('2009-07-18 12:12:12', 'UTL', 23, 2) ('2016-03-20 15:30:00', 'NBACKUP', 24, 80) diff --git a/src/msgs/messages2.sql b/src/msgs/messages2.sql index 595ed870d4..2e2a9ef282 100644 --- a/src/msgs/messages2.sql +++ b/src/msgs/messages2.sql @@ -3336,6 +3336,7 @@ Analyzing database pages ...', NULL, NULL); (NULL, 'main', 'dba.epp', NULL, 21, 58, NULL, 'Other pages: total @1, ENCRYPTED @2 (DB problem!), non-crypted @3', NULL, NULL) (NULL, 'main', 'dba.epp', NULL, 21, 59, NULL, 'Gstat execution time @1', NULL, NULL) (NULL, 'main', 'dba.epp', NULL, 21, 60, NULL, 'Gstat completion time @1', NULL, NULL) +(NULL, 'lastUsedPage', 'dba.epp', NULL, 21, 61, NULL, ' Expected page inventory page @1', NULL, NULL); -- FBSVCMGR -- All messages use the new format. ('fbsvcmgr_bad_am', 'putAccessMode', 'fbsvcmgr.cpp', NULL, 22, 1, NULL, 'Wrong value for access mode', NULL, NULL); diff --git a/src/utilities/gstat/dba.epp b/src/utilities/gstat/dba.epp index 9151bf1274..a9f71b074d 100644 --- a/src/utilities/gstat/dba.epp +++ b/src/utilities/gstat/dba.epp @@ -184,6 +184,7 @@ static bool analyze_data_page(dba_rel*, const data_page*, bool); static ULONG analyze_fragments(dba_rel*, const rhdf*); static ULONG analyze_versions(dba_rel*, const rhdf*); static void analyze_index(const dba_rel*, dba_idx*); +static ULONG lastUsedPage(ULONG); #if (defined WIN_NT) static void db_error(SLONG); @@ -716,7 +717,8 @@ int gstat(Firebird::UtilSvc* uSvc) }; Statist data, index, blob, other; - for (page = 0; true; ++page) + ULONG last = lastUsedPage(header->hdr_page_size); + for (page = 0; page <= last; ++page) { const pag* p = db_read(page, true); if (!p) @@ -1212,6 +1214,59 @@ int gstat(Firebird::UtilSvc* uSvc) } +static ULONG lastUsedPage(ULONG pageSize) +{ + const ULONG pipFirst = FIRST_PIP_PAGE; + ULONG pipLast = pipFirst; + ULONG pagesPerPIP = Ods::pagesPerPIP(pageSize); + ULONG bytesBitPIP = Ods::bytesBitPIP(pageSize); + page_inv_page* pip; + + while (true) + { + const pag* page = db_read(pipLast, true); + if (page->pag_type != pag_pages) + { + dba_print(true, 61, SafeArg() << pipLast); + // msg 61: " Expected page inventory page @1" + return 0; + } + + pip = (page_inv_page*) page; + if (pip->pip_used != pagesPerPIP) + break; + + UCHAR lastByte = pip->pip_bits[bytesBitPIP - 1]; + if (lastByte & 0x80) + break; + + if (pipLast == pipFirst) + pipLast = pagesPerPIP - 1; + else + pipLast += pagesPerPIP; + } + + int last_bit = pip->pip_used; + int byte_num = last_bit / 8; + UCHAR mask = 1 << (last_bit % 8); + while (last_bit >= 0 && (pip->pip_bits[byte_num] & mask)) + { + if (mask == 1) + { + mask = 0x80; + byte_num--; + //fb_assert(byte_num > -1); ??? + } + else + mask >>= 1; + + last_bit--; + } + + return last_bit + (pipLast == pipFirst ? 0 : pipLast); +} + + static char* alloc(size_t size) { /************************************** From 7fd95d68a5dc9047bcac4bd3b1b799ba5dcd049d Mon Sep 17 00:00:00 2001 From: firebirds <> Date: Thu, 19 Apr 2018 00:03:54 +0000 Subject: [PATCH 120/171] increment build number --- src/jrd/build_no.h | 12 ++++++------ src/misc/writeBuildNum.sh | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/jrd/build_no.h b/src/jrd/build_no.h index efa7b449bb..d71d5dc481 100644 --- a/src/jrd/build_no.h +++ b/src/jrd/build_no.h @@ -3,16 +3,16 @@ *** DO NOT EDIT *** TO CHANGE ANY INFORMATION IN HERE PLEASE EDIT src/misc/writeBuildNum.sh - FORMAL BUILD NUMBER:960 + FORMAL BUILD NUMBER:961 */ -#define PRODUCT_VER_STRING "4.0.0.960" -#define FILE_VER_STRING "WI-T4.0.0.960" -#define LICENSE_VER_STRING "WI-T4.0.0.960" -#define FILE_VER_NUMBER 4, 0, 0, 960 +#define PRODUCT_VER_STRING "4.0.0.961" +#define FILE_VER_STRING "WI-T4.0.0.961" +#define LICENSE_VER_STRING "WI-T4.0.0.961" +#define FILE_VER_NUMBER 4, 0, 0, 961 #define FB_MAJOR_VER "4" #define FB_MINOR_VER "0" #define FB_REV_NO "0" -#define FB_BUILD_NO "960" +#define FB_BUILD_NO "961" #define FB_BUILD_TYPE "T" #define FB_BUILD_SUFFIX "Firebird 4.0 Alpha 1" diff --git a/src/misc/writeBuildNum.sh b/src/misc/writeBuildNum.sh index 46468cb16f..c201258a3f 100755 --- a/src/misc/writeBuildNum.sh +++ b/src/misc/writeBuildNum.sh @@ -9,7 +9,7 @@ BuildType=T MajorVer=4 MinorVer=0 RevNo=0 -BuildNum=960 +BuildNum=961 NowAt=`pwd` cd `dirname $0` From 6cb0b2419ce919ce3a5dc929bbfecea1eaafe0ea Mon Sep 17 00:00:00 2001 From: hvlad Date: Thu, 19 Apr 2018 16:43:09 +0300 Subject: [PATCH 121/171] Fixed small memory leak --- src/jrd/Mapping.cpp | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/src/jrd/Mapping.cpp b/src/jrd/Mapping.cpp index 7683f9439d..6744e1f12b 100644 --- a/src/jrd/Mapping.cpp +++ b/src/jrd/Mapping.cpp @@ -979,15 +979,21 @@ public: bool getPrivileges(const PathName& db, const string& name, const string* sqlRole, const string& trusted_role, UserId::Privileges& system_privileges) { - DbCache* c; - return databases.get(db, c) && c->getPrivileges(name, sqlRole, trusted_role, system_privileges); + AutoPtr* c = databases.get(db); + return c && (*c)->getPrivileges(name, sqlRole, trusted_role, system_privileges); } void populate(const PathName& db, Mapping::DbHandle& iDb, const string& name, const string* sqlRole, const string& trusted_role) { - DbCache* c; - if (!databases.get(db, c)) + AutoPtr* ptr = databases.get(db); + DbCache* c = nullptr; + if (ptr) + { + c = ptr->get(); + fb_assert(c); + } + else { c = FB_NEW_POOL(getPool()) DbCache(getPool()); *(databases.put(db)) = c; @@ -999,9 +1005,9 @@ public: void invalidate(const PathName& db) { - DbCache* c; - if (databases.get(db, c)) - c->invalidate(); + AutoPtr* c = databases.get(db); + if (c) + (*c)->invalidate(); } private: @@ -1194,7 +1200,7 @@ private: }; SyncObject sync; - GenericMap > > databases; + GenericMap > > > databases; }; InitInstance spCache; From 37351719227f298890b08e07464c2edf2610d506 Mon Sep 17 00:00:00 2001 From: firebirds <> Date: Fri, 20 Apr 2018 00:04:04 +0000 Subject: [PATCH 122/171] increment build number --- src/jrd/build_no.h | 12 ++++++------ src/misc/writeBuildNum.sh | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/jrd/build_no.h b/src/jrd/build_no.h index d71d5dc481..3d1b6c611e 100644 --- a/src/jrd/build_no.h +++ b/src/jrd/build_no.h @@ -3,16 +3,16 @@ *** DO NOT EDIT *** TO CHANGE ANY INFORMATION IN HERE PLEASE EDIT src/misc/writeBuildNum.sh - FORMAL BUILD NUMBER:961 + FORMAL BUILD NUMBER:962 */ -#define PRODUCT_VER_STRING "4.0.0.961" -#define FILE_VER_STRING "WI-T4.0.0.961" -#define LICENSE_VER_STRING "WI-T4.0.0.961" -#define FILE_VER_NUMBER 4, 0, 0, 961 +#define PRODUCT_VER_STRING "4.0.0.962" +#define FILE_VER_STRING "WI-T4.0.0.962" +#define LICENSE_VER_STRING "WI-T4.0.0.962" +#define FILE_VER_NUMBER 4, 0, 0, 962 #define FB_MAJOR_VER "4" #define FB_MINOR_VER "0" #define FB_REV_NO "0" -#define FB_BUILD_NO "961" +#define FB_BUILD_NO "962" #define FB_BUILD_TYPE "T" #define FB_BUILD_SUFFIX "Firebird 4.0 Alpha 1" diff --git a/src/misc/writeBuildNum.sh b/src/misc/writeBuildNum.sh index c201258a3f..cbb050d701 100755 --- a/src/misc/writeBuildNum.sh +++ b/src/misc/writeBuildNum.sh @@ -9,7 +9,7 @@ BuildType=T MajorVer=4 MinorVer=0 RevNo=0 -BuildNum=961 +BuildNum=962 NowAt=`pwd` cd `dirname $0` From 999c757d652b179a3255b2705b846554362f1201 Mon Sep 17 00:00:00 2001 From: hvlad Date: Fri, 20 Apr 2018 23:41:46 +0300 Subject: [PATCH 123/171] Fixed leak of ThreadSync instance when module (for. ex. engine) is unloaded before worker threads gone. --- src/common/classes/Synchronize.cpp | 40 +++++++++++++++++++++++++++++- src/common/classes/init.cpp | 36 ++++++++++++++++++++++++--- src/common/classes/init.h | 15 +++++++++-- 3 files changed, 85 insertions(+), 6 deletions(-) diff --git a/src/common/classes/Synchronize.cpp b/src/common/classes/Synchronize.cpp index 7a09ec89fb..51f3222df4 100644 --- a/src/common/classes/Synchronize.cpp +++ b/src/common/classes/Synchronize.cpp @@ -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 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); } diff --git a/src/common/classes/init.cpp b/src/common/classes/init.cpp index 9f28f6e720..c477f3eb6a 100644 --- a/src/common/classes/init.cpp +++ b/src/common/classes/init.cpp @@ -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) diff --git a/src/common/classes/init.h b/src/common/classes/init.h index 3ce0e06cdf..5787828733 100644 --- a/src/common/classes/init.h +++ b/src/common/classes/init.h @@ -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 @@ -90,6 +96,11 @@ public: fb_assert(link); } + void remove() + { + InstanceList::remove(); + } + void dtor() { fb_assert(link); From 791d46bcef346d2a158421bce56ecdfdd4fdba42 Mon Sep 17 00:00:00 2001 From: hvlad Date: Fri, 20 Apr 2018 23:46:00 +0300 Subject: [PATCH 124/171] Fixed rare deadlock when one thread is finishing, loaded modules run threadDetach() while another thread loaded some new module. The deadlock is with windows loader lock and plugin's list mutex. --- src/yvalve/PluginManager.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/yvalve/PluginManager.cpp b/src/yvalve/PluginManager.cpp index 9bb607e945..ff43204934 100644 --- a/src/yvalve/PluginManager.cpp +++ b/src/yvalve/PluginManager.cpp @@ -870,6 +870,10 @@ namespace currentPlugin = NULL; } + // Avoid concurrent load of the same module + static Static loadModuleMutex; + MutexLockGuard lmGuard(*(&loadModuleMutex), FB_FUNCTION); + MutexLockGuard g(plugins->mutex, FB_FUNCTION); while (currentName.getWord(namesList, " \t,;")) @@ -889,6 +893,7 @@ namespace RefPtr m(modules->findModule(info.curModule)); if (!m.hasData() && !flShutdown) { + MutexUnlockGuard cout(plugins->mutex, FB_FUNCTION); m = loadModule(info); } if (!m.hasData()) From c603bd673adfce921d755ca56451c110e7ef56a9 Mon Sep 17 00:00:00 2001 From: firebirds <> Date: Sat, 21 Apr 2018 00:04:08 +0000 Subject: [PATCH 125/171] increment build number --- src/jrd/build_no.h | 12 ++++++------ src/misc/writeBuildNum.sh | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/jrd/build_no.h b/src/jrd/build_no.h index 3d1b6c611e..38aa854c31 100644 --- a/src/jrd/build_no.h +++ b/src/jrd/build_no.h @@ -3,16 +3,16 @@ *** DO NOT EDIT *** TO CHANGE ANY INFORMATION IN HERE PLEASE EDIT src/misc/writeBuildNum.sh - FORMAL BUILD NUMBER:962 + FORMAL BUILD NUMBER:964 */ -#define PRODUCT_VER_STRING "4.0.0.962" -#define FILE_VER_STRING "WI-T4.0.0.962" -#define LICENSE_VER_STRING "WI-T4.0.0.962" -#define FILE_VER_NUMBER 4, 0, 0, 962 +#define PRODUCT_VER_STRING "4.0.0.964" +#define FILE_VER_STRING "WI-T4.0.0.964" +#define LICENSE_VER_STRING "WI-T4.0.0.964" +#define FILE_VER_NUMBER 4, 0, 0, 964 #define FB_MAJOR_VER "4" #define FB_MINOR_VER "0" #define FB_REV_NO "0" -#define FB_BUILD_NO "962" +#define FB_BUILD_NO "964" #define FB_BUILD_TYPE "T" #define FB_BUILD_SUFFIX "Firebird 4.0 Alpha 1" diff --git a/src/misc/writeBuildNum.sh b/src/misc/writeBuildNum.sh index cbb050d701..6dce86e3be 100755 --- a/src/misc/writeBuildNum.sh +++ b/src/misc/writeBuildNum.sh @@ -9,7 +9,7 @@ BuildType=T MajorVer=4 MinorVer=0 RevNo=0 -BuildNum=962 +BuildNum=964 NowAt=`pwd` cd `dirname $0` From 5c598b1aa0ad06fad93e40eb748c764d2144b481 Mon Sep 17 00:00:00 2001 From: hvlad Date: Sun, 22 Apr 2018 00:31:55 +0300 Subject: [PATCH 126/171] Avoid recursive locking of plugins list mutex. This fixed deadlock at PluginSet::next. --- src/yvalve/PluginManager.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/yvalve/PluginManager.cpp b/src/yvalve/PluginManager.cpp index ff43204934..0a1d3837fc 100644 --- a/src/yvalve/PluginManager.cpp +++ b/src/yvalve/PluginManager.cpp @@ -1083,8 +1083,6 @@ IPluginSet* PluginManager::getPlugins(CheckStatusWrapper* status, unsigned int i static InitMutex registerBuiltinPlugins("RegisterBuiltinPlugins"); registerBuiltinPlugins.init(); - MutexLockGuard g(plugins->mutex, FB_FUNCTION); - IPluginSet* rc = FB_NEW PluginSet(interfaceType, namesList, firebirdConf); rc->addRef(); return rc; From b1006f7588112216fcbc7268f5d46690761f92fa Mon Sep 17 00:00:00 2001 From: firebirds <> Date: Sun, 22 Apr 2018 00:03:43 +0000 Subject: [PATCH 127/171] increment build number --- src/jrd/build_no.h | 12 ++++++------ src/misc/writeBuildNum.sh | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/jrd/build_no.h b/src/jrd/build_no.h index 38aa854c31..df7f4df8af 100644 --- a/src/jrd/build_no.h +++ b/src/jrd/build_no.h @@ -3,16 +3,16 @@ *** DO NOT EDIT *** TO CHANGE ANY INFORMATION IN HERE PLEASE EDIT src/misc/writeBuildNum.sh - FORMAL BUILD NUMBER:964 + FORMAL BUILD NUMBER:965 */ -#define PRODUCT_VER_STRING "4.0.0.964" -#define FILE_VER_STRING "WI-T4.0.0.964" -#define LICENSE_VER_STRING "WI-T4.0.0.964" -#define FILE_VER_NUMBER 4, 0, 0, 964 +#define PRODUCT_VER_STRING "4.0.0.965" +#define FILE_VER_STRING "WI-T4.0.0.965" +#define LICENSE_VER_STRING "WI-T4.0.0.965" +#define FILE_VER_NUMBER 4, 0, 0, 965 #define FB_MAJOR_VER "4" #define FB_MINOR_VER "0" #define FB_REV_NO "0" -#define FB_BUILD_NO "964" +#define FB_BUILD_NO "965" #define FB_BUILD_TYPE "T" #define FB_BUILD_SUFFIX "Firebird 4.0 Alpha 1" diff --git a/src/misc/writeBuildNum.sh b/src/misc/writeBuildNum.sh index 6dce86e3be..ab990b0c24 100755 --- a/src/misc/writeBuildNum.sh +++ b/src/misc/writeBuildNum.sh @@ -9,7 +9,7 @@ BuildType=T MajorVer=4 MinorVer=0 RevNo=0 -BuildNum=964 +BuildNum=965 NowAt=`pwd` cd `dirname $0` From 835bd1a5503680d43ce239c41a5d072b5b4348a0 Mon Sep 17 00:00:00 2001 From: hvlad Date: Mon, 23 Apr 2018 10:01:39 +0300 Subject: [PATCH 128/171] Fixed bug CORE-5436 : [FB3 SC] Server hangs (under load test) --- src/common/isc_sync.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/common/isc_sync.cpp b/src/common/isc_sync.cpp index e038ae764e..1020c1041b 100644 --- a/src/common/isc_sync.cpp +++ b/src/common/isc_sync.cpp @@ -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); From ea69393b16769ac1b10ce301a299f96acedc52ad Mon Sep 17 00:00:00 2001 From: Roman Simakov Date: Tue, 17 Apr 2018 11:20:26 +0300 Subject: [PATCH 129/171] Fixed CORE-5804: Multiple error in REVOKE operator. Refactored code for revoking grant option, admin option and default roles. Now revoking options for privileges on relation fields recreate necessary privileges for every field. Fixed caching requests (if condition must be the same). --- src/dsql/DdlNodes.epp | 95 +++++++++++++++++++++++-------------------- 1 file changed, 52 insertions(+), 43 deletions(-) diff --git a/src/dsql/DdlNodes.epp b/src/dsql/DdlNodes.epp index abd7247aec..c70c603731 100644 --- a/src/dsql/DdlNodes.epp +++ b/src/dsql/DdlNodes.epp @@ -11389,6 +11389,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) @@ -11402,23 +11404,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; @@ -11487,24 +11488,26 @@ void GrantRevokeNode::grantRevoke(thread_db* tdbb, jrd_tra* transaction, const G } } - 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 @@ -11518,8 +11521,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; @@ -11550,10 +11566,21 @@ void GrantRevokeNode::grantRevoke(thread_db* tdbb, jrd_tra* transaction, const G (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; @@ -11561,25 +11588,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) { From 5541ecfdd6f0e95c30cdb666a91894e83a49e506 Mon Sep 17 00:00:00 2001 From: firebirds <> Date: Tue, 24 Apr 2018 00:03:48 +0000 Subject: [PATCH 130/171] increment build number --- src/jrd/build_no.h | 12 ++++++------ src/misc/writeBuildNum.sh | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/jrd/build_no.h b/src/jrd/build_no.h index df7f4df8af..c984b0ceda 100644 --- a/src/jrd/build_no.h +++ b/src/jrd/build_no.h @@ -3,16 +3,16 @@ *** DO NOT EDIT *** TO CHANGE ANY INFORMATION IN HERE PLEASE EDIT src/misc/writeBuildNum.sh - FORMAL BUILD NUMBER:965 + FORMAL BUILD NUMBER:967 */ -#define PRODUCT_VER_STRING "4.0.0.965" -#define FILE_VER_STRING "WI-T4.0.0.965" -#define LICENSE_VER_STRING "WI-T4.0.0.965" -#define FILE_VER_NUMBER 4, 0, 0, 965 +#define PRODUCT_VER_STRING "4.0.0.967" +#define FILE_VER_STRING "WI-T4.0.0.967" +#define LICENSE_VER_STRING "WI-T4.0.0.967" +#define FILE_VER_NUMBER 4, 0, 0, 967 #define FB_MAJOR_VER "4" #define FB_MINOR_VER "0" #define FB_REV_NO "0" -#define FB_BUILD_NO "965" +#define FB_BUILD_NO "967" #define FB_BUILD_TYPE "T" #define FB_BUILD_SUFFIX "Firebird 4.0 Alpha 1" diff --git a/src/misc/writeBuildNum.sh b/src/misc/writeBuildNum.sh index ab990b0c24..9363d0effb 100755 --- a/src/misc/writeBuildNum.sh +++ b/src/misc/writeBuildNum.sh @@ -9,7 +9,7 @@ BuildType=T MajorVer=4 MinorVer=0 RevNo=0 -BuildNum=965 +BuildNum=967 NowAt=`pwd` cd `dirname $0` From 8e9e03c1aaf1ef514304dc5c7eebef7828c0535f Mon Sep 17 00:00:00 2001 From: hvlad Date: Thu, 26 Apr 2018 22:36:28 +0300 Subject: [PATCH 131/171] Fixed AV's at EDS subsystem - pure virtual call from Manager::shutdown() - garbage m_jrdTran pointer at Transaction::detachFromJrdTran() It could happen when InternalConnection was not destroyed within its bound Jrd::Attachment by some extra-ordinal reason (such as bugcheck). --- src/jrd/extds/ExtDS.cpp | 5 ++++- src/jrd/extds/ExtDS.h | 2 +- src/jrd/extds/InternalDS.cpp | 7 +++++++ 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/jrd/extds/ExtDS.cpp b/src/jrd/extds/ExtDS.cpp index 11a4c9de1c..cfff02d097 100644 --- a/src/jrd/extds/ExtDS.cpp +++ b/src/jrd/extds/ExtDS.cpp @@ -62,10 +62,13 @@ Manager::Manager(MemoryPool& pool) : Manager::~Manager() { + ThreadContextHolder tdbb; + while (m_providers) { Provider* to_delete = m_providers; m_providers = m_providers->m_next; + to_delete->clearConnections(tdbb); delete to_delete; } } @@ -741,7 +744,7 @@ void Transaction::detachFromJrdTran() if (m_scope != traCommon) return; - fb_assert(m_jrdTran); + fb_assert(m_jrdTran || m_connection.isBroken()); if (!m_jrdTran) return; diff --git a/src/jrd/extds/ExtDS.h b/src/jrd/extds/ExtDS.h index 82d47b72ca..9985f5b56b 100644 --- a/src/jrd/extds/ExtDS.h +++ b/src/jrd/extds/ExtDS.h @@ -88,7 +88,6 @@ class Provider : public Firebird::GlobalStorage public: explicit Provider(const char* prvName); - virtual ~Provider(); // return existing or create new Connection virtual Connection* getConnection(Jrd::thread_db* tdbb, const Firebird::PathName& dbName, @@ -120,6 +119,7 @@ public: } protected: + virtual ~Provider(); void clearConnections(Jrd::thread_db* tdbb); virtual Connection* doCreateConnection() = 0; diff --git a/src/jrd/extds/InternalDS.cpp b/src/jrd/extds/InternalDS.cpp index 67b111a4f0..07e5fb3e8f 100644 --- a/src/jrd/extds/InternalDS.cpp +++ b/src/jrd/extds/InternalDS.cpp @@ -334,6 +334,13 @@ void InternalTransaction::doRollback(FbStatusVector* status, thread_db* tdbb, bo { fb_assert(m_transaction); + if (m_connection.isBroken()) + { + m_transaction = NULL; + m_jrdTran = NULL; + return; + } + if (m_scope == traCommon && m_IntConnection.isCurrent()) { if (!retain) { From fe0a74bfe6b3edd886a86a0bfb67923e533acb61 Mon Sep 17 00:00:00 2001 From: hvlad Date: Thu, 26 Apr 2018 22:37:41 +0300 Subject: [PATCH 132/171] Allows to correctly free JTransaction after bugcheck --- src/jrd/jrd.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/jrd/jrd.cpp b/src/jrd/jrd.cpp index 00f2088dcb..fb51765ffd 100644 --- a/src/jrd/jrd.cpp +++ b/src/jrd/jrd.cpp @@ -7367,7 +7367,7 @@ void JTransaction::freeEngineData(CheckStatusWrapper* user_status) try { EngineContextHolder tdbb(user_status, this, FB_FUNCTION); - check_database(tdbb); + check_database(tdbb, true); try { @@ -7390,6 +7390,7 @@ void JTransaction::freeEngineData(CheckStatusWrapper* user_status) } catch (const Exception& ex) { + transaction = NULL; ex.stuffException(user_status); return; } From 146627254de8881f6ded08f7403c979951e77d76 Mon Sep 17 00:00:00 2001 From: firebirds <> Date: Fri, 27 Apr 2018 00:03:11 +0000 Subject: [PATCH 133/171] increment build number --- src/jrd/build_no.h | 12 ++++++------ src/misc/writeBuildNum.sh | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/jrd/build_no.h b/src/jrd/build_no.h index c984b0ceda..f402875ffd 100644 --- a/src/jrd/build_no.h +++ b/src/jrd/build_no.h @@ -3,16 +3,16 @@ *** DO NOT EDIT *** TO CHANGE ANY INFORMATION IN HERE PLEASE EDIT src/misc/writeBuildNum.sh - FORMAL BUILD NUMBER:967 + FORMAL BUILD NUMBER:969 */ -#define PRODUCT_VER_STRING "4.0.0.967" -#define FILE_VER_STRING "WI-T4.0.0.967" -#define LICENSE_VER_STRING "WI-T4.0.0.967" -#define FILE_VER_NUMBER 4, 0, 0, 967 +#define PRODUCT_VER_STRING "4.0.0.969" +#define FILE_VER_STRING "WI-T4.0.0.969" +#define LICENSE_VER_STRING "WI-T4.0.0.969" +#define FILE_VER_NUMBER 4, 0, 0, 969 #define FB_MAJOR_VER "4" #define FB_MINOR_VER "0" #define FB_REV_NO "0" -#define FB_BUILD_NO "967" +#define FB_BUILD_NO "969" #define FB_BUILD_TYPE "T" #define FB_BUILD_SUFFIX "Firebird 4.0 Alpha 1" diff --git a/src/misc/writeBuildNum.sh b/src/misc/writeBuildNum.sh index 9363d0effb..0d1eaf8c34 100755 --- a/src/misc/writeBuildNum.sh +++ b/src/misc/writeBuildNum.sh @@ -9,7 +9,7 @@ BuildType=T MajorVer=4 MinorVer=0 RevNo=0 -BuildNum=967 +BuildNum=969 NowAt=`pwd` cd `dirname $0` From 363dbc7bde3602524a6cb202d03ce67a6233677d Mon Sep 17 00:00:00 2001 From: hvlad Date: Fri, 27 Apr 2018 16:26:41 +0300 Subject: [PATCH 134/171] Addition to the my recent patch (AV related with EDS) --- src/jrd/extds/ExtDS.cpp | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/jrd/extds/ExtDS.cpp b/src/jrd/extds/ExtDS.cpp index cfff02d097..ec41044a4d 100644 --- a/src/jrd/extds/ExtDS.cpp +++ b/src/jrd/extds/ExtDS.cpp @@ -473,14 +473,18 @@ void Connection::clearTransactions(Jrd::thread_db* tdbb) void Connection::clearStatements(thread_db* tdbb) { Statement** stmt_ptr = m_statements.begin(); - Statement** end = m_statements.end(); - - for (; stmt_ptr < end; stmt_ptr++) + while (stmt_ptr < m_statements.end()) { Statement* stmt = *stmt_ptr; if (stmt->isActive()) stmt->close(tdbb); - Statement::deleteStatement(tdbb, stmt); + + // close() above could destroy statement and remove it from m_statements + if (stmt_ptr < m_statements.end() && *stmt_ptr == stmt) + { + Statement::deleteStatement(tdbb, stmt); + stmt_ptr++; + } } m_statements.clear(); @@ -828,6 +832,8 @@ Statement::~Statement() void Statement::deleteStatement(Jrd::thread_db* tdbb, Statement* stmt) { + if (stmt->m_boundReq) + stmt->unBindFromRequest(); stmt->deallocate(tdbb); delete stmt; } From 608105f6797ca487462657556ea7028b8ca18c72 Mon Sep 17 00:00:00 2001 From: hvlad Date: Fri, 27 Apr 2018 16:42:54 +0300 Subject: [PATCH 135/171] Another addition to the my recent patch (AV related with EDS) --- src/jrd/extds/ExtDS.cpp | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/jrd/extds/ExtDS.cpp b/src/jrd/extds/ExtDS.cpp index ec41044a4d..52331c144d 100644 --- a/src/jrd/extds/ExtDS.cpp +++ b/src/jrd/extds/ExtDS.cpp @@ -466,7 +466,15 @@ void Connection::clearTransactions(Jrd::thread_db* tdbb) while (m_transactions.getCount()) { Transaction* tran = m_transactions[0]; - tran->rollback(tdbb, false); + try + { + tran->rollback(tdbb, false); + } + catch (const Exception&) + { + if (!m_deleting) + throw; + } } } @@ -753,6 +761,7 @@ void Transaction::detachFromJrdTran() return; Transaction** tran_ptr = &m_jrdTran->tra_ext_common; + m_jrdTran = NULL; for (; *tran_ptr; tran_ptr = &(*tran_ptr)->m_nextTran) { if (*tran_ptr == this) From 1f423077d1c39776df51dcb42284e76c52098e8e Mon Sep 17 00:00:00 2001 From: firebirds <> Date: Sat, 28 Apr 2018 00:03:10 +0000 Subject: [PATCH 136/171] increment build number --- src/jrd/build_no.h | 12 ++++++------ src/misc/writeBuildNum.sh | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/jrd/build_no.h b/src/jrd/build_no.h index f402875ffd..4024f1b5fa 100644 --- a/src/jrd/build_no.h +++ b/src/jrd/build_no.h @@ -3,16 +3,16 @@ *** DO NOT EDIT *** TO CHANGE ANY INFORMATION IN HERE PLEASE EDIT src/misc/writeBuildNum.sh - FORMAL BUILD NUMBER:969 + FORMAL BUILD NUMBER:971 */ -#define PRODUCT_VER_STRING "4.0.0.969" -#define FILE_VER_STRING "WI-T4.0.0.969" -#define LICENSE_VER_STRING "WI-T4.0.0.969" -#define FILE_VER_NUMBER 4, 0, 0, 969 +#define PRODUCT_VER_STRING "4.0.0.971" +#define FILE_VER_STRING "WI-T4.0.0.971" +#define LICENSE_VER_STRING "WI-T4.0.0.971" +#define FILE_VER_NUMBER 4, 0, 0, 971 #define FB_MAJOR_VER "4" #define FB_MINOR_VER "0" #define FB_REV_NO "0" -#define FB_BUILD_NO "969" +#define FB_BUILD_NO "971" #define FB_BUILD_TYPE "T" #define FB_BUILD_SUFFIX "Firebird 4.0 Alpha 1" diff --git a/src/misc/writeBuildNum.sh b/src/misc/writeBuildNum.sh index 0d1eaf8c34..b36df13305 100755 --- a/src/misc/writeBuildNum.sh +++ b/src/misc/writeBuildNum.sh @@ -9,7 +9,7 @@ BuildType=T MajorVer=4 MinorVer=0 RevNo=0 -BuildNum=969 +BuildNum=971 NowAt=`pwd` cd `dirname $0` From fd4a1849b37c8329f0edb3bdea7e764c33dbf39e Mon Sep 17 00:00:00 2001 From: Adriano dos Santos Fernandes Date: Mon, 30 Apr 2018 13:10:38 -0300 Subject: [PATCH 137/171] Fixed blr_dec* print. --- src/yvalve/gds.cpp | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/yvalve/gds.cpp b/src/yvalve/gds.cpp index 935bab7c78..6cacd49870 100644 --- a/src/yvalve/gds.cpp +++ b/src/yvalve/gds.cpp @@ -2964,10 +2964,11 @@ static int blr_print_dtype(gds_ctl* control) break; case blr_double: + case blr_dec128: { - string = "double"; + string = dtype == blr_double ? "double" : "dec128"; - // for double literal, return the length of the numeric string + // for double/dec_128 literal, return the length of the numeric string const UCHAR* pos = control->ctl_blr_reader.getPos(); const UCHAR v1 = control->ctl_blr_reader.getByte(); const UCHAR v2 = control->ctl_blr_reader.getByte(); @@ -3015,6 +3016,16 @@ static int blr_print_dtype(gds_ctl* control) length = 1; break; + case blr_dec64: + string = "dec64"; + length = sizeof(Firebird::Decimal64); + break; + + case blr_dec_fixed: + string = "dec_fixed"; + length = sizeof(Firebird::DecimalFixed); + break; + case blr_domain_name: string = "domain_name"; // Don't bother with this length. @@ -3076,6 +3087,7 @@ static int blr_print_dtype(gds_ctl* control) case blr_long: case blr_quad: case blr_int64: + case blr_dec_fixed: blr_print_byte(control); break; From 328d204ca2e245070dbbfb542bd00692af0ad986 Mon Sep 17 00:00:00 2001 From: firebirds <> Date: Tue, 1 May 2018 00:02:56 +0000 Subject: [PATCH 138/171] increment build number --- src/jrd/build_no.h | 12 ++++++------ src/misc/writeBuildNum.sh | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/jrd/build_no.h b/src/jrd/build_no.h index 4024f1b5fa..ec249dc3a6 100644 --- a/src/jrd/build_no.h +++ b/src/jrd/build_no.h @@ -3,16 +3,16 @@ *** DO NOT EDIT *** TO CHANGE ANY INFORMATION IN HERE PLEASE EDIT src/misc/writeBuildNum.sh - FORMAL BUILD NUMBER:971 + FORMAL BUILD NUMBER:972 */ -#define PRODUCT_VER_STRING "4.0.0.971" -#define FILE_VER_STRING "WI-T4.0.0.971" -#define LICENSE_VER_STRING "WI-T4.0.0.971" -#define FILE_VER_NUMBER 4, 0, 0, 971 +#define PRODUCT_VER_STRING "4.0.0.972" +#define FILE_VER_STRING "WI-T4.0.0.972" +#define LICENSE_VER_STRING "WI-T4.0.0.972" +#define FILE_VER_NUMBER 4, 0, 0, 972 #define FB_MAJOR_VER "4" #define FB_MINOR_VER "0" #define FB_REV_NO "0" -#define FB_BUILD_NO "971" +#define FB_BUILD_NO "972" #define FB_BUILD_TYPE "T" #define FB_BUILD_SUFFIX "Firebird 4.0 Alpha 1" diff --git a/src/misc/writeBuildNum.sh b/src/misc/writeBuildNum.sh index b36df13305..ced057c85d 100755 --- a/src/misc/writeBuildNum.sh +++ b/src/misc/writeBuildNum.sh @@ -9,7 +9,7 @@ BuildType=T MajorVer=4 MinorVer=0 RevNo=0 -BuildNum=971 +BuildNum=972 NowAt=`pwd` cd `dirname $0` From 7c330bc7b455c22f30f2545059f98d91f4d64ee4 Mon Sep 17 00:00:00 2001 From: hvlad Date: Thu, 3 May 2018 13:17:35 +0300 Subject: [PATCH 139/171] This fixed deadlock on Windows when one thread unload some plugin(s) (due to shutdown, for ex.) and another thread run threadDetach() --- src/yvalve/PluginManager.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/yvalve/PluginManager.cpp b/src/yvalve/PluginManager.cpp index 0a1d3837fc..ee5c83622b 100644 --- a/src/yvalve/PluginManager.cpp +++ b/src/yvalve/PluginManager.cpp @@ -1104,9 +1104,9 @@ void PluginManager::releasePlugin(IPluginBase* plugin) ///fb_assert(parent); if (parent) { - MutexLockGuard g(plugins->mutex, FB_FUNCTION); - parent->release(); + + MutexLockGuard g(plugins->mutex, FB_FUNCTION); if (plugins->wakeIt) { plugins->wakeIt->release(); From 504455779bf0dabecf6a97d7b655416a2684a54b Mon Sep 17 00:00:00 2001 From: firebirds <> Date: Fri, 4 May 2018 00:03:07 +0000 Subject: [PATCH 140/171] increment build number --- src/jrd/build_no.h | 12 ++++++------ src/misc/writeBuildNum.sh | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/jrd/build_no.h b/src/jrd/build_no.h index ec249dc3a6..35012cd4ab 100644 --- a/src/jrd/build_no.h +++ b/src/jrd/build_no.h @@ -3,16 +3,16 @@ *** DO NOT EDIT *** TO CHANGE ANY INFORMATION IN HERE PLEASE EDIT src/misc/writeBuildNum.sh - FORMAL BUILD NUMBER:972 + FORMAL BUILD NUMBER:973 */ -#define PRODUCT_VER_STRING "4.0.0.972" -#define FILE_VER_STRING "WI-T4.0.0.972" -#define LICENSE_VER_STRING "WI-T4.0.0.972" -#define FILE_VER_NUMBER 4, 0, 0, 972 +#define PRODUCT_VER_STRING "4.0.0.973" +#define FILE_VER_STRING "WI-T4.0.0.973" +#define LICENSE_VER_STRING "WI-T4.0.0.973" +#define FILE_VER_NUMBER 4, 0, 0, 973 #define FB_MAJOR_VER "4" #define FB_MINOR_VER "0" #define FB_REV_NO "0" -#define FB_BUILD_NO "972" +#define FB_BUILD_NO "973" #define FB_BUILD_TYPE "T" #define FB_BUILD_SUFFIX "Firebird 4.0 Alpha 1" diff --git a/src/misc/writeBuildNum.sh b/src/misc/writeBuildNum.sh index ced057c85d..ba40789100 100755 --- a/src/misc/writeBuildNum.sh +++ b/src/misc/writeBuildNum.sh @@ -9,7 +9,7 @@ BuildType=T MajorVer=4 MinorVer=0 RevNo=0 -BuildNum=972 +BuildNum=973 NowAt=`pwd` cd `dirname $0` From 6863601af6aec4d31d799473cc7c5b742158018f Mon Sep 17 00:00:00 2001 From: AlexPeshkoff Date: Fri, 4 May 2018 21:12:13 +0300 Subject: [PATCH 141/171] Fixed CORE-5815: Server hangs for 60/120 seconds if client exits during database encryption key transfer callback --- src/remote/server/server.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/remote/server/server.cpp b/src/remote/server/server.cpp index fc845fe2aa..3a3f1f4545 100644 --- a/src/remote/server/server.cpp +++ b/src/remote/server/server.cpp @@ -1600,6 +1600,9 @@ void SRVR_multi_thread( rem_port* main_port, USHORT flags) else { request->req_receive.p_operation = ok ? op_dummy : op_exit; + + if (port->port_server_crypt_callback) + port->port_server_crypt_callback->wakeup(0, NULL); } request->req_port = port; From 1b49baad6b31ebc5ae5e1a5f62ef064ae27ae1ef Mon Sep 17 00:00:00 2001 From: firebirds <> Date: Sat, 5 May 2018 00:03:08 +0000 Subject: [PATCH 142/171] increment build number --- src/jrd/build_no.h | 12 ++++++------ src/misc/writeBuildNum.sh | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/jrd/build_no.h b/src/jrd/build_no.h index 35012cd4ab..f785ace367 100644 --- a/src/jrd/build_no.h +++ b/src/jrd/build_no.h @@ -3,16 +3,16 @@ *** DO NOT EDIT *** TO CHANGE ANY INFORMATION IN HERE PLEASE EDIT src/misc/writeBuildNum.sh - FORMAL BUILD NUMBER:973 + FORMAL BUILD NUMBER:974 */ -#define PRODUCT_VER_STRING "4.0.0.973" -#define FILE_VER_STRING "WI-T4.0.0.973" -#define LICENSE_VER_STRING "WI-T4.0.0.973" -#define FILE_VER_NUMBER 4, 0, 0, 973 +#define PRODUCT_VER_STRING "4.0.0.974" +#define FILE_VER_STRING "WI-T4.0.0.974" +#define LICENSE_VER_STRING "WI-T4.0.0.974" +#define FILE_VER_NUMBER 4, 0, 0, 974 #define FB_MAJOR_VER "4" #define FB_MINOR_VER "0" #define FB_REV_NO "0" -#define FB_BUILD_NO "973" +#define FB_BUILD_NO "974" #define FB_BUILD_TYPE "T" #define FB_BUILD_SUFFIX "Firebird 4.0 Alpha 1" diff --git a/src/misc/writeBuildNum.sh b/src/misc/writeBuildNum.sh index ba40789100..85c3b6ee8d 100755 --- a/src/misc/writeBuildNum.sh +++ b/src/misc/writeBuildNum.sh @@ -9,7 +9,7 @@ BuildType=T MajorVer=4 MinorVer=0 RevNo=0 -BuildNum=973 +BuildNum=974 NowAt=`pwd` cd `dirname $0` From e8d3881fd7cbb3bf9b0ade10ad64cbbde65a7bac Mon Sep 17 00:00:00 2001 From: hvlad Date: Wed, 9 May 2018 12:53:47 +0300 Subject: [PATCH 143/171] Fixed bug CORE-5819 : Attachment might not gone after it was DELETEd FROM MON$ATTACHMENTS --- src/jrd/jrd.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/jrd/jrd.cpp b/src/jrd/jrd.cpp index fb51765ffd..b8bd36655e 100644 --- a/src/jrd/jrd.cpp +++ b/src/jrd/jrd.cpp @@ -7946,6 +7946,7 @@ namespace { StableAttachmentPart* const sAtt = *iter; + MutexLockGuard guardBlocking(*(sAtt->getBlockingMutex()), FB_FUNCTION); MutexLockGuard guard(*(sAtt->getMutex()), FB_FUNCTION); Attachment* attachment = sAtt->getHandle(); From 3f417021dac1c4d7be7ae89e2b62c63a8ad63369 Mon Sep 17 00:00:00 2001 From: firebirds <> Date: Thu, 10 May 2018 00:03:01 +0000 Subject: [PATCH 144/171] increment build number --- src/jrd/build_no.h | 12 ++++++------ src/misc/writeBuildNum.sh | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/jrd/build_no.h b/src/jrd/build_no.h index f785ace367..55d36c0ab4 100644 --- a/src/jrd/build_no.h +++ b/src/jrd/build_no.h @@ -3,16 +3,16 @@ *** DO NOT EDIT *** TO CHANGE ANY INFORMATION IN HERE PLEASE EDIT src/misc/writeBuildNum.sh - FORMAL BUILD NUMBER:974 + FORMAL BUILD NUMBER:975 */ -#define PRODUCT_VER_STRING "4.0.0.974" -#define FILE_VER_STRING "WI-T4.0.0.974" -#define LICENSE_VER_STRING "WI-T4.0.0.974" -#define FILE_VER_NUMBER 4, 0, 0, 974 +#define PRODUCT_VER_STRING "4.0.0.975" +#define FILE_VER_STRING "WI-T4.0.0.975" +#define LICENSE_VER_STRING "WI-T4.0.0.975" +#define FILE_VER_NUMBER 4, 0, 0, 975 #define FB_MAJOR_VER "4" #define FB_MINOR_VER "0" #define FB_REV_NO "0" -#define FB_BUILD_NO "974" +#define FB_BUILD_NO "975" #define FB_BUILD_TYPE "T" #define FB_BUILD_SUFFIX "Firebird 4.0 Alpha 1" diff --git a/src/misc/writeBuildNum.sh b/src/misc/writeBuildNum.sh index 85c3b6ee8d..6a4bec1742 100755 --- a/src/misc/writeBuildNum.sh +++ b/src/misc/writeBuildNum.sh @@ -9,7 +9,7 @@ BuildType=T MajorVer=4 MinorVer=0 RevNo=0 -BuildNum=974 +BuildNum=975 NowAt=`pwd` cd `dirname $0` From 7de1b2ac9b9b87d07f2be7ff740f713b7e841d3b Mon Sep 17 00:00:00 2001 From: AlexPeshkoff Date: Thu, 10 May 2018 15:58:45 +0300 Subject: [PATCH 145/171] Fixed CORE-5822: Wrong error returned to client when WireCrypt=Disabled is used --- src/remote/server/server.cpp | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/src/remote/server/server.cpp b/src/remote/server/server.cpp index 3a3f1f4545..7033d143f9 100644 --- a/src/remote/server/server.cpp +++ b/src/remote/server/server.cpp @@ -1779,13 +1779,8 @@ public: static void setErrorStatus(IStatus* status) { Arg::Gds loginError(isc_login); -#ifndef DEV_BUILD - if (status->getErrors()[1] == isc_missing_data_structures) -#endif - { - loginError << Arg::StatusVector(status->getErrors()); - } - status->setErrors(loginError.value()); + if (!(status->getState() & IStatus::STATE_ERRORS)) + status->setErrors(loginError.value()); } static bool accept_connection(rem_port* port, P_CNCT* connect, PACKET* send) @@ -2004,12 +1999,27 @@ static bool accept_connection(rem_port* port, P_CNCT* connect, PACKET* send) } } + // Send off out gracious acceptance or flag rejection if (!accepted) { HANDSHAKE_DEBUG(fprintf(stderr, "!accepted, sending reject\n")); if (status.getState() & Firebird::IStatus::STATE_ERRORS) - port->send_response(send, 0, 0, &status, false); + { + if (status.getErrors()[1] != isc_missing_data_structures) + { + iscLogStatus("Authentication error", &status); + Arg::Gds loginError(isc_login_error); +#ifdef DEV_BUILD + loginError << Arg::StatusVector(&status); +#endif + LocalStatus tmp; + loginError.copyTo(&tmp); + port->send_response(send, 0, 0, &tmp, false); + } + else + port->send_response(send, 0, 0, &status, false); + } else port->send(send); return false; From 1ce7f66555817cb77688d8d91c0610d13bf06dd9 Mon Sep 17 00:00:00 2001 From: AlexPeshkoff Date: Thu, 10 May 2018 18:18:24 +0300 Subject: [PATCH 146/171] Misc docs addition --- doc/Using_OO_API.html | 77 ++++++++++++++++++------------------------- 1 file changed, 32 insertions(+), 45 deletions(-) diff --git a/doc/Using_OO_API.html b/doc/Using_OO_API.html index 114d7af8ff..e4c50b7a70 100644 --- a/doc/Using_OO_API.html +++ b/doc/Using_OO_API.html @@ -3,27 +3,16 @@ - + - - + + + - - - - - - - - - - - -