diff --git a/docs/sql/data_types/numeric.md b/docs/sql/data_types/numeric.md index d5c14380195..71b72e5f072 100644 --- a/docs/sql/data_types/numeric.md +++ b/docs/sql/data_types/numeric.md @@ -61,18 +61,26 @@ For more complex mathematical operations, however, floating-point arithmetic is In general, we advise that: * If you require exact storage of numbers with a known number of decimal digits and require exact additions, subtractions, and multiplications (such as for monetary amounts), use the [`DECIMAL` data type](#fixed-point-decimals) or its `NUMERIC` alias instead. -* If you want to do fast or complicated calculations, the floating-point data types may be more appropriate. However, if you use the results for anything important, you should evaluate your implementation carefully for corner cases (ranges, infinities, underflows, invalid operations) that may be handled differently from what you expect and you should familiarize yourself with common floating-point pitfalls. The article ["What Every Computer Scientist Should Know About -Floating-Point Arithmetic" by David Goldberg](https://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html) and [the floating point series on Bruce Dawson's blog](https://randomascii.wordpress.com/2017/06/19/sometimes-floating-point-math-is-perfect/) provide excellent starting points. +* If you want to do fast or complicated calculations, the floating-point data types may be more appropriate. However, if you use the results for anything important, you should evaluate your implementation carefully for corner cases (ranges, infinities, underflows, invalid operations) that may be handled differently from what you expect and you should familiarize yourself with common floating-point pitfalls. The article ["What Every Computer Scientist Should Know About Floating-Point Arithmetic" by David Goldberg](https://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html) and [the floating point series on Bruce Dawson's blog](https://randomascii.wordpress.com/2017/06/19/sometimes-floating-point-math-is-perfect/) provide excellent starting points. On most platforms, the `REAL` type has a range of at least 1E-37 to 1E+37 with a precision of at least 6 decimal digits. The `DOUBLE` type typically has a range of around 1E-307 to 1E+308 with a precision of at least 15 digits. Positive numbers outside of these ranges (and negative numbers ourside the mirrored ranges) may cause errors on some platforms but will usually be converted to zero or infinity, respectively. -In addition to ordinary numeric values, the floating-point types have several special values: +In addition to ordinary numeric values, the floating-point types have several special values representing IEEE 754 special values: -* `Infinity` -* `-Infinity` -* `NaN` +* `Infinity`: infinity +* `-Infinity`: negative infinity +* `NaN`: not a number -These represent the IEEE 754 special values "infinity", "negative infinity", and "not-a-number", respectively. (On a machine whose floating-point arithmetic does not follow IEEE 754, these values will probably not work as expected.) When writing these values as constants in a SQL command, you must put quotes around them, for example: `UPDATE table SET x = '-Infinity'`. On input, these strings are recognized in a case-insensitive manner. +> On a machine whose floating-point arithmetic does not follow IEEE 754, these values will probably not work as expected. + +When writing these values as constants in a SQL command, you must put quotes around them, for example: + +```sql +UPDATE table +SET x = '-Infinity'; +``` + +On input, these strings are recognized in a case-insensitive manner. ## Universally Unique Identifiers (`UUID`s) diff --git a/docs/sql/postgresql_compatibility.md b/docs/sql/postgresql_compatibility.md index c5754616cff..e8c34b7e80d 100644 --- a/docs/sql/postgresql_compatibility.md +++ b/docs/sql/postgresql_compatibility.md @@ -6,6 +6,34 @@ title: PostgreSQL Compatibility DuckDB's SQL dialect closely follows the conventions of the PostgreSQL dialect. The few exceptions to this are listed on this page. +## Floating-Point Arithmetic + +DuckDB and PostgreSQL handle floating-point arithmetic differently for division by zero. Neither system confirm the [IEEE Standard for Floating-Point Arithmetic (IEEE 754)](https://en.wikipedia.org/wiki/IEEE_754). +On operations involving infinity values, DuckDB and PostgreSQL align with each other but again they both deviate from IEEE 754. +To show the differences, run the following SQL queries: + +```sql +SELECT 1.0 / 0.0 AS x; +SELECT 0.0 / 0.0 AS x; +SELECT -1.0 / 0.0 AS x; +SELECT 'Infinity'::FLOAT / 'Infinity'::FLOAT AS x; +SELECT 1.0 / 'Infinity'::FLOAT AS x; +SELECT 'Infinity'::FLOAT - 'Infinity'::FLOAT AS x; +SELECT 'Infinity'::FLOAT - 1.0 AS x; +``` + +
+ +| Expression | DuckDB | PostgreSQL | IEEE 754 | +| :---------------------- | -------: | ---------: | --------: | +| 1.0 / 0.0 | NULL | error | Infinity | +| 0.0 / 0.0 | NULL | error | Nan | +| -1.0 / 0.0 | NULL | error | -Infinity | +| 'Infinity' / 'Infinity' | NaN | NaN | NaN | +| 1.0 / 'Infinity' | 0.0 | 0.0 | 0.0 | +| 'Infinity' - 'Infinity' | NaN | NaN | NaN | +| 'Infinity' - 1.0 | Infinity | Infinity | Infinity | + ## Division on Integers When computing division on integers, PostgreSQL performs integer divison, while DuckDB performs float division: @@ -25,9 +53,9 @@ PostgreSQL returns: DuckDB returns: -| x | -|----:| -| 0.5 | +| x | +| ---: | +| 0.5 | To perform integer division in DuckDB, use the `//` operator: @@ -35,9 +63,9 @@ To perform integer division in DuckDB, use the `//` operator: SELECT 1 // 2 AS x; ``` -| x | -|--:| -| 0 | +| x | +| ---: | +| 0 | ## `UNION` of Boolean and Integer Values @@ -57,10 +85,10 @@ ERROR: UNION types boolean and integer cannot be matched DuckDB performs an enforced cast, therefore, it completes the query and returns the following: -| x | -|--:| -| 1 | -| 2 | +| x | +| ---: | +| 1 | +| 2 | ## Case Sensitivity for Quoted Identifiers @@ -103,12 +131,11 @@ SELECT table_name FROM duckdb_tables();
-| table_name | -|---------------| +| table_name | +| ------------- | | MyTaBLe | | PreservedCase | - PostgreSQL's behavior of lowercasing identifiers is accessible using the [`preserve_identifier_case` option]({% link docs/configuration/overview.md %}#local-configuration-options): ```sql @@ -120,7 +147,7 @@ SELECT table_name FROM duckdb_tables();
| table_name | -|------------| +| ---------- | | mytable | However, the case insensitive matching in the system for identifiers cannot be turned off.