8
0
mirror of https://github.com/FirebirdSQL/firebird.git synced 2025-01-22 20:43:02 +01:00

CORE-6109 SQL standard FLOAT type syntax support (#218)

* CORE-6109 SQL standard FLOAT type syntax support

* Fix type or copy/paste error

* Delete unused precision_opt rule
This commit is contained in:
Mark Rotteveel 2019-08-02 19:55:34 +02:00 committed by Dmitry Yemanov
parent 59ab6a98b2
commit 426aeb50c8
2 changed files with 75 additions and 10 deletions

View File

@ -0,0 +1,55 @@
# Floating point types
Firebird has two forms of floating point types:
- approximate numeric types (or binary floating point types)
- decimal floating point types
## Approximate numeric types
The approximate numeric types supported by Firebird are a 32 bit single
precision and a 64 bit double precision floating point type. These types are
available with the following SQL standard type names:
- `REAL` - 32 bit single precision (synonym for `FLOAT`) _(1)_
- `FLOAT` - 32 bit single precision
- `FLOAT(p)` where `p` is the precision of the significand in binary digits _(2, 3)_
- 1 <= `p` <= 24 - 32 bit single precision (synonym for `FLOAT`)
- 25 <= `p` <= 53 - 64 bit double precision (synonym for `DOUBLE PRECISION`)
- `DOUBLE PRECISION` - 64 bit double precision
In addition the following non-standard type names are supported:
- `LONG FLOAT` - 64 bit double precision (synonym for `DOUBLE PRECISION`)
- `LONG FLOAT(p)` where `p` is the precision of the significand in binary digits _(4, 5)_
- 1 <= `p` <= 53 - 64 bit double precision (synonym for `DOUBLE PRECISION`)
These non-standard type names are deprecated and they may be removed in a future
version.
## Decimal floating point types
The decimal floating point types supported by Firebird are a 64 bit Decimal64
with a precision of 16 decimals and a 128 bit Decimal128 with a precision of
34 decimals. These types are available with the following SQL standard type
names:
- `DECFLOAT` - 128 bit Decimal128 (synonym for `DECFLOAT(34)`)
- `DECFLOAT(16)` - 64 bit Decimal64
- `DECFLOAT(34)` - 128 bit Decimal128
## Notes
1. `REAL` has been available as a synonym for `FLOAT` since Firebird 1 and even
earlier, but was never documented.
2. Firebird 3 and earlier supported `FLOAT(p)` where `p` was the
approximate precision in decimal digits, and 0 <= `p` <= 7 mapped to 32 bit
single precision and `p` > 7 to 64 bit double precision. This syntax was never
documented.
3. For `p` in `FLOAT(p)`, the values 1 <= `p` <= 24 are all treated as
`p` = 24, values 25 <= `p` <= 53 are all handled as `p` = 53.
4. Firebird 3 and earlier supported `LONG FLOAT(p)` where `p` was the
approximate precision in decimal digits, where any value for `p` mapped to
64 bit double precision. This type name and syntax were never documented.
3. For `p` in `LONG FLOAT(p)`, the values 1 <= `p` <= 53 are all handled as
`p` = 53.

View File

@ -5095,11 +5095,19 @@ decimal_keyword
%type <legacyField> float_type %type <legacyField> float_type
float_type float_type
: FLOAT precision_opt : FLOAT precision_opt_nz
{ {
// Precision is binary digits of the significand: 1-24 for 32 bit single precision, 25-53 for 64 bit double precision
// Precision 0 is the 'no precision specified' case, which defaults to 32 bit single precision
SLONG precision = $2;
if (precision != 0 && (precision < 1 || precision > 53))
yyabandon(YYPOSNARG(2), -842, Arg::Gds(isc_precision_err2) << Arg::Num(1) << Arg::Num(53));
// Precision must be between 1 and 53
$$ = newNode<dsql_fld>(); $$ = newNode<dsql_fld>();
if ($2 > 7) if (precision > 24)
{ {
$$->dtype = dtype_double; $$->dtype = dtype_double;
$$->length = sizeof(double); $$->length = sizeof(double);
@ -5110,8 +5118,16 @@ float_type
$$->length = sizeof(float); $$->length = sizeof(float);
} }
} }
| LONG FLOAT precision_opt | LONG FLOAT precision_opt_nz
{ {
// Precision is binary digits of the significand: 1-53 for 64 bit double precision
// Precision 0 is the 'no precision specified case', which defaults to 64 bit double precision
SLONG precision = $3;
if (precision != 0 && (precision < 1 || precision > 53))
yyabandon(YYPOSNARG(3), -842, Arg::Gds(isc_precision_err2) << Arg::Num(1) << Arg::Num(53));
// Precision must be between 1 and 53
$$ = newNode<dsql_fld>(); $$ = newNode<dsql_fld>();
$$->dtype = dtype_double; $$->dtype = dtype_double;
$$->length = sizeof(double); $$->length = sizeof(double);
@ -5130,13 +5146,7 @@ float_type
} }
; ;
%type <int32Val> precision_opt // optional precision that does not allow zero
precision_opt
: /* nothing */ { $$ = 0; }
| '(' nonneg_short_integer ')' { $$ = $2; }
;
// alternative to precision_opt that does not allow zero
%type <int32Val> precision_opt_nz %type <int32Val> precision_opt_nz
precision_opt_nz precision_opt_nz
: /* nothing */ { $$ = 0; } : /* nothing */ { $$ = 0; }