google-cloud-bigquery 1.25.0 → 1.30.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.
@@ -124,12 +124,12 @@ module Google
124
124
  # puts routine.routine_id
125
125
  # end
126
126
  #
127
- def all request_limit: nil
127
+ def all request_limit: nil, &block
128
128
  request_limit = request_limit.to_i if request_limit
129
129
  return enum_for :all, request_limit: request_limit unless block_given?
130
130
  results = self
131
131
  loop do
132
- results.each { |r| yield r }
132
+ results.each(&block)
133
133
  if request_limit
134
134
  request_limit -= 1
135
135
  break if request_limit.negative?
@@ -332,9 +332,18 @@ module Google
332
332
  end
333
333
 
334
334
  ##
335
- # Adds a numeric number field to the schema. Numeric is a
336
- # fixed-precision numeric type with 38 decimal digits, 9 that follow the
337
- # decimal point.
335
+ # Adds a numeric number field to the schema. `NUMERIC` is a decimal
336
+ # type with fixed precision and scale. Precision is the number of
337
+ # digits that the number contains. Scale is how many of these
338
+ # digits appear after the decimal point. It supports:
339
+ #
340
+ # Precision: 38
341
+ # Scale: 9
342
+ # Min: -9.9999999999999999999999999999999999999E+28
343
+ # Max: 9.9999999999999999999999999999999999999E+28
344
+ #
345
+ # This type can represent decimal fractions exactly, and is suitable
346
+ # for financial calculations.
338
347
  #
339
348
  # @param [String] name The field name. The name must contain only
340
349
  # letters (a-z, A-Z), numbers (0-9), or underscores (_), and must
@@ -349,6 +358,33 @@ module Google
349
358
  add_field name, :numeric, description: description, mode: mode
350
359
  end
351
360
 
361
+ ##
362
+ # Adds a bignumeric number field to the schema. `BIGNUMERIC` is a
363
+ # decimal type with fixed precision and scale. Precision is the
364
+ # number of digits that the number contains. Scale is how many of
365
+ # these digits appear after the decimal point. It supports:
366
+ #
367
+ # Precision: 76.76 (the 77th digit is partial)
368
+ # Scale: 38
369
+ # Min: -5.7896044618658097711785492504343953926634992332820282019728792003956564819968E+38
370
+ # Max: 5.7896044618658097711785492504343953926634992332820282019728792003956564819967E+38
371
+ #
372
+ # This type can represent decimal fractions exactly, and is suitable
373
+ # for financial calculations.
374
+ #
375
+ # @param [String] name The field name. The name must contain only
376
+ # letters (a-z, A-Z), numbers (0-9), or underscores (_), and must
377
+ # start with a letter or underscore. The maximum length is 128
378
+ # characters.
379
+ # @param [String] description A description of the field.
380
+ # @param [Symbol] mode The field's mode. The possible values are
381
+ # `:nullable`, `:required`, and `:repeated`. The default value is
382
+ # `:nullable`.
383
+ #
384
+ def bignumeric name, description: nil, mode: :nullable
385
+ add_field name, :bignumeric, description: description, mode: mode
386
+ end
387
+
352
388
  ##
353
389
  # Adds a boolean field to the schema.
354
390
  #
@@ -40,8 +40,8 @@ module Google
40
40
  MODES = ["NULLABLE", "REQUIRED", "REPEATED"].freeze
41
41
 
42
42
  # @private
43
- TYPES = ["STRING", "INTEGER", "INT64", "FLOAT", "FLOAT64", "NUMERIC", "BOOLEAN", "BOOL", "BYTES", "TIMESTAMP",
44
- "TIME", "DATETIME", "DATE", "RECORD", "STRUCT"].freeze
43
+ TYPES = ["STRING", "INTEGER", "INT64", "FLOAT", "FLOAT64", "NUMERIC", "BIGNUMERIC", "BOOLEAN", "BOOL",
44
+ "BYTES", "TIMESTAMP", "TIME", "DATETIME", "DATE", "RECORD", "STRUCT"].freeze
45
45
 
46
46
  ##
47
47
  # The name of the field.
@@ -72,10 +72,10 @@ module Google
72
72
  #
73
73
  # @return [String] The field data type. Possible values include
74
74
  # `STRING`, `BYTES`, `INTEGER`, `INT64` (same as `INTEGER`),
