Skip to content

Commit 0227ec9

Browse files
committed
Implemented DecFloat-specific functions present in DB2
1 parent 14906af commit 0227ec9

File tree

5 files changed

+294
-23
lines changed

5 files changed

+294
-23
lines changed

src/common/DecFloat.cpp

Lines changed: 100 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -316,7 +316,7 @@ int Decimal64::compare(DecimalStatus decSt, Decimal64 tgt) const
316316
DecimalContext context(this, decSt);
317317
decDouble r;
318318
decDoubleCompare(&r, &dec, &tgt.dec, &context);
319-
return decDoubleToInt32(&r, &context, DEC_ROUND_UP);
319+
return decDoubleToInt32(&r, &context, DEC_ROUND_HALF_UP);
320320
}
321321

322322
bool Decimal64::isInf() const
@@ -377,6 +377,53 @@ void Decimal64::grabKey(unsigned int* key)
377377
decDoubleFromBCD(&dec, exp, bcd, sign);
378378
}
379379

380+
Decimal64 Decimal64::quantize(DecimalStatus decSt, Decimal64 op2) const
381+
{
382+
DecimalContext context(this, decSt);
383+
Decimal64 rc;
384+
decDoubleQuantize(&rc.dec, &dec, &op2.dec, &context);
385+
return rc;
386+
}
387+
388+
Decimal64 Decimal64::normalize(DecimalStatus decSt) const
389+
{
390+
DecimalContext context(this, decSt);
391+
Decimal64 rc;
392+
decDoubleReduce(&rc.dec, &dec, &context);
393+
return rc;
394+
}
395+
396+
short Decimal64::totalOrder(Decimal64 op2) const
397+
{
398+
decDouble r;
399+
decDoubleCompareTotal(&r, &dec, &op2.dec);
400+
fb_assert(!decDoubleIsNaN(&r));
401+
402+
DecimalContext context2(this, 0);
403+
return decDoubleToInt32(&r, &context2, DEC_ROUND_HALF_UP);
404+
}
405+
406+
short Decimal64::decCompare(Decimal64 op2) const
407+
{
408+
if (decDoubleIsNaN(&dec) || decDoubleIsNaN(&op2.dec))
409+
return 3;
410+
411+
switch (totalOrder(op2))
412+
{
413+
case -1:
414+
return 1;
415+
case 0:
416+
return 0;
417+
case 1:
418+
return 2;
419+
default:
420+
fb_assert(false);
421+
}
422+
423+
// warning silencer
424+
return 3;
425+
}
426+
380427
Decimal128 Decimal128::set(Decimal64 d64)
381428
{
382429
decDoubleToWider(&d64.dec, &dec);
@@ -530,7 +577,7 @@ int Decimal128::compare(DecimalStatus decSt, Decimal128 tgt) const
530577
DecimalContext context(this, decSt);
531578
decQuad r;
532579
decQuadCompare(&r, &dec, &tgt.dec, &context);
533-
return decQuadToInt32(&r, &context, DEC_ROUND_UP);
580+
return decQuadToInt32(&r, &context, DEC_ROUND_HALF_UP);
534581
}
535582

536583
bool Decimal128::isInf() const
@@ -754,9 +801,9 @@ ULONG Decimal128::makeIndexKey(vary* buf)
754801
// Avoid bad data in k in case when coeff is zero
755802
*k = 0;
756803

757-
//
758-
struct tab { UCHAR rshift, lshift; };
759-
static tab table[4] =
804+
// Shifts for moving 10-bit values to bytes buffer
805+
struct ShiftTable { UCHAR rshift, lshift; };
806+
static ShiftTable table[4] =
760807
{
761808
{ 2, 6 },
762809
{ 4, 4 },
@@ -766,7 +813,7 @@ ULONG Decimal128::makeIndexKey(vary* buf)
766813

767814
// compress coeff - 3 decimal digits (999) per 10 bits (1023)
768815
unsigned char* p = coeff;
769-
for (tab* t = table; p < end; p += 3)
816+
for (ShiftTable* t = table; p < end; p += 3)
770817
{
771818
USHORT val = p[0] * 100 + p[1] * 10 + p[2];
772819
fb_assert(val < 1000); // 1024, 10 bit
@@ -790,4 +837,51 @@ ULONG Decimal128::makeIndexKey(vary* buf)
790837
return buf->vary_length;
791838
}
792839

840+
Decimal128 Decimal128::quantize(DecimalStatus decSt, Decimal128 op2) const
841+
{
842+
DecimalContext context(this, decSt);
843+
Decimal128 rc;
844+
decQuadQuantize(&rc.dec, &dec, &op2.dec, &context);
845+
return rc;
846+
}
847+
848+
Decimal128 Decimal128::normalize(DecimalStatus decSt) const
849+
{
850+
DecimalContext context(this, decSt);
851+
Decimal128 rc;
852+
decQuadReduce(&rc.dec, &dec, &context);
853+
return rc;
854+
}
855+
856+
short Decimal128::totalOrder(Decimal128 op2) const
857+
{
858+
decQuad r;
859+
decQuadCompareTotal(&r, &dec, &op2.dec);
860+
fb_assert(!decQuadIsNaN(&r));
861+
862+
DecimalContext context2(this, 0);
863+
return decQuadToInt32(&r, &context2, DEC_ROUND_HALF_UP);
864+
}
865+
866+
short Decimal128::decCompare(Decimal128 op2) const
867+
{
868+
if (decQuadIsNaN(&dec) || decQuadIsNaN(&op2.dec))
869+
return 3;
870+
871+
switch (totalOrder(op2))
872+
{
873+
case -1:
874+
return 1;
875+
case 0:
876+
return 0;
877+
case 1:
878+
return 2;
879+
default:
880+
fb_assert(false);
881+
}
882+
883+
// warning silencer
884+
return 3;
885+
}
886+
793887
} // namespace Firebird

