google-cloud-bigquery 1.14.0 → 1.42.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.
Files changed (51) hide show
  1. checksums.yaml +4 -4
  2. data/AUTHENTICATION.md +17 -54
  3. data/CHANGELOG.md +377 -0
  4. data/CONTRIBUTING.md +328 -116
  5. data/LOGGING.md +1 -1
  6. data/OVERVIEW.md +21 -20
  7. data/TROUBLESHOOTING.md +2 -8
  8. data/lib/google/cloud/bigquery/argument.rb +197 -0
  9. data/lib/google/cloud/bigquery/convert.rb +155 -173
  10. data/lib/google/cloud/bigquery/copy_job.rb +74 -26
  11. data/lib/google/cloud/bigquery/credentials.rb +5 -12
  12. data/lib/google/cloud/bigquery/data.rb +109 -18
  13. data/lib/google/cloud/bigquery/dataset/access.rb +474 -52
  14. data/lib/google/cloud/bigquery/dataset/list.rb +7 -13
  15. data/lib/google/cloud/bigquery/dataset/tag.rb +67 -0
  16. data/lib/google/cloud/bigquery/dataset.rb +1044 -287
  17. data/lib/google/cloud/bigquery/external/avro_source.rb +107 -0
  18. data/lib/google/cloud/bigquery/external/bigtable_source/column.rb +404 -0
  19. data/lib/google/cloud/bigquery/external/bigtable_source/column_family.rb +945 -0
  20. data/lib/google/cloud/bigquery/external/bigtable_source.rb +230 -0
  21. data/lib/google/cloud/bigquery/external/csv_source.rb +481 -0
  22. data/lib/google/cloud/bigquery/external/data_source.rb +771 -0
  23. data/lib/google/cloud/bigquery/external/json_source.rb +170 -0
  24. data/lib/google/cloud/bigquery/external/parquet_source.rb +148 -0
  25. data/lib/google/cloud/bigquery/external/sheets_source.rb +166 -0
  26. data/lib/google/cloud/bigquery/external.rb +50 -2256
  27. data/lib/google/cloud/bigquery/extract_job.rb +226 -61
  28. data/lib/google/cloud/bigquery/insert_response.rb +1 -3
  29. data/lib/google/cloud/bigquery/job/list.rb +10 -14
  30. data/lib/google/cloud/bigquery/job.rb +289 -14
  31. data/lib/google/cloud/bigquery/load_job.rb +810 -136
  32. data/lib/google/cloud/bigquery/model/list.rb +5 -9
  33. data/lib/google/cloud/bigquery/model.rb +247 -16
  34. data/lib/google/cloud/bigquery/policy.rb +432 -0
  35. data/lib/google/cloud/bigquery/project/list.rb +6 -11
  36. data/lib/google/cloud/bigquery/project.rb +509 -250
  37. data/lib/google/cloud/bigquery/query_job.rb +594 -128
  38. data/lib/google/cloud/bigquery/routine/list.rb +165 -0
  39. data/lib/google/cloud/bigquery/routine.rb +1227 -0
  40. data/lib/google/cloud/bigquery/schema/field.rb +413 -63
  41. data/lib/google/cloud/bigquery/schema.rb +221 -48
  42. data/lib/google/cloud/bigquery/service.rb +204 -112
  43. data/lib/google/cloud/bigquery/standard_sql.rb +269 -53
  44. data/lib/google/cloud/bigquery/table/async_inserter.rb +86 -43
  45. data/lib/google/cloud/bigquery/table/list.rb +6 -11
  46. data/lib/google/cloud/bigquery/table.rb +1470 -377
  47. data/lib/google/cloud/bigquery/time.rb +6 -0
  48. data/lib/google/cloud/bigquery/version.rb +1 -1
  49. data/lib/google/cloud/bigquery.rb +4 -6
  50. data/lib/google-cloud-bigquery.rb +14 -13
  51. metadata +66 -38
@@ -23,6 +23,7 @@ require "google/cloud/bigquery/external"
23
23
  require "google/cloud/bigquery/insert_response"
24
24
  require "google/cloud/bigquery/table/async_inserter"
25
25
  require "google/cloud/bigquery/convert"
26
+ require "google/cloud/bigquery/policy"
26
27
  require "google/apis/bigquery_v2"
27
28
 
28
29
  module Google
@@ -36,16 +37,16 @@ module Google
36
37
  # repeated fields.
37
38
  #
38
39
  # The Table class can also represent a
39
- # [view](https://cloud.google.com/bigquery/docs/views), which is a virtual
40
- # table defined by a SQL query. BigQuery's views are logical views, not
41
- # materialized views, which means that the query that defines the view is
42
- # re-executed every time the view is queried. Queries are billed according
43
- # to the total amount of data in all table fields referenced directly or
44
- # indirectly by the top-level query. (See {#view?}, {#query}, {#query=},
45
- # and {Dataset#create_view}.)
40
+ # [logical view](https://cloud.google.com/bigquery/docs/views), which is a virtual
41
+ # table defined by a SQL query (see {#view?} and {Dataset#create_view}); or a
42
+ # [materialized view](https://cloud.google.com/bigquery/docs/materialized-views-intro),
43
+ # which is a precomputed view that periodically caches results of a query for increased
44
+ # performance and efficiency (see {#materialized_view?} and {Dataset#create_materialized_view}).
46
45
  #
47
46
  # @see https://cloud.google.com/bigquery/docs/loading-data#loading_denormalized_nested_and_repeated_data
48
47
  # Loading denormalized, nested, and repeated data
48
+ # @see https://cloud.google.com/bigquery/docs/views Creating views
49
+ # @see https://cloud.google.com/bigquery/docs/materialized-views-intro Introduction to materialized views
49
50
  #
50
51
  # @example
51
52
  # require "google/cloud/bigquery"
@@ -76,7 +77,7 @@ module Google
76
77
  # }
77
78
  # table.insert row
78
79
  #
79
- # @example Creating a BigQuery view:
80
+ # @example Creating a logical view:
80
81
  # require "google/cloud/bigquery"
81
82
  #
82
83
  # bigquery = Google::Cloud::Bigquery.new
@@ -85,6 +86,15 @@ module Google
85
86
  # "SELECT name, age FROM `my_project.my_dataset.my_table`"
86
87
  # view.view? # true
87
88
  #
89
+ # @example Creating a materialized view:
90
+ # require "google/cloud/bigquery"
91
+ #
92
+ # bigquery = Google::Cloud::Bigquery.new
93
+ # dataset = bigquery.dataset "my_dataset"
94
+ # view = dataset.create_materialized_view "my_materialized_view",
95
+ # "SELECT name, age FROM `my_project.my_dataset.my_table`"
96
+ # view.materialized_view? # true
97
+ #
88
98
  class Table
89
99
  ##
90
100
  # @private The Service object.
@@ -98,6 +108,10 @@ module Google
98
108
  # @private A Google API Client Table Reference object.
99
109
  attr_reader :reference
100
110
 
111
+ ##
112
+ # @private The metadata view type string.
113
+ attr_accessor :metadata_view
114
+
101
115
  ##
102
116
  # @private Create an empty Table object.
103
117
  def initialize
@@ -109,8 +123,8 @@ module Google
109
123
  ##
110
124
  # A unique ID for this table.
111
125
  #
112
- # @return [String] The ID must contain only letters (a-z, A-Z), numbers
113
- # (0-9), or underscores (_). The maximum length is 1,024 characters.
126
+ # @return [String] The ID must contain only letters (`[A-Za-z]`), numbers
127
+ # (`[0-9]`), or underscores (`_`). The maximum length is 1,024 characters.
114
128
  #
115
129
  # @!group Attributes
116
130
  #
@@ -122,8 +136,8 @@ module Google
122
136
  ##
123
137
  # The ID of the `Dataset` containing this table.
124
138
  #
125
- # @return [String] The ID must contain only letters (a-z, A-Z), numbers
126
- # (0-9), or underscores (_). The maximum length is 1,024 characters.
139
+ # @return [String] The ID must contain only letters (`[A-Za-z]`), numbers
140
+ # (`[0-9]`), or underscores (`_`). The maximum length is 1,024 characters.
127
141
  #
128
142
  # @!group Attributes
129
143
  #
@@ -144,6 +158,45 @@ module Google
144
158
  @gapi.table_reference.project_id
145
159
  end
146
160
 
161
+ ##
162
+ # The type of the table like if its a TABLE, VIEW or SNAPSHOT etc.,
163
+ #
164
+ # @return [String, nil] Type of the table, or
165
+ # `nil` if the object is a reference (see {#reference?}).
166
+ #
167
+ # @!group Attributes
168
+ #
169
+ def type
170
+ return nil if reference?
171
+ @gapi.type
172
+ end
173
+
174
+ ##
175
+ # The Information about base table and snapshot time of the table.
176
+ #
177
+ # @return [Google::Apis::BigqueryV2::SnapshotDefinition, nil] Snapshot definition of table snapshot, or
178
+ # `nil` if not snapshot or the object is a reference (see {#reference?}).
179
+ #
180
+ # @!group Attributes
181
+ #
182
+ def snapshot_definition
183
+ return nil if reference?
184
+ @gapi.snapshot_definition
185
+ end
186
+
187
+ ##
188
+ # The Information about base table and clone time of the table.
189
+ #
190
+ # @return [Google::Apis::BigqueryV2::CloneDefinition, nil] Clone definition of table clone, or
191
+ # `nil` if not clone or the object is a reference (see {#reference?}).
192
+ #
193
+ # @!group Attributes
194
+ #
195
+ def clone_definition
196
+ return nil if reference?
197
+ @gapi.clone_definition
198
+ end
199
+
147
200
  ##
148
201
  # @private The gapi fragment containing the Project ID, Dataset ID, and
149
202
  # Table ID.
@@ -155,10 +208,87 @@ module Google
155
208
  end
156
209
 
157
210
  ###
158
- # Checks if the table is time-partitioned. See [Partitioned
211
+ # Checks if the table is range partitioned. See [Creating and using integer range partitioned
212
+ # tables](https://cloud.google.com/bigquery/docs/creating-integer-range-partitions).
213
+ #
214
+ # @return [Boolean, nil] `true` when the table is range partitioned, or
215
+ # `false` otherwise, if the object is a resource (see {#resource?});
216
+ # `nil` if the object is a reference (see {#reference?}).
217
+ #
218
+ # @!group Attributes
219
+ #
220
+ def range_partitioning?
221
+ return nil if reference?
222
+ !@gapi.range_partitioning.nil?
223
+ end
224
+
225
+ ###
226
+ # The field on which the table is range partitioned, if any. The field must be a top-level `NULLABLE/REQUIRED`
227
+ # field. The only supported type is `INTEGER/INT64`. See [Creating and using integer range partitioned
228
+ # tables](https://cloud.google.com/bigquery/docs/creating-integer-range-partitions).
229
+ #
230
+ # @return [Integer, nil] The range partition field, or `nil` if not range partitioned or the object is a
231
+ # reference (see {#reference?}).
232
+ #
233
+ # @!group Attributes
234
+ #
235
+ def range_partitioning_field
236
+ return nil if reference?
237
+ ensure_full_data!
238
+ @gapi.range_partitioning.field if range_partitioning?
239
+ end
240
+
241
+ ###
242
+ # The start of range partitioning, inclusive. See [Creating and using integer range partitioned
243
+ # tables](https://cloud.google.com/bigquery/docs/creating-integer-range-partitions).
244
+ #
245
+ # @return [Integer, nil] The start of range partitioning, inclusive, or `nil` if not range partitioned or the
246
+ # object is a reference (see {#reference?}).
247
+ #
248
+ # @!group Attributes
249
+ #
250
+ def range_partitioning_start
251
+ return nil if reference?
252
+ ensure_full_data!
253
+ @gapi.range_partitioning.range.start if range_partitioning?
254
+ end
255
+
256
+ ###
257
+ # The width of each interval. See [Creating and using integer range partitioned
258
+ # tables](https://cloud.google.com/bigquery/docs/creating-integer-range-partitions).
259
+ #
260
+ # @return [Integer, nil] The width of each interval, for data in range partitions, or `nil` if not range
261
+ # partitioned or the object is a reference (see {#reference?}).
262
+ #
263
+ # @!group Attributes
264
+ #
265
+ def range_partitioning_interval
266
+ return nil if reference?
267
+ ensure_full_data!
268
+ return nil unless range_partitioning?
269
+ @gapi.range_partitioning.range.interval
270
+ end
271
+
272
+ ###
273
+ # The end of range partitioning, exclusive. See [Creating and using integer range partitioned
274
+ # tables](https://cloud.google.com/bigquery/docs/creating-integer-range-partitions).
275
+ #
276
+ # @return [Integer, nil] The end of range partitioning, exclusive, or `nil` if not range partitioned or the
277
+ # object is a reference (see {#reference?}).
278
+ #
279
+ # @!group Attributes
280
+ #
281
+ def range_partitioning_end
282
+ return nil if reference?
283
+ ensure_full_data!
284
+ @gapi.range_partitioning.range.end if range_partitioning?
285
+ end
286
+
287
+ ###
288
+ # Checks if the table is time partitioned. See [Partitioned
159
289
  # Tables](https://cloud.google.com/bigquery/docs/partitioned-tables).
160
290
  #
161
- # @return [Boolean, nil] `true` when the table is time-partitioned, or
291
+ # @return [Boolean, nil] `true` when the table is time partitioned, or
162
292
  # `false` otherwise, if the object is a resource (see {#resource?});
163
293
  # `nil` if the object is a reference (see {#reference?}).
164
294
  #
@@ -170,12 +300,13 @@ module Google
170
300
  end
171
301
 
172
302
  ###
173
- # The period for which the table is partitioned, if any. See
303
+ # The period for which the table is time partitioned, if any. See
174
304
  # [Partitioned Tables](https://cloud.google.com/bigquery/docs/partitioned-tables).
175
305
  #
176
- # @return [String, nil] The partition type. Currently the only supported
177
- # value is "DAY", or `nil` if the object is a reference (see
178
- # {#reference?}).
306
+ # @return [String, nil] The time partition type. The supported types are `DAY`,
307
+ # `HOUR`, `MONTH`, and `YEAR`, which will generate one partition per day,
308
+ # hour, month, and year, respectively; or `nil` if not set or the object is a
309
+ # reference (see {#reference?}).
179
310
  #
180
311
  # @!group Attributes
181
312
  #
@@ -186,43 +317,49 @@ module Google
186
317
  end
187
318
 
188
319
  ##
189
- # Sets the partitioning for the table. See [Partitioned
320
+ # Sets the time partitioning type for the table. See [Partitioned
190
321
  # Tables](https://cloud.google.com/bigquery/docs/partitioned-tables).
322
+ # The supported types are `DAY`, `HOUR`, `MONTH`, and `YEAR`, which will
323
+ # generate one partition per day, hour, month, and year, respectively.
191
324
  #
192
- # You can only set partitioning when creating a table as in
193
- # the example below. BigQuery does not allow you to change partitioning
325
+ # You can only set time partitioning when creating a table as in
326
+ # the example below. BigQuery does not allow you to change time partitioning
194
327
  # on an existing table.
195
328
  #
196
- # @param [String] type The partition type. Currently the only
197
- # supported value is "DAY".
329
+ # @param [String] type The time partition type. The supported types are `DAY`,
330
+ # `HOUR`, `MONTH`, and `YEAR`, which will generate one partition per day,
331
+ # hour, month, and year, respectively.
198
332
  #
199
333
  # @example
200
334
  # require "google/cloud/bigquery"
201
335
  #
202
336
  # bigquery = Google::Cloud::Bigquery.new
203
337
  # dataset = bigquery.dataset "my_dataset"
204
- # table = dataset.create_table "my_table" do |table|
205
- # table.time_partitioning_type = "DAY"
338
+ # table = dataset.create_table "my_table" do |t|
339
+ # t.schema do |schema|
340
+ # schema.timestamp "dob", mode: :required
341
+ # end
342
+ # t.time_partitioning_type = "DAY"
343
+ # t.time_partitioning_field = "dob"
206
344
  # end
207
345
  #
208
346
  # @!group Attributes
209
347
  #
210
348
  def time_partitioning_type= type
211
349
  reload! unless resource_full?
212
- @gapi.time_partitioning ||= \
213
- Google::Apis::BigqueryV2::TimePartitioning.new
350
+ @gapi.time_partitioning ||= Google::Apis::BigqueryV2::TimePartitioning.new
214
351
  @gapi.time_partitioning.type = type
215
352
  patch_gapi! :time_partitioning
216
353
  end
217
354
 
218
355
  ###
219
- # The field on which the table is partitioned, if any. If not
220
- # set, the destination table is partitioned by pseudo column
221
- # `_PARTITIONTIME`; if set, the table is partitioned by this field. See
356
+ # The field on which the table is time partitioned, if any. If not
357
+ # set, the destination table is time partitioned by pseudo column
358
+ # `_PARTITIONTIME`; if set, the table is time partitioned by this field. See
222
359
  # [Partitioned Tables](https://cloud.google.com/bigquery/docs/partitioned-tables).
223
360
  #
224
- # @return [String, nil] The partition field, if a field was configured.
225
- # `nil` if not partitioned, not set (partitioned by pseudo column
361
+ # @return [String, nil] The time partition field, if a field was configured.
362
+ # `nil` if not time partitioned, not set (time partitioned by pseudo column
226
363
  # '_PARTITIONTIME') or the object is a reference (see {#reference?}).