75
- # `FLOAT`, `FLOAT64` (same as `FLOAT`), `NUMERIC`, `BOOLEAN`, `BOOL`
76
- # (same as `BOOLEAN`), `TIMESTAMP`, `DATE`, `TIME`, `DATETIME`,
77
- # `RECORD` (where `RECORD` indicates that the field contains a
78
- # nested schema) or `STRUCT` (same as `RECORD`).
75
+ # `FLOAT`, `FLOAT64` (same as `FLOAT`), `NUMERIC`, `BIGNUMERIC`,
76
+ # `BOOLEAN`, `BOOL` (same as `BOOLEAN`), `TIMESTAMP`, `DATE`,
77
+ # `TIME`, `DATETIME`, `RECORD` (where `RECORD` indicates that the
78
+ # field contains a nested schema) or `STRUCT` (same as `RECORD`).
79
79
  #
80
80
  def type
81
81
  @gapi.type
@@ -86,10 +86,10 @@ module Google
86
86
  #
87
87
  # @param [String] new_type The data type. Possible values include
88
88
  # `STRING`, `BYTES`, `INTEGER`, `INT64` (same as `INTEGER`),
89
- # `FLOAT`, `FLOAT64` (same as `FLOAT`), `NUMERIC`, `BOOLEAN`, `BOOL`
90
- # (same as `BOOLEAN`), `TIMESTAMP`, `DATE`, `TIME`, `DATETIME`,
91
- # `RECORD` (where `RECORD` indicates that the field contains a
92
- # nested schema) or `STRUCT` (same as `RECORD`).
89
+ # `FLOAT`, `FLOAT64` (same as `FLOAT`), `NUMERIC`, `BIGNUMERIC`,
90
+ # `BOOLEAN`, `BOOL` (same as `BOOLEAN`), `TIMESTAMP`, `DATE`,
91
+ # `TIME`, `DATETIME`, `RECORD` (where `RECORD` indicates that the
92
+ # field contains a nested schema) or `STRUCT` (same as `RECORD`).
93
93
  #
94
94
  def type= new_type
95
95
  @gapi.update! type: verify_type(new_type)
@@ -199,6 +199,15 @@ module Google
199
199
  type == "NUMERIC"
200
200
  end
201
201
 
202
+ ##
203
+ # Checks if the type of the field is `BIGNUMERIC`.
204
+ #
205
+ # @return [Boolean] `true` when `BIGNUMERIC`, `false` otherwise.
206
+ #
207
+ def bignumeric?
208
+ type == "BIGNUMERIC"
209
+ end
210
+
202
211
  ##
203
212
  # Checks if the type of the field is `BOOLEAN`.
204
213
  #
@@ -299,6 +308,7 @@ module Google
299
308
  # * `:INT64`
300
309
  # * `:FLOAT64`
301
310
  # * `:NUMERIC`
311
+ # * `:BIGNUMERIC`
302
312
  # * `:STRING`
303
313
  # * `:DATETIME`
304
314
  # * `:DATE`
@@ -394,9 +404,18 @@ module Google
394
404
  end
395
405
 
396
406
  ##
397
- # Adds a numeric number field to the schema. Numeric is a
398
- # fixed-precision numeric type with 38 decimal digits, 9 that follow
399
- # the decimal point.
407
+ # Adds a numeric number field to the schema. `NUMERIC` is a decimal
408
+ # type with fixed precision and scale. Precision is the number of
409
+ # digits that the number contains. Scale is how many of these
410
+ # digits appear after the decimal point. It supports:
411
+ #
412
+ # Precision: 38
413
+ # Scale: 9
414
+ # Min: -9.9999999999999999999999999999999999999E+28
415
+ # Max: 9.9999999999999999999999999999999999999E+28
416
+ #
417
+ # This type can represent decimal fractions exactly, and is suitable
418
+ # for financial calculations.
400
419
  #
401
420
  # This can only be called on fields that are of type `RECORD`.
402
421
  #
@@ -415,6 +434,37 @@ module Google
415
434
  add_field name, :numeric, description: description, mode: mode
416
435
  end
417
436
 
437
+ ##
438
+ # Adds a bignumeric number field to the schema. `BIGNUMERIC` is a
439
+ # decimal type with fixed precision and scale. Precision is the
440
+ # number of digits that the number contains. Scale is how many of
441
+ # these digits appear after the decimal point. It supports:
442
+ #
443
+ # Precision: 76.76 (the 77th digit is partial)
444
+ # Scale: 38
445
+ # Min: -5.7896044618658097711785492504343953926634992332820282019728792003956564819968E+38
446
+ # Max: 5.7896044618658097711785492504343953926634992332820282019728792003956564819967E+38
447
+ #
448
+ # This type can represent decimal fractions exactly, and is suitable
449
+ # for financial calculations.
450
+ #
451
+ # This can only be called on fields that are of type `RECORD`.
452
+ #
453
+ # @param [String] name The field name. The name must contain only
454
+ # letters (a-z, A-Z), numbers (0-9), or underscores (_), and must
455
+ # start with a letter or underscore. The maximum length is 128
456
+ # characters.
457
+ # @param [String] description A description of the field.
458
+ # @param [Symbol] mode The field's mode. The possible values are
459
+ # `:nullable`, `:required`, and `:repeated`. The default value is
460
+ # `:nullable`.
461
+ #
462
+ def bignumeric name, description: nil, mode: :nullable
463
+ record_check!
464
+
465
+ add_field name, :bignumeric, description: description, mode: mode
466
+ end
467
+
418
468
  ##