src/common/DecFloat.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,11 @@ class Decimal64
7777
void makeKey(unsigned int* key) const;
7878
void grabKey(unsigned int* key);
7979

80+
Decimal64 quantize(DecimalStatus decSt, Decimal64 op2) const;
81+
Decimal64 normalize(DecimalStatus decSt) const;
82+
short totalOrder(Decimal64 op2) const;
83+
short decCompare(Decimal64 op2) const;
84+
8085
#ifdef DEV_BUILD
8186
int show();
8287
#endif
@@ -130,6 +135,11 @@ class Decimal128
130135
static ULONG getIndexKeyLength();
131136
ULONG makeIndexKey(vary* buf);
132137

138+
Decimal128 quantize(DecimalStatus decSt, Decimal128 op2) const;
139+
Decimal128 normalize(DecimalStatus decSt) const;
140+
short totalOrder(Decimal128 op2) const;
141+
short decCompare(Decimal128 op2) const;
142+
133143
#ifdef DEV_BUILD
134144
int show();
135145
#endif

src/dsql/parse.y

Lines changed: 13 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -590,19 +590,22 @@ using namespace Firebird;
590590
%token <metaNamePtr> REGR_SYY
591591

592592
// tokens added for Firebird 4.0
593-
594593
%token <metaNamePtr> BINARY
594+
%token <metaNamePtr> COMPARE_DECFLOAT
595595
%token <metaNamePtr> CUME_DIST
596+
%token <metaNamePtr> DECFLOAT
596597
%token <metaNamePtr> DEFINER
597598
%token <metaNamePtr> EXCLUDE
598599
%token <metaNamePtr> FOLLOWING
599600
%token <metaNamePtr> INVOKER
600601
%token <metaNamePtr> MESSAGE
602+
%token <metaNamePtr> NORMALIZE_DECFLOAT
601603
%token <metaNamePtr> NTILE
602604
%token <metaNamePtr> OTHERS
603605
%token <metaNamePtr> PERCENT_RANK
604606
%token <metaNamePtr> PRECEDING
605607
%token <metaNamePtr> PRIVILEGE
608+
%token <metaNamePtr> QUANTIZE
606609
%token <metaNamePtr> RANGE
607610
%token <metaNamePtr> RDB_ERROR
608611
%token <metaNamePtr> RDB_ROLE_IN_USE
@@ -611,11 +614,11 @@ using namespace Firebird;
611614
%token <metaNamePtr> SQL
612615
%token <metaNamePtr> SYSTEM
613616
%token <metaNamePtr> TIES
617+
%token <metaNamePtr> TOTALORDER
614618
%token <metaNamePtr> TRAPS
615619
%token <metaNamePtr> UNBOUNDED
616620
%token <metaNamePtr> VARBINARY
617621
%token <metaNamePtr> WINDOW
618-
%token <metaNamePtr> DECFLOAT
619622

620623
// precedence declarations for expression evaluation
621624

@@ -6223,20 +6226,6 @@ cursor_clause
62236226

62246227
// Assignments
62256228

6226-
%type <compoundStmtNode> assignments
6227-
assignments
6228-
: assignment
6229-
{
6230-
$$ = newNode<CompoundStmtNode>();
6231-
$$->statements.add($1);
6232-
}
6233-
| assignments ',' assignment
6234-
{
6235-
$1->statements.add($3);
6236-
$$ = $1;
6237-
}
6238-
;
6239-
62406229
%type <stmtNode> assignment
62416230
assignment
62426231
: update_column_name '=' value
@@ -7595,6 +7584,10 @@ system_function_std_syntax
75957584
| TANH
75967585
| TRUNC
75977586
| UUID_TO_CHAR
7587+
| QUANTIZE
7588+
| TOTALORDER
7589+
| NORMALIZE_DECFLOAT
7590+
| COMPARE_DECFLOAT
75987591
;
75997592

76007593
%type <sysFuncCallNode> system_function_special_syntax
@@ -8309,6 +8302,10 @@ non_reserved_word
83098302
| SYSTEM
83108303
| TIES
83118304
| TRAPS
8305+
| QUANTIZE
8306+
| TOTALORDER
8307+
| NORMALIZE_DECFLOAT
8308+
| COMPARE_DECFLOAT
83128309
;
83138310

83148311
%%

0 commit comments

Comments
 (0)