227
364
  #
228
365
  # @!group Attributes
@@ -234,19 +371,19 @@ module Google
234
371
  end
235
372
 
236
373
  ##
237
- # Sets the field on which to partition the table. If not
238
- # set, the destination table is partitioned by pseudo column
239
- # `_PARTITIONTIME`; if set, the table is partitioned by this field. See
374
+ # Sets the field on which to time partition the table. If not
375
+ # set, the destination table is time partitioned by pseudo column
376
+ # `_PARTITIONTIME`; if set, the table is time partitioned by this field. See
240
377
  # [Partitioned Tables](https://cloud.google.com/bigquery/docs/partitioned-tables).
241
- # The table must also be partitioned.
378
+ # The table must also be time partitioned.
242
379
  #
243
380
  # See {Table#time_partitioning_type=}.
244
381
  #
245
- # You can only set the partitioning field while creating a table as in
246
- # the example below. BigQuery does not allow you to change partitioning
382
+ # You can only set the time partitioning field while creating a table as in
383
+ # the example below. BigQuery does not allow you to change time partitioning
247
384
  # on an existing table.
248
385
  #
249
- # @param [String] field The partition field. The field must be a
386
+ # @param [String] field The time partition field. The field must be a
250
387
  # top-level TIMESTAMP or DATE field. Its mode must be NULLABLE or
251
388
  # REQUIRED.
252
389
  #
@@ -255,30 +392,29 @@ module Google
255
392
  #
256
393
  # bigquery = Google::Cloud::Bigquery.new
257
394
  # dataset = bigquery.dataset "my_dataset"
258
- # table = dataset.create_table "my_table" do |table|
259
- # table.time_partitioning_type = "DAY"
260
- # table.time_partitioning_field = "dob"
261
- # table.schema do |schema|
395
+ # table = dataset.create_table "my_table" do |t|
396
+ # t.schema do |schema|
262
397
  # schema.timestamp "dob", mode: :required
263
398
  # end
399
+ # t.time_partitioning_type = "DAY"
400
+ # t.time_partitioning_field = "dob"
264
401
  # end
265
402
  #
266
403
  # @!group Attributes
267
404
  #
268
405
  def time_partitioning_field= field
269
406
  reload! unless resource_full?
270
- @gapi.time_partitioning ||= \
271
- Google::Apis::BigqueryV2::TimePartitioning.new
407
+ @gapi.time_partitioning ||= Google::Apis::BigqueryV2::TimePartitioning.new
272
408
  @gapi.time_partitioning.field = field
273
409
  patch_gapi! :time_partitioning
274
410
  end
275
411
 
276
412
  ###
277
- # The expiration for the table partitions, if any, in seconds. See
413
+ # The expiration for the time partitions, if any, in seconds. See
278
414
  # [Partitioned Tables](https://cloud.google.com/bigquery/docs/partitioned-tables).
279
415
  #
280
416
  # @return [Integer, nil] The expiration time, in seconds, for data in
281
- # partitions, or `nil` if not present or the object is a reference
417
+ # time partitions, or `nil` if not present or the object is a reference
282
418
  # (see {#reference?}).
283
419
  #
284
420
  # @!group Attributes
@@ -286,15 +422,15 @@ module Google
286
422
  def time_partitioning_expiration
287
423
  return nil if reference?
288
424
  ensure_full_data!
289
- @gapi.time_partitioning.expiration_ms / 1_000 if
290
- time_partitioning? &&
291
- !@gapi.time_partitioning.expiration_ms.nil?
425
+ return nil unless time_partitioning?
426
+ return nil if @gapi.time_partitioning.expiration_ms.nil?
427
+ @gapi.time_partitioning.expiration_ms / 1_000
292
428
  end
293
429
 
294
430
  ##
295
- # Sets the partition expiration for the table. See [Partitioned
431
+ # Sets the time partition expiration for the table. See [Partitioned
296
432
  # Tables](https://cloud.google.com/bigquery/docs/partitioned-tables).
297
- # The table must also be partitioned.
433
+ # The table must also be time partitioned.
298
434
  #
299
435
  # See {Table#time_partitioning_type=}.
300
436
  #
@@ -302,26 +438,30 @@ module Google
302
438
  # {#resource_full?}), the full representation will be retrieved before
303
439
  # the update to comply with ETag-based optimistic concurrency control.
304
440
  #
305
- # @param [Integer] expiration An expiration time, in seconds,
306
- # for data in partitions.
441
+ # @param [Integer, nil] expiration An expiration time, in seconds,
442
+ # for data in time partitions, , or `nil` to indicate no expiration time.
307
443
  #
308
444
  # @example
309
445
  # require "google/cloud/bigquery"
310
446
  #
311
447
  # bigquery = Google::Cloud::Bigquery.new
312
448
  # dataset = bigquery.dataset "my_dataset"
313
- # table = dataset.create_table "my_table" do |table|
314
- # table.time_partitioning_type = "DAY"
315
- # table.time_partitioning_expiration = 86_400
449
+ # table = dataset.create_table "my_table" do |t|
450
+ # t.schema do |schema|
451
+ # schema.timestamp "dob", mode: :required
452
+ # end
453
+ # t.time_partitioning_type = "DAY"
454
+ # t.time_partitioning_field = "dob"
455
+ # t.time_partitioning_expiration = 86_400
316
456
  # end
317
457
  #
318
458
  # @!group Attributes
319
459
  #
320
460
  def time_partitioning_expiration= expiration
321
461
  reload! unless resource_full?
322
- @gapi.time_partitioning ||= \
323
- Google::Apis::BigqueryV2::TimePartitioning.new
324
- @gapi.time_partitioning.expiration_ms = expiration * 1000
462
+ expiration_ms = expiration * 1000 if expiration
463
+ @gapi.time_partitioning ||= Google::Apis::BigqueryV2::TimePartitioning.new
464
+ @gapi.time_partitioning.expiration_ms = expiration_ms
325
465
  patch_gapi! :time_partitioning
326
466
  end
327
467
 
@@ -359,8 +499,8 @@ module Google
359
499
  #
360
500
  # bigquery = Google::Cloud::Bigquery.new
361
501
  # dataset = bigquery.dataset "my_dataset"
362
- # table = dataset.create_table "my_table" do |table|
363
- # table.require_partition_filter = true
502
+ # table = dataset.create_table "my_table" do |t|
503
+ # t.require_partition_filter = true
364
504
  # end
365
505
  #
366
506
  # @!group Attributes
@@ -374,8 +514,13 @@ module Google
374
514
  ###
375
515
  # Checks if the table is clustered.
376
516
  #
517
+ # See {Table::Updater#clustering_fields=}, {Table#clustering_fields} and
518
+ # {Table#clustering_fields=}.
519
+ #
377
520
  # @see https://cloud.google.com/bigquery/docs/clustered-tables
378
- # Introduction to Clustered Tables
521
+ # Introduction to clustered tables
522
+ # @see https://cloud.google.com/bigquery/docs/creating-clustered-tables
523
+ # Creating and using clustered tables
379
524
  #
380
525
  # @return [Boolean, nil] `true` when the table is clustered, or
381
526
  # `false` otherwise, if the object is a resource (see {#resource?});
@@ -390,18 +535,20 @@ module Google
390
535
 
391
536
  ###
392
537
  # One or more fields on which data should be clustered. Must be
393
- # specified with time-based partitioning, data in the table will be
538
+ # specified with time partitioning, data in the table will be
394
539
  # first partitioned and subsequently clustered. The order of the
395
540
  # returned fields determines the sort order of the data.
396
541
  #
397
- # See {Table::Updater#clustering_fields=}.
542
+ # BigQuery supports clustering for both partitioned and non-partitioned
543
+ # tables.
544
+ #
545
+ # See {Table::Updater#clustering_fields=}, {Table#clustering_fields=} and
546
+ # {Table#clustering?}.
398
547
  #
399
- # @see https://cloud.google.com/bigquery/docs/partitioned-tables
400
- # Partitioned Tables
401
548
  # @see https://cloud.google.com/bigquery/docs/clustered-tables
402
- # Introduction to Clustered Tables
549
+ # Introduction to clustered tables
403
550
  # @see https://cloud.google.com/bigquery/docs/creating-clustered-tables
404
- # Creating and Using Clustered Tables
551
+ # Creating and using clustered tables
405
552
  #
406
553
  # @return [Array<String>, nil] The clustering fields, or `nil` if the
407
554
  # table is not clustered or if the table is a reference (see
@@ -415,6 +562,53 @@ module Google
415
562
  @gapi.clustering.fields if clustering?
416
563
  end
417
564
 
565
+ ##
566
+ # Updates the list of fields on which data should be clustered.
567
+ #
568
+ # Only top-level, non-repeated, simple-type fields are supported. When
569
+ # you cluster a table using multiple columns, the order of columns you
570
+ # specify is important. The order of the specified columns determines
571
+ # the sort order of the data.
572
+ #
573
+ # BigQuery supports clustering for both partitioned and non-partitioned
574
+ # tables.
575
+ #
576
+ # See {Table::Updater#clustering_fields=}, {Table#clustering_fields} and
577
+ # {Table#clustering?}.
578
+ #
579
+ # @see https://cloud.google.com/bigquery/docs/clustered-tables
580
+ # Introduction to clustered tables
581
+ # @see https://cloud.google.com/bigquery/docs/creating-clustered-tables
582
+ # Creating and using clustered tables
583
+ # @see https://cloud.google.com/bigquery/docs/creating-clustered-tables#modifying-cluster-spec
584
+ # Modifying clustering specification
585
+ #
586
+ # @param [Array<String>, nil] fields The clustering fields, or `nil` to
587
+ # remove the clustering configuration. Only top-level, non-repeated,
588
+ # simple-type fields are supported.
589
+ #
590
+ # @example
591
+ # require "google/cloud/bigquery"
592
+ #
593
+ # bigquery = Google::Cloud::Bigquery.new
594
+ # dataset = bigquery.dataset "my_dataset"
595
+ # table = dataset.table "my_table"
596
+ #
597
+ # table.clustering_fields = ["last_name", "first_name"]
598
+ #
599
+ # @!group Attributes
600
+ #
601
+ def clustering_fields= fields
602
+ reload! unless resource_full?
603
+ if fields
604
+ @gapi.clustering ||= Google::Apis::BigqueryV2::Clustering.new
605
+ @gapi.clustering.fields = fields
606
+ else
607
+ @gapi.clustering = nil
608
+ end
609
+ patch_gapi! :clustering
610
+ end
611
+
418
612
  ##
419
613
  # The combined Project ID, Dataset ID, and Table ID for this table, in
420
614
  # the format specified by the [Legacy SQL Query
@@ -639,7 +833,7 @@ module Google
639
833
  end
640
834
 
641
835
  ##
642
- # Checks if the table's type is "TABLE".
836
+ # Checks if the table's type is `TABLE`.
643
837
  #
644
838
  # @return [Boolean, nil] `true` when the type is `TABLE`, `false`
645
839
  # otherwise, if the object is a resource (see {#resource?}); `nil` if
@@ -653,8 +847,10 @@ module Google
653
847
  end
654
848
 
655
849
  ##
656
- # Checks if the table's type is "VIEW", indicating that the table
657
- # represents a BigQuery view. See {Dataset#create_view}.
850
+ # Checks if the table's type is `VIEW`, indicating that the table
851
+ # represents a BigQuery logical view. See {Dataset#create_view}.
852
+ #
853
+ # @see https://cloud.google.com/bigquery/docs/views Creating views
658
854
  #
659
855
  # @return [Boolean, nil] `true` when the type is `VIEW`, `false`
660
856
  # otherwise, if the object is a resource (see {#resource?}); `nil` if
@@ -668,7 +864,59 @@ module Google
668
864
  end
669
865
 
670
866
  ##
671
- # Checks if the table's type is "EXTERNAL", indicating that the table
867
+ # Checks if the table's type is `SNAPSHOT`, indicating that the table
868
+ # represents a BigQuery table snapshot.
869
+ #
870
+ # @see https://cloud.google.com/bigquery/docs/table-snapshots-intro
871
+ #
872
+ # @return [Boolean, nil] `true` when the type is `SNAPSHOT`, `false`
873
+ # otherwise, if the object is a resource (see {#resource?}); `nil` if
874
+ # the object is a reference (see {#reference?}).
875
+ #
876
+ # @!group Attributes
877
+ #
878
+ def snapshot?
879
+ return nil if reference?
880
+ @gapi.type == "SNAPSHOT"
881
+ end
882
+
883
+ ##
884
+ # Checks if the table's type is `CLONE`, indicating that the table
885
+ # represents a BigQuery table clone.
886
+ #
887
+ # @see https://cloud.google.com/bigquery/docs/table-clones-intro
888
+ #
889
+ # @return [Boolean, nil] `true` when the type is `CLONE`, `false`
890
+ # otherwise, if the object is a resource (see {#resource?}); `nil` if
891
+ # the object is a reference (see {#reference?}).
892
+ #
893
+ # @!group Attributes
894
+ #
895
+ def clone?
896
+ return nil if reference?
897
+ !@gapi.clone_definition.nil?
898
+ end
899
+
900
+ ##
901
+ # Checks if the table's type is `MATERIALIZED_VIEW`, indicating that
902
+ # the table represents a BigQuery materialized view.
903
+ # See {Dataset#create_materialized_view}.
904
+ #
905
+ # @see https://cloud.google.com/bigquery/docs/materialized-views-intro Introduction to materialized views
906
+ #
907
+ # @return [Boolean, nil] `true` when the type is `MATERIALIZED_VIEW`,
908
+ # `false` otherwise, if the object is a resource (see {#resource?});
909
+ # `nil` if the object is a reference (see {#reference?}).
910
+ #
911
+ # @!group Attributes
912
+ #
913
+ def materialized_view?
914
+ return nil if reference?
915
+ @gapi.type == "MATERIALIZED_VIEW"
916
+ end
917
+
918
+ ##
919
+ # Checks if the table's type is `EXTERNAL`, indicating that the table
672
920
  # represents an External Data Source. See {#external?} and
673
921
  # {External::DataSource}.
674
922
  #
@@ -738,12 +986,19 @@ module Google
738
986
  # @param [Hash<String, String>] labels A hash containing key/value
739
987
  # pairs.
740
988
  #
741
- # * Label keys and values can be no longer than 63 characters.
742
- # * Label keys and values can contain only lowercase letters, numbers,
743
- # underscores, hyphens, and international characters.
744
- # * Label keys and values cannot exceed 128 bytes in size.
745
- # * Label keys must begin with a letter.
746
- # * Label keys must be unique within a table.
989
+ # The labels applied to a resource must meet the following requirements:
990
+ #
991
+ # * Each resource can have multiple labels, up to a maximum of 64.
992
+ # * Each label must be a key-value pair.
993
+ # * Keys have a minimum length of 1 character and a maximum length of
994
+ # 63 characters, and cannot be empty. Values can be empty, and have
995
+ # a maximum length of 63 characters.
996
+ # * Keys and values can contain only lowercase letters, numeric characters,
997
+ # underscores, and dashes. All characters must use UTF-8 encoding, and
998
+ # international characters are allowed.
999
+ # * The key portion of a label must be unique. However, you can use the
1000
+ # same key with multiple resources.
1001
+ # * Keys must start with a lowercase letter or international character.
747
1002
  #
748
1003
  # @example
749
1004
  # require "google/cloud/bigquery"
@@ -873,10 +1128,30 @@ module Google
873
1128
  schema.headers
874
1129
  end
875
1130
 
1131
+ ##
1132
+ # The types of the fields in the table, obtained from its schema.
1133
+ # Types use the same format as the optional query parameter types.
1134
+ #
1135
+ # @return [Hash] A hash with field names as keys, and types as values.
1136
+ #
1137
+ # @example
1138
+ # require "google/cloud/bigquery"
1139
+ #
1140
+ # bigquery = Google::Cloud::Bigquery.new
1141
+ # dataset = bigquery.dataset "my_dataset"
1142
+ # table = dataset.table "my_table"
1143
+ #
1144
+ # table.param_types
1145
+ #
1146
+ def param_types
1147
+ return nil if reference?
1148
+ schema.param_types
1149
+ end
1150
+
876
1151
  ##
877
1152
  # The {EncryptionConfiguration} object that represents the custom
878
- # encryption method used to protect the table. If not set, default
879
- # encryption is used.
1153
+ # encryption method used to protect the table. If not set,
1154
+ # {Dataset#default_encryption} is used.
880
1155
  #
881
1156
  # Present only if the table is using custom encryption.
882
1157
  #
@@ -891,14 +1166,13 @@ module Google
891
1166
  return nil if reference?
892
1167
  ensure_full_data!
893
1168
  return nil if @gapi.encryption_configuration.nil?
894
- EncryptionConfiguration.from_gapi(@gapi.encryption_configuration)
895
- .freeze
1169
+ EncryptionConfiguration.from_gapi(@gapi.encryption_configuration).freeze
896
1170
  end
897
1171
 
898
1172
  ##
899
1173
  # Set the {EncryptionConfiguration} object that represents the custom
900
- # encryption method used to protect the table. If not set, default
901
- # encryption is used.
1174
+ # encryption method used to protect the table. If not set,
1175
+ # {Dataset#default_encryption} is used.
902
1176
  #
903
1177
  # Present only if the table is using custom encryption.
904
1178
  #
