Skip to content

Commit 14906af

Browse files
committed
Control which exceptions in decfloat (underflow, division by zero, etc.) trap SQL statement
1 parent 57af009 commit 14906af

File tree

5 files changed

+145
-30
lines changed

5 files changed

+145
-30
lines changed

configure.ac

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -870,6 +870,16 @@ dnl if 64-bit mode, then archive tool, ar, needs -X64 option
870870
[AC_LANG_PROGRAM(,[[int lp64 = __64BIT__; ]])],
871871
[AR_OPTIONS=-X64],)
872872
fi
873+
874+
XE_SAVE_ENV()
875+
CXXFLAGS="$CXXFLAGS -std=c++11"
876+
AC_CACHE_CHECK([whether the C++ compiler understands noexcept], [ac_cv_cxx_noexcept], [
877+
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[int f(int x) noexcept { return x + 1; }]], [[]])],
878+
[ac_cv_cxx_noexcept=yes], [ac_cv_cxx_noexcept=no])])
879+
XE_RESTORE_ENV()
880+
if test "$ac_cv_cxx_noexcept" = yes; then
881+
AC_DEFINE([HAS_NOEXCEPT], [1], [Define if the C++ compiler understands noexcept.])
882+
fi
873883
AC_LANG_POP(C++)
874884

875885
dnl Check for functions

src/dsql/StmtNodes.cpp

