-
Notifications
You must be signed in to change notification settings - Fork 322
feat: add support for INTERVAL data type to list_rows
#840
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
Changes from 9 commits
5704f1e
5eb3794
9e54277
a89c1c1
60d9ca7
da6ef5b
b73a610
52f2b7b
ca8872e
018a617
2872d85
31c3f92
e3a3a6a
5f78311
bb03618
f3711e7
68035ba
9a011e9
9f6b02d
7cccbd2
152e8c2
f0f3fbd
c4636fa
18aae17
eccea82
5cdeffb
0497b19
92f41b9
0318f54
6b1f238
54e47f7
ced356b
dcc8b57
5c31fe2
2091478
21a2975
87b0d81
7bd48be
d62b950
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -19,8 +19,9 @@ | |
| import decimal | ||
| import math | ||
| import re | ||
| from typing import Union | ||
| from typing import Optional, Union | ||
|
|
||
| from dateutil import relativedelta | ||
| from google.cloud._helpers import UTC | ||
| from google.cloud._helpers import _date_from_iso8601_date | ||
| from google.cloud._helpers import _datetime_from_microseconds | ||
|
|
@@ -42,6 +43,17 @@ | |
| re.VERBOSE, | ||
| ) | ||
|
|
||
| # BigQuery sends data in "canonical format" | ||
| # https://cloud.google.com/bigquery/docs/reference/standard-sql/data-types#interval_type | ||
| _INTERVAL_PATTERN = re.compile( | ||
| r"(?P<calendar_sign>-?)(?P<years>[0-9]+)-(?P<months>[0-9]+) " | ||
| r"(?P<days>-?[0-9]+) " | ||
tswast marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| r"(?P<time_sign>-?)(?P<hours>[0-9]+):(?P<minutes>[0-9]+):" | ||
| r"(?P<seconds>[0-9]+)\.?(?P<fraction>[0-9]+)?$" | ||
|
||
| ) | ||
|
|
||
| # TODO: BigQuery receives data in ISO 8601 duration format | ||
|
|
||
| _MIN_BQ_STORAGE_VERSION = packaging.version.Version("2.0.0") | ||
| _BQ_STORAGE_OPTIONAL_READ_SESSION_VERSION = packaging.version.Version("2.6.0") | ||
|
|
||
|
|
@@ -114,6 +126,38 @@ def _int_from_json(value, field): | |
| return int(value) | ||
|
|
||
|
|
||
| def _interval_from_json( | ||
| value: Optional[str], field | ||
| ) -> Optional[relativedelta.relativedelta]: | ||
| """Coerce 'value' to an interval, if set or not nullable.""" | ||
| if not _not_null(value, field): | ||
| return | ||
tswast marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| if value is None: | ||
| raise TypeError(f"got {value} for REQUIRED field: {repr(field)}") | ||
|
|
||
| parsed = _INTERVAL_PATTERN.match(value) | ||
tswast marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| calendar_sign = -1 if parsed.group("calendar_sign") == "-" else 1 | ||
| years = calendar_sign * int(parsed.group("years")) | ||
| months = calendar_sign * int(parsed.group("months")) | ||
| days = int(parsed.group("days")) | ||
| time_sign = -1 if parsed.group("time_sign") == "-" else 1 | ||
| hours = time_sign * int(parsed.group("hours")) | ||
| minutes = time_sign * int(parsed.group("minutes")) | ||
| seconds = time_sign * int(parsed.group("seconds")) | ||
| fraction = parsed.group("fraction") | ||
| microseconds = time_sign * int(fraction.ljust(6, "0")) if fraction else 0 | ||
|
||
|
|
||
| return relativedelta.relativedelta( | ||
| years=years, | ||
| months=months, | ||
| days=days, | ||
| hours=hours, | ||
| minutes=minutes, | ||
| seconds=seconds, | ||
| microseconds=microseconds, | ||
| ) | ||
|
|
||
|
|
||
| def _float_from_json(value, field): | ||
| """Coerce 'value' to a float, if set or not nullable.""" | ||
| if _not_null(value, field): | ||
|
|
@@ -250,6 +294,7 @@ def _record_from_json(value, field): | |
| _CELLDATA_FROM_JSON = { | ||
| "INTEGER": _int_from_json, | ||
| "INT64": _int_from_json, | ||
| "INTERVAL": _interval_from_json, | ||
| "FLOAT": _float_from_json, | ||
| "FLOAT64": _float_from_json, | ||
| "NUMERIC": _decimal_from_json, | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -254,28 +254,29 @@ class SqlTypeNames(str, enum.Enum): | |
| DATE = "DATE" | ||
| TIME = "TIME" | ||
| DATETIME = "DATETIME" | ||
| INTERVAL = "INTERVAL" # NOTE: not available in legacy types | ||
|
|
||
|
|
||
| class SqlParameterScalarTypes: | ||
| """Supported scalar SQL query parameter types as type objects.""" | ||
|
|
||
| STRING = ScalarQueryParameterType("STRING") | ||
| BOOL = ScalarQueryParameterType("BOOL") | ||
| BOOLEAN = ScalarQueryParameterType("BOOL") | ||
| BIGDECIMAL = ScalarQueryParameterType("BIGNUMERIC") | ||
| BIGNUMERIC = ScalarQueryParameterType("BIGNUMERIC") | ||
| BYTES = ScalarQueryParameterType("BYTES") | ||
| INTEGER = ScalarQueryParameterType("INT64") | ||
| INT64 = ScalarQueryParameterType("INT64") | ||
| DATE = ScalarQueryParameterType("DATE") | ||
| DATETIME = ScalarQueryParameterType("DATETIME") | ||
| DECIMAL = ScalarQueryParameterType("NUMERIC") | ||
| FLOAT = ScalarQueryParameterType("FLOAT64") | ||
| FLOAT64 = ScalarQueryParameterType("FLOAT64") | ||
| NUMERIC = ScalarQueryParameterType("NUMERIC") | ||
| BIGNUMERIC = ScalarQueryParameterType("BIGNUMERIC") | ||
| DECIMAL = ScalarQueryParameterType("NUMERIC") | ||
| BIGDECIMAL = ScalarQueryParameterType("BIGNUMERIC") | ||
| BOOLEAN = ScalarQueryParameterType("BOOL") | ||
| BOOL = ScalarQueryParameterType("BOOL") | ||
| GEOGRAPHY = ScalarQueryParameterType("GEOGRAPHY") | ||
| TIMESTAMP = ScalarQueryParameterType("TIMESTAMP") | ||
| DATE = ScalarQueryParameterType("DATE") | ||
| INT64 = ScalarQueryParameterType("INT64") | ||
| INTEGER = ScalarQueryParameterType("INT64") | ||
| NUMERIC = ScalarQueryParameterType("NUMERIC") | ||
| STRING = ScalarQueryParameterType("STRING") | ||
| TIME = ScalarQueryParameterType("TIME") | ||
| DATETIME = ScalarQueryParameterType("DATETIME") | ||
| TIMESTAMP = ScalarQueryParameterType("TIMESTAMP") | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Did you intend to include INTERVAL?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I did but then reverted it because the query parameter support is incomplete. I could revert the alphabetization, but I figure we should do that at some point. |
||
|
|
||
|
|
||
| class WriteDisposition(object): | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,2 +1,2 @@ | ||
| {"bool_col": true, "bytes_col": "abcd", "date_col": "2021-07-21", "datetime_col": "2021-07-21 11:39:45", "geography_col": "POINT(-122.0838511 37.3860517)", "int64_col": "123456789", "numeric_col": "1.23456789", "bignumeric_col": "10.111213141516171819", "float64_col": "1.25", "string_col": "Hello, World", "time_col": "11:41:43.07616", "timestamp_col": "2021-07-21T17:43:43.945289Z"} | ||
| {"bool_col": null, "bytes_col": null, "date_col": null, "datetime_col": null, "geography_col": null, "int64_col": null, "numeric_col": null, "bignumeric_col": null, "float64_col": null, "string_col": null, "time_col": null, "timestamp_col": null} | ||
| {"bool_col": true, "bytes_col": "SGVsbG8sIFdvcmxkIQ==", "date_col": "2021-07-21", "datetime_col": "2021-07-21 11:39:45", "geography_col": "POINT(-122.0838511 37.3860517)", "int64_col": "123456789", "interval_col": "P7Y11M9DT4H15M37.123456S", "numeric_col": "1.23456789", "bignumeric_col": "10.111213141516171819", "float64_col": "1.25", "rowindex": 0, "string_col": "Hello, World!", "time_col": "11:41:43.07616", "timestamp_col": "2021-07-21T17:43:43.945289Z"} | ||
| {"bool_col": null, "bytes_col": null, "date_col": null, "datetime_col": null, "geography_col": null, "int64_col": null, "interval_col": null, "numeric_col": null, "bignumeric_col": null, "float64_col": null, "rowindex": 1, "string_col": null, "time_col": null, "timestamp_col": null} |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,5 +1,5 @@ | ||
| {"bool_col": true, "bytes_col": "DQo=\n", "date_col": "9999-12-31", "datetime_col": "9999-12-31 23:59:59.999999", "geography_col": "POINT(-135.0000 90.0000)", "int64_col": "9223372036854775807", "numeric_col": "9.9999999999999999999999999999999999999E+28", "bignumeric_col": "9.999999999999999999999999999999999999999999999999999999999999999999999999999E+37", "float64_col": "+inf", "string_col": "Hello, World", "time_col": "23:59:59.99999", "timestamp_col": "9999-12-31T23:59:59.999999Z"} | ||
| {"bool_col": false, "bytes_col": "8J+Zgw==\n", "date_col": "0001-01-01", "datetime_col": "0001-01-01 00:00:00", "geography_col": "POINT(45.0000 -90.0000)", "int64_col": "-9223372036854775808", "numeric_col": "-9.9999999999999999999999999999999999999E+28", "bignumeric_col": "-9.999999999999999999999999999999999999999999999999999999999999999999999999999E+37", "float64_col": "-inf", "string_col": "Hello, World", "time_col": "00:00:00", "timestamp_col": "0001-01-01T00:00:00.000000Z"} | ||
| {"bool_col": true, "bytes_col": "AA==\n", "date_col": "1900-01-01", "datetime_col": "1900-01-01 00:00:00", "geography_col": "POINT(-180.0000 0.0000)", "int64_col": "-1", "numeric_col": "0.000000001", "bignumeric_col": "-0.00000000000000000000000000000000000001", "float64_col": "nan", "string_col": "こんにちは", "time_col": "00:00:00.000001", "timestamp_col": "1900-01-01T00:00:00.000000Z"} | ||
| {"bool_col": false, "bytes_col": "", "date_col": "1970-01-01", "datetime_col": "1970-01-01 00:00:00", "geography_col": "POINT(0 0)", "int64_col": "0", "numeric_col": "0.0", "bignumeric_col": "0.0", "float64_col": 0.0, "string_col": "", "time_col": "12:00:00", "timestamp_col": "1970-01-01T00:00:00.000000Z"} | ||
| {"bool_col": null, "bytes_col": null, "date_col": null, "datetime_col": null, "geography_col": null, "int64_col": null, "numeric_col": null, "bignumeric_col": null, "float64_col": null, "string_col": null, "time_col": null, "timestamp_col": null} | ||
| {"bool_col": true, "bytes_col": "DQo=\n", "date_col": "9999-12-31", "datetime_col": "9999-12-31 23:59:59.999999", "geography_col": "POINT(-135.0000 90.0000)", "int64_col": "9223372036854775807", "interval_col": "P-10000Y0M-3660000DT-87840000H0M0S", "numeric_col": "9.9999999999999999999999999999999999999E+28", "bignumeric_col": "9.999999999999999999999999999999999999999999999999999999999999999999999999999E+37", "float64_col": "+inf", "rowindex": 0, "string_col": "Hello, World", "time_col": "23:59:59.999999", "timestamp_col": "9999-12-31T23:59:59.999999Z"} | ||
| {"bool_col": false, "bytes_col": "8J+Zgw==\n", "date_col": "0001-01-01", "datetime_col": "0001-01-01 00:00:00", "geography_col": "POINT(45.0000 -90.0000)", "int64_col": "-9223372036854775808", "interval_col": "P10000Y0M3660000DT87840000H0M0S", "numeric_col": "-9.9999999999999999999999999999999999999E+28", "bignumeric_col": "-9.999999999999999999999999999999999999999999999999999999999999999999999999999E+37", "float64_col": "-inf", "rowindex": 1, "string_col": "Hello, World", "time_col": "00:00:00", "timestamp_col": "0001-01-01T00:00:00.000000Z"} | ||
| {"bool_col": true, "bytes_col": "AA==\n", "date_col": "1900-01-01", "datetime_col": "1900-01-01 00:00:00", "geography_col": "POINT(-180.0000 0.0000)", "int64_col": "-1", "interval_col": "P0Y0M0DT0H0M0.000001S", "numeric_col": "0.000000001", "bignumeric_col": "-0.00000000000000000000000000000000000001", "float64_col": "nan", "rowindex": 2, "string_col": "こんにちは", "time_col": "00:00:00.000001", "timestamp_col": "1900-01-01T00:00:00.000000Z"} | ||
| {"bool_col": false, "bytes_col": "", "date_col": "1970-01-01", "datetime_col": "1970-01-01 00:00:00", "geography_col": "POINT(0 0)", "int64_col": "0", "interval_col": "P0Y0M0DT0H0M0S", "numeric_col": "0.0", "bignumeric_col": "0.0", "float64_col": 0.0, "rowindex": 3, "string_col": "", "time_col": "12:00:00", "timestamp_col": "1970-01-01T00:00:00.000000Z"} | ||
| {"bool_col": null, "bytes_col": null, "date_col": null, "datetime_col": null, "geography_col": null, "int64_col": null, "interval_col": null, "numeric_col": null, "bignumeric_col": null, "float64_col": null, "rowindex": 4, "string_col": null, "time_col": null, "timestamp_col": null} |
Uh oh!
There was an error while loading. Please reload this page.