From 234a5385cdf519d0e065860be6d63ede203dff7d Mon Sep 17 00:00:00 2001 From: Kirill Zaborsky Date: Wed, 29 Dec 2021 20:15:40 +0300 Subject: [PATCH] Fix support for FLOAT64 in BigQuery PR-URL: https://github.com/hasura/graphql-engine-mono/pull/3209 GitOrigin-RevId: e7e981bcd043f0daab4b70344afb684484361758 --- CHANGELOG.md | 1 + server/src-lib/Hasura/Backends/BigQuery/Types.hs | 12 ++++++++++-- .../bigquery/schema_setup_bigquery.yaml | 3 +++ .../bigquery/select_query_all_types.yaml | 5 +++++ 4 files changed, 19 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 526ba663d96..b90f3b70d22 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ - server: extend support for insert mutations to tables without primary key constraint in a MSSQL backend - cli: migrate and seed subcommands has an option in prompt to choose and apply operation on all available databases +- server: fix parsing FLOAT64s in scientific notation and non-finite ones in BigQuery ## v2.1.1 diff --git a/server/src-lib/Hasura/Backends/BigQuery/Types.hs b/server/src-lib/Hasura/Backends/BigQuery/Types.hs index f3e54710d71..aaae0d15037 100644 --- a/server/src-lib/Hasura/Backends/BigQuery/Types.hs +++ b/server/src-lib/Hasura/Backends/BigQuery/Types.hs @@ -80,7 +80,7 @@ import Hasura.Prelude import Hasura.RQL.Types.Common qualified as RQL import Language.GraphQL.Draft.Syntax qualified as G import Language.Haskell.TH.Syntax -import Text.ParserCombinators.ReadP (readP_to_S) +import Text.ParserCombinators.ReadP (eof, readP_to_S) data Select = Select { selectTop :: !Top, @@ -939,8 +939,16 @@ liberalDecimalParser fromText json = viaText <|> viaNumber text <- J.parseJSON json -- Parsing scientific is safe; it doesn't normalise until we ask -- it to. - case readP_to_S scientificP (T.unpack text) of + let -- See https://cloud.google.com/bigquery/docs/reference/standard-sql/conversion_functions#cast_as_floating_point + isNonFinite = + let noSign = case T.uncons text of + Just ('+', rest) -> rest + Just ('-', rest) -> rest + _ -> text + in T.toLower noSign `elem` ["nan", "infinity", "inf"] + case readP_to_S (scientificP <* eof) (T.unpack text) of [_] -> pure (fromText text) + [] | isNonFinite -> pure (fromText text) _ -> fail ("String containing decimal places is invalid: " ++ show text) viaNumber = do d <- J.parseJSON json diff --git a/server/tests-py/queries/graphql_query/bigquery/schema_setup_bigquery.yaml b/server/tests-py/queries/graphql_query/bigquery/schema_setup_bigquery.yaml index e75d0c45b5c..5369f7960dd 100644 --- a/server/tests-py/queries/graphql_query/bigquery/schema_setup_bigquery.yaml +++ b/server/tests-py/queries/graphql_query/bigquery/schema_setup_bigquery.yaml @@ -11,6 +11,7 @@ args: `bytes` BYTES, `integer` INT64, `float` FLOAT64, + `special_floats` ARRAY, `numeric` NUMERIC, `bignumeric` BIGNUMERIC, `boolean` BOOL, @@ -39,6 +40,8 @@ args: CODE_POINTS_TO_BYTES([0,1,2,3,4,5]), 1, 1, + -- IEEE_DIVIDE(x, 0) returns Infinity and Infinity/Infinity is NaN + [1.23e23, IEEE_DIVIDE(-1, 0), IEEE_DIVIDE(1, 0)/IEEE_DIVIDE(1, 0)], 1, 1, true, diff --git a/server/tests-py/queries/graphql_query/bigquery/select_query_all_types.yaml b/server/tests-py/queries/graphql_query/bigquery/select_query_all_types.yaml index 0065e752117..ceb3b4fc59b 100644 --- a/server/tests-py/queries/graphql_query/bigquery/select_query_all_types.yaml +++ b/server/tests-py/queries/graphql_query/bigquery/select_query_all_types.yaml @@ -8,6 +8,10 @@ response: bytes: AAECAwQF integer: '1' float: '1.0' + special_floats: + - '1.23E23' + - '-Infinity' + - 'NaN' numeric: '1' bignumeric: '1' boolean: true @@ -24,6 +28,7 @@ query: bytes integer float + special_floats numeric bignumeric boolean