419
469
  # Adds a boolean field to the nested schema of a record field.
420
470
  #
@@ -483,7 +483,7 @@ module Google
483
483
  table_id: m["tbl"]
484
484
  }.delete_if { |_, v| v.nil? }
485
485
  str_table_ref_hash = default_ref.to_h.merge str_table_ref_hash
486
- ref = Google::Apis::BigqueryV2::TableReference.new str_table_ref_hash
486
+ ref = Google::Apis::BigqueryV2::TableReference.new(**str_table_ref_hash)
487
487
  validate_table_ref ref
488
488
  ref
489
489
  end
@@ -554,9 +554,9 @@ module Google
554
554
  nil
555
555
  end
556
556
 
557
- def execute backoff: nil
557
+ def execute backoff: nil, &block
558
558
  if backoff
559
- Backoff.new(retries: retries).execute { yield }
559
+ Backoff.new(retries: retries).execute(&block)
560
560
  else
561
561
  yield
562
562
  end
@@ -590,22 +590,20 @@ module Google
590
590
  def execute
591
591
  current_retries = 0
592
592
  loop do
593
- begin
594
- return yield
595
- rescue Google::Apis::Error => e
596
- raise e unless retry? e.body, current_retries
597
-
598
- @backoff.call current_retries
599
- current_retries += 1
600
- end
593
+ return yield
594
+ rescue Google::Apis::Error => e
595
+ raise e unless retry? e.body, current_retries
596
+
597
+ @backoff.call current_retries
598
+ current_retries += 1
601
599
  end
602
600
  end
603
601
 
604
602
  protected
605
603
 
606
604
  def retry? result, current_retries #:nodoc:
607
- if current_retries < @retries
608
- return true if retry_error_reason? result
605
+ if current_retries < @retries && retry_error_reason?(result)
606
+ return true
609
607
  end
610
608
  false
611
609
  end
@@ -273,6 +273,17 @@ module Google
273
273
  type_kind == "NUMERIC".freeze
274
274
  end
275
275
 
276
+ ##
277
+ # Checks if the {#type_kind} of the field is `BIGNUMERIC`.
278
+ #
279
+ # @return [Boolean] `true` when `BIGNUMERIC`, `false` otherwise.
280
+ #
281
+ # @!group Helpers
282
+ #
283
+ def bignumeric?
284
+ type_kind == "BIGNUMERIC".freeze
285
+ end
286
+
276
287
  ##
277
288
  # Checks if the {#type_kind} of the field is `BOOL`.
278
289
  #
@@ -401,11 +412,12 @@ module Google
401
412
  # @private New Google::Apis::BigqueryV2::StandardSqlDataType from a String or StandardSql::DataType object.
402
413
  def self.gapi_from_string_or_data_type data_type
403
414
  return if data_type.nil?
404
- if data_type.is_a? StandardSql::DataType
415
+ case data_type
416
+ when StandardSql::DataType
405
417
  data_type.to_gapi
406
- elsif data_type.is_a? Hash
418
+ when Hash
407
419
  data_type
408
- elsif data_type.is_a?(String) || data_type.is_a?(Symbol)
420
+ when String, Symbol
409
421
  Google::Apis::BigqueryV2::StandardSqlDataType.new type_kind: data_type.to_s.upcase
410
422
  else
411
423
  raise ArgumentError, "Unable to convert #{data_type} to Google::Apis::BigqueryV2::StandardSqlDataType"
@@ -37,16 +37,16 @@ module Google
37
37
  # repeated fields.
38
38
  #
39
39
  # The Table class can also represent a
40
- # [view](https://cloud.google.com/bigquery/docs/views), which is a virtual
41
- # table defined by a SQL query. BigQuery's views are logical views, not
42
- # materialized views, which means that the query that defines the view is
43
- # re-executed every time the view is queried. Queries are billed according
44
- # to the total amount of data in all table fields referenced directly or
45
- # indirectly by the top-level query. (See {#view?}, {#query}, {#query=},
46
- # 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}).
47
45
  #
48
46
  # @see https://cloud.google.com/bigquery/docs/loading-data#loading_denormalized_nested_and_repeated_data
49
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
50
50
  #
51
51
  # @example
52
52
  # require "google/cloud/bigquery"
