mirror of
https://github.com/FirebirdSQL/firebird.git
synced 2025-01-22 16:43:03 +01:00
Control which exceptions in decfloat (underflow, division by zero, etc.) trap SQL statement
This commit is contained in:
parent
57af009fd8
commit
14906afe06
10
configure.ac
10
configure.ac
@ -870,6 +870,16 @@ dnl if 64-bit mode, then archive tool, ar, needs -X64 option
|
||||
[AC_LANG_PROGRAM(,[[int lp64 = __64BIT__; ]])],
|
||||
[AR_OPTIONS=-X64],)
|
||||
fi
|
||||
|
||||
XE_SAVE_ENV()
|
||||
CXXFLAGS="$CXXFLAGS -std=c++11"
|
||||
AC_CACHE_CHECK([whether the C++ compiler understands noexcept], [ac_cv_cxx_noexcept], [
|
||||
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[int f(int x) noexcept { return x + 1; }]], [[]])],
|
||||
[ac_cv_cxx_noexcept=yes], [ac_cv_cxx_noexcept=no])])
|
||||
XE_RESTORE_ENV()
|
||||
if test "$ac_cv_cxx_noexcept" = yes; then
|
||||
AC_DEFINE([HAS_NOEXCEPT], [1], [Define if the C++ compiler understands noexcept.])
|
||||
fi
|
||||
AC_LANG_POP(C++)
|
||||
|
||||
dnl Check for functions
|
||||
|
@ -7972,49 +7972,100 @@ void SetRoleNode::execute(thread_db* tdbb, dsql_req* request) const
|
||||
namespace
|
||||
{
|
||||
|
||||
struct RoundMode
|
||||
struct TextCode
|
||||
{
|
||||
const char* name;
|
||||
USHORT val;
|
||||
};
|
||||
|
||||
#define FB_RMODE(x) { STRINGIZE(x), x }
|
||||
//#define FB_TEXTCODE(x) { STRINGIZE(x), x }
|
||||
#define FB_TEXTCODE(x) { #x, x }
|
||||
|
||||
const RoundMode roundModes[] = {
|
||||
FB_RMODE(DEC_ROUND_CEILING),
|
||||
FB_RMODE(DEC_ROUND_UP),
|
||||
FB_RMODE(DEC_ROUND_HALF_UP),
|
||||
FB_RMODE(DEC_ROUND_HALF_EVEN),
|
||||
FB_RMODE(DEC_ROUND_HALF_DOWN),
|
||||
FB_RMODE(DEC_ROUND_DOWN),
|
||||
FB_RMODE(DEC_ROUND_FLOOR),
|
||||
const TextCode roundModes[] = {
|
||||
FB_TEXTCODE(DEC_ROUND_CEILING),
|
||||
FB_TEXTCODE(DEC_ROUND_UP),
|
||||
FB_TEXTCODE(DEC_ROUND_HALF_UP),
|
||||
FB_TEXTCODE(DEC_ROUND_HALF_EVEN),
|
||||
FB_TEXTCODE(DEC_ROUND_HALF_DOWN),
|
||||
FB_TEXTCODE(DEC_ROUND_DOWN),
|
||||
FB_TEXTCODE(DEC_ROUND_FLOOR),
|
||||
{ "DEC_ROUND_REROUND", DEC_ROUND_05UP },
|
||||
{ NULL, 0 }
|
||||
};
|
||||
|
||||
#undef FB_RMODE
|
||||
|
||||
//DEC_ROUND_
|
||||
//0123456789
|
||||
const unsigned FB_RMODE_OFFSET = 10;
|
||||
|
||||
const TextCode ieeeTraps[] = {
|
||||
FB_TEXTCODE(DEC_IEEE_754_Division_by_zero),
|
||||
FB_TEXTCODE(DEC_IEEE_754_Inexact),
|
||||
FB_TEXTCODE(DEC_IEEE_754_Invalid_operation),
|
||||
FB_TEXTCODE(DEC_IEEE_754_Overflow),
|
||||
FB_TEXTCODE(DEC_IEEE_754_Underflow),
|
||||
{ NULL, 0 }
|
||||
};
|
||||
|
||||
//DEC_IEEE_754_
|
||||
//0123456789012
|
||||
const unsigned FB_TRAPS_OFFSET = 13;
|
||||
|
||||
#undef FB_TEXTCODE
|
||||
|
||||
const TextCode* getCodeByText(const MetaName& text, const TextCode* textCode, unsigned offset)
|
||||
{
|
||||
NoCaseString name(text.c_str(), text.length());
|
||||
|
||||
for (const TextCode* tc = textCode; tc->name; ++tc)
|
||||
{
|
||||
if (name == &tc->name[offset])
|
||||
return tc;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void SetRoundNode::execute(thread_db* tdbb, dsql_req* request) const
|
||||
}
|
||||
|
||||
|
||||
//--------------------
|
||||
|
||||
|
||||
SetRoundNode::SetRoundNode(MemoryPool& pool, Firebird::MetaName* name)
|
||||
: SessionManagementNode(pool)
|
||||
{
|
||||
fb_assert(name);
|
||||
const TextCode* mode = getCodeByText(*name, roundModes, FB_RMODE_OFFSET);
|
||||
if (!mode)
|
||||
(Arg::Gds(isc_random) << "Invalid round mode for decfloat").raise();
|
||||
rndMode = mode->val;
|
||||
}
|
||||
|
||||
void SetRoundNode::execute(thread_db* tdbb, dsql_req* /*request*/) const
|
||||
{
|
||||
SET_TDBB(tdbb);
|
||||
Attachment* const attachment = tdbb->getAttachment();
|
||||
attachment->att_dec_status.roundingMode = rndMode;
|
||||
}
|
||||
|
||||
for (const RoundMode* r = roundModes; r->name; ++r)
|
||||
{
|
||||
if (rndName == &r->name[FB_RMODE_OFFSET])
|
||||
{
|
||||
attachment->att_dec_status.roundingMode = r->val;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
(Arg::Gds(isc_random) << "Invalid round mode for decfloat").raise();
|
||||
//--------------------
|
||||
|
||||
|
||||
void SetTrapsNode::trap(Firebird::MetaName* name)
|
||||
{
|
||||
fb_assert(name);
|
||||
const TextCode* trap = getCodeByText(*name, ieeeTraps, FB_TRAPS_OFFSET);
|
||||
if (!trap)
|
||||
(Arg::Gds(isc_random) << "Invalid decfloat trap").raise();
|
||||
traps |= trap->val;
|
||||
}
|
||||
|
||||
void SetTrapsNode::execute(thread_db* tdbb, dsql_req* /*request*/) const
|
||||
{
|
||||
SET_TDBB(tdbb);
|
||||
Attachment* const attachment = tdbb->getAttachment();
|
||||
attachment->att_dec_status.decExtFlag = traps;
|
||||
}
|
||||
|
||||
|
||||
|
@ -1584,9 +1584,31 @@ public:
|
||||
class SetRoundNode : public SessionManagementNode
|
||||
{
|
||||
public:
|
||||
SetRoundNode(MemoryPool& pool, Firebird::MetaName* name)
|
||||
SetRoundNode(MemoryPool& pool, Firebird::MetaName* name);
|
||||
|
||||
public:
|
||||
virtual Firebird::string internalPrint(NodePrinter& printer) const
|
||||
{
|
||||
SessionManagementNode::internalPrint(printer);
|
||||
|
||||
NODE_PRINT(printer, rndMode);
|
||||
|
||||
return "SetRoundNode";
|
||||
}
|
||||
|
||||
virtual void execute(thread_db* tdbb, dsql_req* request) const;
|
||||
|
||||
public:
|
||||
USHORT rndMode;
|
||||
};
|
||||
|
||||
|
||||
class SetTrapsNode : public SessionManagementNode
|
||||
{
|
||||
public:
|
||||
SetTrapsNode(MemoryPool& pool)
|
||||
: SessionManagementNode(pool),
|
||||
rndName(pool, *name)
|
||||
traps(0u)
|
||||
{
|
||||
}
|
||||
|
||||
@ -1595,15 +1617,17 @@ public:
|
||||
{
|
||||
SessionManagementNode::internalPrint(printer);
|
||||
|
||||
NODE_PRINT(printer, rndName);
|
||||
NODE_PRINT(printer, traps);
|
||||
|
||||
return "SetRoundNode";
|
||||
return "SetTrapsNode";
|
||||
}
|
||||
|
||||
virtual void execute(thread_db* tdbb, dsql_req* request) const;
|
||||
|
||||
void trap(Firebird::MetaName* name);
|
||||
|
||||
public:
|
||||
Firebird::MetaName rndName;
|
||||
USHORT traps;
|
||||
};
|
||||
|
||||
|
||||
|
@ -611,6 +611,7 @@ using namespace Firebird;
|
||||
%token <metaNamePtr> SQL
|
||||
%token <metaNamePtr> SYSTEM
|
||||
%token <metaNamePtr> TIES
|
||||
%token <metaNamePtr> TRAPS
|
||||
%token <metaNamePtr> UNBOUNDED
|
||||
%token <metaNamePtr> VARBINARY
|
||||
%token <metaNamePtr> WINDOW
|
||||
@ -756,8 +757,9 @@ using namespace Firebird;
|
||||
Jrd::MappingNode* mappingNode;
|
||||
Jrd::MappingNode::OP mappingOp;
|
||||
Jrd::SetRoleNode* setRoleNode;
|
||||
Jrd::SetRoundNode* setRoundNode;
|
||||
Jrd::CreateAlterRoleNode* createAlterRoleNode;
|
||||
Jrd::SetRoundNode* setRoundNode;
|
||||
Jrd::SetTrapsNode* setTrapsNode;
|
||||
}
|
||||
|
||||
%include types.y
|
||||
@ -816,7 +818,7 @@ tra_statement
|
||||
%type <mngNode> mng_statement
|
||||
mng_statement
|
||||
: set_round { $$ = $1; }
|
||||
// | set_traps { $$ = $1; }
|
||||
| set_traps { $$ = $1; }
|
||||
| set_role { $$ = $1; }
|
||||
;
|
||||
|
||||
@ -5024,6 +5026,32 @@ set_round
|
||||
{ $$ = newNode<SetRoundNode>($4); }
|
||||
;
|
||||
|
||||
%type <setTrapsNode> set_traps
|
||||
set_traps
|
||||
: SET DECFLOAT TRAPS TO
|
||||
{ $$ = newNode<SetTrapsNode>(); }
|
||||
traps_list_opt($5)
|
||||
{ $$ = $5; }
|
||||
;
|
||||
|
||||
%type traps_list_opt(<setTrapsNode>)
|
||||
traps_list_opt($setTrapsNode)
|
||||
: // nothing
|
||||
| traps_list($setTrapsNode)
|
||||
;
|
||||
|
||||
%type traps_list(<setTrapsNode>)
|
||||
traps_list($setTrapsNode)
|
||||
: trap($setTrapsNode)
|
||||
| traps_list ',' trap($setTrapsNode)
|
||||
;
|
||||
|
||||
%type trap(<setTrapsNode>)
|
||||
trap($setTrapsNode)
|
||||
: valid_symbol_name
|
||||
{ $setTrapsNode->trap($1); }
|
||||
;
|
||||
|
||||
%type tran_option_list_opt(<setTransactionNode>)
|
||||
tran_option_list_opt($setTransactionNode)
|
||||
: // nothing
|
||||
@ -8280,6 +8308,7 @@ non_reserved_word
|
||||
| SQL
|
||||
| SYSTEM
|
||||
| TIES
|
||||
| TRAPS
|
||||
;
|
||||
|
||||
%%
|
||||
|
@ -440,6 +440,7 @@ static const TOK tokens[] =
|
||||
{TOK_TO, "TO", false},
|
||||
{TOK_TRAILING, "TRAILING", false},
|
||||
{TOK_TRANSACTION, "TRANSACTION", true},
|
||||
{TOK_TRAPS, "TRAPS", true},
|
||||
{TOK_TRIGGER, "TRIGGER", false},
|
||||
{TOK_TRIM, "TRIM", false},
|
||||
{TOK_TRUE, "TRUE", false},
|
||||
|
Loading…
Reference in New Issue
Block a user