google-cloud-bigquery 1.17.0 → 1.18.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 35c396da998783ed10060a16abd258256f2b14fd9f1a2bae8842a01db2edcd61
4
- data.tar.gz: c942df4f34c23a7403344d532b62ad740c0073604d184f2851f4278310558250
3
+ metadata.gz: a73d3045289c56feffa2def6b2f46764fa271e617629253b01e43bd689017f43
4
+ data.tar.gz: ac4730e78ce2a9734bcfc9c8adc5bc87576e2cbd9171e59c970cf54972c7c93f
5
5
  SHA512:
6
- metadata.gz: d8b5a6f8dbec478cbb582f756ce27297e9e284a3146f644bc60a585ac952d7558235603d7a7a53a026cc9f2237bc6bf19890357b39b9559dcf1e4da671e19b7f
7
- data.tar.gz: 86cbd63bffb1956b4d5685c79662befc444a6e15337f3da58118cc3cac6f3d7609b06f7be5ee836667f501dc7887b0acd5790fa9ec4f7f954606ab7780aa358a
6
+ metadata.gz: 3b792a52259418fd31e3507723702b3d5934289e34bdc326b844f85b5495b57d6af208ccf4043f70c3ec3e5492691e03aa7ffadc92c223035b2a82dc2730b5ae
7
+ data.tar.gz: 83eaa86026274ea0d0da3ee86770e0f10883510520fc35f3058bb37b5df09eb4f31f13db4fd5908f2056999128204bc4ab75606d4e4bffc1acd30dff7e334506
data/CHANGELOG.md CHANGED
@@ -1,5 +1,26 @@
1
1
  # Release History
2
2
 
3
+ ### 1.18.0 / 2019-11-06
4
+
5
+ #### Features
6
+
7
+ * Add optional query parameter types
8
+ * Allow query parameters to be nil/NULL when providing an optional
9
+ * Add types argument to the following methods:
10
+ * Project#query
11
+ * Project#query_job
12
+ * Dataset#query
13
+ * Dataset#query_job
14
+ * Add param types helper methods
15
+ * Return the BigQuery field type code, using the same format as the
16
+ * Add Schema::Field#param_type
17
+ * Add Schema#param_types
18
+ * Add Data#param_types
19
+ * Add Table#param_types
20
+ * Add External::CvsSource#param_types
21
+ * Add External::JsonSource#param_types
22
+ * Add support for all_users special role in Dataset access
23
+
3
24
  ### 1.17.0 / 2019-10-29
4
25
 
5
26
  This release requires Ruby 2.4 or later.
@@ -75,11 +75,7 @@ module Google
75
75
  elsif Array === value[:v]
76
76
  value[:v].map { |v| format_value v, field }
77
77
  elsif Hash === value[:v]
78
- if value[:v].empty?
79
- nil
80
- else
81
- format_row value[:v], field.fields
82
- end
78
+ format_row value[:v], field.fields
83
79
  elsif field.type == "STRING"
84
80
  String value[:v]
85
81
  elsif field.type == "INTEGER"
@@ -115,99 +111,106 @@ module Google
115
111
 
116
112
  ##
117
113
  # @private