@@ -77,7 +77,7 @@ module Google
77
77
  # }
78
78
  # table.insert row
79
79
  #
80
- # @example Creating a BigQuery view:
80
+ # @example Creating a logical view:
81
81
  # require "google/cloud/bigquery"
82
82
  #
83
83
  # bigquery = Google::Cloud::Bigquery.new
@@ -86,6 +86,15 @@ module Google
86
86
  # "SELECT name, age FROM `my_project.my_dataset.my_table`"
87
87
  # view.view? # true
88
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
+ #
89
98
  class Table
90
99
  ##
91
100
  # @private The Service object.
@@ -386,8 +395,8 @@ module Google
386
395
  # {#resource_full?}), the full representation will be retrieved before
387
396
  # the update to comply with ETag-based optimistic concurrency control.
388
397
  #
389
- # @param [Integer] expiration An expiration time, in seconds,
390
- # for data in time partitions.
398
+ # @param [Integer, nil] expiration An expiration time, in seconds,
399
+ # for data in time partitions, , or `nil` to indicate no expiration time.
391
400
  #
392
401
  # @example
393
402
  # require "google/cloud/bigquery"
@@ -407,8 +416,9 @@ module Google
407
416
  #
408
417
  def time_partitioning_expiration= expiration
409
418
  reload! unless resource_full?
419
+ expiration_ms = expiration * 1000 if expiration
410
420
  @gapi.time_partitioning ||= Google::Apis::BigqueryV2::TimePartitioning.new
411
- @gapi.time_partitioning.expiration_ms = expiration * 1000
421
+ @gapi.time_partitioning.expiration_ms = expiration_ms
412
422
  patch_gapi! :time_partitioning
413
423
  end
414
424
 
@@ -726,7 +736,7 @@ module Google
726
736
  end
727
737
 
728
738
  ##
729
- # Checks if the table's type is "TABLE".
739
+ # Checks if the table's type is `TABLE`.
730
740
  #
731
741
  # @return [Boolean, nil] `true` when the type is `TABLE`, `false`
732
742
  # otherwise, if the object is a resource (see {#resource?}); `nil` if
@@ -740,8 +750,10 @@ module Google
740
750
  end
741
751
 
742
752
  ##
743
- # Checks if the table's type is "VIEW", indicating that the table
744
- # represents a BigQuery view. See {Dataset#create_view}.
753
+ # Checks if the table's type is `VIEW`, indicating that the table
754
+ # represents a BigQuery logical view. See {Dataset#create_view}.
755
+ #
756
+ # @see https://cloud.google.com/bigquery/docs/views Creating views
745
757
  #
746
758
  # @return [Boolean, nil] `true` when the type is `VIEW`, `false`
747
759
  # otherwise, if the object is a resource (see {#resource?}); `nil` if
@@ -755,7 +767,25 @@ module Google
755
767
  end
756
768
 
757
769
  ##
758
- # Checks if the table's type is "EXTERNAL", indicating that the table
770
+ # Checks if the table's type is `MATERIALIZED_VIEW`, indicating that
771
+ # the table represents a BigQuery materialized view.
772
+ # See {Dataset#create_materialized_view}.
773
+ #
774
+ # @see https://cloud.google.com/bigquery/docs/materialized-views-intro Introduction to materialized views
775
+ #
776
+ # @return [Boolean, nil] `true` when the type is `MATERIALIZED_VIEW`,
777
+ # `false` otherwise, if the object is a resource (see {#resource?});
778
+ # `nil` if the object is a reference (see {#reference?}).
779
+ #
780
+ # @!group Attributes
781
+ #
782
+ def materialized_view?
783
+ return nil if reference?
784
+ @gapi.type == "MATERIALIZED_VIEW"
785
+ end
786
+
787
+ ##
788
+ # Checks if the table's type is `EXTERNAL`, indicating that the table
759
789
  # represents an External Data Source. See {#external?} and
760
790
  # {External::DataSource}.
761
791
  #
@@ -1138,21 +1168,24 @@ module Google
1138
1168
  end
1139
1169
 
1140
1170
  ##
1141
- # The query that executes each time the view is loaded.
1171
+ # The query that defines the view or materialized view. See {#view?} and
1172
+ # {#materialized_view?}.
1142
1173
  #
1143
- # @return [String] The query that defines the view.
1174
+ # @return [String, nil] The query that defines the view or materialized_view;
1175
+ # or `nil` if not a view or materialized view.
1144
1176
  #
1145
1177
  # @!group Attributes
1146
1178
  #
1147
1179
  def query
1148
- @gapi.view&.query
1180
+ view? ? @gapi.view&.query : @gapi.materialized_view&.query
1149
1181
  end
1150
1182
 
