From a4a8e2329421767bcecce6ca2179d418d607903f Mon Sep 17 00:00:00 2001 From: Mohammad Aziz Date: Thu, 6 May 2021 08:10:22 +0530 Subject: [PATCH] sql/pgwire: change formatting of floating point infinity values Postgres drivers such as JDBC rely on infinite values to be formatted as full words in order to be able to parse the value. Release note (sql change): Floating point infinity values are now formatted as `Infinity` (or `-Infinity` if negative). This is for compatibility with Postgres --- pkg/cmd/generate-binary/main.go | 8 ++++---- pkg/sql/pgwire/testdata/encodings.json | 28 ++++++++++++++++++++++++++ pkg/sql/pgwire/types.go | 15 ++++++++++++-- 3 files changed, 45 insertions(+), 6 deletions(-) diff --git a/pkg/cmd/generate-binary/main.go b/pkg/cmd/generate-binary/main.go index 4e9d5b0f172d..180f26ca66e5 100644 --- a/pkg/cmd/generate-binary/main.go +++ b/pkg/cmd/generate-binary/main.go @@ -213,8 +213,8 @@ var inputs = map[string][]string{ // float encodings. These deviations are still correct, and it's not worth // special casing them into the code, so they are commented out here. //"NaN", - //"Inf", - //"-Inf", + "Inf", + "-Inf", "-000.000", "-0000021234.23246346000000", "-1.2", @@ -234,8 +234,8 @@ var inputs = map[string][]string{ // float encodings. These deviations are still correct, and it's not worth // special casing them into the code, so they are commented out here. //"NaN", - //"Inf", - //"-Inf", + "Inf", + "-Inf", "-000.000", "-0000021234.2", "-1.2", diff --git a/pkg/sql/pgwire/testdata/encodings.json b/pkg/sql/pgwire/testdata/encodings.json index e1827a2d978c..8fc92ee74347 100644 --- a/pkg/sql/pgwire/testdata/encodings.json +++ b/pkg/sql/pgwire/testdata/encodings.json @@ -692,6 +692,20 @@ "TextAsBinary": [123, 50, 46, 50, 50, 56, 57, 57, 55, 49, 49, 53, 57, 49, 48, 48, 50, 56, 52, 44, 51, 52, 48, 57, 53, 56, 57, 50, 54, 56, 53, 50, 48, 57, 53, 54, 57, 51, 52, 50, 53, 48, 46, 50, 51, 52, 48, 57, 56, 55, 51, 50, 48, 52, 53, 49, 50, 48, 57, 51, 52, 55, 48, 49, 50, 51, 57, 56, 52, 54, 44, 52, 50, 125], "Binary": [0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 6, 164, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 18, 0, 5, 0, 0, 0, 0, 0, 16, 0, 2, 8, 241, 37, 239, 23, 22, 1, 28, 0, 0, 0, 34, 0, 13, 0, 5, 0, 0, 0, 27, 0, 34, 3, 190, 36, 52, 20, 89, 22, 61, 16, 154, 9, 36, 38, 145, 7, 253, 4, 185, 13, 142, 4, 215, 33, 12, 0, 0, 0, 10, 0, 1, 0, 0, 0, 0, 0, 0, 0, 42] }, + { + "SQL": "'Inf'::float4", + "Oid": 700, + "Text": "Infinity", + "TextAsBinary": [73, 110, 102, 105, 110, 105, 116, 121], + "Binary": [127, 128, 0, 0] + }, + { + "SQL": "'-Inf'::float4", + "Oid": 700, + "Text": "-Infinity", + "TextAsBinary": [45, 73, 110, 102, 105, 110, 105, 116, 121], + "Binary": [255, 128, 0, 0] + }, { "SQL": "'-000.000'::float4", "Oid": 700, @@ -755,6 +769,20 @@ "TextAsBinary": [49, 46, 52, 48, 49, 51, 101, 45, 52, 53], "Binary": [0, 0, 0, 1] }, + { + "SQL": "'Inf'::float8", + "Oid": 701, + "Text": "Infinity", + "TextAsBinary": [73, 110, 102, 105, 110, 105, 116, 121], + "Binary": [127, 240, 0, 0, 0, 0, 0, 0] + }, + { + "SQL": "'-Inf'::float8", + "Oid": 701, + "Text": "-Infinity", + "TextAsBinary": [45, 73, 110, 102, 105, 110, 105, 116, 121], + "Binary": [255, 240, 0, 0, 0, 0, 0, 0] + }, { "SQL": "'-000.000'::float8", "Oid": 701, diff --git a/pkg/sql/pgwire/types.go b/pkg/sql/pgwire/types.go index 0e46e5a8c074..17e1a2595cfa 100644 --- a/pkg/sql/pgwire/types.go +++ b/pkg/sql/pgwire/types.go @@ -98,8 +98,19 @@ func (b *writeBuffer) writeTextDatum( b.write(s) case *tree.DFloat: - // Start at offset 4 because `putInt32` clobbers the first 4 bytes. - s := strconv.AppendFloat(b.putbuf[4:4], float64(*v), 'g', conv.GetFloatPrec(), 64) + fl := float64(*v) + var s []byte + // PostgreSQL supports 'Inf' as a valid literal for the floating point + // special value Infinity, therefore handling the special cases for them. + // (https://github.com/cockroachdb/cockroach/issues/62601) + if math.IsInf(fl, 1) { + s = []byte("Infinity") + } else if math.IsInf(fl, -1) { + s = []byte("-Infinity") + } else { + // Start at offset 4 because `putInt32` clobbers the first 4 bytes. + s = strconv.AppendFloat(b.putbuf[4:4], fl, 'g', conv.GetFloatPrec(), 64) + } b.putInt32(int32(len(s))) b.write(s)