diff --git a/ibis/backends/bigquery/datatypes.py b/ibis/backends/bigquery/datatypes.py index 77154fd0aa0e..be3bd0eac612 100644 --- a/ibis/backends/bigquery/datatypes.py +++ b/ibis/backends/bigquery/datatypes.py @@ -66,12 +66,15 @@ def trans_type(t): @ibis_type_to_bigquery_type.register(dt.Decimal) def trans_numeric(t): - if (t.precision, t.scale) not in [(38, 9), (None, None)]: - raise TypeError( - "BigQuery only supports decimal types with precision of 38 and " - "scale of 9" - ) - return "NUMERIC" + if (t.precision, t.scale) == (76, 38): + return 'BIGNUMERIC' + if (t.precision, t.scale) in [(38, 9), (None, None)]: + return "NUMERIC" + raise TypeError( + "BigQuery only supports decimal types with precision of 38 and " + f"scale of 9 (NUMERIC) or precision of 76 and scale of 38 (BIGNUMERIC). " + f"Current precision: {t.precision}. Current scale: {t.scale}" + ) @ibis_type_to_bigquery_type.register(dt.JSON) diff --git a/ibis/backends/bigquery/tests/unit/test_datatypes.py b/ibis/backends/bigquery/tests/unit/test_datatypes.py index a889f272a0d7..d2f79020198c 100644 --- a/ibis/backends/bigquery/tests/unit/test_datatypes.py +++ b/ibis/backends/bigquery/tests/unit/test_datatypes.py @@ -49,7 +49,8 @@ def test_no_ambiguities(): param( "array>", "ARRAY>", id="array" ), - param(dt.Decimal(38, 9), "NUMERIC", id="decimal"), + param(dt.Decimal(38, 9), "NUMERIC", id="decimal-numeric"), + param(dt.Decimal(76, 38), "BIGNUMERIC", id="decimal-bignumeric"), ], ) def test_simple(datatype, expected): diff --git a/ibis/backends/tests/test_generic.py b/ibis/backends/tests/test_generic.py index 60cbea5f1160..19e3fe0566f9 100644 --- a/ibis/backends/tests/test_generic.py +++ b/ibis/backends/tests/test_generic.py @@ -1374,6 +1374,40 @@ def test_exists(batting, awards_players, method_name): ], id="decimal-big", ), + param( + ibis.literal(decimal.Decimal("1.1"), type=dt.Decimal(76, 38)), + { + 'bigquery': "BIGNUMERIC", + 'snowflake': "VARCHAR", + 'sqlite': "real", + 'trino': 'decimal(2,1)', + "duckdb": "DECIMAL(18,3)", + "postgres": "numeric", + }, + marks=[ + pytest.mark.broken( + ['clickhouse'], + "Code: 46. DB::Exception: Unknown function Decimal: " + "While processing toTypeName(Decimal('1.2')).", + raises=ClickhouseDriverOperationalError, + ), + pytest.mark.broken( + ['impala'], + "impala.error.HiveServer2Error: AnalysisException: Syntax error in line 1:" + "SELECT typeof(Decimal('1.2')) AS `TypeOf(Decimal('1.2'))" + "Encountered: DECIMAL" + "Expected: ALL, CASE, CAST, DEFAULT, DISTINCT, EXISTS, FALSE, IF, " + "INTERVAL, LEFT, NOT, NULL, REPLACE, RIGHT, TRUNCATE, TRUE, IDENTIFIER" + "CAUSED BY: Exception: Syntax error", + ), + pytest.mark.broken( + ['duckdb'], + "(duckdb.ParserException) Parser Error: Width must be between 1 and 38!", + raises=sqlalchemy.exc.ProgrammingError, + ), + ], + id="decimal-big", + ), param( ibis.array([1.0, 2.0, 3.0]), {