@@ -906,7 +1180,6 @@ module Google
906
1180
  # {#resource_full?}), the full representation will be retrieved before
907
1181
  # the update to comply with ETag-based optimistic concurrency control.
908
1182
  #
909
- #
910
1183
  # @see https://cloud.google.com/bigquery/docs/customer-managed-encryption
911
1184
  # Protecting Data with Cloud KMS Keys
912
1185
  #
@@ -986,7 +1259,7 @@ module Google
986
1259
  def buffer_bytes
987
1260
  return nil if reference?
988
1261
  ensure_full_data!
989
- @gapi.streaming_buffer.estimated_bytes if @gapi.streaming_buffer
1262
+ @gapi.streaming_buffer&.estimated_bytes
990
1263
  end
991
1264
 
992
1265
  ##
@@ -1004,7 +1277,7 @@ module Google
1004
1277
  def buffer_rows
1005
1278
  return nil if reference?
1006
1279
  ensure_full_data!
1007
- @gapi.streaming_buffer.estimated_rows if @gapi.streaming_buffer
1280
+ @gapi.streaming_buffer&.estimated_rows
1008
1281
  end
1009
1282
 
1010
1283
  ##
@@ -1026,21 +1299,24 @@ module Google
1026
1299
  end
1027
1300
 
1028
1301
  ##
1029
- # The query that executes each time the view is loaded.
1302
+ # The query that defines the view or materialized view. See {#view?} and
1303
+ # {#materialized_view?}.
1030
1304
  #
1031
- # @return [String] The query that defines the view.
1305
+ # @return [String, nil] The query that defines the view or materialized_view;
1306
+ # or `nil` if not a view or materialized view.
1032
1307
  #
1033
1308
  # @!group Attributes
1034
1309
  #
1035
1310
  def query
1036
- @gapi.view.query if @gapi.view
1311
+ view? ? @gapi.view&.query : @gapi.materialized_view&.query
1037
1312
  end
1038
1313
 
1039
1314
  ##
1040
- # Updates the query that executes each time the view is loaded.
1315
+ # Updates the query that defines the view. (See {#view?}.) Not supported
1316
+ # for materialized views.
1041
1317
  #
1042
- # This sets the query using standard SQL. To specify legacy SQL or to
1043
- # use user-defined function resources use (#set_query) instead.
1318
+ # This method sets the query using standard SQL. To specify legacy SQL or
1319
+ # to use user-defined function resources for a view, use (#set_query) instead.
1044
1320
  #
1045
1321
  # @see https://cloud.google.com/bigquery/query-reference BigQuery Query
1046
1322
  # Reference
@@ -1055,7 +1331,7 @@ module Google
1055
1331
  # view = dataset.table "my_view"
1056
1332
  #
1057
1333
  # view.query = "SELECT first_name FROM " \
1058
- # "`my_project.my_dataset.my_table`"
1334
+ # "`my_project.my_dataset.my_table`"
1059
1335
  #
1060
1336
  # @!group Lifecycle
1061
1337
  #
@@ -1064,12 +1340,12 @@ module Google
1064
1340
  end
1065
1341
 
1066
1342
  ##
1067
- # Updates the query that executes each time the view is loaded. Allows
1068
- # setting of standard vs. legacy SQL and user-defined function
1069
- # resources.
1343
+ # Updates the query that defines the view. (See {#view?}.) Not supported for
1344
+ # materialized views.
1070
1345
  #
1071
- # @see https://cloud.google.com/bigquery/query-reference BigQuery Query
1072
- # Reference
1346
+ # Allows setting of standard vs. legacy SQL and user-defined function resources.
1347
+ #
1348
+ # @see https://cloud.google.com/bigquery/query-reference BigQuery Query Reference
1073
1349
  #
1074
1350
  # @param [String] query The query that defines the view.
1075
1351
  # @param [Boolean] standard_sql Specifies whether to use BigQuery's
@@ -1081,14 +1357,23 @@ module Google
1081
1357
  # SQL](https://cloud.google.com/bigquery/docs/reference/legacy-sql)
1082
1358
  # dialect. Optional. The default value is false.
1083
1359
  # @param [Array<String>, String] udfs User-defined function resources
1084
- # used in the query. May be either a code resource to load from a
1085
- # Google Cloud Storage URI (`gs://bucket/path`), or an inline resource
1086
- # that contains code for a user-defined function (UDF). Providing an
1087
- # inline code resource is equivalent to providing a URI for a file
1088
- # containing the same code. See [User-Defined
1089
- # Functions](https://cloud.google.com/bigquery/docs/reference/standard-sql/user-defined-functions).
1360
+ # used in a legacy SQL query. Optional.
1090
1361
  #
1091
- # @example
1362
+ # May be either a code resource to load from a Google Cloud Storage URI
1363
+ # (`gs://bucket/path`), or an inline resource that contains code for a
1364
+ # user-defined function (UDF). Providing an inline code resource is equivalent
1365
+ # to providing a URI for a file containing the same code.
1366
+ #
1367
+ # This parameter is used for defining User Defined Function (UDF)
1368
+ # resources only when using legacy SQL. Users of standard SQL should
1369
+ # leverage either DDL (e.g. `CREATE [TEMPORARY] FUNCTION ...`) or the
1370
+ # Routines API to define UDF resources.
1371
+ #
1372
+ # For additional information on migrating, see: [Migrating to
1373
+ # standard SQL - Differences in user-defined JavaScript
1374
+ # functions](https://cloud.google.com/bigquery/docs/reference/standard-sql/migrating-from-legacy-sql#differences_in_user-defined_javascript_functions)
1375
+ #
1376
+ # @example Update a view:
1092
1377
  # require "google/cloud/bigquery"
1093
1378
  #
1094
1379
  # bigquery = Google::Cloud::Bigquery.new
@@ -1096,41 +1381,45 @@ module Google
1096
1381
  # view = dataset.table "my_view"
1097
1382
  #
1098
1383
  # view.set_query "SELECT first_name FROM " \
1099
- # "`my_project.my_dataset.my_table`",
1384
+ # "`my_project.my_dataset.my_table`",
1100
1385
  # standard_sql: true
1101
1386
  #
1102
1387
  # @!group Lifecycle
1103
1388
  #
1104
1389
  def set_query query, standard_sql: nil, legacy_sql: nil, udfs: nil
1390
+ raise "Updating the query is not supported for Table type: #{@gapi.type}" unless view?
1105
1391
  use_legacy_sql = Convert.resolve_legacy_sql standard_sql, legacy_sql
1106
- @gapi.view = Google::Apis::BigqueryV2::ViewDefinition.new \
1392
+ @gapi.view = Google::Apis::BigqueryV2::ViewDefinition.new(
1107
1393
  query: query,
1108
1394
  use_legacy_sql: use_legacy_sql,
1109
1395
  user_defined_function_resources: udfs_gapi(udfs)
1396
+ )
1110
1397
  patch_gapi! :view
1111
1398
  end
1112
1399
 
1113
1400
  ##
1114
- # Checks if the view's query is using legacy sql.
1401
+ # Checks if the view's query is using legacy sql. See {#view?}.
1115
1402
  #
1116
- # @return [Boolean] `true` when legacy sql is used, `false` otherwise.
1403
+ # @return [Boolean] `true` when legacy sql is used, `false` otherwise; or `nil` if not a logical view.
1117
1404
  #
1118
1405
  # @!group Attributes
1119
1406
  #
1120
1407
  def query_legacy_sql?
1408
+ return nil unless @gapi.view
1121
1409
  val = @gapi.view.use_legacy_sql
1122
1410
  return true if val.nil?
1123
1411
  val
1124
1412
  end
1125
1413
 
1126
1414
  ##
1127
- # Checks if the view's query is using standard sql.
1415
+ # Checks if the view's query is using standard sql. See {#view?}.
1128
1416
  #
1129
1417
  # @return [Boolean] `true` when standard sql is used, `false` otherwise.
1130
1418
  #
1131
1419
  # @!group Attributes
1132
1420
  #
1133
1421
  def query_standard_sql?
1422
+ return nil unless @gapi.view
1134
1423
  !query_legacy_sql?
1135
1424
  end
1136
1425
 
@@ -1142,18 +1431,193 @@ module Google
1142
1431
  # equivalent to providing a URI for a file containing the same code. See
1143
1432
  # [User-Defined
1144
1433
  # Functions](https://cloud.google.com/bigquery/docs/reference/standard-sql/user-defined-functions).
1434
+ # See {#view?}.
1145
1435
  #
1146
- # @return [Array<String>] An array containing Google Cloud Storage URIs
1147
- # and/or inline source code.
1436
+ # @return [Array<String>, nil] An array containing Google Cloud Storage URIs
1437
+ # and/or inline source code, or `nil` if not a logical view.
1148
1438
  #
1149
1439
  # @!group Attributes
1150
1440
  #
1151
1441
  def query_udfs
1442
+ return nil unless @gapi.view
1152
1443
  udfs_gapi = @gapi.view.user_defined_function_resources
1153
1444
  return [] if udfs_gapi.nil?
1154
1445
  Array(udfs_gapi).map { |udf| udf.inline_code || udf.resource_uri }
1155
1446
  end
1156
1447
 
1448
+ ##
1449
+ # Whether automatic refresh of the materialized view is enabled. When true,
1450
+ # the materialized view is updated when the base table is updated. The default
1451
+ # value is true. See {#materialized_view?}.
1452
+ #
1453
+ # @return [Boolean, nil] `true` when automatic refresh is enabled, `false` otherwise;
1454
+ # or `nil` if not a materialized view.
1455
+ #
1456
+ # @!group Attributes
1457
+ #
1458
+ def enable_refresh?
1459
+ return nil unless @gapi.materialized_view
1460
+ val = @gapi.materialized_view.enable_refresh
1461
+ return true if val.nil?
1462
+ val
1463
+ end
1464
+
1465
+ ##
1466
+ # Sets whether automatic refresh of the materialized view is enabled. When true,
1467
+ # the materialized view is updated when the base table is updated. See {#materialized_view?}.
1468
+ #
1469
+ # @param [Boolean] new_enable_refresh `true` when automatic refresh is enabled, `false` otherwise.
1470
+ #
1471
+ # @!group Attributes
1472
+ #
1473
+ def enable_refresh= new_enable_refresh
1474
+ @gapi.materialized_view = Google::Apis::BigqueryV2::MaterializedViewDefinition.new(
1475
+ enable_refresh: new_enable_refresh
1476
+ )
1477
+ patch_gapi! :materialized_view
1478
+ end
1479
+
1480
+ ##
1481
+ # The time when the materialized view was last modified.
1482
+ # See {#materialized_view?}.
1483
+ #
1484
+ # @return [Time, nil] The time, or `nil` if not present or not a materialized view.
1485
+ #
1486
+ # @!group Attributes
1487
+ #
1488
+ def last_refresh_time
1489
+ Convert.millis_to_time @gapi.materialized_view&.last_refresh_time
1490
+ end
1491
+
1492
+ ##
1493
+ # The maximum frequency in milliseconds at which the materialized view will be refreshed.
1494
+ # See {#materialized_view?}.
1495
+ #
1496
+ # @return [Integer, nil] The maximum frequency in milliseconds;
1497
+ # or `nil` if not a materialized view.
1498
+ #
1499
+ # @!group Attributes
1500
+ #
1501
+ def refresh_interval_ms
1502
+ @gapi.materialized_view&.refresh_interval_ms
1503
+ end
1504
+
1505
+ ##
1506
+ # Sets the maximum frequency at which the materialized view will be refreshed.
1507
+ # See {#materialized_view?}.
1508
+ #
1509
+ # @param [Integer] new_refresh_interval_ms The maximum frequency in milliseconds.
1510
+ #
1511
+ # @!group Attributes
1512
+ #
1513
+ def refresh_interval_ms= new_refresh_interval_ms
1514
+ @gapi.materialized_view = Google::Apis::BigqueryV2::MaterializedViewDefinition.new(
1515
+ refresh_interval_ms: new_refresh_interval_ms
1516
+ )
1517
+ patch_gapi! :materialized_view
1518
+ end
1519
+
1520
+ ##
1521
+ # Gets the Cloud IAM access control policy for the table. The latest policy will be read from the service. See
1522
+ # also {#update_policy}.
1523
+ #
1524
+ # @see https://cloud.google.com/iam/docs/managing-policies Managing Policies
1525
+ # @see https://cloud.google.com/bigquery/docs/table-access-controls-intro Controlling access to tables
1526
+ #
1527
+ # @return [Policy] The frozen policy for the table.
1528
+ #
1529
+ # @example
1530
+ # require "google/cloud/bigquery"
1531
+ #
1532
+ # bigquery = Google::Cloud::Bigquery.new
1533
+ # dataset = bigquery.dataset "my_dataset"
1534
+ # table = dataset.table "my_table"
1535
+ #
1536
+ # policy = table.policy
1537
+ #
1538
+ # policy.frozen? #=> true
1539
+ # binding_owner = policy.bindings.find { |b| b.role == "roles/owner" }
1540
+ # binding_owner.role #=> "roles/owner"
1541
+ # binding_owner.members #=> ["user:owner@example.com"]
1542
+ # binding_owner.frozen? #=> true
1543
+ # binding_owner.members.frozen? #=> true
1544
+ #
1545
+ def policy
1546
+ raise ArgumentError, "Block argument not supported: Use #update_policy instead." if block_given?
1547
+ ensure_service!
1548
+ gapi = service.get_table_policy dataset_id, table_id
1549
+ Policy.from_gapi(gapi).freeze
1550
+ end
1551
+
1552
+ ##
1553
+ # Updates the Cloud IAM access control policy for the table. The latest policy will be read from the service.
1554
+ # See also {#policy}.
1555
+ #
1556
+ # @see https://cloud.google.com/iam/docs/managing-policies Managing Policies
1557
+ # @see https://cloud.google.com/bigquery/docs/table-access-controls-intro Controlling access to tables
1558
+ #
1559
+ # @yield [policy] A block for updating the policy. The latest policy will be read from the service and passed to
1560
+ # the block. After the block completes, the modified policy will be written to the service.
1561
+ # @yieldparam [Policy] policy The mutable Policy for the table.
1562
+ #
1563
+ # @return [Policy] The updated and frozen policy for the table.
1564
+ #
1565
+ # @example Update the policy by passing a block.
1566
+ # require "google/cloud/bigquery"
1567
+ #
1568
+ # bigquery = Google::Cloud::Bigquery.new
1569
+ # dataset = bigquery.dataset "my_dataset"
1570
+ # table = dataset.table "my_table"
1571
+ #
1572
+ # table.update_policy do |p|
1573
+ # p.grant role: "roles/viewer", members: "user:viewer@example.com"
1574
+ # p.revoke role: "roles/editor", members: "user:editor@example.com"
1575
+ # p.revoke role: "roles/owner"
1576
+ # end # 2 API calls
1577
+ #
1578
+ def update_policy
1579
+ raise ArgumentError, "A block updating the policy must be provided" unless block_given?
1580
+ ensure_service!
1581
+ gapi = service.get_table_policy dataset_id, table_id
1582
+ policy = Policy.from_gapi gapi
1583
+ yield policy
1584
+ # TODO: Check for changes before calling RPC
1585
+ gapi = service.set_table_policy dataset_id, table_id, policy.to_gapi
1586
+ Policy.from_gapi(gapi).freeze
1587
+ end
1588
+
1589
+ ##
1590
+ # Tests the specified permissions against the [Cloud
1591
+ # IAM](https://cloud.google.com/iam/) access control policy.
1592
+ #
1593
+ # @see https://cloud.google.com/iam/docs/managing-policies Managing Policies
1594
+ #
1595
+ # @param [String, Array<String>] permissions The set of permissions
1596
+ # against which to check access. Permissions must be of the format
1597
+ # `bigquery.resource.capability`.
1598
+ # See https://cloud.google.com/bigquery/docs/access-control#bigquery.
1599
+ #
1600
+ # @return [Array<String>] The frozen array of permissions held by the caller.
1601
+ #
1602
+ # @example
1603
+ # require "google/cloud/bigquery"
1604
+ #
1605
+ # bigquery = Google::Cloud::Bigquery.new
1606
+ # dataset = bigquery.dataset "my_dataset"
1607
+ # table = dataset.table "my_table"
1608
+ #
1609
+ # permissions = table.test_iam_permissions "bigquery.tables.get",
1610
+ # "bigquery.tables.delete"
1611
+ # permissions.include? "bigquery.tables.get" #=> true
1612
+ # permissions.include? "bigquery.tables.delete" #=> false
1613
+ #
1614
+ def test_iam_permissions *permissions
1615
+ permissions = Array(permissions).flatten
1616
+ ensure_service!
1617
+ gapi = service.test_table_permissions dataset_id, table_id, permissions
1618
+ gapi.permissions.freeze
1619
+ end
1620
+
1157
1621
  ##
1158
1622
  # Retrieves data from the table.
1159
1623
  #
@@ -1177,12 +1641,13 @@ module Google
1177
1641
  # table = dataset.table "my_table"
1178
1642
  #
1179
1643
  # data = table.data
1644
+ #
1645
+ # # Iterate over the first page of results
1180
1646
  # data.each do |row|
1181
- # puts row[:first_name]
1182
- # end
1183
- # if data.next?
1184
- # more_data = data.next if data.next?
1647
+ # puts row[:name]
1185
1648
  # end