Lines changed: 74 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -7972,49 +7972,100 @@ void SetRoleNode::execute(thread_db* tdbb, dsql_req* request) const
79727972
namespace
79737973
{
79747974

7975-
struct RoundMode
7975+
struct TextCode
79767976
{
79777977
const char* name;
79787978
USHORT val;
79797979
};
79807980

7981-
#define FB_RMODE(x) { STRINGIZE(x), x }
7982-
7983-
const RoundMode roundModes[] = {
7984-
FB_RMODE(DEC_ROUND_CEILING),
7985-
FB_RMODE(DEC_ROUND_UP),
7986-
FB_RMODE(DEC_ROUND_HALF_UP),
7987-
FB_RMODE(DEC_ROUND_HALF_EVEN),
7988-
FB_RMODE(DEC_ROUND_HALF_DOWN),
7989-
FB_RMODE(DEC_ROUND_DOWN),
7990-
FB_RMODE(DEC_ROUND_FLOOR),
7981+
//#define FB_TEXTCODE(x) { STRINGIZE(x), x }
7982+
#define FB_TEXTCODE(x) { #x, x }
7983+
7984+
const TextCode roundModes[] = {
7985+
FB_TEXTCODE(DEC_ROUND_CEILING),
7986+
FB_TEXTCODE(DEC_ROUND_UP),
7987+
FB_TEXTCODE(DEC_ROUND_HALF_UP),
7988+
FB_TEXTCODE(DEC_ROUND_HALF_EVEN),
7989+
FB_TEXTCODE(DEC_ROUND_HALF_DOWN),
7990+
FB_TEXTCODE(DEC_ROUND_DOWN),
7991+
FB_TEXTCODE(DEC_ROUND_FLOOR),
79917992
{ "DEC_ROUND_REROUND", DEC_ROUND_05UP },
79927993
{ NULL, 0 }
79937994
};
79947995

7995-
#undef FB_RMODE
7996-
79977996
//DEC_ROUND_
79987997
//0123456789
79997998
const unsigned FB_RMODE_OFFSET = 10;
80007999

8000+
const TextCode ieeeTraps[] = {
8001+
FB_TEXTCODE(DEC_IEEE_754_Division_by_zero),
8002+
FB_TEXTCODE(DEC_IEEE_754_Inexact),
8003+
FB_TEXTCODE(DEC_IEEE_754_Invalid_operation),
8004+
FB_TEXTCODE(DEC_IEEE_754_Overflow),
8005+
FB_TEXTCODE(DEC_IEEE_754_Underflow),
8006+
{ NULL, 0 }
8007+
};
8008+
8009+
//DEC_IEEE_754_
8010+
//0123456789012
8011+
const unsigned FB_TRAPS_OFFSET = 13;
8012+
8013+
#undef FB_TEXTCODE
8014+
8015+
const TextCode* getCodeByText(const MetaName& text, const TextCode* textCode, unsigned offset)
8016+
{
8017+
NoCaseString name(text.c_str(), text.length());
8018+
8019+
for (const TextCode* tc = textCode; tc->name; ++tc)
8020+
{
8021+
if (name == &tc->name[offset])
8022+
return tc;
8023+
}
8024+
8025+
return nullptr;
8026+
}
8027+
8028+
}
8029+
8030+
8031+
//--------------------
8032+
8033+
8034+
SetRoundNode::SetRoundNode(MemoryPool& pool, Firebird::MetaName* name)
8035+
: SessionManagementNode(pool)
8036+
{
8037+
fb_assert(name);
8038+
const TextCode* mode = getCodeByText(*name, roundModes, FB_RMODE_OFFSET);
8039+
if (!mode)
8040+
(Arg::Gds(isc_random) << "Invalid round mode for decfloat").raise();
8041+
rndMode = mode->val;
80018042
}
80028043

8003-
void SetRoundNode::execute(thread_db* tdbb, dsql_req* request) const
8044+
void SetRoundNode::execute(thread_db* tdbb, dsql_req* /*request*/) const
80048045
{
80058046
SET_TDBB(tdbb);
80068047
Attachment* const attachment = tdbb->getAttachment();
8048+
attachment->att_dec_status.roundingMode = rndMode;
8049+
}
80078050

8008-
for (const RoundMode* r = roundModes; r->name; ++r)
8009-
{
8010-
if (rndName == &r->name[FB_RMODE_OFFSET])
8011-
{
8012-
attachment->att_dec_status.roundingMode = r->val;
8013-
return;
8014-
}
8015-
}
80168051

8017-
(Arg::Gds(isc_random) << "Invalid round mode for decfloat").raise();
8052+
//--------------------
8053+
8054+
8055+
void SetTrapsNode::trap(Firebird::MetaName* name)
8056+
{
8057+
fb_assert(name);
8058+
const TextCode* trap = getCodeByText(*name, ieeeTraps, FB_TRAPS_OFFSET);
8059+
if (!trap)
8060+
(Arg::Gds(isc_random) << "Invalid decfloat trap").raise();
8061+
traps |= trap->val;
8062+
}
8063+
8064+
void SetTrapsNode::execute(thread_db* tdbb, dsql_req* /*request*/) const
8065+
{
8066+
SET_TDBB(tdbb);
8067+
Attachment* const attachment = tdbb->getAttachment();
8068+
attachment->att_dec_status.decExtFlag = traps;
80188069
}
80198070

80208071

src/dsql/StmtNodes.h

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1584,9 +1584,31 @@ class SetRoleNode : public SessionManagementNode
15841584
class SetRoundNode : public SessionManagementNode
15851585
{
15861586
public:
1587-
SetRoundNode(MemoryPool& pool, Firebird::MetaName* name)
1587+
SetRoundNode(MemoryPool& pool, Firebird::MetaName* name);
1588+
1589+
public:
1590+
virtual Firebird::string internalPrint(NodePrinter& printer) const
1591+
{
1592+
SessionManagementNode::internalPrint(printer);
1593+
1594+
NODE_PRINT(printer, rndMode);
1595+
1596+
return "SetRoundNode";
1597+
}
1598+
1599+
virtual void execute(thread_db* tdbb, dsql_req* request) const;
1600+
1601+
public:
1602+
USHORT rndMode;
1603+
};
1604+
1605+
1606+
class SetTrapsNode : public SessionManagementNode
1607+
{
1608+
public:
1609+
SetTrapsNode(MemoryPool& pool)
15881610
: SessionManagementNode(pool),
1589-
rndName(pool, *name)
1611+
traps(0u)
15901612
{
15911613
}
15921614

@@ -1595,15 +1617,17 @@ class SetRoundNode : public SessionManagementNode
15951617
{
15961618
SessionManagementNode::internalPrint(printer);
15971619

1598-
NODE_PRINT(printer, rndName);
1620+
NODE_PRINT(printer, traps);
15991621

1600-
return "SetRoundNode";
1622+
return "SetTrapsNode";
16011623
}
16021624

16031625
virtual void execute(thread_db* tdbb, dsql_req* request) const;
16041626

1627+
void trap(Firebird::MetaName* name);
1628+
16051629
public:
1606-
Firebird::MetaName rndName;
1630+
USHORT traps;
16071631
};
16081632

16091633

src/dsql/parse.y

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -611,6 +611,7 @@ using namespace Firebird;
611611
%token <metaNamePtr> SQL
612612
%token <metaNamePtr> SYSTEM
613613
%token <metaNamePtr> TIES
614+
%token <metaNamePtr> TRAPS
614615
%token <metaNamePtr> UNBOUNDED
615616
%token <metaNamePtr> VARBINARY
616617
%token <metaNamePtr> WINDOW
@@ -756,8 +757,9 @@ using namespace Firebird;
756757
Jrd::MappingNode* mappingNode;
757758
Jrd::MappingNode::OP mappingOp;
758759
Jrd::SetRoleNode* setRoleNode;
759-
Jrd::SetRoundNode* setRoundNode;
760760
Jrd::CreateAlterRoleNode* createAlterRoleNode;
761+
Jrd::SetRoundNode* setRoundNode;
762+
Jrd::SetTrapsNode* setTrapsNode;
761763
}
762764

