From: <ale...@us...> - 2014-04-22 13:37:18
|
Revision: 59470 http://sourceforge.net/p/firebird/code/59470 Author: alexpeshkoff Date: 2014-04-22 13:37:14 +0000 (Tue, 22 Apr 2014) Log Message: ----------- Fixed CORE-2119: Use entries in restrict list of ExternalFileAccess parameter to mangle filenames with relative path, also fixed assertion and diagnostics related to EXTERNAL FILE tables Modified Paths: -------------- firebird/trunk/lang_helpers/gds_codes.ftn firebird/trunk/lang_helpers/gds_codes.pas firebird/trunk/src/common/os/path_utils.h firebird/trunk/src/common/os/posix/path_utils.cpp firebird/trunk/src/common/os/win32/path_utils.cpp firebird/trunk/src/dsql/DdlNodes.epp firebird/trunk/src/include/gen/codetext.h firebird/trunk/src/include/gen/iberror.h firebird/trunk/src/include/gen/msgs.h firebird/trunk/src/include/gen/sql_code.h firebird/trunk/src/include/gen/sql_state.h firebird/trunk/src/jrd/constants.h firebird/trunk/src/jrd/ext.cpp firebird/trunk/src/msgs/facilities2.sql firebird/trunk/src/msgs/messages2.sql firebird/trunk/src/msgs/system_errors2.sql Modified: firebird/trunk/lang_helpers/gds_codes.ftn =================================================================== --- firebird/trunk/lang_helpers/gds_codes.ftn 2014-04-22 00:45:43 UTC (rev 59469) +++ firebird/trunk/lang_helpers/gds_codes.ftn 2014-04-22 13:37:14 UTC (rev 59470) @@ -1854,6 +1854,8 @@ PARAMETER (GDS__dyn_cant_modify_sysobj = 336068895) INTEGER*4 GDS__dyn_cant_use_zero_increment PARAMETER (GDS__dyn_cant_use_zero_increment = 336068896) + INTEGER*4 GDS__dyn_cant_use_in_foreignkey + PARAMETER (GDS__dyn_cant_use_in_foreignkey = 336068897) INTEGER*4 GDS__gbak_unknown_switch PARAMETER (GDS__gbak_unknown_switch = 336330753) INTEGER*4 GDS__gbak_page_size_missing Modified: firebird/trunk/lang_helpers/gds_codes.pas =================================================================== --- firebird/trunk/lang_helpers/gds_codes.pas 2014-04-22 00:45:43 UTC (rev 59469) +++ firebird/trunk/lang_helpers/gds_codes.pas 2014-04-22 13:37:14 UTC (rev 59470) @@ -934,6 +934,7 @@ gds_dyn_duplicate_package_item = 336068894; gds_dyn_cant_modify_sysobj = 336068895; gds_dyn_cant_use_zero_increment = 336068896; + gds_dyn_cant_use_in_foreignkey = 336068897; gds_gbak_unknown_switch = 336330753; gds_gbak_page_size_missing = 336330754; gds_gbak_page_size_toobig = 336330755; Modified: firebird/trunk/src/common/os/path_utils.h =================================================================== --- firebird/trunk/src/common/os/path_utils.h 2014-04-22 00:45:43 UTC (rev 59469) +++ firebird/trunk/src/common/os/path_utils.h 2014-04-22 13:37:14 UTC (rev 59470) @@ -167,6 +167,11 @@ platform. **/ static void setDirIterator(char* path); + + /** makeDir creates directory passed as parameter. + return value is 0 on success or error code on error. + **/ + static int makeDir(const Firebird::PathName& path); }; #endif // JRD_OS_PATH_UTILS_H Modified: firebird/trunk/src/common/os/posix/path_utils.cpp =================================================================== --- firebird/trunk/src/common/os/posix/path_utils.cpp 2014-04-22 00:45:43 UTC (rev 59469) +++ firebird/trunk/src/common/os/posix/path_utils.cpp 2014-04-22 13:37:14 UTC (rev 59470) @@ -200,3 +200,13 @@ *path = '/'; } } + +int PathUtils::makeDir(const Firebird::PathName& path) +{ + int rc = mkdir(path.c_str(), 0770) ? errno : 0; + if (rc == 0) + { + // try to set exact access we need but ignore possible errors + chmod(path.c_str(), 0770); + } +} Modified: firebird/trunk/src/common/os/win32/path_utils.cpp =================================================================== --- firebird/trunk/src/common/os/win32/path_utils.cpp 2014-04-22 00:45:43 UTC (rev 59469) +++ firebird/trunk/src/common/os/win32/path_utils.cpp 2014-04-22 13:37:14 UTC (rev 59470) @@ -1,7 +1,8 @@ #include "firebird.h" #include "../common/os/path_utils.h" -#include <io.h> // _access +#include <io.h> // _access +#include <direct.h> // _mkdir /// The Win32 implementation of the path_utils abstraction. @@ -195,3 +196,7 @@ } } +int PathUtils::makeDir(const Firebird::PathName& path) +{ + return _mkdir(path.c_str()) ? errno : 0; +} Modified: firebird/trunk/src/dsql/DdlNodes.epp =================================================================== --- firebird/trunk/src/dsql/DdlNodes.epp 2014-04-22 00:45:43 UTC (rev 59469) +++ firebird/trunk/src/dsql/DdlNodes.epp 2014-04-22 13:37:14 UTC (rev 59470) @@ -83,7 +83,11 @@ const MetaName& fieldName); static bool isItSqlRole(thread_db* tdbb, jrd_tra* transaction, const MetaName& inputName, MetaName& outputName); -static void makeRelationScopeName(const MetaName& name, const rel_t type, string& message); +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); +static void checkFkPairTypes(const rel_t masterType, const MetaName& masterName, + const rel_t childType, const MetaName& childName); static void modifyLocalFieldPosition(thread_db* tdbb, jrd_tra* transaction, const MetaName& relationName, const MetaName& fieldName, USHORT newPosition, USHORT existingPosition); @@ -116,8 +120,8 @@ const MetaName& childRelName, const MetaName& masterIndexName) { AutoCacheRequest request(tdbb, drq_l_rel_info, DYN_REQUESTS); - bool error = false; - string master, child; + MetaName masterRelName; + rel_t masterType, childType; FOR(REQUEST_HANDLE request TRANSACTION_HANDLE transaction) RLC_M IN RDB$RELATION_CONSTRAINTS CROSS @@ -129,32 +133,20 @@ REL_C.RDB$RELATION_NAME EQ childRelName.c_str() AND REL_M.RDB$RELATION_NAME EQ RLC_M.RDB$RELATION_NAME { - const rel_t masterType = relationType(REL_M.RDB$RELATION_TYPE.NULL, REL_M.RDB$RELATION_TYPE); - fb_assert(masterType == rel_persistent || - masterType == rel_global_temp_preserve || - masterType == rel_global_temp_delete); + fb_assert(!masterRelName.hasData()); - const rel_t childType = relationType(REL_C.RDB$RELATION_TYPE.NULL, REL_C.RDB$RELATION_TYPE); - fb_assert(childType == rel_persistent || - childType == rel_global_temp_preserve || - childType == rel_global_temp_delete); + masterRelName = REL_M.RDB$RELATION_NAME; + masterType = relationType(REL_M.RDB$RELATION_TYPE.NULL, REL_M.RDB$RELATION_TYPE); + childType = relationType(REL_C.RDB$RELATION_TYPE.NULL, REL_C.RDB$RELATION_TYPE); - error = masterType != childType && - !(masterType == rel_global_temp_preserve && childType == rel_global_temp_delete); - - if (error) - { - makeRelationScopeName(masterIndexName, masterType, master); - makeRelationScopeName(childRelName, childType, child); - break; - } } END_FOR - if (error) + if (masterRelName.hasData()) { - // Msg 232 : "%s can't reference %s" - status_exception::raise(Arg::PrivateDyn(232) << child << master); + checkRelationType(masterType, masterRelName); + checkRelationType(childType, childRelName); + checkFkPairTypes(masterType, masterRelName, childType, childRelName); } } @@ -171,8 +163,8 @@ } AutoCacheRequest request(tdbb, drq_l_rel_info2, DYN_REQUESTS); - bool error = false; - string master, child; + MetaName masterRelName; + rel_t masterType; FOR(REQUEST_HANDLE request TRANSACTION_HANDLE transaction) RLC_C IN RDB$RELATION_CONSTRAINTS CROSS @@ -185,27 +177,17 @@ IND_M.RDB$INDEX_NAME EQ IND_C.RDB$FOREIGN_KEY AND IND_M.RDB$RELATION_NAME EQ REL_M.RDB$RELATION_NAME { - const rel_t masterType = relationType(REL_M.RDB$RELATION_TYPE.NULL, REL_M.RDB$RELATION_TYPE); - fb_assert(masterType == rel_persistent || - masterType == rel_global_temp_preserve || - masterType == rel_global_temp_delete); + fb_assert(!masterRelName.hasData()); - error = masterType != childType && - !(masterType == rel_global_temp_preserve && childType == rel_global_temp_delete); - - if (error) - { - makeRelationScopeName(REL_M.RDB$RELATION_NAME, masterType, master); - makeRelationScopeName(childRelName, childType, child); - break; - } + masterType = relationType(REL_M.RDB$RELATION_TYPE.NULL, REL_M.RDB$RELATION_TYPE); + masterRelName = REL_M.RDB$RELATION_NAME; } END_FOR - if (error) + if (masterRelName.hasData()) { - // Msg 232 : "%s can't reference %s" - status_exception::raise(Arg::PrivateDyn(232) << child << master); + checkRelationType(masterType, masterRelName); + checkFkPairTypes(masterType, masterRelName, childType, childRelName); } } @@ -480,20 +462,63 @@ } // Make string with relation name and type of its temporary scope. -static void makeRelationScopeName(const MetaName& name, const rel_t type, string& message) +static void makeRelationScopeName(string& to, const MetaName& name, const rel_t type) { - const char* scope = NULL; + const char* scope = getRelationScopeName(type); + to.printf(scope, name.c_str()); +} - if (type == rel_global_temp_preserve) - scope = REL_SCOPE_GTT_PRESERVE; - else if (type == rel_global_temp_delete) - scope = REL_SCOPE_GTT_DELETE; - else - scope = REL_SCOPE_PERSISTENT; +// Get relation type name +static const char* getRelationScopeName(const rel_t type) +{ + switch(type) + { + case rel_global_temp_preserve: + return REL_SCOPE_GTT_PRESERVE; + case rel_global_temp_delete: + return REL_SCOPE_GTT_DELETE; + case rel_external: + return REL_SCOPE_EXTERNAL; + case rel_view: + return REL_SCOPE_VIEW; + case rel_virtual: + return REL_SCOPE_VIRTUAL; + } - message.printf(scope, name.c_str()); + return REL_SCOPE_PERSISTENT; } +// Check does relation of given type can be used in FK +static void checkRelationType(const rel_t type, const MetaName& name) +{ + if (type == rel_persistent || + type == rel_global_temp_preserve || + type == rel_global_temp_delete) + { + return; + } + + string scope; + makeRelationScopeName(scope, name, type); + (Arg::PrivateDyn(289) << scope).raise(); +} + +// Check does pair of relations can be used in FK +static void checkFkPairTypes(const rel_t masterType, const MetaName& masterName, + const rel_t childType, const MetaName& childName) +{ + if (masterType != childType && + !(masterType == rel_global_temp_preserve && childType == rel_global_temp_delete)) + { + string master, child; + makeRelationScopeName(master, masterName, masterType); + makeRelationScopeName(child, childName, childType); + // Msg 232 : "%s can't reference %s" + status_exception::raise(Arg::PrivateDyn(232) << child << master); + } +} + + // Alters the position of a field with respect to the // other fields in the relation. This will only affect // the order in which the fields will be returned when either @@ -6567,25 +6592,11 @@ if (externalFile->length() >= sizeof(REL.RDB$EXTERNAL_FILE)) status_exception::raise(Arg::Gds(isc_dyn_name_longer)); - REL.RDB$EXTERNAL_FILE.NULL = FALSE; - strcpy(REL.RDB$EXTERNAL_FILE, externalFile->c_str()); - if (ISC_check_if_remote(externalFile->c_str(), false)) status_exception::raise(Arg::PrivateDyn(163)); - // Check for any path, present in filename. - // If miss it, file will be searched in External Tables Dirs, - // that's why no expand_filename required. - - PathName path, file; - PathUtils::splitLastComponent(path, file, externalFile->c_str()); - - if (path.hasData()) // path component present in filename - { - ISC_expand_filename(REL.RDB$EXTERNAL_FILE, strlen(REL.RDB$EXTERNAL_FILE), - REL.RDB$EXTERNAL_FILE, sizeof(REL.RDB$EXTERNAL_FILE), false); - } - + REL.RDB$EXTERNAL_FILE.NULL = FALSE; + strcpy(REL.RDB$EXTERNAL_FILE, externalFile->c_str()); REL.RDB$RELATION_TYPE = rel_external; } } Modified: firebird/trunk/src/include/gen/codetext.h =================================================================== --- firebird/trunk/src/include/gen/codetext.h 2014-04-22 00:45:43 UTC (rev 59469) +++ firebird/trunk/src/include/gen/codetext.h 2014-04-22 13:37:14 UTC (rev 59470) @@ -923,6 +923,7 @@ {"dyn_duplicate_package_item", 336068894}, {"dyn_cant_modify_sysobj", 336068895}, {"dyn_cant_use_zero_increment", 336068896}, + {"dyn_cant_use_in_foreignkey", 336068897}, {"gbak_unknown_switch", 336330753}, {"gbak_page_size_missing", 336330754}, {"gbak_page_size_toobig", 336330755}, Modified: firebird/trunk/src/include/gen/iberror.h =================================================================== --- firebird/trunk/src/include/gen/iberror.h 2014-04-22 00:45:43 UTC (rev 59469) +++ firebird/trunk/src/include/gen/iberror.h 2014-04-22 13:37:14 UTC (rev 59470) @@ -957,6 +957,7 @@ const ISC_STATUS isc_dyn_duplicate_package_item = 336068894L; const ISC_STATUS isc_dyn_cant_modify_sysobj = 336068895L; const ISC_STATUS isc_dyn_cant_use_zero_increment = 336068896L; +const ISC_STATUS isc_dyn_cant_use_in_foreignkey = 336068897L; const ISC_STATUS isc_gbak_unknown_switch = 336330753L; const ISC_STATUS isc_gbak_page_size_missing = 336330754L; const ISC_STATUS isc_gbak_page_size_toobig = 336330755L; @@ -1277,7 +1278,7 @@ const ISC_STATUS isc_trace_switch_param_miss = 337182758L; const ISC_STATUS isc_trace_param_act_notcompat = 337182759L; const ISC_STATUS isc_trace_mandatory_switch_miss = 337182760L; -const ISC_STATUS isc_err_max = 1221; +const ISC_STATUS isc_err_max = 1222; #else /* c definitions */ @@ -2204,6 +2205,7 @@ #define isc_dyn_duplicate_package_item 336068894L #define isc_dyn_cant_modify_sysobj 336068895L #define isc_dyn_cant_use_zero_increment 336068896L +#define isc_dyn_cant_use_in_foreignkey 336068897L #define isc_gbak_unknown_switch 336330753L #define isc_gbak_page_size_missing 336330754L #define isc_gbak_page_size_toobig 336330755L @@ -2524,7 +2526,7 @@ #define isc_trace_switch_param_miss 337182758L #define isc_trace_param_act_notcompat 337182759L #define isc_trace_mandatory_switch_miss 337182760L -#define isc_err_max 1221 +#define isc_err_max 1222 #endif Modified: firebird/trunk/src/include/gen/msgs.h =================================================================== --- firebird/trunk/src/include/gen/msgs.h 2014-04-22 00:45:43 UTC (rev 59469) +++ firebird/trunk/src/include/gen/msgs.h 2014-04-22 13:37:14 UTC (rev 59470) @@ -926,6 +926,7 @@ {336068894, "Duplicate @1 @2"}, /* dyn_duplicate_package_item */ {336068895, "System @1 @2 cannot be modified"}, /* dyn_cant_modify_sysobj */ {336068896, "INCREMENT BY 0 is an illegal option for sequence @1"}, /* dyn_cant_use_zero_increment */ + {336068897, "Can't use @1 in FOREIGN KEY constraint"}, /* dyn_cant_use_in_foreignkey */ {336330753, "found unknown switch"}, /* gbak_unknown_switch */ {336330754, "page size parameter missing"}, /* gbak_page_size_missing */ {336330755, "Page size specified (@1) greater than limit (16384 bytes)"}, /* gbak_page_size_toobig */ Modified: firebird/trunk/src/include/gen/sql_code.h =================================================================== --- firebird/trunk/src/include/gen/sql_code.h 2014-04-22 00:45:43 UTC (rev 59469) +++ firebird/trunk/src/include/gen/sql_code.h 2014-04-22 13:37:14 UTC (rev 59470) @@ -922,6 +922,7 @@ {336068894, -901}, /* 286 dyn_duplicate_package_item */ {336068895, -901}, /* 287 dyn_cant_modify_sysobj */ {336068896, -901}, /* 288 dyn_cant_use_zero_increment */ + {336068897, -901}, /* 289 dyn_cant_use_in_foreignkey */ {336330753, -901}, /* 1 gbak_unknown_switch */ {336330754, -901}, /* 2 gbak_page_size_missing */ {336330755, -901}, /* 3 gbak_page_size_toobig */ Modified: firebird/trunk/src/include/gen/sql_state.h =================================================================== --- firebird/trunk/src/include/gen/sql_state.h 2014-04-22 00:45:43 UTC (rev 59469) +++ firebird/trunk/src/include/gen/sql_state.h 2014-04-22 13:37:14 UTC (rev 59470) @@ -922,6 +922,7 @@ {336068894, "42000"}, // 286 dyn_duplicate_package_item {336068895, "42000"}, // 287 dyn_cant_modify_sysobj {336068896, "42000"}, // 288 dyn_cant_use_zero_increment + {336068897, "42000"}, // 289 dyn_cant_use_in_foreignkey {336330753, "00000"}, // 1 gbak_unknown_switch {336330754, "00000"}, // 2 gbak_page_size_missing {336330755, "00000"}, // 3 gbak_page_size_toobig Modified: firebird/trunk/src/jrd/constants.h =================================================================== --- firebird/trunk/src/jrd/constants.h 2014-04-22 00:45:43 UTC (rev 59469) +++ firebird/trunk/src/jrd/constants.h 2014-04-22 13:37:14 UTC (rev 59470) @@ -102,6 +102,9 @@ const char* const REL_SCOPE_PERSISTENT = "persistent table \"%s\""; const char* const REL_SCOPE_GTT_PRESERVE = "global temporary table \"%s\" of type ON COMMIT PRESERVE ROWS"; const char* const REL_SCOPE_GTT_DELETE = "global temporary table \"%s\" of type ON COMMIT DELETE ROWS"; +const char* const REL_SCOPE_EXTERNAL = "external table \"%s\""; +const char* const REL_SCOPE_VIEW = "view \"%s\""; +const char* const REL_SCOPE_VIRTUAL = "virtual table \"%s\""; // literal strings in rdb$ref_constraints to be used to identify // the cascade actions for referential constraints. Used Modified: firebird/trunk/src/jrd/ext.cpp =================================================================== --- firebird/trunk/src/jrd/ext.cpp 2014-04-22 00:45:43 UTC (rev 59469) +++ firebird/trunk/src/jrd/ext.cpp 2014-04-22 13:37:14 UTC (rev 59470) @@ -58,6 +58,7 @@ #include "../common/config/dir_list.h" #include "../common/os/path_utils.h" #include "../common/classes/init.h" +#include "../common/isc_f_proto.h" #if defined _MSC_VER && _MSC_VER < 1400 // NS: in VS2003 these only work with static CRT @@ -258,20 +259,45 @@ _setmaxstdio(2048); #endif - // If file_name has no path part, expand it in ExternalFilesPath. - PathName path, name; - PathUtils::splitLastComponent(path, name, file_name); - if (path.isEmpty()) + // If file_name is relative expand it in ExternalFilesPath. + PathName newName, name(file_name); + if (PathUtils::isRelative(name)) { - // path component not present in file_name ExternalFileDirectoryList::create(dbb); - if (!(dbb->dbb_external_file_directory_list->expandFileName(path, name))) + if (!(dbb->dbb_external_file_directory_list->expandFileName(newName, name))) { - dbb->dbb_external_file_directory_list->defaultName(path, name); + if (!dbb->dbb_external_file_directory_list->defaultName(newName, name)) + { + ISC_expand_filename(newName, false); + } } - file_name = path.c_str(); + file_name = newName.c_str(); + name = newName; } + // Create missing path components + ObjectsArray<PathName> paths; + for(;;) + { + PathName path, file; + PathUtils::splitLastComponent(path, file, name); + if (path.isEmpty()) + break; + + int rc = PathUtils::makeDir(path.c_str()); + if (rc == 0 || rc == EEXIST) + break; + paths.push(path); + name = path; + } + while(paths.hasData()) + { + PathName path(paths.pop()); + if (PathUtils::makeDir(path.c_str()) != 0) + break; + } + paths.clear(); + ExternalFile* file = FB_NEW_RPT(*relation->rel_pool, (strlen(file_name) + 1)) ExternalFile(); relation->rel_file = file; strcpy(file->ext_filename, file_name); Modified: firebird/trunk/src/msgs/facilities2.sql =================================================================== --- firebird/trunk/src/msgs/facilities2.sql 2014-04-22 00:45:43 UTC (rev 59469) +++ firebird/trunk/src/msgs/facilities2.sql 2014-04-22 13:37:14 UTC (rev 59470) @@ -6,7 +6,7 @@ ('2013-11-13 15:59:10', 'GFIX', 3, 122) ('1996-11-07 13:39:40', 'GPRE', 4, 1) ('2012-08-27 21:26:00', 'DSQL', 7, 33) -('2014-04-07 23:01:14', 'DYN', 8, 289) +('2014-04-22 16:39:03', 'DYN', 8, 290) ('1996-11-07 13:39:40', 'INSTALL', 10, 1) ('1996-11-07 13:38:41', 'TEST', 11, 4) ('2014-04-04 16:08:08', 'GBAK', 12, 354) Modified: firebird/trunk/src/msgs/messages2.sql =================================================================== --- firebird/trunk/src/msgs/messages2.sql 2014-04-22 00:45:43 UTC (rev 59469) +++ firebird/trunk/src/msgs/messages2.sql 2014-04-22 13:37:14 UTC (rev 59470) @@ -1927,6 +1927,7 @@ ('dyn_duplicate_package_item', NULL, 'PackageNodes.epp', NULL, 8, 286, NULL, 'Duplicate @1 @2', NULL, NULL); ('dyn_cant_modify_sysobj', NULL, 'DdlNodes.epp', NULL, 8, 287, NULL, 'System @1 @2 cannot be modified', NULL, 'Ex: System generator rdb$... cannot be modified'); ('dyn_cant_use_zero_increment', NULL, 'DdlNodes.epp', NULL, 8, 288, NULL, 'INCREMENT BY 0 is an illegal option for sequence @1', NULL, NULL); +('dyn_cant_use_in_foreignkey', NULL, 'DdlNodes.epp', NULL, 8, 289, NULL, 'Can''t use @1 in FOREIGN KEY constraint', NULL, NULL); COMMIT WORK; -- TEST (NULL, 'main', 'test.c', NULL, 11, 0, NULL, 'This is a modified text message', NULL, NULL); Modified: firebird/trunk/src/msgs/system_errors2.sql =================================================================== --- firebird/trunk/src/msgs/system_errors2.sql 2014-04-22 00:45:43 UTC (rev 59469) +++ firebird/trunk/src/msgs/system_errors2.sql 2014-04-22 13:37:14 UTC (rev 59470) @@ -911,6 +911,7 @@ (-901, '42', '000', 8, 286, 'dyn_duplicate_package_item', NULL, NULL) (-901, '42', '000', 8, 287, 'dyn_cant_modify_sysobj', NULL, NULL) (-901, '42', '000', 8, 288, 'dyn_cant_use_zero_increment', NULL, NULL) +(-901, '42', '000', 8, 289, 'dyn_cant_use_in_foreignkey', NULL, NULL) -- GBAK (-901, '00', '000', 12, 1, 'gbak_unknown_switch', NULL, NULL) (-901, '00', '000', 12, 2, 'gbak_page_size_missing', NULL, NULL) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |