Skip to content

Commit f2475fb

Browse files
authored
Add NaN support (#100)
1 parent c81bc84 commit f2475fb

File tree

22 files changed

+1295
-233
lines changed

22 files changed

+1295
-233
lines changed

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ Features
4040
- `timestamp`: `text` and `int`,
4141
- `uuid`: `text`(32..39) and `blob`(16),
4242
- `bool`: `text`(1..5) and `int`,
43-
- `double precision`, `float` and `numeric`: `real` values and special values with `text` affinity (`+Infinity` and `-Infinity`).
43+
- `double precision`, `float` and `numeric`: `real` values and special values with `text` affinity (`+Infinity`, `-Infinity`, `NaN`).
4444
- Support mixed SQLite [data affinity](https://www.sqlite.org/datatype3.html) output (`INSERT`/`UPDATE`) for such data types as
4545
- `timestamp`: `text`(default) or `int`,
4646
- `uuid`: `text`(36) or `blob`(16)(default).
@@ -572,7 +572,7 @@ SQLite `text` affinity values which is different for SQLite unique checks can be
572572
- SQLite promises to preserve the 15 most significant digits of a floating point value. The big value which exceed 15 most significant digits may become different value after inserted.
573573
- SQLite does not support `numeric` type as PostgreSQL. Therefore, it does not allow to store numbers with too high precision and scale. Error out of range occurs.
574574
- SQLite does not support `NaN` special value for IEEE 754-2008 numbers. Please use this special value very cerefully because there is no such conception in SQLite at all and `NaN` value treated in SQLite as `NULL`.
575-
- SQLite support `+Infinity` and `-Infinity` special values for IEEE 754-2008 numbers in SQL expressions with numeric context. This values can be readed with both `text` and `real` affiniy, but can be writed to SQLite only with `real` affinity (as signed out of range value `9e999`).
575+
- SQLite support `+Infinity` and `-Infinity` special values for IEEE 754-2008 numbers in SQL expressions with numeric context. This values can be readed with both `text` and `real` affiniy, but can be writed to SQLite only with `real` affinity (as signed out of range value `9.0e999`).
576576

577577
### Boolean values
578578
- `sqlite_fdw` boolean values support exists only for `bool` columns in foreign table. SQLite documentation recommends to store boolean as value with `integer` [affinity](https://www.sqlite.org/datatype3.html). `NULL` isn't converted, 1 converted to `true`, all other `NOT NULL` values converted to `false`. During `SELECT ... WHERE condition_column` condition converted only to `condition_column`.

expected/12.16/extra/float4.out

Lines changed: 107 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1240,6 +1240,9 @@ INSERT INTO "type_FLOAT_INF" (i, f) VALUES (13, 'Inf');
12401240
INSERT INTO "type_FLOAT_INF" (i, f) VALUES (14, '+Inf');
12411241
--Testcase 288:
12421242
INSERT INTO "type_FLOAT_INF" (i, f) VALUES (15, '-Inf');
1243+
--Testcase 289: SQLite ignores NaN
1244+
--see https://github.com/sqlite/sqlite/blob/6db0b11e078f4b651f0cf00f845f3d77700c1a3a/src/vdbemem.c#L973
1245+
INSERT INTO "type_FLOAT_INF" (i, f) VALUES (16, 'NaN');
12431246
--Testcase 290:
12441247
ALTER FOREIGN TABLE "type_FLOAT_INF" ALTER COLUMN "f" TYPE text;
12451248
--Testcase 291:
@@ -1255,7 +1258,7 @@ INSERT INTO "type_FLOAT_INF" (i, f) VALUES (21, '+Inf');
12551258
--Testcase 296:
12561259
INSERT INTO "type_FLOAT_INF" (i, f) VALUES (22, '-Inf');
12571260
--Testcase 297:
1258-
--INSERT INTO "type_FLOAT_INF" (i, f) VALUES (23, 'NaN');
1261+
INSERT INTO "type_FLOAT_INF" (i, f) VALUES (23, 'NaN');
12591262
--Testcase 298:
12601263
INSERT INTO "type_FLOAT_INF" (i, f) VALUES (24, 'Infinity__');
12611264
--Testcase 299:
@@ -1293,13 +1296,15 @@ SELECT * FROM "type_FLOAT_INF";
12931296
13 | Infinity
12941297
14 | Infinity
12951298
15 | -Infinity
1299+
16 |
12961300
17 | Infinity
12971301
18 | Infinity
12981302
19 | -Infinity
12991303
20 | Infinity
13001304
21 | Infinity
13011305
22 | -Infinity
1302-
(19 rows)
1306+
23 | NaN
1307+
(21 rows)
13031308

13041309
--Testcase 306:
13051310
SELECT * FROM "type_FLOAT_INF+";
@@ -1318,13 +1323,15 @@ SELECT * FROM "type_FLOAT_INF+";
13181323
13 | Infinity | real | 3
13191324
14 | Infinity | real | 3
13201325
15 | -Infinity | real | 4
1326+
16 | | null |
13211327
17 | Infinity | text | 8
13221328
18 | Infinity | text | 9
13231329
19 | -Infinity | text | 9
13241330
20 | Infinity | text | 3
13251331
21 | Infinity | text | 4
13261332
22 | -Infinity | text | 4
1327-
(19 rows)
1333+
23 | NaN | text | 3
1334+
(21 rows)
13281335

13291336
--Testcase 307:
13301337
SELECT * FROM "type_FLOAT_INF+" ORDER BY f ASC, i;
@@ -1349,12 +1356,16 @@ SELECT * FROM "type_FLOAT_INF+" ORDER BY f ASC, i;
13491356
18 | Infinity | text | 9
13501357
20 | Infinity | text | 3
13511358
21 | Infinity | text | 4
1352-
(19 rows)
1359+
23 | NaN | text | 3
1360+
16 | | null |
1361+
(21 rows)
13531362

13541363
--Testcase 308:
13551364
SELECT * FROM "type_FLOAT_INF+" ORDER BY f DESC, i;
13561365
i | f | t | l
13571366
----+-----------+------+---
1367+
16 | | null |
1368+
23 | NaN | text | 3
13581369
2 | Infinity | real | 3
13591370
4 | Infinity | real | 3
13601371
10 | Infinity | real | 3
@@ -1374,13 +1385,14 @@ SELECT * FROM "type_FLOAT_INF+" ORDER BY f DESC, i;
13741385
15 | -Infinity | real | 4
13751386
19 | -Infinity | text | 9
13761387
22 | -Infinity | text | 4
1377-
(19 rows)
1388+
(21 rows)
13781389

13791390
--Testcase 309:
13801391
SELECT * FROM "type_FLOAT_INF+" WHERE f > '+Infinity' ORDER BY i;
1381-
i | f | t | l
1382-
---+---+---+---
1383-
(0 rows)
1392+
i | f | t | l
1393+
----+-----+------+---
1394+
23 | NaN | text | 3
1395+
(1 row)
13841396

13851397
--Testcase 310:
13861398
SELECT * FROM "type_FLOAT_INF+" WHERE f < '+Infinity' ORDER BY i;
@@ -1415,9 +1427,10 @@ SELECT * FROM "type_FLOAT_INF+" WHERE f = '+Infinity' ORDER BY i;
14151427

14161428
--Testcase 312:
14171429
SELECT * FROM "type_FLOAT_INF+" WHERE f > '+Inf' ORDER BY i;
1418-
i | f | t | l
1419-
---+---+---+---
1420-
(0 rows)
1430+
i | f | t | l
1431+
----+-----+------+---
1432+
23 | NaN | text | 3
1433+
(1 row)
14211434

14221435
--Testcase 313:
14231436
SELECT * FROM "type_FLOAT_INF+" WHERE f < '+Inf' ORDER BY i;
@@ -1467,7 +1480,8 @@ SELECT * FROM "type_FLOAT_INF+" WHERE f > '-Infinity' ORDER BY i;
14671480
18 | Infinity | text | 9
14681481
20 | Infinity | text | 3
14691482
21 | Infinity | text | 4
1470-
(13 rows)
1483+
23 | NaN | text | 3
1484+
(14 rows)
14711485

14721486
--Testcase 316:
14731487
SELECT * FROM "type_FLOAT_INF+" WHERE f < '-Infinity' ORDER BY i;
@@ -1504,7 +1518,8 @@ SELECT * FROM "type_FLOAT_INF+" WHERE f > '-Inf' ORDER BY i;
15041518
18 | Infinity | text | 9
15051519
20 | Infinity | text | 3
15061520
21 | Infinity | text | 4
1507-
(13 rows)
1521+
23 | NaN | text | 3
1522+
(14 rows)
15081523

15091524
--Testcase 319:
15101525
SELECT * FROM "type_FLOAT_INF+" WHERE f < '-Inf' ORDER BY i;
@@ -1526,9 +1541,10 @@ SELECT * FROM "type_FLOAT_INF+" WHERE f = '-Inf' ORDER BY i;
15261541

15271542
--Testcase 321:
15281543
SELECT * FROM "type_FLOAT_INF+" WHERE f > 'Infinity' ORDER BY i;
1529-
i | f | t | l
1530-
---+---+---+---
1531-
(0 rows)
1544+
i | f | t | l
1545+
----+-----+------+---
1546+
23 | NaN | text | 3
1547+
(1 row)
15321548

15331549
--Testcase 322:
15341550
SELECT * FROM "type_FLOAT_INF+" WHERE f < 'Infinity' ORDER BY i;
@@ -1563,9 +1579,10 @@ SELECT * FROM "type_FLOAT_INF+" WHERE f = 'Infinity' ORDER BY i;
15631579

15641580
--Testcase 324:
15651581
SELECT * FROM "type_FLOAT_INF+" WHERE f > 'Inf' ORDER BY i;
1566-
i | f | t | l
1567-
---+---+---+---
1568-
(0 rows)
1582+
i | f | t | l
1583+
----+-----+------+---
1584+
23 | NaN | text | 3
1585+
(1 row)
15691586

15701587
--Testcase 325:
15711588
SELECT * FROM "type_FLOAT_INF+" WHERE f < 'Inf' ORDER BY i;
@@ -1598,6 +1615,44 @@ SELECT * FROM "type_FLOAT_INF+" WHERE f = 'Inf' ORDER BY i;
15981615
21 | Infinity | text | 4
15991616
(10 rows)
16001617

1618+
--Testcase 327:
1619+
SELECT * FROM "type_FLOAT_INF+" WHERE f > 'NaN' ORDER BY i;
1620+
i | f | t | l
1621+
---+---+---+---
1622+
(0 rows)
1623+
1624+
--Testcase 328:
1625+
SELECT * FROM "type_FLOAT_INF+" WHERE f < 'NaN' ORDER BY i;
1626+
i | f | t | l
1627+
----+-----------+------+---
1628+
1 | -Infinity | real | 4
1629+
2 | Infinity | real | 3
1630+
3 | -Infinity | real | 4
1631+
4 | Infinity | real | 3
1632+
5 | -1e+308 | real | 9
1633+
6 | 0 | real | 3
1634+
7 | 1e+308 | real | 8
1635+
10 | Infinity | real | 3
1636+
11 | Infinity | real | 3
1637+
12 | -Infinity | real | 4
1638+
13 | Infinity | real | 3
1639+
14 | Infinity | real | 3
1640+
15 | -Infinity | real | 4
1641+
17 | Infinity | text | 8
1642+
18 | Infinity | text | 9
1643+
19 | -Infinity | text | 9
1644+
20 | Infinity | text | 3
1645+
21 | Infinity | text | 4
1646+
22 | -Infinity | text | 4
1647+
(19 rows)
1648+
1649+
--Testcase 329:
1650+
SELECT * FROM "type_FLOAT_INF+" WHERE f = 'NaN' ORDER BY i;
1651+
i | f | t | l
1652+
----+-----+------+---
1653+
23 | NaN | text | 3
1654+
(1 row)
1655+
16011656
--Testcase 330:
16021657
EXPLAIN (VERBOSE, COSTS OFF)
16031658
SELECT * FROM "type_FLOAT_INF+" WHERE f > '+Infinity' ORDER BY i;
@@ -1796,6 +1851,39 @@ SELECT * FROM "type_FLOAT_INF+" WHERE f = 'Inf' ORDER BY i;
17961851
SQLite query: SELECT `i`, sqlite_fdw_float(`f`), `t`, `l` FROM main."type_FLOAT_INF+" WHERE ((sqlite_fdw_float(`f`) = 9e999))
17971852
(6 rows)
17981853

1854+
--Testcase 348:
1855+
EXPLAIN (VERBOSE, COSTS OFF)
1856+
SELECT * FROM "type_FLOAT_INF+" WHERE f > 'NaN' ORDER BY i;
1857+
QUERY PLAN
1858+
-------------------------------------------------------------------------------------------------------------------------------------------------------------
1859+
Foreign Scan on public."type_FLOAT_INF+"
1860+
Output: i, f, t, l
1861+
SQLite query: SELECT `i`, sqlite_fdw_float(`f`), `t`, `l` FROM main."type_FLOAT_INF+" WHERE ((sqlite_fdw_float(`f`) > 'NaN')) ORDER BY `i` ASC NULLS LAST
1862+
(3 rows)
1863+
1864+
--Testcase 349:
1865+
EXPLAIN (VERBOSE, COSTS OFF)
1866+
SELECT * FROM "type_FLOAT_INF+" WHERE f < 'NaN' ORDER BY i;
1867+
QUERY PLAN
1868+
-------------------------------------------------------------------------------------------------------------------------------------------------------------
1869+
Foreign Scan on public."type_FLOAT_INF+"
1870+
Output: i, f, t, l
1871+
SQLite query: SELECT `i`, sqlite_fdw_float(`f`), `t`, `l` FROM main."type_FLOAT_INF+" WHERE ((sqlite_fdw_float(`f`) < 'NaN')) ORDER BY `i` ASC NULLS LAST
1872+
(3 rows)
1873+
1874+
--Testcase 350:
1875+
EXPLAIN (VERBOSE, COSTS OFF)
1876+
SELECT * FROM "type_FLOAT_INF+" WHERE f = 'NaN' ORDER BY i;
1877+
QUERY PLAN
1878+
---------------------------------------------------------------------------------------------------------------------------------------
1879+
Sort
1880+
Output: i, f, t, l
1881+
Sort Key: "type_FLOAT_INF+".i
1882+
-> Foreign Scan on public."type_FLOAT_INF+"
1883+
Output: i, f, t, l
1884+
SQLite query: SELECT `i`, sqlite_fdw_float(`f`), `t`, `l` FROM main."type_FLOAT_INF+" WHERE ((sqlite_fdw_float(`f`) = 'NaN'))
1885+
(6 rows)
1886+
17991887
--Testcase 351:
18001888
DELETE FROM "type_FLOAT_INF" WHERE i >= 10;
18011889
--Testcase 352:

0 commit comments

Comments
 (0)