1649
+ # # Retrieve the next page of results
1650
+ # data = data.next if data.next?
1186
1651
  #
1187
1652
  # @example Retrieve all rows of data: (See {Data#all})
1188
1653
  # require "google/cloud/bigquery"
@@ -1192,8 +1657,9 @@ module Google
1192
1657
  # table = dataset.table "my_table"
1193
1658
  #
1194
1659
  # data = table.data
1660
+ #
1195
1661
  # data.all do |row|
1196
- # puts row[:first_name]
1662
+ # puts row[:name]
1197
1663
  # end
1198
1664
  #
1199
1665
  # @!group Data
@@ -1201,9 +1667,7 @@ module Google
1201
1667
  def data token: nil, max: nil, start: nil
1202
1668
  ensure_service!
1203
1669
  reload! unless resource_full?
1204
- options = { token: token, max: max, start: start }
1205
- data_json = service.list_tabledata \
1206
- dataset_id, table_id, options
1670
+ data_json = service.list_tabledata dataset_id, table_id, token: token, max: max, start: start
1207
1671
  Data.from_gapi_json data_json, gapi, nil, service
1208
1672
  end
1209
1673
 
@@ -1246,37 +1710,250 @@ module Google
1246
1710
  # * `empty` - An error will be returned if the destination table
1247
1711
  # already contains data.
1248
1712
  # @param [String] job_id A user-defined ID for the copy job. The ID
1249
- # must contain only letters (a-z, A-Z), numbers (0-9), underscores
1250
- # (_), or dashes (-). The maximum length is 1,024 characters. If
1713
+ # must contain only letters (`[A-Za-z]`), numbers (`[0-9]`), underscores
1714
+ # (`_`), or dashes (`-`). The maximum length is 1,024 characters. If
1251
1715
  # `job_id` is provided, then `prefix` will not be used.
1252
1716
  #
1253
- # See [Generating a job
1254
- # ID](https://cloud.google.com/bigquery/docs/managing-jobs#generate-jobid).
1255
- # @param [String] prefix A string, usually human-readable, that will be
1256
- # prepended to a generated value to produce a unique job ID. For
1257
- # example, the prefix `daily_import_job_` can be given to generate a
1258
- # job ID such as `daily_import_job_12vEDtMQ0mbp1Mo5Z7mzAFQJZazh`. The
1259
- # prefix must contain only letters (a-z, A-Z), numbers (0-9),
1260
- # underscores (_), or dashes (-). The maximum length of the entire ID
1261
- # is 1,024 characters. If `job_id` is provided, then `prefix` will not
1262
- # be used.
1263
- # @param [Hash] labels A hash of user-provided labels associated with
1264
- # the job. You can use these to organize and group your jobs. Label
1265
- # keys and values can be no longer than 63 characters, can only
1266
- # contain lowercase letters, numeric characters, underscores and
1267
- # dashes. International characters are allowed. Label values are
1268
- # optional. Label keys must start with a letter and each label in the
1269
- # list must have a different key. See [Requirements for
1270
- # labels](https://cloud.google.com/bigquery/docs/creating-managing-labels#requirements).
1271
- # @param [Boolean] dryrun If set, don't actually run this job. Behavior
1272
- # is undefined however for non-query jobs and may result in an error.
1273
- # Deprecated.
1717
+ # See [Generating a job
1718
+ # ID](https://cloud.google.com/bigquery/docs/managing-jobs#generate-jobid).
1719
+ # @param [String] prefix A string, usually human-readable, that will be
1720
+ # prepended to a generated value to produce a unique job ID. For
1721
+ # example, the prefix `daily_import_job_` can be given to generate a
1722
+ # job ID such as `daily_import_job_12vEDtMQ0mbp1Mo5Z7mzAFQJZazh`. The
1723
+ # prefix must contain only letters (`[A-Za-z]`), numbers (`[0-9]`),
1724
+ # underscores (`_`), or dashes (`-`). The maximum length of the entire ID
1725
+ # is 1,024 characters. If `job_id` is provided, then `prefix` will not
1726
+ # be used.
1727
+ # @param [Hash] labels A hash of user-provided labels associated with
1728
+ # the job. You can use these to organize and group your jobs.
1729
+ #
1730
+ # The labels applied to a resource must meet the following requirements:
1731
+ #
1732
+ # * Each resource can have multiple labels, up to a maximum of 64.
1733
+ # * Each label must be a key-value pair.
1734
+ # * Keys have a minimum length of 1 character and a maximum length of
1735
+ # 63 characters, and cannot be empty. Values can be empty, and have
1736
+ # a maximum length of 63 characters.
1737
+ # * Keys and values can contain only lowercase letters, numeric characters,
1738
+ # underscores, and dashes. All characters must use UTF-8 encoding, and
1739
+ # international characters are allowed.
1740
+ # * The key portion of a label must be unique. However, you can use the
1741
+ # same key with multiple resources.
1742
+ # * Keys must start with a lowercase letter or international character.
1743
+ # @param [Boolean] dryrun If set, don't actually run this job. Behavior
1744
+ # is undefined however for non-query jobs and may result in an error.
1745
+ # Deprecated.
1746
+ #
1747
+ # @yield [job] a job configuration object
1748
+ # @yieldparam [Google::Cloud::Bigquery::CopyJob::Updater] job a job
1749
+ # configuration object for setting additional options.
1750
+ #
1751
+ # @return [Google::Cloud::Bigquery::CopyJob]
1752
+ #
1753
+ # @example
1754
+ # require "google/cloud/bigquery"
1755
+ #
1756
+ # bigquery = Google::Cloud::Bigquery.new
1757
+ # dataset = bigquery.dataset "my_dataset"
1758
+ # table = dataset.table "my_table"
1759
+ # destination_table = dataset.table "my_destination_table"
1760
+ #
1761
+ # copy_job = table.copy_job destination_table
1762
+ #
1763
+ # @example Passing a string identifier for the destination table:
1764
+ # require "google/cloud/bigquery"
1765
+ #
1766
+ # bigquery = Google::Cloud::Bigquery.new
1767
+ # dataset = bigquery.dataset "my_dataset"
1768
+ # table = dataset.table "my_table"
1769
+ #
1770
+ # copy_job = table.copy_job "other-project:other_dataset.other_table"
1771
+ #
1772
+ # copy_job.wait_until_done!
1773
+ # copy_job.done? #=> true
1774
+ #
1775
+ # @!group Data
1776
+ #
1777
+ def copy_job destination_table, create: nil, write: nil, job_id: nil, prefix: nil, labels: nil, dryrun: nil,
1778
+ operation_type: nil
1779
+ ensure_service!
1780
+ options = { create: create,
1781
+ write: write,
1782
+ dryrun: dryrun,
1783
+ labels: labels,
1784
+ job_id: job_id,
1785
+ prefix: prefix,
1786
+ operation_type: operation_type }
1787
+ updater = CopyJob::Updater.from_options(
1788
+ service,
1789
+ table_ref,
1790
+ Service.get_table_ref(destination_table, default_ref: table_ref),
1791
+ options
1792
+ )
1793
+ updater.location = location if location # may be table reference
1794
+
1795
+ yield updater if block_given?
1796
+
1797
+ job_gapi = updater.to_gapi
1798
+ gapi = service.copy_table job_gapi
1799
+ Job.from_gapi gapi, service
1800
+ end
1801
+
1802
+ ##
1803
+ # Copies the data from the table to another table using a synchronous
1804
+ # method that blocks for a response. Timeouts and transient errors are
1805
+ # generally handled as needed to complete the job. See also
1806
+ # {#copy_job}.
1807
+ #
1808
+ # The geographic location for the job ("US", "EU", etc.) can be set via
1809
+ # {CopyJob::Updater#location=} in a block passed to this method. If the
1810
+ # table is a full resource representation (see {#resource_full?}), the
1811
+ # location of the job will be automatically set to the location of the
1812
+ # table.
1813
+ #
1814
+ # @param [Table, String] destination_table The destination for the
1815
+ # copied data. This can also be a string identifier as specified by
1816
+ # the [Standard SQL Query
1817
+ # Reference](https://cloud.google.com/bigquery/docs/reference/standard-sql/query-syntax#from-clause)
1818
+ # (`project-name.dataset_id.table_id`) or the [Legacy SQL Query
1819
+ # Reference](https://cloud.google.com/bigquery/query-reference#from)
1820
+ # (`project-name:dataset_id.table_id`). This is useful for referencing
1821
+ # tables in other projects and datasets.
1822
+ # @param [String] create Specifies whether the job is allowed to create
1823
+ # new tables. The default value is `needed`.
1824
+ #
1825
+ # The following values are supported:
1826
+ #
1827
+ # * `needed` - Create the table if it does not exist.
1828
+ # * `never` - The table must already exist. A 'notFound' error is
1829
+ # raised if the table does not exist.
1830
+ # @param [String] write Specifies how to handle data already present in
1831
+ # the destination table. The default value is `empty`.
1832
+ #
1833
+ # The following values are supported:
1834
+ #
1835
+ # * `truncate` - BigQuery overwrites the table data.
1836
+ # * `append` - BigQuery appends the data to the table.
1837
+ # * `empty` - An error will be returned if the destination table
1838
+ # already contains data.
1839
+ # @yield [job] a job configuration object
1840
+ # @yieldparam [Google::Cloud::Bigquery::CopyJob::Updater] job a job
1841
+ # configuration object for setting additional options.
1842
+ #
1843
+ # @return [Boolean] Returns `true` if the copy operation succeeded.
1844
+ #
1845
+ # @example
1846
+ # require "google/cloud/bigquery"
1847
+ #
1848
+ # bigquery = Google::Cloud::Bigquery.new
1849
+ # dataset = bigquery.dataset "my_dataset"
1850
+ # table = dataset.table "my_table"
1851
+ # destination_table = dataset.table "my_destination_table"
1852
+ #
1853
+ # table.copy destination_table
1854
+ #
1855
+ # @example Passing a string identifier for the destination table:
1856
+ # require "google/cloud/bigquery"
1857
+ #
1858
+ # bigquery = Google::Cloud::Bigquery.new
1859
+ # dataset = bigquery.dataset "my_dataset"
1860
+ # table = dataset.table "my_table"
1861
+ #
1862
+ # table.copy "other-project:other_dataset.other_table"
1863
+ #
1864
+ # @!group Data
1865
+ #
1866
+ def copy destination_table, create: nil, write: nil, &block
1867
+ copy_job_with_operation_type destination_table,
1868
+ create: create,
1869
+ write: write,
1870
+ operation_type: OperationType::COPY,
1871
+ &block
1872
+ end
1873
+
1874
+ ##
1875
+ # Clones the data from the table to another table using a synchronous
1876
+ # method that blocks for a response.
1877
+ # The source and destination table have the same table type, but only bill for
1878
+ # unique data.
1879
+ # Timeouts and transient errors are generally handled as needed to complete the job.
1880
+ # See also {#copy_job}.
1881
+ #
1882
+ # The geographic location for the job ("US", "EU", etc.) can be set via
1883
+ # {CopyJob::Updater#location=} in a block passed to this method. If the
1884
+ # table is a full resource representation (see {#resource_full?}), the
1885
+ # location of the job will be automatically set to the location of the
1886
+ # table.
1887
+ #
1888
+ # @param [Table, String] destination_table The destination for the
1889
+ # copied data. This can also be a string identifier as specified by
1890
+ # the [Standard SQL Query
1891
+ # Reference](https://cloud.google.com/bigquery/docs/reference/standard-sql/query-syntax#from-clause)
1892
+ # (`project-name.dataset_id.table_id`) or the [Legacy SQL Query
1893
+ # Reference](https://cloud.google.com/bigquery/query-reference#from)
1894
+ # (`project-name:dataset_id.table_id`). This is useful for referencing
1895
+ # tables in other projects and datasets.
1896
+ #
1897
+ # @yield [job] a job configuration object
1898
+ # @yieldparam [Google::Cloud::Bigquery::CopyJob::Updater] job a job
1899
+ # configuration object for setting additional options.
1900
+ #
1901
+ # @return [Boolean] Returns `true` if the copy operation succeeded.
1902
+ #
1903
+ # @example
1904
+ # require "google/cloud/bigquery"
1905
+ #
1906
+ # bigquery = Google::Cloud::Bigquery.new
1907
+ # dataset = bigquery.dataset "my_dataset"
1908
+ # table = dataset.table "my_table"
1909
+ # destination_table = dataset.table "my_destination_table"
1910
+ #
1911
+ # table.clone destination_table
1912
+ #
1913
+ # @example Passing a string identifier for the destination table:
1914
+ # require "google/cloud/bigquery"
1915
+ #
1916
+ # bigquery = Google::Cloud::Bigquery.new
1917
+ # dataset = bigquery.dataset "my_dataset"
1918
+ # table = dataset.table "my_table"
1919
+ #
1920
+ # table.clone "other-project:other_dataset.other_table"
1921
+ #
1922
+ # @!group Data
1923
+ #
1924
+ def clone destination_table, &block
1925
+ copy_job_with_operation_type destination_table,
1926
+ operation_type: OperationType::CLONE,
1927
+ &block
1928
+ end
1929
+
1930
+ ##
1931
+ # Takes snapshot of the data from the table to another table using a synchronous
1932
+ # method that blocks for a response.
1933
+ # The source table type is TABLE and the destination table type is SNAPSHOT.
1934
+ # Timeouts and transient errors are generally handled as needed to complete the job.
1935
+ # See also {#copy_job}.
1936
+ #
1937
+ # The geographic location for the job ("US", "EU", etc.) can be set via
1938
+ # {CopyJob::Updater#location=} in a block passed to this method. If the
1939
+ # table is a full resource representation (see {#resource_full?}), the
1940
+ # location of the job will be automatically set to the location of the
1941
+ # table.
1942
+ #
1943
+ # @param [Table, String] destination_table The destination for the
1944
+ # copied data. This can also be a string identifier as specified by
1945
+ # the [Standard SQL Query
1946
+ # Reference](https://cloud.google.com/bigquery/docs/reference/standard-sql/query-syntax#from-clause)
1947
+ # (`project-name.dataset_id.table_id`) or the [Legacy SQL Query
1948
+ # Reference](https://cloud.google.com/bigquery/query-reference#from)
1949
+ # (`project-name:dataset_id.table_id`). This is useful for referencing
1950
+ # tables in other projects and datasets.
1274
1951
  #
1275
1952
  # @yield [job] a job configuration object
1276
1953
  # @yieldparam [Google::Cloud::Bigquery::CopyJob::Updater] job a job
1277
1954
  # configuration object for setting additional options.
1278
1955
  #
1279
- # @return [Google::Cloud::Bigquery::CopyJob]
1956
+ # @return [Boolean] Returns `true` if the copy operation succeeded.
1280
1957
  #
1281
1958
  # @example
1282
1959
  # require "google/cloud/bigquery"
@@ -1286,7 +1963,7 @@ module Google
1286
1963
  # table = dataset.table "my_table"
1287
1964
  # destination_table = dataset.table "my_destination_table"
1288
1965
  #
1289
- # copy_job = table.copy_job destination_table
1966
+ # table.snapshot destination_table
1290
1967
  #
1291
1968
  # @example Passing a string identifier for the destination table:
1292
1969
  # require "google/cloud/bigquery"
@@ -1295,38 +1972,22 @@ module Google
1295
1972
  # dataset = bigquery.dataset "my_dataset"
1296
1973
  # table = dataset.table "my_table"
1297
1974
  #
1298
- # copy_job = table.copy_job "other-project:other_dataset.other_table"
1299
- #
1300
- # copy_job.wait_until_done!
1301
- # copy_job.done? #=> true
1975
+ # table.snapshot "other-project:other_dataset.other_table"
1302
1976
  #
1303
1977
  # @!group Data
1304
1978
  #
1305
- def copy_job destination_table, create: nil, write: nil, job_id: nil,
1306
- prefix: nil, labels: nil, dryrun: nil
1307
- ensure_service!
1308
- options = { create: create, write: write, dryrun: dryrun,
1309
- labels: labels, job_id: job_id, prefix: prefix }
1310
- updater = CopyJob::Updater.from_options(
1311
- service,
1312
- table_ref,
1313
- Service.get_table_ref(destination_table, default_ref: table_ref),
1314
- options
1315
- )
1316
- updater.location = location if location # may be table reference
1317
-
1318
- yield updater if block_given?
1319
-
1320
- job_gapi = updater.to_gapi
1321
- gapi = service.copy_table job_gapi
1322
- Job.from_gapi gapi, service
1979
+ def snapshot destination_table, &block
1980
+ copy_job_with_operation_type destination_table,
1981
+ operation_type: OperationType::SNAPSHOT,
1982
+ &block
1323
1983
  end
1324
1984
 
1325
1985
  ##
1326
- # Copies the data from the table to another table using a synchronous
1327
- # method that blocks for a response. Timeouts and transient errors are
1328
- # generally handled as needed to complete the job. See also
1329
- # {#copy_job}.
1986
+ # Restore the data from the table to another table using a synchronous
1987
+ # method that blocks for a response.
1988
+ # The source table type is SNAPSHOT and the destination table type is TABLE.
1989
+ # Timeouts and transient errors are generally handled as needed to complete the job.
1990
+ # See also {#copy_job}.
1330
1991
  #
1331
1992
  # The geographic location for the job ("US", "EU", etc.) can be set via
1332
1993
  # {CopyJob::Updater#location=} in a block passed to this method. If the