1151
1183
  ##
1152
- # Updates the query that executes each time the view is loaded.
1184
+ # Updates the query that defines the view. (See {#view?}.) Not supported
1185
+ # for materialized views.
1153
1186
  #
1154
- # This sets the query using standard SQL. To specify legacy SQL or to
1155
- # use user-defined function resources use (#set_query) instead.
1187
+ # This method sets the query using standard SQL. To specify legacy SQL or
1188
+ # to use user-defined function resources for a view, use (#set_query) instead.
1156
1189
  #
1157
1190
  # @see https://cloud.google.com/bigquery/query-reference BigQuery Query
1158
1191
  # Reference
@@ -1167,7 +1200,7 @@ module Google
1167
1200
  # view = dataset.table "my_view"
1168
1201
  #
1169
1202
  # view.query = "SELECT first_name FROM " \
1170
- # "`my_project.my_dataset.my_table`"
1203
+ # "`my_project.my_dataset.my_table`"
1171
1204
  #
1172
1205
  # @!group Lifecycle
1173
1206
  #
@@ -1176,12 +1209,12 @@ module Google
1176
1209
  end
1177
1210
 
1178
1211
  ##
1179
- # Updates the query that executes each time the view is loaded. Allows
1180
- # setting of standard vs. legacy SQL and user-defined function
1181
- # resources.
1212
+ # Updates the query that defines the view. (See {#view?}.) Not supported for
1213
+ # materialized views.
1182
1214
  #
1183
- # @see https://cloud.google.com/bigquery/query-reference BigQuery Query
1184
- # Reference
1215
+ # Allows setting of standard vs. legacy SQL and user-defined function resources.
1216
+ #
1217
+ # @see https://cloud.google.com/bigquery/query-reference BigQuery Query Reference
1185
1218
  #
1186
1219
  # @param [String] query The query that defines the view.
1187
1220
  # @param [Boolean] standard_sql Specifies whether to use BigQuery's
@@ -1193,11 +1226,12 @@ module Google
1193
1226
  # SQL](https://cloud.google.com/bigquery/docs/reference/legacy-sql)
1194
1227
  # dialect. Optional. The default value is false.
1195
1228
  # @param [Array<String>, String] udfs User-defined function resources
1196
- # used in a legacy SQL query. May be either a code resource to load from
1197
- # a Google Cloud Storage URI (`gs://bucket/path`), or an inline resource
1198
- # that contains code for a user-defined function (UDF). Providing an
1199
- # inline code resource is equivalent to providing a URI for a file
1200
- # containing the same code.
1229
+ # used in a legacy SQL query. Optional.
1230
+ #
1231
+ # May be either a code resource to load from a Google Cloud Storage URI
1232
+ # (`gs://bucket/path`), or an inline resource that contains code for a
1233
+ # user-defined function (UDF). Providing an inline code resource is equivalent
1234
+ # to providing a URI for a file containing the same code.
1201
1235
  #
1202
1236
  # This parameter is used for defining User Defined Function (UDF)
1203
1237
  # resources only when using legacy SQL. Users of standard SQL should
@@ -1208,7 +1242,7 @@ module Google
1208
1242
  # standard SQL - Differences in user-defined JavaScript
1209
1243
  # functions](https://cloud.google.com/bigquery/docs/reference/standard-sql/migrating-from-legacy-sql#differences_in_user-defined_javascript_functions)
1210
1244
  #
1211
- # @example
1245
+ # @example Update a view:
1212
1246
  # require "google/cloud/bigquery"
1213
1247
  #
1214
1248
  # bigquery = Google::Cloud::Bigquery.new
@@ -1216,12 +1250,13 @@ module Google
1216
1250
  # view = dataset.table "my_view"
1217
1251
  #
1218
1252
  # view.set_query "SELECT first_name FROM " \
1219
- # "`my_project.my_dataset.my_table`",
1253
+ # "`my_project.my_dataset.my_table`",
1220
1254
  # standard_sql: true
1221
1255
  #
1222
1256
  # @!group Lifecycle
1223
1257
  #
1224
1258
  def set_query query, standard_sql: nil, legacy_sql: nil, udfs: nil
1259
+ raise "Updating the query is not supported for Table type: #{@gapi.type}" unless view?
1225
1260
  use_legacy_sql = Convert.resolve_legacy_sql standard_sql, legacy_sql
