google-cloud-bigquery 1.17.0 → 1.18.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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