763765
%include types.y
@@ -816,7 +818,7 @@ tra_statement
816818
%type <mngNode> mng_statement
817819
mng_statement
818820
: set_round { $$ = $1; }
819-
// | set_traps { $$ = $1; }
821+
| set_traps { $$ = $1; }
820822
| set_role { $$ = $1; }
821823
;
822824

@@ -5024,6 +5026,32 @@ set_round
50245026
{ $$ = newNode<SetRoundNode>($4); }
50255027
;
50265028

5029+
%type <setTrapsNode> set_traps
5030+
set_traps
5031+
: SET DECFLOAT TRAPS TO
5032+
{ $$ = newNode<SetTrapsNode>(); }
5033+
traps_list_opt($5)
5034+
{ $$ = $5; }
5035+
;
5036+
5037+
%type traps_list_opt(<setTrapsNode>)
5038+
traps_list_opt($setTrapsNode)
5039+
: // nothing
5040+
| traps_list($setTrapsNode)
5041+
;
5042+
5043+
%type traps_list(<setTrapsNode>)
5044+
traps_list($setTrapsNode)
5045+
: trap($setTrapsNode)
5046+
| traps_list ',' trap($setTrapsNode)
5047+
;
5048+
5049+
%type trap(<setTrapsNode>)
5050+
trap($setTrapsNode)
5051+
: valid_symbol_name
5052+
{ $setTrapsNode->trap($1); }
5053+
;
5054+
50275055
%type tran_option_list_opt(<setTransactionNode>)
50285056
tran_option_list_opt($setTransactionNode)
50295057
: // nothing
@@ -8280,6 +8308,7 @@ non_reserved_word
82808308
| SQL
82818309
| SYSTEM
82828310
| TIES
8311+
| TRAPS
82838312
;
82848313

82858314
%%

src/yvalve/keywords.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -440,6 +440,7 @@ static const TOK tokens[] =
440440
{TOK_TO, "TO", false},
441441
{TOK_TRAILING, "TRAILING", false},
442442
{TOK_TRANSACTION, "TRANSACTION", true},
443+
{TOK_TRAPS, "TRAPS", true},
443444
{TOK_TRIGGER, "TRIGGER", false},
444445
{TOK_TRIM, "TRIM", false},
445446
{TOK_TRUE, "TRUE", false},

0 commit comments

Comments
 (0)