@@ -1373,7 +2034,7 @@ module Google
1373
2034
  # table = dataset.table "my_table"
1374
2035
  # destination_table = dataset.table "my_destination_table"
1375
2036
  #
1376
- # table.copy destination_table
2037
+ # table.restore destination_table
1377
2038
  #
1378
2039
  # @example Passing a string identifier for the destination table:
1379
2040
  # require "google/cloud/bigquery"
@@ -1382,15 +2043,16 @@ module Google
1382
2043
  # dataset = bigquery.dataset "my_dataset"
1383
2044
  # table = dataset.table "my_table"
1384
2045
  #
1385
- # table.copy "other-project:other_dataset.other_table"
2046
+ # table.restore "other-project:other_dataset.other_table"
1386
2047
  #
1387
2048
  # @!group Data
1388
2049
  #
1389
- def copy destination_table, create: nil, write: nil, &block
1390
- job = copy_job destination_table, create: create, write: write, &block
1391
- job.wait_until_done!
1392
- ensure_job_succeeded! job
1393
- true
2050
+ def restore destination_table, create: nil, write: nil, &block
2051
+ copy_job_with_operation_type destination_table,
2052
+ create: create,
2053
+ write: write,
2054
+ operation_type: OperationType::RESTORE,
2055
+ &block
1394
2056
  end
1395
2057
 
1396
2058
  ##
@@ -1404,11 +2066,11 @@ module Google
1404
2066
  # The geographic location for the job ("US", "EU", etc.) can be set via
1405
2067
  # {ExtractJob::Updater#location=} in a block passed to this method. If
1406
2068
  # the table is a full resource representation (see {#resource_full?}),
1407
- # the location of the job will be automatically set to the location of
2069
+ # the location of the job will automatically be set to the location of
1408
2070
  # the table.
1409
2071
  #
1410
- # @see https://cloud.google.com/bigquery/exporting-data-from-bigquery
1411
- # Exporting Data From BigQuery
2072
+ # @see https://cloud.google.com/bigquery/docs/exporting-data
2073
+ # Exporting table data
1412
2074
  #
1413
2075
  # @param [Google::Cloud::Storage::File, String, Array<String>]
1414
2076
  # extract_url The Google Storage file or file URI pattern(s) to which
@@ -1419,7 +2081,7 @@ module Google
1419
2081
  # The following values are supported:
1420
2082
  #
1421
2083
  # * `csv` - CSV
1422
- # * `json` - [Newline-delimited JSON](http://jsonlines.org/)
2084
+ # * `json` - [Newline-delimited JSON](https://jsonlines.org/)
1423
2085
  # * `avro` - [Avro](http://avro.apache.org/)
1424
2086
  # @param [String] compression The compression type to use for exported
1425
2087
  # files. Possible values include `GZIP` and `NONE`. The default value
@@ -1429,8 +2091,8 @@ module Google
1429
2091
  # @param [Boolean] header Whether to print out a header row in the
1430
2092
  # results. Default is `true`.
1431
2093
  # @param [String] job_id A user-defined ID for the extract job. The ID
1432
- # must contain only letters (a-z, A-Z), numbers (0-9), underscores
1433
- # (_), or dashes (-). The maximum length is 1,024 characters. If
2094
+ # must contain only letters (`[A-Za-z]`), numbers (`[0-9]`), underscores
2095
+ # (`_`), or dashes (`-`). The maximum length is 1,024 characters. If
1434
2096
  # `job_id` is provided, then `prefix` will not be used.
1435
2097
  #
1436
2098
  # See [Generating a job
@@ -1439,18 +2101,26 @@ module Google
1439
2101
  # prepended to a generated value to produce a unique job ID. For
1440
2102
  # example, the prefix `daily_import_job_` can be given to generate a
1441
2103
  # job ID such as `daily_import_job_12vEDtMQ0mbp1Mo5Z7mzAFQJZazh`. The
1442
- # prefix must contain only letters (a-z, A-Z), numbers (0-9),
1443
- # underscores (_), or dashes (-). The maximum length of the entire ID
2104
+ # prefix must contain only letters (`[A-Za-z]`), numbers (`[0-9]`),
2105
+ # underscores (`_`), or dashes (`-`). The maximum length of the entire ID
1444
2106
  # is 1,024 characters. If `job_id` is provided, then `prefix` will not
1445
2107
  # be used.
1446
2108
  # @param [Hash] labels A hash of user-provided labels associated with
1447
- # the job. You can use these to organize and group your jobs. Label
1448
- # keys and values can be no longer than 63 characters, can only
1449
- # contain lowercase letters, numeric characters, underscores and
1450
- # dashes. International characters are allowed. Label values are
1451
- # optional. Label keys must start with a letter and each label in the
1452
- # list must have a different key. See [Requirements for
1453
- # labels](https://cloud.google.com/bigquery/docs/creating-managing-labels#requirements).
2109
+ # the job. You can use these to organize and group your jobs.
2110
+ #
2111
+ # The labels applied to a resource must meet the following requirements:
2112
+ #
2113
+ # * Each resource can have multiple labels, up to a maximum of 64.
2114
+ # * Each label must be a key-value pair.
2115
+ # * Keys have a minimum length of 1 character and a maximum length of
2116
+ # 63 characters, and cannot be empty. Values can be empty, and have
2117
+ # a maximum length of 63 characters.
2118
+ # * Keys and values can contain only lowercase letters, numeric characters,
2119
+ # underscores, and dashes. All characters must use UTF-8 encoding, and
2120
+ # international characters are allowed.
2121
+ # * The key portion of a label must be unique. However, you can use the
2122
+ # same key with multiple resources.
2123
+ # * Keys must start with a lowercase letter or international character.
1454
2124
  # @param [Boolean] dryrun If set, don't actually run this job. Behavior
1455
2125
  # is undefined however for non-query jobs and may result in an error.
1456
2126
  # Deprecated.
@@ -1475,15 +2145,12 @@ module Google
1475
2145
  #
1476
2146
  # @!group Data
1477
2147
  #
1478
- def extract_job extract_url, format: nil, compression: nil,
1479
- delimiter: nil, header: nil, job_id: nil, prefix: nil,
1480
- labels: nil, dryrun: nil
2148
+ def extract_job extract_url, format: nil, compression: nil, delimiter: nil, header: nil, job_id: nil,
2149
+ prefix: nil, labels: nil, dryrun: nil
1481
2150
  ensure_service!
1482
- options = { format: format, compression: compression,
1483
- delimiter: delimiter, header: header, dryrun: dryrun,
2151
+ options = { format: format, compression: compression, delimiter: delimiter, header: header, dryrun: dryrun,
1484
2152
  job_id: job_id, prefix: prefix, labels: labels }
1485
- updater = ExtractJob::Updater.from_options service, table_ref,
1486
- extract_url, options
2153
+ updater = ExtractJob::Updater.from_options service, table_ref, extract_url, options
1487
2154
  updater.location = location if location # may be table reference
1488
2155
 
1489
2156
  yield updater if block_given?
@@ -1505,8 +2172,8 @@ module Google
1505
2172
  # the location of the job will be automatically set to the location of
1506
2173
  # the table.
1507
2174
  #
1508
- # @see https://cloud.google.com/bigquery/exporting-data-from-bigquery
1509
- # Exporting Data From BigQuery
2175
+ # @see https://cloud.google.com/bigquery/docs/exporting-data
2176
+ # Exporting table data
1510
2177
  #
1511
2178
  # @param [Google::Cloud::Storage::File, String, Array<String>]
1512
2179
  # extract_url The Google Storage file or file URI pattern(s) to which
@@ -1517,7 +2184,7 @@ module Google
1517
2184
  # The following values are supported:
1518
2185
  #
1519
2186
  # * `csv` - CSV
1520
- # * `json` - [Newline-delimited JSON](http://jsonlines.org/)
2187
+ # * `json` - [Newline-delimited JSON](https://jsonlines.org/)
1521
2188
  # * `avro` - [Avro](http://avro.apache.org/)
1522
2189
  # @param [String] compression The compression type to use for exported
1523
2190
  # files. Possible values include `GZIP` and `NONE`. The default value
@@ -1554,8 +2221,7 @@ module Google
1554
2221
  #
1555
2222
  # @!group Data
1556
2223
  #
1557
- def extract extract_url, format: nil, compression: nil, delimiter: nil,
1558
- header: nil, &block
2224
+ def extract extract_url, format: nil, compression: nil, delimiter: nil, header: nil, &block
1559
2225
  job = extract_job extract_url,
1560
2226
  format: format,
1561
2227
  compression: compression,
@@ -1589,7 +2255,7 @@ module Google
1589
2255
  # The following values are supported:
1590
2256
  #
1591
2257
  # * `csv` - CSV
1592
- # * `json` - [Newline-delimited JSON](http://jsonlines.org/)
2258
+ # * `json` - [Newline-delimited JSON](https://jsonlines.org/)
1593
2259
  # * `avro` - [Avro](http://avro.apache.org/)
1594
2260
  # * `orc` - [ORC](https://cloud.google.com/bigquery/docs/loading-data-cloud-storage-orc)
1595
2261
  # * `parquet` - [Parquet](https://parquet.apache.org/)
@@ -1673,8 +2339,8 @@ module Google
1673
2339
  # value is `0`. This property is useful if you have header rows in the
1674
2340
  # file that should be skipped.
1675
2341
  # @param [String] job_id A user-defined ID for the load job. The ID
1676
- # must contain only letters (a-z, A-Z), numbers (0-9), underscores
1677
- # (_), or dashes (-). The maximum length is 1,024 characters. If
2342
+ # must contain only letters (`[A-Za-z]`), numbers (`[0-9]`), underscores
2343
+ # (`_`), or dashes (`-`). The maximum length is 1,024 characters. If
1678
2344
  # `job_id` is provided, then `prefix` will not be used.
1679
2345
  #
1680
2346
  # See [Generating a job
@@ -1683,18 +2349,26 @@ module Google
1683
2349
  # prepended to a generated value to produce a unique job ID. For
1684
2350
  # example, the prefix `daily_import_job_` can be given to generate a
1685
2351
  # job ID such as `daily_import_job_12vEDtMQ0mbp1Mo5Z7mzAFQJZazh`. The
1686
- # prefix must contain only letters (a-z, A-Z), numbers (0-9),
1687
- # underscores (_), or dashes (-). The maximum length of the entire ID
2352
+ # prefix must contain only letters (`[A-Za-z]`), numbers (`[0-9]`),
2353
+ # underscores (`_`), or dashes (`-`). The maximum length of the entire ID
1688
2354
  # is 1,024 characters. If `job_id` is provided, then `prefix` will not
1689
2355
  # be used.
1690
2356
  # @param [Hash] labels A hash of user-provided labels associated with
1691
- # the job. You can use these to organize and group your jobs. Label
1692
- # keys and values can be no longer than 63 characters, can only
1693
- # contain lowercase letters, numeric characters, underscores and
1694
- # dashes. International characters are allowed. Label values are
1695
- # optional. Label keys must start with a letter and each label in the
1696
- # list must have a different key. See [Requirements for
1697
- # labels](https://cloud.google.com/bigquery/docs/creating-managing-labels#requirements).
2357
+ # the job. You can use these to organize and group your jobs.
2358
+ #
2359
+ # The labels applied to a resource must meet the following requirements:
2360
+ #
2361
+ # * Each resource can have multiple labels, up to a maximum of 64.
2362
+ # * Each label must be a key-value pair.
2363
+ # * Keys have a minimum length of 1 character and a maximum length of
2364
+ # 63 characters, and cannot be empty. Values can be empty, and have
2365
+ # a maximum length of 63 characters.
2366
+ # * Keys and values can contain only lowercase letters, numeric characters,
2367
+ # underscores, and dashes. All characters must use UTF-8 encoding, and
2368
+ # international characters are allowed.
2369
+ # * The key portion of a label must be unique. However, you can use the
2370
+ # same key with multiple resources.
2371
+ # * Keys must start with a lowercase letter or international character.
1698
2372
  # @param [Boolean] dryrun If set, don't actually run this job. Behavior
1699
2373
  # is undefined however for non-query jobs and may result in an error.
1700
2374
  # Deprecated.
@@ -1751,28 +2425,18 @@ module Google
1751
2425
  #
1752
2426
  # @!group Data
1753
2427
  #
1754
- def load_job files, format: nil, create: nil, write: nil,
1755
- projection_fields: nil, jagged_rows: nil,
1756
- quoted_newlines: nil, encoding: nil, delimiter: nil,
1757
- ignore_unknown: nil, max_bad_records: nil, quote: nil,
1758
- skip_leading: nil, job_id: nil, prefix: nil, labels: nil,
1759
- autodetect: nil, null_marker: nil, dryrun: nil
2428
+ def load_job files, format: nil, create: nil, write: nil, projection_fields: nil, jagged_rows: nil,
2429
+ quoted_newlines: nil, encoding: nil, delimiter: nil, ignore_unknown: nil, max_bad_records: nil,
2430
+ quote: nil, skip_leading: nil, job_id: nil, prefix: nil, labels: nil, autodetect: nil,
2431
+ null_marker: nil, dryrun: nil
1760
2432
  ensure_service!
1761
2433
 
1762
- updater = load_job_updater format: format, create: create,
1763
- write: write,
1764
- projection_fields: projection_fields,
1765
- jagged_rows: jagged_rows,
1766
- quoted_newlines: quoted_newlines,
1767
- encoding: encoding,
1768
- delimiter: delimiter,
1769
- ignore_unknown: ignore_unknown,
1770
- max_bad_records: max_bad_records,
1771
- quote: quote, skip_leading: skip_leading,
1772
- dryrun: dryrun, job_id: job_id,
1773
- prefix: prefix, schema: schema,
1774
- labels: labels, autodetect: autodetect,
1775
- null_marker: null_marker
2434
+ updater = load_job_updater format: format, create: create, write: write, projection_fields: projection_fields,
2435
+ jagged_rows: jagged_rows, quoted_newlines: quoted_newlines, encoding: encoding,
2436
+ delimiter: delimiter, ignore_unknown: ignore_unknown,
2437
+ max_bad_records: max_bad_records, quote: quote, skip_leading: skip_leading,
2438
+ dryrun: dryrun, job_id: job_id, prefix: prefix, schema: schema, labels: labels,
2439
+ autodetect: autodetect, null_marker: null_marker
1776
2440
 
1777
2441
  yield updater if block_given?
1778
2442
 
@@ -1804,7 +2468,7 @@ module Google
1804
2468
  # The following values are supported:
1805
2469
  #
1806
2470
  # * `csv` - CSV
1807
- # * `json` - [Newline-delimited JSON](http://jsonlines.org/)
2471
+ # * `json` - [Newline-delimited JSON](https://jsonlines.org/)
1808
2472
  # * `avro` - [Avro](http://avro.apache.org/)
1809
2473
  # * `orc` - [ORC](https://cloud.google.com/bigquery/docs/loading-data-cloud-storage-orc)
1810
2474
  # * `parquet` - [Parquet](https://parquet.apache.org/)
@@ -1946,20 +2610,13 @@ module Google
1946
2610
  #
1947
2611
  # @!group Data
1948
2612
  #
1949
- def load files, format: nil, create: nil, write: nil,
1950
- projection_fields: nil, jagged_rows: nil, quoted_newlines: nil,
1951
- encoding: nil, delimiter: nil, ignore_unknown: nil,
1952
- max_bad_records: nil, quote: nil, skip_leading: nil,
1953
- autodetect: nil, null_marker: nil, &block
1954
- job = load_job files, format: format, create: create, write: write,
1955
- projection_fields: projection_fields,
1956
- jagged_rows: jagged_rows,
1957
- quoted_newlines: quoted_newlines,
1958
- encoding: encoding, delimiter: delimiter,
1959
- ignore_unknown: ignore_unknown,
1960
- max_bad_records: max_bad_records,
1961
- quote: quote, skip_leading: skip_leading,
1962
- autodetect: autodetect,
2613
+ def load files, format: nil, create: nil, write: nil, projection_fields: nil, jagged_rows: nil,
2614
+ quoted_newlines: nil, encoding: nil, delimiter: nil, ignore_unknown: nil, max_bad_records: nil,
2615
+ quote: nil, skip_leading: nil, autodetect: nil, null_marker: nil, &block
2616
+ job = load_job files, format: format, create: create, write: write, projection_fields: projection_fields,
2617
+ jagged_rows: jagged_rows, quoted_newlines: quoted_newlines, encoding: encoding,
2618
+ delimiter: delimiter, ignore_unknown: ignore_unknown, max_bad_records: max_bad_records,
2619
+ quote: quote, skip_leading: skip_leading, autodetect: autodetect,
1963
2620
  null_marker: null_marker, &block
1964
2621
 
1965
2622
  job.wait_until_done!
@@ -1972,17 +2629,48 @@ module Google
1972
2629
  # need to complete a load operation before the data can appear in query
1973
2630
  # results.
1974
2631
  #
2632
+ # Simple Ruby types are generally accepted per JSON rules, along with the following support for BigQuery's more
2633
+ # complex types:
2634
+ #
2635
+ # | BigQuery | Ruby | Notes |
2636
+ # |--------------|--------------------------------------|----------------------------------------------------|
2637
+ # | `NUMERIC` | `BigDecimal` | `BigDecimal` values will be rounded to scale 9. |
2638
+ # | `BIGNUMERIC` | `String` | Pass as `String` to avoid rounding to scale 9. |
2639
+ # | `DATETIME` | `DateTime` | `DATETIME` does not support time zone. |
2640
+ # | `DATE` | `Date` | |
2641
+ # | `GEOGRAPHY` | `String` | Well-known text (WKT) or GeoJSON. |
2642
+ # | `TIMESTAMP` | `Time` | |
2643
+ # | `TIME` | `Google::Cloud::BigQuery::Time` | |
2644
+ # | `BYTES` | `File`, `IO`, `StringIO`, or similar | |
2645
+ # | `ARRAY` | `Array` | Nested arrays, `nil` values are not supported. |
2646
+ # | `STRUCT` | `Hash` | Hash keys may be strings or symbols. |
2647
+ #
2648
+ # For `GEOGRAPHY` data, see [Working with BigQuery GIS data](https://cloud.google.com/bigquery/docs/gis-data).
2649
+ #
2650
+ # Because BigQuery's streaming API is designed for high insertion rates,
2651
+ # modifications to the underlying table metadata are eventually
2652
+ # consistent when interacting with the streaming system. In most cases
2653
+ # metadata changes are propagated within minutes, but during this period
2654
+ # API responses may reflect the inconsistent state of the table.
2655
+ #
1975
2656
  # @see https://cloud.google.com/bigquery/streaming-data-into-bigquery
1976
2657
  # Streaming Data Into BigQuery
1977
2658
  #
2659
+ # @see https://cloud.google.com/bigquery/troubleshooting-errors#metadata-errors-for-streaming-inserts
2660
+ # BigQuery Troubleshooting: Metadata errors for streaming inserts
2661
+ #
1978
2662
  # @param [Hash, Array<Hash>] rows A hash object or array of hash objects
1979
- # containing the data. Required.
1980
- # @param [Array<String>] insert_ids A unique ID for each row. BigQuery
1981
- # uses this property to detect duplicate insertion requests on a
1982
- # best-effort basis. For more information, see [data
1983
- # consistency](https://cloud.google.com/bigquery/streaming-data-into-bigquery#dataconsistency).
1984
- # Optional. If not provided, the client library will assign a UUID to
1985
- # each row before the request is sent.
2663
+ # containing the data. Required. `BigDecimal` values will be rounded to
2664
+ # scale 9 to conform with the BigQuery `NUMERIC` data type. To avoid
2665
+ # rounding `BIGNUMERIC` type values with scale greater than 9, use `String`
2666
+ # instead of `BigDecimal`.
2667
+ # @param [Array<String|Symbol>, Symbol] insert_ids A unique ID for each row. BigQuery uses this property to
2668
+ # detect duplicate insertion requests on a best-effort basis. For more information, see [data
2669
+ # consistency](https://cloud.google.com/bigquery/streaming-data-into-bigquery#dataconsistency). Optional. If
2670
+ # not provided, the client library will assign a UUID to each row before the request is sent.
2671
+ #
2672
+ # The value `:skip` can be provided to skip the generation of IDs for all rows, or to skip the generation of an
2673
+ # ID for a specific row in the array.
1986
2674
  # @param [Boolean] skip_invalid Insert all valid rows of a request, even
1987
2675
  # if invalid rows exist. The default value is `false`, which causes
1988
2676
  # the entire request to fail if any invalid rows exist.
@@ -2018,21 +2706,38 @@ module Google
2018
2706
  # ]
2019
2707
  # table.insert rows
2020
2708
  #
2709
+ # @example Pass `BIGNUMERIC` value as a string to avoid rounding to scale 9 in the conversion from `BigDecimal`:
2710
+ # require "google/cloud/bigquery"
2711
+ #
2712
+ # bigquery = Google::Cloud::Bigquery.new
2713
+ # dataset = bigquery.dataset "my_dataset"
2714
+ # table = dataset.table "my_table"
2715
+ #
2716
+ # row = {
2717
+ # "my_numeric" => BigDecimal("123456798.987654321"),
2718
+ # "my_bignumeric" => "123456798.98765432100001" # BigDecimal would be rounded, use String instead!
2719
+ # }
2720
+ # table.insert row
2721
+ #
2021
2722
  # @!group Data
2022
2723
  #
2023
2724
  def insert rows, insert_ids: nil, skip_invalid: nil, ignore_unknown: nil
2024
2725
  rows = [rows] if rows.is_a? Hash
2726
+ raise ArgumentError, "No rows provided" if rows.empty?
2727
+
2728
+ insert_ids = Array.new(rows.count) { :skip } if insert_ids == :skip
2025
2729
  insert_ids = Array insert_ids
2026
- if insert_ids.count > 0 && insert_ids.count != rows.count
2730
+ if insert_ids.count.positive? && insert_ids.count != rows.count
2027
2731
  raise ArgumentError, "insert_ids must be the same size as rows"
2028
2732
  end
2029
- rows = [rows] if rows.is_a? Hash
2030
- raise ArgumentError, "No rows provided" if rows.empty?
2733
+
2031
2734
  ensure_service!
2032
- options = { skip_invalid: skip_invalid,
2033
- ignore_unknown: ignore_unknown,
2034
- insert_ids: insert_ids }
2035
- gapi = service.insert_tabledata dataset_id, table_id, rows, options
2735
+ gapi = service.insert_tabledata dataset_id,
2736
+ table_id,
2737
+ rows,
2738
+ skip_invalid: skip_invalid,
2739
+ ignore_unknown: ignore_unknown,
2740
+ insert_ids: insert_ids
2036
2741
  InsertResponse.from_gapi rows, gapi
2037
2742
  end
2038
2743
 
@@ -2083,15 +2788,12 @@ module Google
2083
2788
  #
2084
2789
  # inserter.stop.wait!
2085
2790
  #
2086
- def insert_async skip_invalid: nil, ignore_unknown: nil,
2087
- max_bytes: 10000000, max_rows: 500, interval: 10,
2791
+ def insert_async skip_invalid: nil, ignore_unknown: nil, max_bytes: 10_000_000, max_rows: 500, interval: 10,
2088
2792
  threads: 4, &block
2089
2793
  ensure_service!
2090
2794
 
2091
- AsyncInserter.new self, skip_invalid: skip_invalid,
2092
- ignore_unknown: ignore_unknown,
2093
- max_bytes: max_bytes, max_rows: max_rows,
2094
- interval: interval, threads: threads, &block
2795
+ AsyncInserter.new self, skip_invalid: skip_invalid, ignore_unknown: ignore_unknown, max_bytes: max_bytes,
2796
+ max_rows: max_rows, interval: interval, threads: threads, &block
2095
2797
  end
2096
2798
 
2097
2799
  ##
@@ -2138,7 +2840,7 @@ module Google
2138
2840
  #
2139
2841
  def reload!
2140
2842
  ensure_service!
2141
- @gapi = service.get_table dataset_id, table_id
2843
+ @gapi = service.get_table dataset_id, table_id, metadata_view: metadata_view
2142
2844
  @reference = nil
2143
2845
  @exists = nil
2144
2846
  self
@@ -2166,7 +2868,7 @@ module Google
2166
2868
  # table = dataset.table "my_table", skip_lookup: true
2167
2869
  # table.exists? # true
2168
2870
  #
2169
- def exists? force: nil
2871
+ def exists? force: false
2170
2872
  return gapi_exists? if force
2171
2873
  # If we have a value, return it
2172
2874
  return @exists unless @exists.nil?
@@ -2272,15 +2974,16 @@ module Google
2272
2974
 
2273
2975
  ##
2274
2976
  # @private New Table from a Google API Client object.
2275
- def self.from_gapi gapi, service
2977
+ def self.from_gapi gapi, service, metadata_view: nil
2276
2978
  new.tap do |f|
2277
2979
  f.gapi = gapi
2278
2980
  f.service = service
2981
+ f.metadata_view = metadata_view
2279
2982
  end
2280
2983
  end
2281
2984
 
2282
2985
  ##
2283
- # @private New lazy Table object without making an HTTP request.
2986
+ # @private New lazy Table object without making an HTTP request, for use with the skip_lookup option.
2284
2987
  def self.new_reference project_id, dataset_id, table_id, service
2285
2988
  raise ArgumentError, "dataset_id is required" unless dataset_id
2286
2989
  raise ArgumentError, "table_id is required" unless table_id
@@ -2306,6 +3009,17 @@ module Google
2306
3009
 
2307
3010
  protected
2308
3011
 
3012
+ def copy_job_with_operation_type destination_table, create: nil, write: nil, operation_type: nil, &block
3013
+ job = copy_job destination_table,
3014
+ create: create,
3015
+ write: write,
3016
+ operation_type: operation_type,
3017
+ &block
3018
+ job.wait_until_done!
3019
+ ensure_job_succeeded! job
3020
+ true
3021
+ end
3022
+
2309
3023
  ##
2310
3024
  # Raise an error unless an active service is available.
2311
3025
  def ensure_service!
@@ -2333,10 +3047,8 @@ module Google
2333
3047
  def patch_gapi! *attributes
2334
3048
  return if attributes.empty?
2335
3049
  ensure_service!
2336
- patch_args = Hash[attributes.map do |attr|
2337
- [attr, @gapi.send(attr)]
2338
- end]
2339
- patch_gapi = Google::Apis::BigqueryV2::Table.new patch_args
3050
+ patch_args = attributes.to_h { |attr| [attr, @gapi.send(attr)] }
3051
+ patch_gapi = Google::Apis::BigqueryV2::Table.new(**patch_args)
2340
3052
  patch_gapi.etag = etag if etag
2341
3053
  @gapi = service.patch_table dataset_id, table_id, patch_gapi
2342
3054
 
@@ -2373,11 +3085,8 @@ module Google
2373
3085
  )
