diff --git a/lang_helpers/gds_codes.ftn b/lang_helpers/gds_codes.ftn index a321e115f4..97352261e9 100644 --- a/lang_helpers/gds_codes.ftn +++ b/lang_helpers/gds_codes.ftn @@ -1928,6 +1928,10 @@ C -- PARAMETER (GDS__odd_hex_len = 335545257) INTEGER*4 GDS__invalid_hex_digit PARAMETER (GDS__invalid_hex_digit = 335545258) + INTEGER*4 GDS__bind_err + PARAMETER (GDS__bind_err = 335545259) + INTEGER*4 GDS__bind_statement + PARAMETER (GDS__bind_statement = 335545260) INTEGER*4 GDS__gfix_db_name PARAMETER (GDS__gfix_db_name = 335740929) INTEGER*4 GDS__gfix_invalid_sw diff --git a/lang_helpers/gds_codes.pas b/lang_helpers/gds_codes.pas index 50d65a974c..a9d869c1bb 100644 --- a/lang_helpers/gds_codes.pas +++ b/lang_helpers/gds_codes.pas @@ -1923,6 +1923,10 @@ const gds_odd_hex_len = 335545257; isc_invalid_hex_digit = 335545258; gds_invalid_hex_digit = 335545258; + isc_bind_err = 335545259; + gds_bind_err = 335545259; + isc_bind_statement = 335545260; + gds_bind_statement = 335545260; isc_gfix_db_name = 335740929; gds_gfix_db_name = 335740929; isc_gfix_invalid_sw = 335740930; diff --git a/src/common/utils.cpp b/src/common/utils.cpp index 4a236f6dc1..12fc2f86fe 100644 --- a/src/common/utils.cpp +++ b/src/common/utils.cpp @@ -1570,21 +1570,22 @@ unsigned sqlTypeToDsc(unsigned runOffset, unsigned sqlType, unsigned sqlLength, return runOffset + sizeof(SSHORT); } +const ISC_STATUS* nextArg(const ISC_STATUS* v) throw() +{ + do + { + v += (v[0] == isc_arg_cstring ? 3 : 2); + } while (v[0] != isc_arg_warning && v[0] != isc_arg_gds && v[0] != isc_arg_end); + + return v; +} + bool containsErrorCode(const ISC_STATUS* v, ISC_STATUS code) { -#ifdef DEV_BUILD -const ISC_STATUS* const origen = v; -#endif - while (v[0] == isc_arg_gds) + for (; v[0] == isc_arg_gds; v = nextArg(v)) { if (v[1] == code) return true; - - do - { - v += (v[0] == isc_arg_cstring ? 3 : 2); - } while (v[0] != isc_arg_warning && v[0] != isc_arg_gds && v[0] != isc_arg_end); - fb_assert(v - origen < ISC_STATUS_LENGTH); } return false; diff --git a/src/common/utils_proto.h b/src/common/utils_proto.h index 478c46a450..fa362bec68 100644 --- a/src/common/utils_proto.h +++ b/src/common/utils_proto.h @@ -143,6 +143,10 @@ namespace fb_utils unsigned int subStatus(const ISC_STATUS* in, unsigned int cin, const ISC_STATUS* sub, unsigned int csub) throw(); bool cmpStatus(unsigned int len, const ISC_STATUS* a, const ISC_STATUS* b) throw(); + const ISC_STATUS* nextArg(const ISC_STATUS* v) throw(); + + // Check does vector contain particular code or not + bool containsErrorCode(const ISC_STATUS* v, ISC_STATUS code); enum FetchPassResult { FETCH_PASS_OK, @@ -191,9 +195,6 @@ namespace fb_utils unsigned sqlTypeToDsc(unsigned prevOffset, unsigned sqlType, unsigned sqlLength, unsigned* dtype, unsigned* len, unsigned* offset, unsigned* nullOffset); - // Check does vector contain particular code or not - bool containsErrorCode(const ISC_STATUS* v, ISC_STATUS code); - bool inline isNetworkError(ISC_STATUS code) { return code == isc_network_error || diff --git a/src/include/gen/codetext.h b/src/include/gen/codetext.h index 26f2be5e30..9735dbf190 100644 --- a/src/include/gen/codetext.h +++ b/src/include/gen/codetext.h @@ -960,6 +960,8 @@ static const struct { {"invalid_decfloat_bind", 335545256}, {"odd_hex_len", 335545257}, {"invalid_hex_digit", 335545258}, + {"bind_err", 335545259}, + {"bind_statement", 335545260}, {"gfix_db_name", 335740929}, {"gfix_invalid_sw", 335740930}, {"gfix_incmp_sw", 335740932}, diff --git a/src/include/gen/iberror.h b/src/include/gen/iberror.h index d804b61684..50a58219b1 100644 --- a/src/include/gen/iberror.h +++ b/src/include/gen/iberror.h @@ -994,6 +994,8 @@ const ISC_STATUS isc_invalid_time_zone_bind = 335545255L; const ISC_STATUS isc_invalid_decfloat_bind = 335545256L; const ISC_STATUS isc_odd_hex_len = 335545257L; const ISC_STATUS isc_invalid_hex_digit = 335545258L; +const ISC_STATUS isc_bind_err = 335545259L; +const ISC_STATUS isc_bind_statement = 335545260L; const ISC_STATUS isc_gfix_db_name = 335740929L; const ISC_STATUS isc_gfix_invalid_sw = 335740930L; const ISC_STATUS isc_gfix_incmp_sw = 335740932L; @@ -1481,7 +1483,7 @@ const ISC_STATUS isc_trace_switch_user_only = 337182757L; 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 = 1425; +const ISC_STATUS isc_err_max = 1427; #else /* c definitions */ @@ -2445,6 +2447,8 @@ const ISC_STATUS isc_err_max = 1425; #define isc_invalid_decfloat_bind 335545256L #define isc_odd_hex_len 335545257L #define isc_invalid_hex_digit 335545258L +#define isc_bind_err 335545259L +#define isc_bind_statement 335545260L #define isc_gfix_db_name 335740929L #define isc_gfix_invalid_sw 335740930L #define isc_gfix_incmp_sw 335740932L @@ -2932,7 +2936,7 @@ const ISC_STATUS isc_err_max = 1425; #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 1425 +#define isc_err_max 1427 #endif diff --git a/src/include/gen/msgs.h b/src/include/gen/msgs.h index ee8f74b928..f330f2a314 100644 --- a/src/include/gen/msgs.h +++ b/src/include/gen/msgs.h @@ -963,6 +963,8 @@ Data source : @4"}, /* eds_statement */ {335545256, "Invalid decfloat bind mode @1"}, /* invalid_decfloat_bind */ {335545257, "Invalid hex text length @1, should be multiple of 2"}, /* odd_hex_len */ {335545258, "Invalid hex digit @1 at position @2"}, /* invalid_hex_digit */ + {335545259, "Error processing isc_dpb_set_bind clumplet \"@1\""}, /* bind_err */ + {335545260, "The following statement failed: @1"}, /* bind_statement */ {335740929, "data base file name (@1) already given"}, /* gfix_db_name */ {335740930, "invalid switch @1"}, /* gfix_invalid_sw */ {335740932, "incompatible switch combination"}, /* gfix_incmp_sw */ diff --git a/src/include/gen/sql_code.h b/src/include/gen/sql_code.h index 61ba047ba8..d4c3800c50 100644 --- a/src/include/gen/sql_code.h +++ b/src/include/gen/sql_code.h @@ -959,6 +959,8 @@ static const struct { {335545256, -901}, /* 936 invalid_decfloat_bind */ {335545257, -901}, /* 937 odd_hex_len */ {335545258, -901}, /* 938 invalid_hex_digit */ + {335545259, -902}, /* 939 bind_err */ + {335545260, -902}, /* 940 bind_statement */ {335740929, -901}, /* 1 gfix_db_name */ {335740930, -901}, /* 2 gfix_invalid_sw */ {335740932, -901}, /* 4 gfix_incmp_sw */ diff --git a/src/include/gen/sql_state.h b/src/include/gen/sql_state.h index a29434ee96..26984b624e 100644 --- a/src/include/gen/sql_state.h +++ b/src/include/gen/sql_state.h @@ -959,6 +959,8 @@ static const struct { {335545256, "42000"}, // 936 invalid_decfloat_bind {335545257, "22023"}, // 937 odd_hex_len {335545258, "22023"}, // 938 invalid_hex_digit + {335545259, "08004"}, // 939 bind_err + {335545260, "08004"}, // 940 bind_statement {335740929, "00000"}, // 1 gfix_db_name {335740930, "00000"}, // 2 gfix_invalid_sw {335740932, "00000"}, // 4 gfix_incmp_sw diff --git a/src/jrd/jrd.cpp b/src/jrd/jrd.cpp index b1e105beb1..0a53d15f38 100644 --- a/src/jrd/jrd.cpp +++ b/src/jrd/jrd.cpp @@ -1151,8 +1151,31 @@ namespace Jrd { rules[i].insert(0, "SET BIND OF "); - AutoPreparedStatement ps(att->prepareStatement(tdbb, nullptr, rules[i].ToString())); - ps->execute(tdbb, nullptr); + try + { + AutoPreparedStatement ps(att->prepareStatement(tdbb, nullptr, rules[i].ToString())); + ps->execute(tdbb, nullptr); + } + catch (const Exception& ex) + { + FbLocalStatus status; + ex.stuffException(&status); + + // strip spam messages + const ISC_STATUS* v = status->getErrors(); + for (; v[0] == isc_arg_gds; v = fb_utils::nextArg(v)) + { + if (v[1] != isc_dsql_error && v[1] != isc_sqlerr) + break; + } + + // build and throw new vector + Arg::Gds newErr(isc_bind_err); + newErr << options.dpb_set_bind << + Arg::Gds(isc_bind_statement) << rules[i]; + newErr << Arg::StatusVector(v); + newErr.raise(); + } } } diff --git a/src/msgs/facilities2.sql b/src/msgs/facilities2.sql index e6de13afef..7505c9944e 100644 --- a/src/msgs/facilities2.sql +++ b/src/msgs/facilities2.sql @@ -1,7 +1,7 @@ /* MAX_NUMBER is the next number to be used, always one more than the highest message number. */ set bulk_insert INSERT INTO FACILITIES (LAST_CHANGE, FACILITY, FAC_CODE, MAX_NUMBER) VALUES (?, ?, ?, ?); -- -('2019-04-16 12:14:00', 'JRD', 0, 939) +('2019-11-13 17:10:00', 'JRD', 0, 941) ('2015-03-17 18:33:00', 'QLI', 1, 533) ('2018-03-17 12:00:00', 'GFIX', 3, 136) ('1996-11-07 13:39:40', 'GPRE', 4, 1) diff --git a/src/msgs/messages2.sql b/src/msgs/messages2.sql index dbeb5f4343..d9bb7ab933 100644 --- a/src/msgs/messages2.sql +++ b/src/msgs/messages2.sql @@ -1046,6 +1046,8 @@ Data source : @4', NULL, NULL) ('invalid_decfloat_bind', NULL, 'jrd.cpp', NULL, 0, 936, NULL, 'Invalid decfloat bind mode @1', NULL, NULL); ('odd_hex_len', NULL, 'SysFunction.cpp', NULL, 0, 937, NULL, 'Invalid hex text length @1, should be multiple of 2', NULL, NULL); ('invalid_hex_digit', NULL, 'SysFunction.cpp', NULL, 0, 938, NULL, 'Invalid hex digit @1 at position @2', NULL, NULL); +('bind_err', NULL, 'jrd.cpp', NULL, 0, 939, NULL, 'Error processing isc_dpb_set_bind clumplet "@1"', NULL, NULL); +('bind_statement', NULL, 'jrd.cpp', NULL, 0, 940, NULL, 'The following statement failed: @1', NULL, NULL); -- QLI (NULL, NULL, NULL, NULL, 1, 0, NULL, 'expected type', NULL, NULL); (NULL, NULL, NULL, NULL, 1, 1, NULL, 'bad block type', NULL, NULL); diff --git a/src/msgs/system_errors2.sql b/src/msgs/system_errors2.sql index 2f68135daf..397c8588fa 100644 --- a/src/msgs/system_errors2.sql +++ b/src/msgs/system_errors2.sql @@ -945,6 +945,8 @@ set bulk_insert INSERT INTO SYSTEM_ERRORS (SQL_CODE, SQL_CLASS, SQL_SUBCLASS, FA (-901, '42', '000', 0, 936, 'invalid_decfloat_bind', NULL, NULL) (-901, '22', '023', 0, 937, 'odd_hex_len', NULL, NULL) (-901, '22', '023', 0, 938, 'invalid_hex_digit', NULL, NULL) +(-902, '08', '004', 0, 939, 'bind_err', NULL, NULL) +(-902, '08', '004', 0, 940, 'bind_statement', NULL, NULL) -- GFIX (-901, '00', '000', 3, 1, 'gfix_db_name', NULL, NULL) (-901, '00', '000', 3, 2, 'gfix_invalid_sw', NULL, NULL)