diff --git a/google/cloud/spanner_v1/_helpers.py b/google/cloud/spanner_v1/_helpers.py index e0e2bfdbd0..c26b876461 100644 --- a/google/cloud/spanner_v1/_helpers.py +++ b/google/cloud/spanner_v1/_helpers.py @@ -134,8 +134,6 @@ def _make_value_pb(value): """ if value is None: return Value(null_value="NULL_VALUE") - if isinstance(value, (list, tuple)): - return Value(list_value=_make_list_value_pb(value)) if isinstance(value, bool): return Value(bool_value=value) if isinstance(value, int): @@ -228,6 +226,11 @@ def _parse_value_pb(value_pb, field_type): return float(value_pb.string_value) else: return value_pb.number_value + elif type_code == TypeCode.FLOAT32: + if value_pb.HasField("string_value"): + return float(value_pb.string_value) + else: + return value_pb.number_value elif type_code == TypeCode.DATE: return _date_from_iso8601_date(value_pb.string_value) elif type_code == TypeCode.TIMESTAMP: diff --git a/google/cloud/spanner_v1/param_types.py b/google/cloud/spanner_v1/param_types.py index 0c03f7ecc6..6bceac1ab5 100644 --- a/google/cloud/spanner_v1/param_types.py +++ b/google/cloud/spanner_v1/param_types.py @@ -26,6 +26,7 @@ BOOL = Type(code=TypeCode.BOOL) INT64 = Type(code=TypeCode.INT64) FLOAT64 = Type(code=TypeCode.FLOAT64) +Float32 = Type(code=TypeCode.FLOAT32) DATE = Type(code=TypeCode.DATE) TIMESTAMP = Type(code=TypeCode.TIMESTAMP) NUMERIC = Type(code=TypeCode.NUMERIC) diff --git a/google/cloud/spanner_v1/types/type.py b/google/cloud/spanner_v1/types/type.py index f25c465dd4..d9b6b9def5 100644 --- a/google/cloud/spanner_v1/types/type.py +++ b/google/cloud/spanner_v1/types/type.py @@ -50,6 +50,9 @@ class TypeCode(proto.Enum): FLOAT64 (3): Encoded as ``number``, or the strings ``"NaN"``, ``"Infinity"``, or ``"-Infinity"``. + FLOAT32 (15): + Encoded as TBD (``number`` or ``string``), or the strings + ``"NaN"``, ``"Infinity"``, or ``"-Infinity"``. TIMESTAMP (4): Encoded as ``string`` in RFC 3339 timestamp format. The time zone must be present, and must be ``"Z"``. @@ -99,6 +102,7 @@ class TypeCode(proto.Enum): BOOL = 1 INT64 = 2 FLOAT64 = 3 + FLOAT32 = 15 TIMESTAMP = 4 DATE = 5 STRING = 6 diff --git a/tests/_fixtures.py b/tests/_fixtures.py index b6f4108490..8b8e11da19 100644 --- a/tests/_fixtures.py +++ b/tests/_fixtures.py @@ -40,6 +40,8 @@ date_array ARRAY, float_value FLOAT64, float_array ARRAY, + float32_value FLOAT32, + float32_array ARRAY, string_value STRING(16), string_array ARRAY, timestamp_value TIMESTAMP, diff --git a/tests/system/test_session_api.py b/tests/system/test_session_api.py index 30981322cc..04f70bf0f5 100644 --- a/tests/system/test_session_api.py +++ b/tests/system/test_session_api.py @@ -20,6 +20,7 @@ import threading import time import pytest +import numpy import grpc from google.rpc import code_pb2 @@ -81,6 +82,8 @@ "numeric_array", "json_value", "json_array", + "float32_value", + "float32_array", ) EMULATOR_ALL_TYPES_COLUMNS = LIVE_ALL_TYPES_COLUMNS[:-4] @@ -113,35 +116,40 @@ AllTypesRowData(pkey=102, bool_value=False), AllTypesRowData(pkey=103, bytes_value=BYTES_1), AllTypesRowData(pkey=104, date_value=SOME_DATE), - AllTypesRowData(pkey=105, float_value=1.4142136), - AllTypesRowData(pkey=106, string_value="VALUE"), - AllTypesRowData(pkey=107, timestamp_value=SOME_TIME), - AllTypesRowData(pkey=108, timestamp_value=NANO_TIME), - AllTypesRowData(pkey=109, numeric_value=NUMERIC_1), - AllTypesRowData(pkey=110, json_value=JSON_1), - AllTypesRowData(pkey=111, json_value=JsonObject([JSON_1, JSON_2])), + AllTypesRowData(pkey=105, float32_value=1.414213), + AllTypesRowData(pkey=106, float_value=1.4142136), + AllTypesRowData(pkey=107, string_value="VALUE"), + AllTypesRowData(pkey=108, timestamp_value=SOME_TIME), + AllTypesRowData(pkey=109, timestamp_value=NANO_TIME), + AllTypesRowData(pkey=110, numeric_value=NUMERIC_1), + AllTypesRowData(pkey=111, json_value=JSON_1), + AllTypesRowData(pkey=112, json_value=JsonObject([JSON_1, JSON_2])), # empty array values AllTypesRowData(pkey=201, int_array=[]), AllTypesRowData(pkey=202, bool_array=[]), AllTypesRowData(pkey=203, bytes_array=[]), AllTypesRowData(pkey=204, date_array=[]), AllTypesRowData(pkey=205, float_array=[]), - AllTypesRowData(pkey=206, string_array=[]), - AllTypesRowData(pkey=207, timestamp_array=[]), - AllTypesRowData(pkey=208, numeric_array=[]), - AllTypesRowData(pkey=209, json_array=[]), + AllTypesRowData(pkey=206, float32_array=[]), + AllTypesRowData(pkey=207, string_array=[]), + AllTypesRowData(pkey=208, timestamp_array=[]), + AllTypesRowData(pkey=209, numeric_array=[]), + AllTypesRowData(pkey=210, json_array=[]), # non-empty array values, including nulls AllTypesRowData(pkey=301, int_array=[123, 456, None]), AllTypesRowData(pkey=302, bool_array=[True, False, None]), AllTypesRowData(pkey=303, bytes_array=[BYTES_1, BYTES_2, None]), AllTypesRowData(pkey=304, date_array=[SOME_DATE, None]), AllTypesRowData( - pkey=305, float_array=[3.1415926, 2.71828, math.inf, -math.inf, None] + pkey=305, float32_array=[3.1415926, 2.71828, math.inf, -math.inf, None] ), - AllTypesRowData(pkey=306, string_array=["One", "Two", None]), - AllTypesRowData(pkey=307, timestamp_array=[SOME_TIME, NANO_TIME, None]), - AllTypesRowData(pkey=308, numeric_array=[NUMERIC_1, NUMERIC_2, None]), - AllTypesRowData(pkey=309, json_array=[JSON_1, JSON_2, None]), + AllTypesRowData( + pkey=306, float_array=[3.1415926, 2.71828, math.inf, -math.inf, None] + ), + AllTypesRowData(pkey=307, string_array=["One", "Two", None]), + AllTypesRowData(pkey=308, timestamp_array=[SOME_TIME, NANO_TIME, None]), + AllTypesRowData(pkey=309, numeric_array=[NUMERIC_1, NUMERIC_2, None]), + AllTypesRowData(pkey=310, json_array=[JSON_1, JSON_2, None]), ) EMULATOR_ALL_TYPES_ROWDATA = ( # all nulls @@ -2156,6 +2164,14 @@ def test_execute_sql_w_float_bindings_transfinite(sessions_database, database_di expected=[(NEG_INF,)], order=False, ) + _check_sql_results( + sessions_database, + sql=f"SELECT {placeholder}", + params={key: NEG_INF}, + param_types={key: spanner_v1.param_types.Float32}, + expected=[(NEG_INF,)], + order=False, + ) key = "p1" if database_dialect == DatabaseDialect.POSTGRESQL else "pos_inf" placeholder = "$1" if database_dialect == DatabaseDialect.POSTGRESQL else f"@{key}" @@ -2168,7 +2184,14 @@ def test_execute_sql_w_float_bindings_transfinite(sessions_database, database_di expected=[(POS_INF,)], order=False, ) - + _check_sql_results( + sessions_database, + sql=f"SELECT {placeholder}", + params={key: POS_INF}, + param_types={key: spanner_v1.param_types.Float32}, + expected=[(POS_INF,)], + order=False, + ) def test_execute_sql_w_bytes_bindings(sessions_database, database_dialect): _bind_test_helper( diff --git a/tests/system/test_table_api.py b/tests/system/test_table_api.py index 7d4da2b363..f2624eeb2c 100644 --- a/tests/system/test_table_api.py +++ b/tests/system/test_table_api.py @@ -69,6 +69,7 @@ def test_table_schema(shared_database, database_dialect): ("bool_value", spanner_v1.TypeCode.BOOL), ("bytes_value", spanner_v1.TypeCode.BYTES), ("float_value", spanner_v1.TypeCode.FLOAT64), + ("float32_value", spanner_v1.TypeCode.FLOAT32), ("string_value", spanner_v1.TypeCode.STRING), ("timestamp_value", spanner_v1.TypeCode.TIMESTAMP), ("date_value", spanner_v1.TypeCode.DATE), pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy