Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix: support empty array in _from_api_repr_struct #2010

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 14 additions & 1 deletion google/cloud/bigquery/query.py
Original file line number Diff line number Diff line change
Expand Up @@ -689,7 +689,20 @@ def _from_api_repr_struct(cls, resource):
struct_resource["parameterValue"] = array_value
struct_value = StructQueryParameter.from_api_repr(struct_resource)
converted.append(struct_value)
return cls(name, "STRUCT", converted)
return cls(
name,
StructQueryParameterType(
*[
ScalarQueryParameterType(
struct_type["type"]["type"], name=struct_type["name"]
)
for struct_type in resource["parameterType"]["arrayType"][
"structTypes"
]
]
),
values=converted,
)

@classmethod
def _from_api_repr_scalar(cls, resource):
Expand Down
79 changes: 68 additions & 11 deletions tests/unit/test_query.py
Original file line number Diff line number Diff line change
Expand Up @@ -169,8 +169,10 @@ def test_from_api_repr(self):
self.assertEqual(field._type, "STRING")

def test_to_api_repr(self):
from google.cloud.bigquery.query import ScalarQueryParameterType
from google.cloud.bigquery.query import StructQueryParameterType
from google.cloud.bigquery.query import (
ScalarQueryParameterType,
StructQueryParameterType,
)
Comment on lines +172 to +175
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we do import within each test instead of at the top of the test module?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And i believe these import changes are from running nox -s blacken and nox -s lint.


array_item_type = StructQueryParameterType(
ScalarQueryParameterType("INTEGER", name="weight", description="in kg"),
Expand Down Expand Up @@ -223,8 +225,10 @@ def test_raises_error_without_any_fields(self):
self._make_one()

def test_from_api_repr(self):
from google.cloud.bigquery.query import ArrayQueryParameterType
from google.cloud.bigquery.query import ScalarQueryParameterType
from google.cloud.bigquery.query import (
ArrayQueryParameterType,
ScalarQueryParameterType,
)

api_resource = {
"type": "STRUCT",
Expand Down Expand Up @@ -1299,8 +1303,46 @@ def test_from_api_repr_w_none_values(self):
self.assertEqual(param.array_type, "INT64")
self.assertEqual(param.values, [1, None])

def test_from_api_repr_w_struct_type(self):
from google.cloud.bigquery.query import StructQueryParameter
def test_from_api_repr_w_empty_struct_array(self):
from google.cloud.bigquery.query import (
ScalarQueryParameterType,
StructQueryParameterType,
)

RESOURCE = {
"parameterType": {
"type": "ARRAY",
"arrayType": {
"type": "STRUCT",
"structTypes": [
{"name": "name", "type": {"type": "STRING"}},
{"name": "age", "type": {"type": "INT64"}},
],
},
},
"parameterValue": {"arrayValues": []},
}

klass = self._get_target_class()
param = klass.from_api_repr(RESOURCE)

self.assertEqual(
str(param.array_type),
str(
StructQueryParameterType(
ScalarQueryParameterType("STRING", name="name"),
ScalarQueryParameterType("INT64", name="age"),
)
),
)
self.assertEqual(param.values, [])

def test_from_api_repr_w_nonempty_struct_array(self):
from google.cloud.bigquery.query import (
ScalarQueryParameterType,
StructQueryParameter,
StructQueryParameterType,
)

RESOURCE = {
"parameterType": {
Expand Down Expand Up @@ -1342,7 +1384,16 @@ def test_from_api_repr_w_struct_type(self):
_make_subparam("name", "STRING", "Bharney Rhubbyl"),
_make_subparam("age", "INT64", 31),
)
self.assertEqual(param.array_type, "STRUCT")

self.assertEqual(
str(param.array_type),
str(
StructQueryParameterType(
ScalarQueryParameterType("STRING", name="name"),
ScalarQueryParameterType("INT64", name="age"),
)
),
)
Comment on lines +1388 to +1396
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It doesn't work to do assertEqual(param.array_type, StuctQueryParameterType(Sclar...). Not sure what the better way would be.

self.assertEqual(param.values, [phred, bharney])

def test_to_api_repr_w_name(self):
Expand Down Expand Up @@ -1414,8 +1465,10 @@ def test_to_api_repr_w_record_type(self):
self.assertEqual(param.to_api_repr(), EXPECTED)

def test_to_api_repr_w_empty_array_of_records_type(self):
from google.cloud.bigquery.query import ScalarQueryParameterType
from google.cloud.bigquery.query import StructQueryParameterType
from google.cloud.bigquery.query import (
ScalarQueryParameterType,
StructQueryParameterType,
)

EXPECTED = {
"parameterType": {
Expand Down Expand Up @@ -1497,8 +1550,10 @@ def test___repr__array_type_scalar_type_instance(self):
self.assertEqual(repr(int_items), expected)

def test___repr__array_type_struct_type_instance(self):
from google.cloud.bigquery.query import ScalarQueryParameterType
from google.cloud.bigquery.query import StructQueryParameterType
from google.cloud.bigquery.query import (
ScalarQueryParameterType,
StructQueryParameterType,
)

struct_items = self._make_one(
"struct_items",
Expand Down Expand Up @@ -2054,6 +2109,7 @@ def test_w_scalar(self):

def test_w_scalar_timestamp(self):
from google.cloud._helpers import UTC

from google.cloud.bigquery.query import ScalarQueryParameter

RESOURCE = {
Expand All @@ -2073,6 +2129,7 @@ def test_w_scalar_timestamp(self):

def test_w_scalar_timestamp_micros(self):
from google.cloud._helpers import UTC

from google.cloud.bigquery.query import ScalarQueryParameter

RESOURCE = {
Expand Down