1226
1261
  @gapi.view = Google::Apis::BigqueryV2::ViewDefinition.new(
1227
1262
  query: query,
@@ -1232,26 +1267,28 @@ module Google
1232
1267
  end
1233
1268
 
1234
1269
  ##
1235
- # Checks if the view's query is using legacy sql.
1270
+ # Checks if the view's query is using legacy sql. See {#view?}.
1236
1271
  #
1237
- # @return [Boolean] `true` when legacy sql is used, `false` otherwise.
1272
+ # @return [Boolean] `true` when legacy sql is used, `false` otherwise; or `nil` if not a logical view.
1238
1273
  #
1239
1274
  # @!group Attributes
1240
1275
  #
1241
1276
  def query_legacy_sql?
1277
+ return nil unless @gapi.view
1242
1278
  val = @gapi.view.use_legacy_sql
1243
1279
  return true if val.nil?
1244
1280
  val
1245
1281
  end
1246
1282
 
1247
1283
  ##
1248
- # Checks if the view's query is using standard sql.
1284
+ # Checks if the view's query is using standard sql. See {#view?}.
1249
1285
  #
1250
1286
  # @return [Boolean] `true` when standard sql is used, `false` otherwise.
1251
1287
  #
1252
1288
  # @!group Attributes
1253
1289
  #
1254
1290
  def query_standard_sql?
1291
+ return nil unless @gapi.view
1255
1292
  !query_legacy_sql?
1256
1293
  end
1257
1294
 
@@ -1263,18 +1300,92 @@ module Google
1263
1300
  # equivalent to providing a URI for a file containing the same code. See
1264
1301
  # [User-Defined
1265
1302
  # Functions](https://cloud.google.com/bigquery/docs/reference/standard-sql/user-defined-functions).
1303
+ # See {#view?}.
1266
1304
  #
1267
- # @return [Array<String>] An array containing Google Cloud Storage URIs
1268
- # and/or inline source code.
1305
+ # @return [Array<String>, nil] An array containing Google Cloud Storage URIs
1306
+ # and/or inline source code, or `nil` if not a logical view.
1269
1307
  #
1270
1308
  # @!group Attributes
1271
1309
  #
1272
1310
  def query_udfs
1311
+ return nil unless @gapi.view
1273
1312
  udfs_gapi = @gapi.view.user_defined_function_resources
1274
1313
  return [] if udfs_gapi.nil?
1275
1314
  Array(udfs_gapi).map { |udf| udf.inline_code || udf.resource_uri }
1276
1315
  end
1277
1316
 
1317
+ ##
1318
+ # Whether automatic refresh of the materialized view is enabled. When true,
1319
+ # the materialized view is updated when the base table is updated. The default
1320
+ # value is true. See {#materialized_view?}.
1321
+ #
1322
+ # @return [Boolean, nil] `true` when automatic refresh is enabled, `false` otherwise;
1323
+ # or `nil` if not a materialized view.
1324
+ #
1325
+ # @!group Attributes
1326
+ #
1327
+ def enable_refresh?
1328
+ return nil unless @gapi.materialized_view
1329
+ val = @gapi.materialized_view.enable_refresh
1330
+ return true if val.nil?
1331
+ val
1332
+ end
1333
+
1334
+ ##
1335
+ # Sets whether automatic refresh of the materialized view is enabled. When true,
1336
+ # the materialized view is updated when the base table is updated. See {#materialized_view?}.
1337
+ #
1338
+ # @param [Boolean] new_enable_refresh `true` when automatic refresh is enabled, `false` otherwise.
1339
+ #
1340
+ # @!group Attributes
1341
+ #
1342
+ def enable_refresh= new_enable_refresh
1343
+ @gapi.materialized_view = Google::Apis::BigqueryV2::MaterializedViewDefinition.new(
1344
+ enable_refresh: new_enable_refresh
1345
+ )
1346
+ patch_gapi! :materialized_view
1347
+ end
1348
+
1349
+ ##
1350
+ # The time when the materialized view was last modified.
1351
+ # See {#materialized_view?}.
1352
+ #
1353
+ # @return [Time, nil] The time, or `nil` if not present or not a materialized view.
1354
+ #
1355
+ # @!group Attributes
1356
+ #
1357
+ def last_refresh_time
1358
+ Convert.millis_to_time @gapi.materialized_view&.last_refresh_time
1359
+ end
1360
+
1361
+ ##
1362
+ # The maximum frequency in milliseconds at which the materialized view will be refreshed.
1363
+ # See {#materialized_view?}.
1364
+ #
1365
+ # @return [Integer, nil] The maximum frequency in milliseconds;
1366
+ # or `nil` if not a materialized view.
1367
+ #
1368
+ # @!group Attributes
1369
+ #
1370
+ def refresh_interval_ms
1371
+ @gapi.materialized_view&.refresh_interval_ms
1372
+ end
1373
+
1374
+ ##
1375
+ # Sets the maximum frequency at which the materialized view will be refreshed.
1376
+ # See {#materialized_view?}.
1377
+ #
1378
+ # @param [Integer] new_refresh_interval_ms The maximum frequency in milliseconds.
1379
+ #
1380
+ # @!group Attributes
1381
+ #
1382
+ def refresh_interval_ms= new_refresh_interval_ms
1383
+ @gapi.materialized_view = Google::Apis::BigqueryV2::MaterializedViewDefinition.new(
1384
+ refresh_interval_ms: new_refresh_interval_ms
1385
+ )
1386
+ patch_gapi! :materialized_view
1387
+ end
1388
+
1278
1389
  ##
1279
1390
  # Gets the Cloud IAM access control policy for the table. The latest policy will be read from the service. See
1280
1391
  # also {#update_policy}.
@@ -2195,6 +2306,21 @@ module Google
2195
2306
  # need to complete a load operation before the data can appear in query
2196
2307
  # results.
2197
2308
  #
2309
+ # Simple Ruby types are generally accepted per JSON rules, along with the following support for BigQuery's more
2310
+ # complex types:
2311
+ #
2312
+ # | BigQuery | Ruby | Notes |
2313
+ # |--------------|--------------------------------------|----------------------------------------------------|
2314
+ # | `NUMERIC` | `BigDecimal` | `BigDecimal` values will be rounded to scale 9. |
2315
+ # | `BIGNUMERIC` | `String` | Pass as `String` to avoid rounding to scale 9. |
2316
+ # | `DATETIME` | `DateTime` | `DATETIME` does not support time zone. |
2317
+ # | `DATE` | `Date` | |
2318
+ # | `TIMESTAMP` | `Time` | |
2319
+ # | `TIME` | `Google::Cloud::BigQuery::Time` | |
2320
+ # | `BYTES` | `File`, `IO`, `StringIO`, or similar | |
2321
+ # | `ARRAY` | `Array` | Nested arrays, `nil` values are not supported. |
2322
+ # | `STRUCT` | `Hash` | Hash keys may be strings or symbols. |
2323
+ #
2198
2324
  # Because BigQuery's streaming API is designed for high insertion rates,
2199
2325
  # modifications to the underlying table metadata are eventually
2200
2326
  # consistent when interacting with the streaming system. In most cases
@@ -2208,7 +2334,10 @@ module Google
2208
2334
  # BigQuery Troubleshooting: Metadata errors for streaming inserts
2209
2335
  #
2210
2336
  # @param [Hash, Array<Hash>] rows A hash object or array of hash objects
2211
- # containing the data. Required.
2337
+ # containing the data. Required. `BigDecimal` values will be rounded to
2338
+ # scale 9 to conform with the BigQuery `NUMERIC` data type. To avoid
2339
+ # rounding `BIGNUMERIC` type values with scale greater than 9, use `String`
2340
+ # instead of `BigDecimal`.
2212
2341
  # @param [Array<String|Symbol>, Symbol] insert_ids A unique ID for each row. BigQuery uses this property to
2213
2342
  # detect duplicate insertion requests on a best-effort basis. For more information, see [data
2214
2343
  # consistency](https://cloud.google.com/bigquery/streaming-data-into-bigquery#dataconsistency). Optional. If
@@ -2251,6 +2380,19 @@ module Google
2251
2380
  # ]
2252
2381
  # table.insert rows
2253
2382
  #
2383
+ # @example Pass `BIGNUMERIC` value as a string to avoid rounding to scale 9 in the conversion from `BigDecimal`:
2384
+ # require "google/cloud/bigquery"
2385
+ #
2386
+ # bigquery = Google::Cloud::Bigquery.new
2387
+ # dataset = bigquery.dataset "my_dataset"
2388
+ # table = dataset.table "my_table"
2389
+ #
2390
+ # row = {
2391
+ # "my_numeric" => BigDecimal("123456798.987654321"),
2392
+ # "my_bignumeric" => "123456798.98765432100001" # BigDecimal would be rounded, use String instead!
2393
+ # }
2394
+ # table.insert row
2395
+ #
2254
2396
  # @!group Data
2255
2397
  #
2256
2398
  def insert rows, insert_ids: nil, skip_invalid: nil, ignore_unknown: nil
@@ -2264,8 +2406,12 @@ module Google
2264
2406
  end
2265
2407
 
2266
2408
  ensure_service!
2267
- options = { skip_invalid: skip_invalid, ignore_unknown: ignore_unknown, insert_ids: insert_ids }
2268
- gapi = service.insert_tabledata dataset_id, table_id, rows, options
2409
+ gapi = service.insert_tabledata dataset_id,
2410
+ table_id,
2411
+ rows,
2412
+ skip_invalid: skip_invalid,
2413
+ ignore_unknown: ignore_unknown,
2414
+ insert_ids: insert_ids
2269
2415
  InsertResponse.from_gapi rows, gapi
2270
2416
  end
2271
2417
 
@@ -2564,7 +2710,7 @@ module Google
2564
2710
  return if attributes.empty?
2565
2711
  ensure_service!
2566
2712
  patch_args = Hash[attributes.map { |attr| [attr, @gapi.send(attr)] }]
2567
- patch_gapi = Google::Apis::BigqueryV2::Table.new patch_args
2713
+ patch_gapi = Google::Apis::BigqueryV2::Table.new(**patch_args)
2568
2714
  patch_gapi.etag = etag if etag
2569
2715
  @gapi = service.patch_table dataset_id, table_id, patch_gapi
2570
2716
 
@@ -2690,12 +2836,11 @@ module Google
2690
2836
 
2691
2837
  def load_local_or_uri file, updater
2692
2838
  job_gapi = updater.to_gapi
2693
- job = if local_file? file
2694
- load_local file, job_gapi
2695
- else
2696
- load_storage file, job_gapi
2697
- end
2698
- job
2839
+ if local_file? file
2840
+ load_local file, job_gapi
2841
+ else
2842
+ load_storage file, job_gapi
2843
+ end
2699
2844
  end
2700
2845
 
2701
2846
  def storage_url? files
@@ -2748,6 +2893,7 @@ module Google
2748
2893
  ##
2749
2894
  # @private Create an Updater object.
2750
2895
  def initialize gapi
2896
+ super()
2751
2897
  @updates = []
2752
2898
  @gapi = gapi
2753
2899
  @schema = nil
@@ -3115,9 +3261,18 @@ module Google
3115
3261
  end
3116
3262
 
3117
3263
  ##
3118
- # Adds a numeric number field to the schema. Numeric is a
3119
- # fixed-precision numeric type with 38 decimal digits, 9 that follow
3120
- # the decimal point.
3264
+ # Adds a numeric number field to the schema. `NUMERIC` is a decimal
3265
+ # type with fixed precision and scale. Precision is the number of
3266
+ # digits that the number contains. Scale is how many of these
3267
+ # digits appear after the decimal point. It supports:
3268
+ #
3269
+ # Precision: 38
3270
+ # Scale: 9
3271
+ # Min: -9.9999999999999999999999999999999999999E+28
3272
+ # Max: 9.9999999999999999999999999999999999999E+28
3273
+ #
3274
+ # This type can represent decimal fractions exactly, and is suitable
3275
+ # for financial calculations.
3121
3276
  #
3122
3277
  # See {Schema#numeric}
3123
3278
  #
@@ -3144,6 +3299,45 @@ module Google
3144
3299
  schema.numeric name, description: description, mode: mode
3145
3300
  end
3146
3301
 
3302
+ ##
3303
+ # Adds a bignumeric number field to the schema. `BIGNUMERIC` is a
3304
+ # decimal type with fixed precision and scale. Precision is the
3305
+ # number of digits that the number contains. Scale is how many of
3306
+ # these digits appear after the decimal point. It supports:
3307
+ #
3308
+ # Precision: 76.76 (the 77th digit is partial)
3309
+ # Scale: 38
3310
+ # Min: -5.7896044618658097711785492504343953926634992332820282019728792003956564819968E+38
3311
+ # Max: 5.7896044618658097711785492504343953926634992332820282019728792003956564819967E+38
3312
+ #
3313
+ # This type can represent decimal fractions exactly, and is suitable
3314
+ # for financial calculations.
3315
+ #
3316
+ # See {Schema#bignumeric}
3317
+ #
3318
+ # @param [String] name The field name. The name must contain only
3319
+ # letters (a-z, A-Z), numbers (0-9), or underscores (_), and must
3320
+ # start with a letter or underscore. The maximum length is 128
3321
+ # characters.
3322
+ # @param [String] description A description of the field.
3323
+ # @param [Symbol] mode The field's mode. The possible values are
3324
+ # `:nullable`, `:required`, and `:repeated`. The default value is
3325
+ # `:nullable`.
3326
+ #
3327
+ # @example
3328
+ # require "google/cloud/bigquery"
3329
+ #
3330
+ # bigquery = Google::Cloud::Bigquery.new
3331
+ # dataset = bigquery.dataset "my_dataset"
3332
+ # table = dataset.create_table "my_table" do |schema|
3333
+ # schema.bignumeric "total_cost", mode: :required
3334
+ # end
3335
+ #
3336
+ # @!group Schema
3337
+ def bignumeric name, description: nil, mode: :nullable
3338
+ schema.bignumeric name, description: description, mode: mode
3339
+ end
3340
+
3147
3341
  ##
3148
3342
  # Adds a boolean field to the schema.
3149
3343
  #