2374
3086
  end
2375
3087
 
2376
- def load_job_csv_options! job, jagged_rows: nil,
2377
- quoted_newlines: nil,
2378
- delimiter: nil,
2379
- quote: nil, skip_leading: nil,
2380
- null_marker: nil
3088
+ def load_job_csv_options! job, jagged_rows: nil, quoted_newlines: nil, delimiter: nil, quote: nil,
3089
+ skip_leading: nil, null_marker: nil
2381
3090
  job.jagged_rows = jagged_rows unless jagged_rows.nil?
2382
3091
  job.quoted_newlines = quoted_newlines unless quoted_newlines.nil?
2383
3092
  job.delimiter = delimiter unless delimiter.nil?
@@ -2386,17 +3095,11 @@ module Google
2386
3095
  job.skip_leading = skip_leading unless skip_leading.nil?
2387
3096
  end
2388
3097
 
2389
- def load_job_file_options! job, format: nil,
2390
- projection_fields: nil,
2391
- jagged_rows: nil, quoted_newlines: nil,
2392
- encoding: nil, delimiter: nil,
2393
- ignore_unknown: nil, max_bad_records: nil,
2394
- quote: nil, skip_leading: nil,
2395
- null_marker: nil
3098
+ def load_job_file_options! job, format: nil, projection_fields: nil, jagged_rows: nil, quoted_newlines: nil,
3099
+ encoding: nil, delimiter: nil, ignore_unknown: nil, max_bad_records: nil, quote: nil,
3100
+ skip_leading: nil, null_marker: nil
2396
3101
  job.format = format unless format.nil?
2397
- unless projection_fields.nil?
2398
- job.projection_fields = projection_fields
2399
- end
3102
+ job.projection_fields = projection_fields unless projection_fields.nil?
2400
3103
  job.encoding = encoding unless encoding.nil?
2401
3104
  job.ignore_unknown = ignore_unknown unless ignore_unknown.nil?
2402
3105
  job.max_bad_records = max_bad_records unless max_bad_records.nil?
@@ -2408,16 +3111,11 @@ module Google
2408
3111
  null_marker: null_marker
2409
3112
  end
2410
3113
 
2411
- def load_job_updater format: nil, create: nil,
2412
- write: nil, projection_fields: nil,
2413
- jagged_rows: nil, quoted_newlines: nil,
2414
- encoding: nil, delimiter: nil,
2415
- ignore_unknown: nil, max_bad_records: nil,
2416
- quote: nil, skip_leading: nil, dryrun: nil,
2417
- schema: nil, job_id: nil, prefix: nil, labels: nil,
2418
- autodetect: nil, null_marker: nil
2419
- new_job = load_job_gapi table_id, dryrun, job_id: job_id,
2420
- prefix: prefix
3114
+ def load_job_updater format: nil, create: nil, write: nil, projection_fields: nil, jagged_rows: nil,
3115
+ quoted_newlines: nil, encoding: nil, delimiter: nil, ignore_unknown: nil,
3116
+ max_bad_records: nil, quote: nil, skip_leading: nil, dryrun: nil, schema: nil, job_id: nil,
3117
+ prefix: nil, labels: nil, autodetect: nil, null_marker: nil
3118
+ new_job = load_job_gapi table_id, dryrun, job_id: job_id, prefix: prefix
2421
3119
  LoadJob::Updater.new(new_job).tap do |job|
2422
3120
  job.location = location if location # may be table reference
2423
3121
  job.create = create unless create.nil?
@@ -2455,9 +3153,7 @@ module Google
2455
3153
  job_gapi.configuration.load.update! source_uris: urls
2456
3154
  if job_gapi.configuration.load.source_format.nil?
2457
3155
  source_format = Convert.derive_source_format_from_list urls
2458
- unless source_format.nil?
2459
- job_gapi.configuration.load.source_format = source_format
2460
- end
3156
+ job_gapi.configuration.load.source_format = source_format unless source_format.nil?
2461
3157
  end
2462
3158
  end
2463
3159
 
@@ -2469,9 +3165,7 @@ module Google
2469
3165
  path = Pathname(file).to_path
2470
3166
  if job_gapi.configuration.load.source_format.nil?
2471
3167
  source_format = Convert.derive_source_format path
2472
- unless source_format.nil?
2473
- job_gapi.configuration.load.source_format = source_format
2474
- end
3168
+ job_gapi.configuration.load.source_format = source_format unless source_format.nil?
2475
3169
  end
2476
3170
 
2477
3171
  gapi = service.load_table_file file, job_gapi
@@ -2480,21 +3174,18 @@ module Google
2480
3174
 
2481
3175
  def load_local_or_uri file, updater
2482
3176
  job_gapi = updater.to_gapi
2483
- job = if local_file? file
2484
- load_local file, job_gapi
2485
- else
2486
- load_storage file, job_gapi
2487
- end
2488
- job
3177
+ if local_file? file
3178
+ load_local file, job_gapi
3179
+ else
3180
+ load_storage file, job_gapi
3181
+ end
2489
3182
  end
2490
3183
 
2491
3184
  def storage_url? files
2492
3185
  [files].flatten.all? do |file|
2493
3186
  file.respond_to?(:to_gs_url) ||
2494
- (file.respond_to?(:to_str) &&
2495
- file.to_str.downcase.start_with?("gs://")) ||
2496
- (file.is_a?(URI) &&
2497
- file.to_s.downcase.start_with?("gs://"))
3187
+ (file.respond_to?(:to_str) && file.to_str.downcase.start_with?("gs://")) ||
3188
+ (file.is_a?(URI) && file.to_s.downcase.start_with?("gs://"))
2498
3189
  end
2499
3190
  end
2500
3191
 
@@ -2531,42 +3222,200 @@ module Google
2531
3222
  end
2532
3223
 
2533
3224
  ##
2534
- # Yielded to a block to accumulate changes for a patch request.
3225
+ # Yielded to a block to accumulate changes for a create request. See {Dataset#create_table}.
2535
3226
  class Updater < Table
2536
3227
  ##
2537
- # A list of attributes that were updated.
3228
+ # @private A list of attributes that were updated.
2538
3229
  attr_reader :updates
2539
3230
 
2540
3231
  ##
2541
- # Create an Updater object.
3232
+ # @private Create an Updater object.
2542
3233
  def initialize gapi
3234
+ super()
2543
3235
  @updates = []
2544
3236
  @gapi = gapi
2545
3237
  @schema = nil
2546
3238
  end
2547
3239
 
2548
3240
  ##