118
- def self.to_query_param value
119
- if TrueClass === value
120
- return Google::Apis::BigqueryV2::QueryParameter.new(
121
- parameter_type: Google::Apis::BigqueryV2::QueryParameterType.new(type: "BOOL"),
122
- parameter_value: Google::Apis::BigqueryV2::QueryParameterValue.new(value: true)
123
- )
124
- elsif FalseClass === value
125
- return Google::Apis::BigqueryV2::QueryParameter.new(
126
- parameter_type: Google::Apis::BigqueryV2::QueryParameterType.new(type: "BOOL"),
127
- parameter_value: Google::Apis::BigqueryV2::QueryParameterValue.new(value: false)
128
- )
129
- elsif Integer === value
130
- return Google::Apis::BigqueryV2::QueryParameter.new(
131
- parameter_type: Google::Apis::BigqueryV2::QueryParameterType.new(type: "INT64"),
132
- parameter_value: Google::Apis::BigqueryV2::QueryParameterValue.new(value: value)
133
- )
134
- elsif Float === value
135
- return Google::Apis::BigqueryV2::QueryParameter.new(
136
- parameter_type: Google::Apis::BigqueryV2::QueryParameterType.new(type: "FLOAT64"),
137
- parameter_value: Google::Apis::BigqueryV2::QueryParameterValue.new(value: value)
138
- )
139
- elsif BigDecimal === value
140
- # Round to precision of 9
141
- value_str = value.finite? ? value.round(9).to_s("F") : value.to_s
142
- return Google::Apis::BigqueryV2::QueryParameter.new(
143
- parameter_type: Google::Apis::BigqueryV2::QueryParameterType.new(type: "NUMERIC"),
144
- parameter_value: Google::Apis::BigqueryV2::QueryParameterValue.new(value: value_str)
145
- )
146
- elsif String === value
147
- return Google::Apis::BigqueryV2::QueryParameter.new(
148
- parameter_type: Google::Apis::BigqueryV2::QueryParameterType.new(type: "STRING"),
149
- parameter_value: Google::Apis::BigqueryV2::QueryParameterValue.new(value: value)
150
- )
151
- elsif DateTime === value
152
- return Google::Apis::BigqueryV2::QueryParameter.new(
153
- parameter_type: Google::Apis::BigqueryV2::QueryParameterType.new(type: "DATETIME"),
154
- parameter_value: Google::Apis::BigqueryV2::QueryParameterValue.new(value: value.strftime("%Y-%m-%d %H:%M:%S.%6N"))
155
- )
156
- elsif Date === value
157
- return Google::Apis::BigqueryV2::QueryParameter.new(
158
- parameter_type: Google::Apis::BigqueryV2::QueryParameterType.new(type: "DATE"),
159
- parameter_value: Google::Apis::BigqueryV2::QueryParameterValue.new(value: value.to_s)
160
- )
161
- elsif ::Time === value
162
- return Google::Apis::BigqueryV2::QueryParameter.new(
163
- parameter_type: Google::Apis::BigqueryV2::QueryParameterType.new(type: "TIMESTAMP"),
164
- parameter_value: Google::Apis::BigqueryV2::QueryParameterValue.new(
165
- value: value.strftime("%Y-%m-%d %H:%M:%S.%6N%:z"))
166
- )
167
- elsif Bigquery::Time === value
168
- return Google::Apis::BigqueryV2::QueryParameter.new(
169
- parameter_type: Google::Apis::BigqueryV2::QueryParameterType.new(type: "TIME"),
170
- parameter_value: Google::Apis::BigqueryV2::QueryParameterValue.new(value: value.value)
171
- )
172
- elsif value.respond_to?(:read) && value.respond_to?(:rewind)
173
- value.rewind
174
- return Google::Apis::BigqueryV2::QueryParameter.new(
175
- parameter_type: Google::Apis::BigqueryV2::QueryParameterType.new(type: "BYTES"),
176
- parameter_value: Google::Apis::BigqueryV2::QueryParameterValue.new(value: Base64.strict_encode64(
177
- value.read.force_encoding("ASCII-8BIT")))
114
+ def self.to_query_param param, type = nil
115
+ type ||= default_query_param_type_for param
116
+
117
+ Google::Apis::BigqueryV2::QueryParameter.new(
118
+ parameter_type: to_query_param_type(type),
119
+ parameter_value: to_query_param_value(param)
120
+ )
121
+ end
122
+
123
+ ##
124
+ # @private
125
+ def self.to_query_param_value value
126
+ return Google::Apis::BigqueryV2::QueryParameterValue.new value: nil if value.nil?
127
+
128
+ json_value = to_json_value value
129
+
130
+ if Array === json_value
131
+ array_values = json_value.map { |v| to_query_param_value v }
132
+ Google::Apis::BigqueryV2::QueryParameterValue.new array_values: array_values
133
+ elsif Hash === json_value
134
+ struct_pairs = json_value.map do |key, value|
135
+ [String(key), to_query_param_value(value)]
136
+ end
137
+ struct_values = Hash[struct_pairs]
138
+ Google::Apis::BigqueryV2::QueryParameterValue.new struct_values: struct_values
139
+ else
140
+ # Everything else is converted to a string, per the API expectations.
141
+ Google::Apis::BigqueryV2::QueryParameterValue.new value: json_value.to_s
142
+ end
143
+ end
144
+
145
+ def self.to_query_param_type type
146
+ if Array === type
147
+ Google::Apis::BigqueryV2::QueryParameterType.new(
148
+ type: "ARRAY".freeze,
149
+ array_type: to_query_param_type(type.first)
178
150
  )
179
- elsif Array === value
180
- array_params = value.map { |param| Convert.to_query_param param }
181
- return Google::Apis::BigqueryV2::QueryParameter.new(
182
- parameter_type: Google::Apis::BigqueryV2::QueryParameterType.new(
183
- type: "ARRAY",
184
- array_type: array_params.first.parameter_type
185
- ),
186
- parameter_value: Google::Apis::BigqueryV2::QueryParameterValue.new(
187
- array_values: array_params.map(&:parameter_value)
188
- )
151
+ elsif Hash === type
152
+ Google::Apis::BigqueryV2::QueryParameterType.new(
153
+ type: "STRUCT".freeze,
154
+ struct_types: type.map do |key, val|
155
+ Google::Apis::BigqueryV2::QueryParameterType::StructType.new(
156
+ name: String(key),
157
+ type: to_query_param_type(val)
158
+ )
159
+ end
189
160
  )
190
- elsif Hash === value
191
- struct_pairs = value.map do |name, param|
192
- struct_param = Convert.to_query_param param
193
- [Google::Apis::BigqueryV2::QueryParameterType::StructType.new(
194
- name: String(name),
195
- type: struct_param.parameter_type
196
- ), struct_param.parameter_value]
161
+ else
162
+ Google::Apis::BigqueryV2::QueryParameterType.new(type: type.to_s.freeze)
163
+ end
164
+ end
165
+
166
+ def self.default_query_param_type_for param
167
+ raise ArgumentError, "nil params are not supported, must assign optional type" if param.nil?
168
+
169
+ case param
170
+ when String
171
+ :STRING
172
+ when Symbol
173
+ :STRING
174
+ when TrueClass
175
+ :BOOL
176
+ when FalseClass
177
+ :BOOL
178
+ when Integer
179
+ :INT64
180
+ when BigDecimal
181
+ :NUMERIC
182
+ when Numeric
183
+ :FLOAT64
184
+ when ::Time
185
+ :TIMESTAMP
186
+ when Bigquery::Time
187
+ :TIME
188
+ when DateTime
189
+ :DATETIME
190
+ when Date
191
+ :DATE
192
+ when Array
193
+ if param.empty?
194
+ raise ArgumentError, "Cannot determine type for empty array values"
197
195
  end
198
- struct_values = Hash[struct_pairs.map do |type, value|
199
- [type.name.to_sym, value]
196
+ non_nil_values = param.compact.map { |p| default_query_param_type_for p }.compact
197
+ if non_nil_values.empty?
198
+ raise ArgumentError, "Cannot determine type for array of nil values"
199
+ end
200
+ if non_nil_values.uniq.count > 1
201
+ raise ArgumentError, "Cannot determine type for array of different types of values"
202
+ end
203
+ [non_nil_values.first]
204
+ when Hash
205
+ Hash[param.map do |key, value|
206
+ [key, default_query_param_type_for(value)]
200
207
  end]
201
-
202
- return Google::Apis::BigqueryV2::QueryParameter.new(
203
- parameter_type: Google::Apis::BigqueryV2::QueryParameterType.new(
204
- type: "STRUCT",
205
- struct_types: struct_pairs.map(&:first)
206
- ),
207
- parameter_value: Google::Apis::BigqueryV2::QueryParameterValue.new(struct_values: struct_values)
208
- )
209
208
  else
210
- raise "A query parameter of type #{value.class} is not supported."
209
+ if param.respond_to?(:read) && param.respond_to?(:rewind)
210
+ :BYTES
211
+ else
212
+ raise "A query parameter of type #{param.class} is not supported"
213
+ end
211
214
  end
212
215
  end
213
216
 
@@ -222,6 +225,9 @@ module Google
222
225
  value.strftime "%Y-%m-%d %H:%M:%S.%6N%:z"
223
226
  elsif Bigquery::Time === value
224
227
  value.value
228
+ elsif BigDecimal === value
229
+ # Round to precision of 9
230
+ value.finite? ? value.round(9).to_s("F") : value.to_s
225
231
  elsif value.respond_to?(:read) && value.respond_to?(:rewind)
226
232
  value.rewind
227
233
  Base64.strict_encode64(value.read.force_encoding("ASCII-8BIT"))
@@ -200,6 +200,28 @@ module Google
200
200
  schema.headers
201
201
  end
202
202
 
203
+ ##
204
+ # The types of the fields in the data, obtained from the schema of the
205
+ # table from which the data was read. Types use the same format as the
206
+ # optional query parameter types.
207
+ #
208
+ # @return [Hash] A hash with field names as keys, and types as values.
209
+ #
210
+ # @example
211
+ # require "google/cloud/bigquery"
212
+ #
213
+ # bigquery = Google::Cloud::Bigquery.new
214
+ # dataset = bigquery.dataset "my_dataset"
215
+ # table = dataset.table "my_table"
216
+ #
217
+ # data = table.data
218
+ #
219
+ # data.param_types
220
+ #
221
+ def param_types
222
+ schema.param_types
223
+ end
224
+
203
225
  ##
204
226
  # The type of query statement, if valid. Possible values (new values
205
227
  # might be added in the future):
@@ -824,27 +824,6 @@ module Google
824
824
  # Sets the current dataset as the default dataset in the query. Useful
825
825
  # for using unqualified table names.
826
826
  #
827
- # When using standard SQL and passing arguments using `params`, Ruby
828
- # types are mapped to BigQuery types as follows:
829
- #
830
- # | BigQuery | Ruby | Notes |
831
- # |-------------|----------------|---|
832
- # | `BOOL` | `true`/`false` | |
833
- # | `INT64` | `Integer` | |
834
- # | `FLOAT64` | `Float` | |
835
- # | `NUMERIC` | `BigDecimal` | Will be rounded to 9 decimal places |
836
- # | `STRING` | `String` | |
837
- # | `DATETIME` | `DateTime` | `DATETIME` does not support time zone. |
838
- # | `DATE` | `Date` | |
839
- # | `TIMESTAMP` | `Time` | |
840
- # | `TIME` | `Google::Cloud::BigQuery::Time` | |
841
- # | `BYTES` | `File`, `IO`, `StringIO`, or similar | |
842
- # | `ARRAY` | `Array` | Nested arrays, `nil` values are not supported. |
843
- # | `STRUCT` | `Hash` | Hash keys may be strings or symbols. |
844
- #
845
- # See [Data Types](https://cloud.google.com/bigquery/docs/reference/standard-sql/data-types)
846
- # for an overview of each BigQuery data type, including allowed values.
847
- #
848
827
  # The geographic location for the job ("US", "EU", etc.) can be set via
849
828
  # {QueryJob::Updater#location=} in a block passed to this method. If the
850
829
  # dataset is a full resource representation (see {#resource_full?}), the
@@ -855,13 +834,55 @@ module Google
855
834
  # syntax](https://cloud.google.com/bigquery/query-reference), of the
856
835
  # query to execute. Example: "SELECT count(f1) FROM
857
836
  # [myProjectId:myDatasetId.myTableId]".
858
- # @param [Array, Hash] params Standard SQL only. Used to pass query
859
- # arguments when the `query` string contains either positional (`?`)
860
- # or named (`@myparam`) query parameters. If value passed is an array
861
- # `["foo"]`, the query must use positional query parameters. If value
862
- # passed is a hash `{ myparam: "foo" }`, the query must use named
863
- # query parameters. When set, `legacy_sql` will automatically be set
864
- # to false and `standard_sql` to true.
837
+ # @param [Array, Hash] params Standard SQL only. Used to pass query arguments when the `query` string contains
838
+ # either positional (`?`) or named (`@myparam`) query parameters. If value passed is an array `["foo"]`, the
839
+ # query must use positional query parameters. If value passed is a hash `{ myparam: "foo" }`, the query must
840
+ # use named query parameters. When set, `legacy_sql` will automatically be set to false and `standard_sql` to
841
+ # true.
842
+ #
843
+ # Ruby types are mapped to BigQuery types as follows:
844
+ #
845
+ # | BigQuery | Ruby | Notes |
846
+ # |-------------|--------------------------------------|------------------------------------------------|
847
+ # | `BOOL` | `true`/`false` | |
848
+ # | `INT64` | `Integer` | |
849
+ # | `FLOAT64` | `Float` | |
850
+ # | `NUMERIC` | `BigDecimal` | Will be rounded to 9 decimal places |
851
+ # | `STRING` | `String` | |
852
+ # | `DATETIME` | `DateTime` | `DATETIME` does not support time zone. |
853
+ # | `DATE` | `Date` | |
854
+ # | `TIMESTAMP` | `Time` | |
855
+ # | `TIME` | `Google::Cloud::BigQuery::Time` | |
856
+ # | `BYTES` | `File`, `IO`, `StringIO`, or similar | |
857
+ # | `ARRAY` | `Array` | Nested arrays, `nil` values are not supported. |
858
+ # | `STRUCT` | `Hash` | Hash keys may be strings or symbols. |
859
+ #
860
+ # See [Data Types](https://cloud.google.com/bigquery/docs/reference/standard-sql/data-types) for an overview
861
+ # of each BigQuery data type, including allowed values.
862
+ # @param [Array, Hash] types Standard SQL only. Types of the SQL parameters in `params`. It is not always to
863
+ # infer the right SQL type from a value in `params`. In these cases, `types` must be used to specify the SQL
864
+ # type for these values.
865
+ #
866
+ # Must match the value type passed to `params`. This must be an `Array` when the query uses positional query
867
+ # parameters. This must be an `Hash` when the query uses named query parameters. The values should be BigQuery
868
+ # type codes from the following list:
869
+ #
870
+ # * `:BOOL`
871
+ # * `:INT64`
872
+ # * `:FLOAT64`
873
+ # * `:NUMERIC`
874
+ # * `:STRING`
875
+ # * `:DATETIME`
876
+ # * `:DATE`
877
+ # * `:TIMESTAMP`
878
+ # * `:TIME`
879
+ # * `:BYTES`
880
+ # * `Array` - Lists are specified by providing the type code in an array. For example, an array of integers
881
+ # are specified as `[:INT64]`.
882
+ # * `Hash` - Types for STRUCT values (`Hash` objects) are specified using a `Hash` object, where the keys
883
+ # match the `params` hash, and the values are the types value that matches the data.
884
+ #
885
+ # Types are optional.
865
886
  # @param [Hash<String|Symbol, External::DataSource>] external A Hash
866
887
  # that represents the mapping of the external tables to the table
867
888
  # names used in the SQL query. The hash keys are the table names, and
@@ -1025,6 +1046,24 @@ module Google
1025
1046
  # end
1026
1047
  # end
1027
1048
  #
1049
+ # @example Query using named query parameters with types:
1050
+ # require "google/cloud/bigquery"
1051
+ #
1052
+ # bigquery = Google::Cloud::Bigquery.new
1053
+ # dataset = bigquery.dataset "my_dataset"
1054
+ #
1055
+ # job = dataset.query_job "SELECT name FROM my_table " \
1056
+ # "WHERE id IN UNNEST(@ids)",
1057
+ # params: { ids: [] },
1058
+ # types: { ids: [:INT64] }
1059
+ #
1060
+ # job.wait_until_done!
1061
+ # if !job.failed?
1062
+ # job.data.each do |row|
1063
+ # puts row[:name]
1064
+ # end
1065
+ # end
1066
+ #
1028
1067
  # @example Execute a DDL statement:
1029
1068
  # require "google/cloud/bigquery"
1030
1069
  #
@@ -1077,16 +1116,16 @@ module Google
1077
1116
  #
1078
1117
  # @!group Data
1079
1118
  #
1080
- def query_job query, params: nil, external: nil, priority: "INTERACTIVE", cache: true, table: nil, create: nil,
1081
- write: nil, dryrun: nil, standard_sql: nil, legacy_sql: nil, large_results: nil, flatten: nil,
1082
- maximum_billing_tier: nil, maximum_bytes_billed: nil, job_id: nil, prefix: nil, labels: nil,
1083
- udfs: nil
1119
+ def query_job query, params: nil, types: nil, external: nil, priority: "INTERACTIVE", cache: true, table: nil,
1120
+ create: nil, write: nil, dryrun: nil, standard_sql: nil, legacy_sql: nil, large_results: nil,
1121
+ flatten: nil, maximum_billing_tier: nil, maximum_bytes_billed: nil, job_id: nil, prefix: nil,
1122
+ labels: nil, udfs: nil
1084
1123
  ensure_service!
1085
- options = { priority: priority, cache: cache, table: table, create: create, write: write, dryrun: dryrun,
1086
- large_results: large_results, flatten: flatten, legacy_sql: legacy_sql,
1087
- standard_sql: standard_sql, maximum_billing_tier: maximum_billing_tier,
1088
- maximum_bytes_billed: maximum_bytes_billed, job_id: job_id, prefix: prefix, params: params,
1089
- external: external, labels: labels, udfs: udfs }
1124
+ options = { params: params, types: types, external: external, priority: priority, cache: cache, table: table,
1125
+ create: create, write: write, dryrun: dryrun, standard_sql: standard_sql, legacy_sql: legacy_sql,
1126
+ large_results: large_results, flatten: flatten, maximum_billing_tier: maximum_billing_tier,
1127
+ maximum_bytes_billed: maximum_bytes_billed, job_id: job_id, prefix: prefix, labels: labels,
1128
+ udfs: udfs }
1090
1129
 
1091
1130
  updater = QueryJob::Updater.from_options service, query, options
1092
1131
  updater.dataset = self
@@ -1108,27 +1147,6 @@ module Google
1108
1147
  # Sets the current dataset as the default dataset in the query. Useful
1109
1148
  # for using unqualified table names.
1110
1149
  #
1111
- # When using standard SQL and passing arguments using `params`, Ruby
1112
- # types are mapped to BigQuery types as follows:
1113
- #
1114
- # | BigQuery | Ruby | Notes |
1115
- # |-------------|----------------|---|
1116
- # | `BOOL` | `true`/`false` | |
1117
- # | `INT64` | `Integer` | |
1118
- # | `FLOAT64` | `Float` | |
1119
- # | `NUMERIC` | `BigDecimal` | Will be rounded to 9 decimal places |
1120
- # | `STRING` | `String` | |
1121
- # | `DATETIME` | `DateTime` | `DATETIME` does not support time zone. |
1122
- # | `DATE` | `Date` | |
1123
- # | `TIMESTAMP` | `Time` | |
1124
- # | `TIME` | `Google::Cloud::BigQuery::Time` | |
1125
- # | `BYTES` | `File`, `IO`, `StringIO`, or similar | |
1126
- # | `ARRAY` | `Array` | Nested arrays, `nil` values are not supported. |
1127
- # | `STRUCT` | `Hash` | Hash keys may be strings or symbols. |
1128
- #
1129
- # See [Data Types](https://cloud.google.com/bigquery/docs/reference/standard-sql/data-types)
1130
- # for an overview of each BigQuery data type, including allowed values.
1131
- #
1132
1150
  # The geographic location for the job ("US", "EU", etc.) can be set via
1133
1151
  # {QueryJob::Updater#location=} in a block passed to this method. If the
1134
1152
  # dataset is a full resource representation (see {#resource_full?}), the
@@ -1141,13 +1159,55 @@ module Google
1141
1159
  # syntax](https://cloud.google.com/bigquery/query-reference), of the
1142
1160
  # query to execute. Example: "SELECT count(f1) FROM
1143
1161
  # [myProjectId:myDatasetId.myTableId]".
1144
- # @param [Array, Hash] params Standard SQL only. Used to pass query
1145
- # arguments when the `query` string contains either positional (`?`)
1146
- # or named (`@myparam`) query parameters. If value passed is an array
1147
- # `["foo"]`, the query must use positional query parameters. If value
1148
- # passed is a hash `{ myparam: "foo" }`, the query must use named
1149
- # query parameters. When set, `legacy_sql` will automatically be set
1150
- # to false and `standard_sql` to true.
1162
+ # @param [Array, Hash] params Standard SQL only. Used to pass query arguments when the `query` string contains
1163
+ # either positional (`?`) or named (`@myparam`) query parameters. If value passed is an array `["foo"]`, the
1164
+ # query must use positional query parameters. If value passed is a hash `{ myparam: "foo" }`, the query must
1165
+ # use named query parameters. When set, `legacy_sql` will automatically be set to false and `standard_sql` to
1166
+ # true.
1167
+ #
1168
+ # Ruby types are mapped to BigQuery types as follows:
1169
+ #
1170
+ # | BigQuery | Ruby | Notes |
1171
+ # |-------------|--------------------------------------|------------------------------------------------|
1172
+ # | `BOOL` | `true`/`false` | |
1173
+ # | `INT64` | `Integer` | |
1174
+ # | `FLOAT64` | `Float` | |
1175
+ # | `NUMERIC` | `BigDecimal` | Will be rounded to 9 decimal places |
1176
+ # | `STRING` | `String` | |
1177
+ # | `DATETIME` | `DateTime` | `DATETIME` does not support time zone. |
1178
+ # | `DATE` | `Date` | |
1179
+ # | `TIMESTAMP` | `Time` | |
1180
+ # | `TIME` | `Google::Cloud::BigQuery::Time` | |
1181
+ # | `BYTES` | `File`, `IO`, `StringIO`, or similar | |
1182
+ # | `ARRAY` | `Array` | Nested arrays, `nil` values are not supported. |
1183
+ # | `STRUCT` | `Hash` | Hash keys may be strings or symbols. |
1184
+ #
1185
+ # See [Data Types](https://cloud.google.com/bigquery/docs/reference/standard-sql/data-types) for an overview
1186
+ # of each BigQuery data type, including allowed values.
1187
+ # @param [Array, Hash] types Standard SQL only. Types of the SQL parameters in `params`. It is not always to
1188
+ # infer the right SQL type from a value in `params`. In these cases, `types` must be used to specify the SQL
1189
+ # type for these values.
1190
+ #
1191
+ # Must match the value type passed to `params`. This must be an `Array` when the query uses positional query
1192
+ # parameters. This must be an `Hash` when the query uses named query parameters. The values should be BigQuery
1193
+ # type codes from the following list:
1194
+ #
1195
+ # * `:BOOL`
1196
+ # * `:INT64`
1197
+ # * `:FLOAT64`
1198
+ # * `:NUMERIC`
1199
+ # * `:STRING`
1200
+ # * `:DATETIME`
1201
+ # * `:DATE`
1202
+ # * `:TIMESTAMP`
1203
+ # * `:TIME`
1204
+ # * `:BYTES`
1205
+ # * `Array` - Lists are specified by providing the type code in an array. For example, an array of integers
1206
+ # are specified as `[:INT64]`.
1207
+ # * `Hash` - Types for STRUCT values (`Hash` objects) are specified using a `Hash` object, where the keys
1208
+ # match the `params` hash, and the values are the types value that matches the data.
1209
+ #
1210
+ # Types are optional.
1151
1211
  # @param [Hash<String|Symbol, External::DataSource>] external A Hash
1152
1212
  # that represents the mapping of the external tables to the table
1153
1213
  # names used in the SQL query. The hash keys are the table names, and
@@ -1239,6 +1299,21 @@ module Google
1239
1299
  # puts row[:name]
1240
1300
  # end
1241
1301
  #
1302
+ # @example Query using named query parameters with types:
1303
+ # require "google/cloud/bigquery"
1304
+ #
1305
+ # bigquery = Google::Cloud::Bigquery.new
1306
+ # dataset = bigquery.dataset "my_dataset"
1307
+ #
1308
+ # data = dataset.query "SELECT name FROM my_table " \
1309
+ # "WHERE id IN UNNEST(@ids)",
1310
+ # params: { ids: [] },
1311
+ # types: { ids: [:INT64] }
1312
+ #
1313
+ # data.each do |row|
1314
+ # puts row[:name]
1315
+ # end
1316
+ #
1242
1317
  # @example Execute a DDL statement:
1243
1318
  # require "google/cloud/bigquery"
1244
1319
  #
@@ -1282,9 +1357,10 @@ module Google
1282
1357
  #
1283
1358
  # @!group Data
1284
1359
  #
1285
- def query query, params: nil, external: nil, max: nil, cache: true, standard_sql: nil, legacy_sql: nil, &block
1286
- job = query_job query, params: params, external: external, cache: cache, standard_sql: standard_sql,
1287
- legacy_sql: legacy_sql, &block
1360
+ def query query, params: nil, types: nil, external: nil, max: nil, cache: true,
1361
+ standard_sql: nil, legacy_sql: nil, &block
1362
+ job = query_job query, params: params, types: types, external: external, cache: cache,
1363
+ standard_sql: standard_sql, legacy_sql: legacy_sql, &block
1288
1364
  job.wait_until_done!
1289
1365
  ensure_job_succeeded! job
1290
1366