Skip to content

Commit 84f435c

Browse files
committed
Let users select legacy datatype (CHAR, DOUBLE or BIGINT with scale) to be used instead DECFLOAT when talking to old client
1 parent b80e5f4 commit 84f435c

File tree

7 files changed

+115
-14
lines changed

7 files changed

+115
-14
lines changed

src/common/DecFloat.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,18 @@ struct DecimalStatus
5151
USHORT decExtFlag, roundingMode;
5252
};
5353

54+
struct DecimalBinding
55+
{
56+
DecimalBinding()
57+
: bind(DEC_NATIVE), numScale(0)
58+
{ }
59+
60+
enum Bind { DEC_NATIVE, DEC_TEXT, DEC_DOUBLE, DEC_NUMERIC };
61+
62+
Bind bind;
63+
SCHAR numScale;
64+
};
65+
5466
class Decimal64
5567
{
5668
friend class Decimal128;

src/dsql/StmtNodes.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8072,6 +8072,17 @@ void SetTrapsNode::execute(thread_db* tdbb, dsql_req* /*request*/) const
80728072
//--------------------
80738073

80748074

8075+
void SetBindNode::execute(thread_db* tdbb, dsql_req* /*request*/) const
8076+
{
8077+
SET_TDBB(tdbb);
8078+
Attachment* const attachment = tdbb->getAttachment();
8079+
attachment->att_dec_binding = bind;
8080+
}
8081+
8082+
8083+
//--------------------
8084+
8085+
80758086
StmtNode* UpdateOrInsertNode::dsqlPass(DsqlCompilerScratch* dsqlScratch)
80768087
{
80778088
thread_db* tdbb = JRD_get_thread_data(); // necessary?

src/dsql/StmtNodes.h

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1631,6 +1631,32 @@ class SetTrapsNode : public SessionManagementNode
16311631
};
16321632

16331633

1634+
class SetBindNode : public SessionManagementNode
1635+
{
1636+
public:
1637+
SetBindNode(MemoryPool& pool)
1638+
: SessionManagementNode(pool)
1639+
{
1640+
}
1641+
1642+
public:
1643+
virtual Firebird::string internalPrint(NodePrinter& printer) const
1644+
{
1645+
SessionManagementNode::internalPrint(printer);
1646+
1647+
NODE_PRINT(printer, bind.bind);
1648+
NODE_PRINT(printer, bind.numScale);
1649+
1650+
return "SetBindNode";
1651+
}
1652+
1653+
virtual void execute(thread_db* tdbb, dsql_req* request) const;
1654+
1655+
public:
1656+
Firebird::DecimalBinding bind;
1657+
};
1658+
1659+
16341660
class UpdateOrInsertNode : public TypedNode<DsqlOnlyStmtNode, StmtNode::TYPE_UPDATE_OR_INSERT>
16351661
{
16361662
public:

src/dsql/gen.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,25 @@ void GEN_port(DsqlCompilerScratch* dsqlScratch, dsql_msg* message)
201201
if (fromCharSet != toCharSet)
202202
parameter->par_desc.setTextType(toCharSet);
203203
}
204+
else if (parameter->par_desc.isDecFloat())
205+
{
206+
const DecimalBinding& b = tdbb->getAttachment()->att_dec_binding;
207+
switch (b.bind)
208+
{
209+
case DecimalBinding::DEC_NATIVE:
210+
break;
211+
case DecimalBinding::DEC_TEXT:
212+
parameter->par_desc.makeText((parameter->par_desc.dsc_dtype == dtype_dec64 ?
213+
DECDOUBLE_String : DECQUAD_String) - 1, ttype_ascii);
214+
break;
215+
case DecimalBinding::DEC_DOUBLE:
216+
parameter->par_desc.makeDouble();
217+
break;
218+
case DecimalBinding::DEC_NUMERIC:
219+
parameter->par_desc.makeInt64(b.numScale);
220+
break;
221+
}
222+
}
204223

205224
if (parameter->par_desc.dsc_dtype == dtype_text && parameter->par_index != 0)
206225
{

src/dsql/parse.y

Lines changed: 44 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -591,6 +591,7 @@ using namespace Firebird;
591591

592592
// tokens added for Firebird 4.0
593593
%token <metaNamePtr> BINARY
594+
%token <metaNamePtr> BIND
594595
%token <metaNamePtr> COMPARE_DECFLOAT
595596
%token <metaNamePtr> CUME_DIST
596597
%token <metaNamePtr> DECFLOAT
@@ -599,6 +600,7 @@ using namespace Firebird;
599600
%token <metaNamePtr> FOLLOWING
600601
%token <metaNamePtr> INVOKER
601602
%token <metaNamePtr> MESSAGE
603+
%token <metaNamePtr> NATIVE
602604
%token <metaNamePtr> NORMALIZE_DECFLOAT
603605
%token <metaNamePtr> NTILE
604606
%token <metaNamePtr> OTHERS
@@ -763,6 +765,7 @@ using namespace Firebird;
763765
Jrd::CreateAlterRoleNode* createAlterRoleNode;
764766
Jrd::SetRoundNode* setRoundNode;
765767
Jrd::SetTrapsNode* setTrapsNode;
768+
Jrd::SetBindNode* setBindNode;
766769
}
767770

768771
%include types.y
@@ -822,6 +825,7 @@ tra_statement
822825
mng_statement
823826
: set_round { $$ = $1; }
824827
| set_traps { $$ = $1; }
828+
| set_bind { $$ = $1; }
825829
| set_role { $$ = $1; }
826830
;
827831

@@ -4075,7 +4079,6 @@ keyword_or_column
40754079
| VAR_POP
40764080
| UNBOUNDED // added in FB 4.0
40774081
| WINDOW
4078-
| DECFLOAT
40794082
;
40804083

40814084
col_opt
@@ -4720,14 +4723,7 @@ varbinary_character_keyword
47204723

47214724
%type <legacyField> decfloat_type
47224725
decfloat_type
4723-
: DECFLOAT
4724-
{
4725-
$$ = newNode<dsql_fld>();
4726-
$$->dtype = dtype_dec64;
4727-
$$->length = sizeof(Decimal64);
4728-
$$->precision = 16;
4729-
}
4730-
| DECFLOAT '(' signed_long_integer ')'
4726+
: DECFLOAT '(' signed_long_integer ')'
47314727
{
47324728
if ($3 != 16 && $3 != 34)
47334729
yyabandon(YYPOSNARG(3), -842, isc_decprecision_err); // DecFloat precision must be 16 or 34.
@@ -5037,6 +5033,14 @@ set_traps
50375033
{ $$ = $5; }
50385034
;
50395035

5036+
%type <setBindNode> set_bind
5037+
set_bind
5038+
: SET DECFLOAT BIND
5039+
{ $$ = newNode<SetBindNode>(); }
5040+
bind_clause($4)
5041+
{ $$ = $4; }
5042+
;
5043+
50405044
%type traps_list_opt(<setTrapsNode>)
50415045
traps_list_opt($setTrapsNode)
50425046
: // nothing
@@ -5055,6 +5059,29 @@ trap($setTrapsNode)
50555059
{ $setTrapsNode->trap($1); }
50565060
;
50575061

5062+
%type bind_clause(<setBindNode>)
5063+
bind_clause($setBindNode)
5064+
: NATIVE
5065+
// do nothing
5066+
| character_keyword
5067+
{ $setBindNode->bind.bind = DecimalBinding::DEC_TEXT; }
5068+
| DOUBLE PRECISION
5069+
{ $setBindNode->bind.bind = DecimalBinding::DEC_DOUBLE; }
5070+
| BIGINT scale_clause($setBindNode)
5071+
{ $setBindNode->bind.bind = DecimalBinding::DEC_NUMERIC; }
5072+
;
5073+
5074+
%type scale_clause(<setBindNode>)
5075+
scale_clause($setBindNode)
5076+
: // nothing
5077+
| ',' signed_long_integer
5078+
{
5079+
if ($2 > 18 || $2 < 0)
5080+
yyabandon(YYPOSNARG(2), -842, isc_scale_nogt); // Scale must be between 0 and precision
5081+
$setBindNode->bind.numScale = -$2;
5082+
}
5083+
;
5084+
50585085
%type tran_option_list_opt(<setTransactionNode>)
50595086
tran_option_list_opt($setTransactionNode)
50605087
: // nothing
@@ -8285,27 +8312,30 @@ non_reserved_word
82858312
| SERVERWIDE
82868313
| INCREMENT
82878314
| TRUSTED
8288-
| CUME_DIST // added in FB 4.0
8315+
| BIND // added in FB 4.0
8316+
| COMPARE_DECFLOAT
8317+
| CUME_DIST
8318+
| DECFLOAT
82898319
| DEFINER
82908320
| EXCLUDE
82918321
| FOLLOWING
82928322
| INVOKER
82938323
| MESSAGE
8324+
| NATIVE
8325+
| NORMALIZE_DECFLOAT
82948326
| NTILE
82958327
| OTHERS
82968328
| PERCENT_RANK
82978329
| PRECEDING
82988330
| PRIVILEGE
8331+
| QUANTIZE
82998332
| RANGE
83008333
| SECURITY
83018334
| SQL
83028335
| SYSTEM
83038336
| TIES
8304-
| TRAPS
8305-
| QUANTIZE
83068337
| TOTALORDER
8307-
| NORMALIZE_DECFLOAT
8308-
| COMPARE_DECFLOAT
8338+
| TRAPS
83098339
;
83108340

83118341
%%

src/jrd/Attachment.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -337,6 +337,7 @@ class Attachment : public pool_alloc<type_att>
337337
Firebird::Array<JrdStatement*> att_dyn_req; // internal dyn statements
338338
Firebird::ICryptKeyCallback* att_crypt_callback; // callback for DB crypt
339339
Firebird::DecimalStatus att_dec_status; // error handling and rounding
340+
Firebird::DecimalBinding att_dec_binding; // use legacy datatype for DecFloat in outer world
340341

341342
jrd_req* findSystemRequest(thread_db* tdbb, USHORT id, USHORT which);
342343

src/yvalve/keywords.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ static const TOK tokens[] =
9595
{TOK_BIN_SHR, "BIN_SHR", true},
9696
{TOK_BIN_XOR, "BIN_XOR", true},
9797
{TOK_BINARY, "BINARY", false},
98+
{TOK_BIND, "BIND", true},
9899
{TOK_BIT_LENGTH, "BIT_LENGTH", false},
99100
{TOK_BLOB, "BLOB", false},
100101
{TOK_BLOCK, "BLOCK", true},
@@ -283,6 +284,7 @@ static const TOK tokens[] =
283284
{TOK_NAME, "NAME", true},
284285
{TOK_NAMES, "NAMES", true},
285286
{TOK_NATIONAL, "NATIONAL", false},
287+
{TOK_NATIVE, "NATIVE", true},
286288
{TOK_NATURAL, "NATURAL", false},
287289
{TOK_NCHAR, "NCHAR", false},
288290
{TOK_NEXT, "NEXT", true},

0 commit comments

Comments
 (0)