2549
- # Sets one or more fields on which data should be clustered. Must be
2550
- # specified with time-based partitioning, data in the table will be
2551
- # first partitioned and subsequently clustered.
3241
+ # Sets the field on which to range partition the table. See [Creating and using integer range partitioned
3242
+ # tables](https://cloud.google.com/bigquery/docs/creating-integer-range-partitions).
3243
+ #
3244
+ # See {Table::Updater#range_partitioning_start=}, {Table::Updater#range_partitioning_interval=} and
3245
+ # {Table::Updater#range_partitioning_end=}.
3246
+ #
3247
+ # You can only set range partitioning when creating a table as in the example below. BigQuery does not allow
3248
+ # you to change partitioning on an existing table.
3249
+ #
3250
+ # @param [String] field The range partition field. The table is partitioned by this
3251
+ # field. The field must be a top-level `NULLABLE/REQUIRED` field. The only supported
3252
+ # type is `INTEGER/INT64`.
3253
+ #
3254
+ # @example
3255
+ # require "google/cloud/bigquery"
3256
+ #
3257
+ # bigquery = Google::Cloud::Bigquery.new
3258
+ # dataset = bigquery.dataset "my_dataset"
3259
+ #
3260
+ # table = dataset.create_table "my_table" do |t|
3261
+ # t.schema do |schema|
3262
+ # schema.integer "my_table_id", mode: :required
3263
+ # schema.string "my_table_data", mode: :required
3264
+ # end
3265
+ # t.range_partitioning_field = "my_table_id"
3266
+ # t.range_partitioning_start = 0
3267
+ # t.range_partitioning_interval = 10
3268
+ # t.range_partitioning_end = 100
3269
+ # end
3270
+ #
3271
+ # @!group Attributes
3272
+ #
3273
+ def range_partitioning_field= field
3274
+ reload! unless resource_full?
3275
+ @gapi.range_partitioning ||= Google::Apis::BigqueryV2::RangePartitioning.new(
3276
+ range: Google::Apis::BigqueryV2::RangePartitioning::Range.new
3277
+ )
3278
+ @gapi.range_partitioning.field = field
3279
+ patch_gapi! :range_partitioning
3280
+ end
3281
+
3282
+ ##
3283
+ # Sets the start of range partitioning, inclusive, for the table. See [Creating and using integer range
3284
+ # partitioned tables](https://cloud.google.com/bigquery/docs/creating-integer-range-partitions).
3285
+ #
3286
+ # You can only set range partitioning when creating a table as in the example below. BigQuery does not allow
3287
+ # you to change partitioning on an existing table.
3288
+ #
3289
+ # See {Table::Updater#range_partitioning_field=}, {Table::Updater#range_partitioning_interval=} and
3290
+ # {Table::Updater#range_partitioning_end=}.
3291
+ #
3292
+ # @param [Integer] range_start The start of range partitioning, inclusive.
3293
+ #
3294
+ # @example
3295
+ # require "google/cloud/bigquery"
3296
+ #
3297
+ # bigquery = Google::Cloud::Bigquery.new
3298
+ # dataset = bigquery.dataset "my_dataset"
3299
+ #
3300
+ # table = dataset.create_table "my_table" do |t|
3301
+ # t.schema do |schema|
3302
+ # schema.integer "my_table_id", mode: :required
3303
+ # schema.string "my_table_data", mode: :required
3304
+ # end
3305
+ # t.range_partitioning_field = "my_table_id"
3306
+ # t.range_partitioning_start = 0
3307
+ # t.range_partitioning_interval = 10
3308
+ # t.range_partitioning_end = 100
3309
+ # end
3310
+ #
3311
+ # @!group Attributes
3312
+ #
3313
+ def range_partitioning_start= range_start
3314
+ reload! unless resource_full?
3315
+ @gapi.range_partitioning ||= Google::Apis::BigqueryV2::RangePartitioning.new(
3316
+ range: Google::Apis::BigqueryV2::RangePartitioning::Range.new
3317
+ )
3318
+ @gapi.range_partitioning.range.start = range_start
3319
+ patch_gapi! :range_partitioning
3320
+ end
3321
+
3322
+ ##
3323
+ # Sets width of each interval for data in range partitions. See [Creating and using integer range partitioned
3324
+ # tables](https://cloud.google.com/bigquery/docs/creating-integer-range-partitions).
3325
+ #
3326
+ # You can only set range partitioning when creating a table as in the example below. BigQuery does not allow
3327
+ # you to change partitioning on an existing table.
3328
+ #
3329
+ # See {Table::Updater#range_partitioning_field=}, {Table::Updater#range_partitioning_start=} and
3330
+ # {Table::Updater#range_partitioning_end=}.
3331
+ #
3332
+ # @param [Integer] range_interval The width of each interval, for data in partitions.
3333
+ #
3334
+ # @example
3335
+ # require "google/cloud/bigquery"
3336
+ #
3337
+ # bigquery = Google::Cloud::Bigquery.new
3338
+ # dataset = bigquery.dataset "my_dataset"
3339
+ #
3340
+ # table = dataset.create_table "my_table" do |t|
3341
+ # t.schema do |schema|
3342
+ # schema.integer "my_table_id", mode: :required
3343
+ # schema.string "my_table_data", mode: :required
3344
+ # end
3345
+ # t.range_partitioning_field = "my_table_id"
3346
+ # t.range_partitioning_start = 0
3347
+ # t.range_partitioning_interval = 10
3348
+ # t.range_partitioning_end = 100
3349
+ # end
3350
+ #
3351
+ # @!group Attributes
3352
+ #
3353
+ def range_partitioning_interval= range_interval
3354
+ reload! unless resource_full?
3355
+ @gapi.range_partitioning ||= Google::Apis::BigqueryV2::RangePartitioning.new(
3356
+ range: Google::Apis::BigqueryV2::RangePartitioning::Range.new
3357
+ )
3358
+ @gapi.range_partitioning.range.interval = range_interval
3359
+ patch_gapi! :range_partitioning
3360
+ end
3361
+
3362
+ ##
3363
+ # Sets the end of range partitioning, exclusive, for the table. See [Creating and using integer range
3364
+ # partitioned tables](https://cloud.google.com/bigquery/docs/creating-integer-range-partitions).
3365
+ #
3366
+ # You can only set range partitioning when creating a table as in the example below. BigQuery does not allow
3367
+ # you to change partitioning on an existing table.
3368
+ #
3369
+ # See {Table::Updater#range_partitioning_start=}, {Table::Updater#range_partitioning_interval=} and
3370
+ # {Table::Updater#range_partitioning_field=}.
3371
+ #
3372
+ # @param [Integer] range_end The end of range partitioning, exclusive.
3373
+ #
3374
+ # @example
3375
+ # require "google/cloud/bigquery"
3376
+ #
3377
+ # bigquery = Google::Cloud::Bigquery.new
3378
+ # dataset = bigquery.dataset "my_dataset"
3379
+ #
3380
+ # table = dataset.create_table "my_table" do |t|
3381
+ # t.schema do |schema|
3382
+ # schema.integer "my_table_id", mode: :required
3383
+ # schema.string "my_table_data", mode: :required
3384
+ # end
3385
+ # t.range_partitioning_field = "my_table_id"
3386
+ # t.range_partitioning_start = 0
3387
+ # t.range_partitioning_interval = 10
3388
+ # t.range_partitioning_end = 100
3389
+ # end
3390
+ #
3391
+ # @!group Attributes
3392
+ #
3393
+ def range_partitioning_end= range_end
3394
+ reload! unless resource_full?
3395
+ @gapi.range_partitioning ||= Google::Apis::BigqueryV2::RangePartitioning.new(
3396
+ range: Google::Apis::BigqueryV2::RangePartitioning::Range.new
3397
+ )
3398
+ @gapi.range_partitioning.range.end = range_end
3399
+ patch_gapi! :range_partitioning
3400
+ end
3401
+
3402
+ ##
3403
+ # Sets the list of fields on which data should be clustered.
2552
3404
  #
2553
3405
  # Only top-level, non-repeated, simple-type fields are supported. When
2554
3406
  # you cluster a table using multiple columns, the order of columns you
2555
3407
  # specify is important. The order of the specified columns determines
2556
3408
  # the sort order of the data.
2557
3409
  #
2558
- # You can only set the clustering fields while creating a table as in
2559
- # the example below. BigQuery does not allow you to change clustering
2560
- # on an existing table.
3410
+ # BigQuery supports clustering for both partitioned and non-partitioned
3411
+ # tables.
2561
3412
  #
2562
- # See {Table#clustering_fields}.
3413
+ # See {Table#clustering_fields} and {Table#clustering_fields=}.
2563
3414
  #
2564
- # @see https://cloud.google.com/bigquery/docs/partitioned-tables
2565
- # Partitioned Tables
2566
3415
  # @see https://cloud.google.com/bigquery/docs/clustered-tables
2567
- # Introduction to Clustered Tables
3416
+ # Introduction to clustered tables
2568
3417
  # @see https://cloud.google.com/bigquery/docs/creating-clustered-tables
2569
- # Creating and Using Clustered Tables
3418
+ # Creating and using clustered tables
2570
3419
  #
2571
3420
  # @param [Array<String>] fields The clustering fields. Only top-level,
2572
3421
  # non-repeated, simple-type fields are supported.
@@ -2576,15 +3425,15 @@ module Google
2576
3425
  #
2577
3426
  # bigquery = Google::Cloud::Bigquery.new
2578
3427
  # dataset = bigquery.dataset "my_dataset"
2579
- # table = dataset.create_table "my_table" do |table|
2580
- # table.time_partitioning_type = "DAY"
2581
- # table.time_partitioning_field = "dob"
2582
- # table.schema do |schema|
3428
+ # table = dataset.create_table "my_table" do |t|
3429
+ # t.schema do |schema|
2583
3430
  # schema.timestamp "dob", mode: :required
2584
3431
  # schema.string "first_name", mode: :required
2585
3432
  # schema.string "last_name", mode: :required
2586
3433
  # end
2587
- # table.clustering_fields = ["last_name", "first_name"]
3434
+ # t.time_partitioning_type = "DAY"
3435
+ # t.time_partitioning_field = "dob"
3436
+ # t.clustering_fields = ["last_name", "first_name"]
2588
3437
  # end
2589
3438
  #
2590
3439
  # @!group Attributes
@@ -2666,13 +3515,19 @@ module Google
2666
3515
  # See {Schema#string}.
2667
3516
  #
2668
3517
  # @param [String] name The field name. The name must contain only
2669
- # letters (a-z, A-Z), numbers (0-9), or underscores (_), and must
3518
+ # letters (`[A-Za-z]`), numbers (`[0-9]`), or underscores (`_`), and must
2670
3519
  # start with a letter or underscore. The maximum length is 128
2671
3520
  # characters.
2672
3521
  # @param [String] description A description of the field.
2673
3522
  # @param [Symbol] mode The field's mode. The possible values are
2674
3523
  # `:nullable`, `:required`, and `:repeated`. The default value is
2675
3524
  # `:nullable`.
3525
+ # @param [Array<String>, String] policy_tags The policy tag list or
3526
+ # single policy tag for the field. Policy tag identifiers are of
3527
+ # the form `projects/*/locations/*/taxonomies/*/policyTags/*`.
3528
+ # At most 1 policy tag is currently allowed.
3529
+ # @param [Integer] max_length The maximum UTF-8 length of strings
3530
+ # allowed in the field.
2676
3531
  #
2677
3532
  # @example
2678
3533
  # require "google/cloud/bigquery"
@@ -2684,8 +3539,8 @@ module Google
2684
3539
  # end
2685
3540
  #
2686
3541
  # @!group Schema
2687
- def string name, description: nil, mode: :nullable
2688
- schema.string name, description: description, mode: mode
3542
+ def string name, description: nil, mode: :nullable, policy_tags: nil, max_length: nil
3543
+ schema.string name, description: description, mode: mode, policy_tags: policy_tags, max_length: max_length
2689
3544
  end
2690
3545
 
2691
3546
  ##
@@ -2694,13 +3549,17 @@ module Google
2694
3549
  # See {Schema#integer}.
2695
3550
  #
2696
3551
  # @param [String] name The field name. The name must contain only
2697
- # letters (a-z, A-Z), numbers (0-9), or underscores (_), and must
3552
+ # letters (`[A-Za-z]`), numbers (`[0-9]`), or underscores (`_`), and must
2698
3553
  # start with a letter or underscore. The maximum length is 128
2699
3554
  # characters.
2700
3555
  # @param [String] description A description of the field.
2701
3556
  # @param [Symbol] mode The field's mode. The possible values are
2702
3557
  # `:nullable`, `:required`, and `:repeated`. The default value is
2703
3558
  # `:nullable`.
3559
+ # @param [Array<String>, String] policy_tags The policy tag list or
3560
+ # single policy tag for the field. Policy tag identifiers are of
3561
+ # the form `projects/*/locations/*/taxonomies/*/policyTags/*`.
3562
+ # At most 1 policy tag is currently allowed.
2704
3563
  #
2705
3564
  # @example
2706
3565
  # require "google/cloud/bigquery"
@@ -2712,8 +3571,8 @@ module Google
2712
3571
  # end
2713
3572
  #
2714
3573
  # @!group Schema
2715
- def integer name, description: nil, mode: :nullable
2716
- schema.integer name, description: description, mode: mode
3574
+ def integer name, description: nil, mode: :nullable, policy_tags: nil
3575
+ schema.integer name, description: description, mode: mode, policy_tags: policy_tags
2717
3576
  end
2718
3577
 
2719
3578
  ##
@@ -2722,13 +3581,17 @@ module Google
2722
3581
  # See {Schema#float}.
2723
3582
  #
2724
3583
  # @param [String] name The field name. The name must contain only
2725
- # letters (a-z, A-Z), numbers (0-9), or underscores (_), and must
3584
+ # letters (`[A-Za-z]`), numbers (`[0-9]`), or underscores (`_`), and must
2726
3585
  # start with a letter or underscore. The maximum length is 128
2727
3586
  # characters.
2728
3587
  # @param [String] description A description of the field.
2729
3588
  # @param [Symbol] mode The field's mode. The possible values are
2730
3589
  # `:nullable`, `:required`, and `:repeated`. The default value is
2731
3590
  # `:nullable`.
3591
+ # @param [Array<String>, String] policy_tags The policy tag list or
3592
+ # single policy tag for the field. Policy tag identifiers are of
3593
+ # the form `projects/*/locations/*/taxonomies/*/policyTags/*`.
3594
+ # At most 1 policy tag is currently allowed.
2732
3595
  #
2733
3596
  # @example
2734
3597
  # require "google/cloud/bigquery"
@@ -2740,25 +3603,48 @@ module Google
2740
3603
  # end
2741
3604
  #
2742
3605
  # @!group Schema
2743
- def float name, description: nil, mode: :nullable
2744
- schema.float name, description: description, mode: mode
3606
+ def float name, description: nil, mode: :nullable, policy_tags: nil
3607
+ schema.float name, description: description, mode: mode, policy_tags: policy_tags
2745
3608
  end
2746
3609
 
2747
3610
  ##
2748
- # Adds a numeric number field to the schema. Numeric is a
2749
- # fixed-precision numeric type with 38 decimal digits, 9 that follow
2750
- # the decimal point.
3611
+ # Adds a numeric number field to the schema. `NUMERIC` is a decimal
3612
+ # type with fixed precision and scale. Precision is the number of
3613
+ # digits that the number contains. Scale is how many of these
3614
+ # digits appear after the decimal point. It supports:
3615
+ #
3616
+ # Precision: 38
3617
+ # Scale: 9
3618
+ # Min: -9.9999999999999999999999999999999999999E+28
3619
+ # Max: 9.9999999999999999999999999999999999999E+28
3620
+ #
3621
+ # This type can represent decimal fractions exactly, and is suitable
3622
+ # for financial calculations.
2751
3623
  #
2752
3624
  # See {Schema#numeric}
2753
3625
  #
2754
3626
  # @param [String] name The field name. The name must contain only
2755
- # letters (a-z, A-Z), numbers (0-9), or underscores (_), and must
3627
+ # letters (`[A-Za-z]`), numbers (`[0-9]`), or underscores (`_`), and must
2756
3628
  # start with a letter or underscore. The maximum length is 128
2757
3629
  # characters.
2758
3630
  # @param [String] description A description of the field.
2759
3631
  # @param [Symbol] mode The field's mode. The possible values are
2760
3632
  # `:nullable`, `:required`, and `:repeated`. The default value is
2761
3633
  # `:nullable`.
3634
+ # @param [Array<String>, String] policy_tags The policy tag list or
3635
+ # single policy tag for the field. Policy tag identifiers are of
3636
+ # the form `projects/*/locations/*/taxonomies/*/policyTags/*`.
3637
+ # At most 1 policy tag is currently allowed.
3638
+ # @param [Integer] precision The precision (maximum number of total
3639
+ # digits) for the field. Acceptable values for precision must be:
3640
+ # `1 ≤ (precision - scale) ≤ 29`. Values for scale must be:
3641
+ # `0 ≤ scale ≤ 9`. If the scale value is set, the precision value
3642
+ # must be set as well.
3643
+ # @param [Integer] scale The scale (maximum number of digits in the
3644
+ # fractional part) for the field. Acceptable values for precision
3645
+ # must be: `1 ≤ (precision - scale) ≤ 29`. Values for scale must
3646
+ # be: `0 ≤ scale ≤ 9`. If the scale value is set, the precision
3647
+ # value must be set as well.
2762
3648
  #
2763
3649
  # @example
2764
3650
  # require "google/cloud/bigquery"
@@ -2770,8 +3656,71 @@ module Google
2770
3656
  # end
2771
3657
  #
2772
3658
  # @!group Schema
2773
- def numeric name, description: nil, mode: :nullable
2774
- schema.numeric name, description: description, mode: mode
3659
+ def numeric name, description: nil, mode: :nullable, policy_tags: nil, precision: nil, scale: nil
3660
+ schema.numeric name,
3661
+ description: description,
3662
+ mode: mode,
3663
+ policy_tags: policy_tags,
3664
+ precision: precision,
3665
+ scale: scale
3666
+ end
3667
+
3668
+ ##
3669
+ # Adds a bignumeric number field to the schema. `BIGNUMERIC` is a
3670
+ # decimal type with fixed precision and scale. Precision is the
3671
+ # number of digits that the number contains. Scale is how many of
3672
+ # these digits appear after the decimal point. It supports:
3673
+ #
3674
+ # Precision: 76.76 (the 77th digit is partial)
3675
+ # Scale: 38
3676
+ # Min: -5.7896044618658097711785492504343953926634992332820282019728792003956564819968E+38
3677
+ # Max: 5.7896044618658097711785492504343953926634992332820282019728792003956564819967E+38
3678
+ #
3679
+ # This type can represent decimal fractions exactly, and is suitable
3680
+ # for financial calculations.
3681
+ #
3682
+ # See {Schema#bignumeric}
3683
+ #
3684
+ # @param [String] name The field name. The name must contain only
3685
+ # letters (`[A-Za-z]`), numbers (`[0-9]`), or underscores (`_`), and must
3686
+ # start with a letter or underscore. The maximum length is 128
3687
+ # characters.
3688
+ # @param [String] description A description of the field.
3689
+ # @param [Symbol] mode The field's mode. The possible values are
3690
+ # `:nullable`, `:required`, and `:repeated`. The default value is
3691
+ # `:nullable`.
3692
+ # @param [Array<String>, String] policy_tags The policy tag list or
3693
+ # single policy tag for the field. Policy tag identifiers are of
3694
+ # the form `projects/*/locations/*/taxonomies/*/policyTags/*`.
3695
+ # At most 1 policy tag is currently allowed.
3696
+ # @param [Integer] precision The precision (maximum number of total
3697
+ # digits) for the field. Acceptable values for precision must be:
3698
+ # `1 ≤ (precision - scale) ≤ 38`. Values for scale must be:
3699
+ # `0 ≤ scale ≤ 38`. If the scale value is set, the precision value
3700
+ # must be set as well.
3701
+ # @param [Integer] scale The scale (maximum number of digits in the
3702
+ # fractional part) for the field. Acceptable values for precision
3703
+ # must be: `1 ≤ (precision - scale) ≤ 38`. Values for scale must
3704
+ # be: `0 ≤ scale ≤ 38`. If the scale value is set, the precision
3705
+ # value must be set as well.
3706
+ #
3707
+ # @example
3708
+ # require "google/cloud/bigquery"
3709
+ #
3710
+ # bigquery = Google::Cloud::Bigquery.new
3711
+ # dataset = bigquery.dataset "my_dataset"
3712
+ # table = dataset.create_table "my_table" do |schema|
3713
+ # schema.bignumeric "total_cost", mode: :required
3714
+ # end
3715
+ #
3716
+ # @!group Schema
3717
+ def bignumeric name, description: nil, mode: :nullable, policy_tags: nil, precision: nil, scale: nil
3718
+ schema.bignumeric name,
3719
+ description: description,
3720
+ mode: mode,
3721
+ policy_tags: policy_tags,
3722
+ precision: precision,
3723
+ scale: scale
2775
3724
  end
2776
3725
 
2777
3726
  ##
@@ -2780,13 +3729,17 @@ module Google
2780
3729
  # See {Schema#boolean}.
2781
3730
  #
2782
3731
  # @param [String] name The field name. The name must contain only
2783
- # letters (a-z, A-Z), numbers (0-9), or underscores (_), and must
3732
+ # letters (`[A-Za-z]`), numbers (`[0-9]`), or underscores (`_`), and must
2784
3733
  # start with a letter or underscore. The maximum length is 128
2785
3734
  # characters.
2786
3735
  # @param [String] description A description of the field.
2787
3736
  # @param [Symbol] mode The field's mode. The possible values are
2788
3737
  # `:nullable`, `:required`, and `:repeated`. The default value is
2789
3738
  # `:nullable`.
3739
+ # @param [Array<String>, String] policy_tags The policy tag list or
3740
+ # single policy tag for the field. Policy tag identifiers are of
3741
+ # the form `projects/*/locations/*/taxonomies/*/policyTags/*`.
3742
+ # At most 1 policy tag is currently allowed.
2790
3743
  #
2791
3744
  # @example
2792
3745
  # require "google/cloud/bigquery"
@@ -2798,8 +3751,8 @@ module Google
2798
3751
  # end
2799
3752
  #
2800
3753
  # @!group Schema
2801
- def boolean name, description: nil, mode: :nullable
2802
- schema.boolean name, description: description, mode: mode
3754
+ def boolean name, description: nil, mode: :nullable, policy_tags: nil
3755
+ schema.boolean name, description: description, mode: mode, policy_tags: policy_tags
2803
3756
  end
2804
3757
 
2805
3758
  ##
@@ -2808,13 +3761,19 @@ module Google
2808
3761
  # See {Schema#bytes}.
2809
3762
  #
2810
3763
  # @param [String] name The field name. The name must contain only
2811
- # letters (a-z, A-Z), numbers (0-9), or underscores (_), and must
3764
+ # letters (`[A-Za-z]`), numbers (`[0-9]`), or underscores (`_`), and must
2812
3765
  # start with a letter or underscore. The maximum length is 128
2813
3766
  # characters.
2814
3767
  # @param [String] description A description of the field.
2815
3768
  # @param [Symbol] mode The field's mode. The possible values are
2816
3769
  # `:nullable`, `:required`, and `:repeated`. The default value is
2817
3770
  # `:nullable`.
3771
+ # @param [Array<String>, String] policy_tags The policy tag list or
3772
+ # single policy tag for the field. Policy tag identifiers are of
3773
+ # the form `projects/*/locations/*/taxonomies/*/policyTags/*`.
3774
+ # At most 1 policy tag is currently allowed.
3775
+ # @param [Integer] max_length The maximum the maximum number of
3776
+ # bytes in the field.
2818
3777
  #
2819
3778
  # @example
2820
3779
  # require "google/cloud/bigquery"
@@ -2826,8 +3785,8 @@ module Google
2826
3785
  # end
2827
3786
  #
2828
3787
  # @!group Schema
2829
- def bytes name, description: nil, mode: :nullable
2830
- schema.bytes name, description: description, mode: mode
3788
+ def bytes name, description: nil, mode: :nullable, policy_tags: nil, max_length: nil
3789
+ schema.bytes name, description: description, mode: mode, policy_tags: policy_tags, max_length: max_length
2831
3790
  end
2832
3791
 
2833
3792
  ##
@@ -2836,13 +3795,17 @@ module Google
2836
3795
  # See {Schema#timestamp}.
2837
3796
  #
2838
3797
  # @param [String] name The field name. The name must contain only
2839
- # letters (a-z, A-Z), numbers (0-9), or underscores (_), and must
3798
+ # letters (`[A-Za-z]`), numbers (`[0-9]`), or underscores (`_`), and must
2840
3799
  # start with a letter or underscore. The maximum length is 128
2841
3800
  # characters.
2842
3801
  # @param [String] description A description of the field.
2843
3802
  # @param [Symbol] mode The field's mode. The possible values are
2844
3803
  # `:nullable`, `:required`, and `:repeated`. The default value is
2845
3804
  # `:nullable`.
3805
+ # @param [Array<String>, String] policy_tags The policy tag list or
3806
+ # single policy tag for the field. Policy tag identifiers are of
3807
+ # the form `projects/*/locations/*/taxonomies/*/policyTags/*`.
3808
+ # At most 1 policy tag is currently allowed.
2846
3809
  #
2847
3810
  # @example
2848
3811
  # require "google/cloud/bigquery"
@@ -2854,8 +3817,8 @@ module Google
2854
3817
  # end
2855
3818
  #
2856
3819
  # @!group Schema
2857
- def timestamp name, description: nil, mode: :nullable
2858
- schema.timestamp name, description: description, mode: mode
3820
+ def timestamp name, description: nil, mode: :nullable, policy_tags: nil
3821
+ schema.timestamp name, description: description, mode: mode, policy_tags: policy_tags
2859
3822
  end
2860
3823
 
2861
3824
  ##
@@ -2864,13 +3827,17 @@ module Google
2864
3827
  # See {Schema#time}.
2865
3828
  #
2866
3829
  # @param [String] name The field name. The name must contain only
2867
- # letters (a-z, A-Z), numbers (0-9), or underscores (_), and must
3830
+ # letters (`[A-Za-z]`), numbers (`[0-9]`), or underscores (`_`), and must
2868
3831
  # start with a letter or underscore. The maximum length is 128
2869
3832
  # characters.
2870
3833
  # @param [String] description A description of the field.
2871
3834
  # @param [Symbol] mode The field's mode. The possible values are
2872
3835
  # `:nullable`, `:required`, and `:repeated`. The default value is
2873
3836
  # `:nullable`.
3837
+ # @param [Array<String>, String] policy_tags The policy tag list or
3838
+ # single policy tag for the field. Policy tag identifiers are of
3839
+ # the form `projects/*/locations/*/taxonomies/*/policyTags/*`.
3840
+ # At most 1 policy tag is currently allowed.
2874
3841
  #
2875
3842
  # @example
2876
3843
  # require "google/cloud/bigquery"
@@ -2882,8 +3849,8 @@ module Google
2882
3849
  # end
2883
3850
  #
2884
3851
  # @!group Schema
2885
- def time name, description: nil, mode: :nullable
2886
- schema.time name, description: description, mode: mode
3852
+ def time name, description: nil, mode: :nullable, policy_tags: nil
3853
+ schema.time name, description: description, mode: mode, policy_tags: policy_tags
2887
3854
  end
2888
3855
 
2889
3856
  ##
@@ -2892,13 +3859,17 @@ module Google
2892
3859
  # See {Schema#datetime}.
2893
3860
  #
2894
3861
  # @param [String] name The field name. The name must contain only
2895
- # letters (a-z, A-Z), numbers (0-9), or underscores (_), and must
3862
+ # letters (`[A-Za-z]`), numbers (`[0-9]`), or underscores (`_`), and must
2896
3863
  # start with a letter or underscore. The maximum length is 128
2897
3864
  # characters.
2898
3865
  # @param [String] description A description of the field.
2899
3866
  # @param [Symbol] mode The field's mode. The possible values are
2900
3867
  # `:nullable`, `:required`, and `:repeated`. The default value is
2901
3868
  # `:nullable`.
3869
+ # @param [Array<String>, String] policy_tags The policy tag list or
3870
+ # single policy tag for the field. Policy tag identifiers are of
3871
+ # the form `projects/*/locations/*/taxonomies/*/policyTags/*`.
3872
+ # At most 1 policy tag is currently allowed.
2902
3873
  #
2903
3874
  # @example
2904
3875
  # require "google/cloud/bigquery"
@@ -2910,8 +3881,8 @@ module Google
2910
3881
  # end
2911
3882
  #
2912
3883
  # @!group Schema
2913
- def datetime name, description: nil, mode: :nullable
2914
- schema.datetime name, description: description, mode: mode
3884
+ def datetime name, description: nil, mode: :nullable, policy_tags: nil
3885
+ schema.datetime name, description: description, mode: mode, policy_tags: policy_tags
2915
3886
  end
2916
3887
 
2917
3888
  ##
@@ -2920,13 +3891,17 @@ module Google
2920
3891
  # See {Schema#date}.
2921
3892
  #
2922
3893
  # @param [String] name The field name. The name must contain only
2923
- # letters (a-z, A-Z), numbers (0-9), or underscores (_), and must
3894
+ # letters (`[A-Za-z]`), numbers (`[0-9]`), or underscores (`_`), and must
2924
3895
  # start with a letter or underscore. The maximum length is 128
2925
3896
  # characters.
2926
3897
  # @param [String] description A description of the field.
2927
3898
  # @param [Symbol] mode The field's mode. The possible values are
2928
3899
  # `:nullable`, `:required`, and `:repeated`. The default value is
2929
3900
  # `:nullable`.
3901
+ # @param [Array<String>, String] policy_tags The policy tag list or
3902
+ # single policy tag for the field. Policy tag identifiers are of
3903
+ # the form `projects/*/locations/*/taxonomies/*/policyTags/*`.
3904
+ # At most 1 policy tag is currently allowed.
2930
3905
  #
2931
3906
  # @example
2932
3907
  # require "google/cloud/bigquery"
@@ -2938,8 +3913,39 @@ module Google
2938
3913
  # end
2939
3914
  #
2940
3915
  # @!group Schema
2941
- def date name, description: nil, mode: :nullable
2942
- schema.date name, description: description, mode: mode
3916
+ def date name, description: nil, mode: :nullable, policy_tags: nil
3917
+ schema.date name, description: description, mode: mode, policy_tags: policy_tags
3918
+ end
3919
+
3920
+ ##
3921
+ # Adds a geography field to the schema.
3922
+ #
3923
+ # @see https://cloud.google.com/bigquery/docs/gis-data Working with BigQuery GIS data
3924
+ #
3925
+ # @param [String] name The field name. The name must contain only
3926
+ # letters (`[A-Za-z]`), numbers (`[0-9]`), or underscores (`_`), and must
3927
+ # start with a letter or underscore. The maximum length is 128
3928
+ # characters.
3929
+ # @param [String] description A description of the field.
3930
+ # @param [Symbol] mode The field's mode. The possible values are
3931
+ # `:nullable`, `:required`, and `:repeated`. The default value is
3932
+ # `:nullable`.
3933
+ # @param [Array<String>, String] policy_tags The policy tag list or
3934
+ # single policy tag for the field. Policy tag identifiers are of
3935
+ # the form `projects/*/locations/*/taxonomies/*/policyTags/*`.
3936
+ # At most 1 policy tag is currently allowed.
3937
+ #
3938
+ # @example
3939
+ # require "google/cloud/bigquery"
3940
+ #
3941
+ # bigquery = Google::Cloud::Bigquery.new
3942
+ # dataset = bigquery.dataset "my_dataset"
3943
+ # table = dataset.create_table "my_table" do |schema|
3944
+ # schema.geography "home", mode: :required
3945
+ # end
3946
+ #
3947
+ def geography name, description: nil, mode: :nullable, policy_tags: nil
3948
+ schema.geography name, description: description, mode: mode, policy_tags: policy_tags
2943
3949
  end
2944
3950
 
2945
3951
  ##
@@ -2952,7 +3958,7 @@ module Google
2952
3958
  # See {Schema#record}.
2953
3959
  #
2954
3960
  # @param [String] name The field name. The name must contain only
2955
- # letters (a-z, A-Z), numbers (0-9), or underscores (_), and must
3961
+ # letters (`[A-Za-z]`), numbers (`[0-9]`), or underscores (`_`), and must
2956
3962
  # start with a letter or underscore. The maximum length is 128
2957
3963
  # characters.
2958
3964
  # @param [String] description A description of the field.
@@ -2982,7 +3988,92 @@ module Google
2982
3988
  end
2983
3989
 
2984
3990
  ##
2985
- # Make sure any access changes are saved
3991
+ # @raise [RuntimeError] not implemented
3992
+ def data(*)
3993
+ raise "not implemented in #{self.class}"
3994
+ end
3995
+
3996
+ ##
3997
+ # @raise [RuntimeError] not implemented
3998
+ def copy_job(*)
3999
+ raise "not implemented in #{self.class}"
4000
+ end
4001
+
4002
+ ##
4003
+ # @raise [RuntimeError] not implemented
4004
+ def copy(*)
4005
+ raise "not implemented in #{self.class}"
4006
+ end
4007
+
4008
+ ##
4009
+ # @raise [RuntimeError] not implemented
4010
+ def extract_job(*)
4011
+ raise "not implemented in #{self.class}"
4012
+ end
4013
+
4014
+ ##
4015
+ # @raise [RuntimeError] not implemented
4016
+ def extract(*)
4017
+ raise "not implemented in #{self.class}"
4018
+ end
4019
+
4020
+ ##
4021
+ # @raise [RuntimeError] not implemented
4022
+ def load_job(*)
4023
+ raise "not implemented in #{self.class}"
4024
+ end
4025
+
4026
+ ##
4027
+ # @raise [RuntimeError] not implemented
4028
+ def load(*)
4029
+ raise "not implemented in #{self.class}"
4030
+ end
4031
+
4032
+ ##
4033
+ # @raise [RuntimeError] not implemented
4034
+ def insert(*)
4035
+ raise "not implemented in #{self.class}"
4036
+ end
4037
+
4038
+ ##
4039
+ # @raise [RuntimeError] not implemented
4040
+ def insert_async(*)
4041
+ raise "not implemented in #{self.class}"
4042
+ end
4043
+
4044
+ ##
4045
+ # @raise [RuntimeError] not implemented
4046
+ def delete
4047
+ raise "not implemented in #{self.class}"
4048
+ end
4049
+
4050
+ ##
4051
+ # @raise [RuntimeError] not implemented
4052
+ def query_job(*)
4053
+ raise "not implemented in #{self.class}"
4054
+ end
4055
+
4056
+ ##
4057
+ # @raise [RuntimeError] not implemented
4058
+ def query(*)
4059
+ raise "not implemented in #{self.class}"
4060
+ end
4061
+
4062
+ ##
4063
+ # @raise [RuntimeError] not implemented
4064
+ def external(*)
4065
+ raise "not implemented in #{self.class}"
4066
+ end
4067
+
4068
+ ##
4069
+ # @raise [RuntimeError] not implemented
4070
+ def reload!
4071
+ raise "not implemented in #{self.class}"
4072
+ end
4073
+ alias refresh! reload!
4074
+
4075
+ ##
4076
+ # @private Make sure any access changes are saved
2986
4077
  def check_for_mutated_schema!
2987
4078
  return if @schema.nil?
2988
4079
  return unless @schema.changed?
@@ -2990,6 +4081,8 @@ module Google
2990
4081
  patch_gapi! :schema
2991
4082
  end
2992
4083
 
4084
+ ##
4085
+ # @private
2993
4086
  def to_gapi
2994
4087
  check_for_mutated_schema!
2995
4088
  @gapi