lib/google/cloud/bigquery/job.rb in google-cloud-bigquery-1.20.0 vs lib/google/cloud/bigquery/job.rb in google-cloud-bigquery-1.21.0
- old
+ new
@@ -196,10 +196,76 @@
def ended_at
Convert.millis_to_time @gapi.statistics.end_time
end
##
+ # The number of child jobs executed.
+ #
+ # @return [Integer] The number of child jobs executed.
+ #
+ def num_child_jobs
+ @gapi.statistics.num_child_jobs || 0
+ end
+
+ ##
+ # If this is a child job, the id of the parent.
+ #
+ # @return [String, nil] The ID of the parent job, or `nil` if not a child job.
+ #
+ def parent_job_id
+ @gapi.statistics.parent_job_id
+ end
+
+ ##
+ # The statistics including stack frames for a child job of a script.
+ #
+ # @return [Google::Cloud::Bigquery::Job::ScriptStatistics, nil] The script statistics, or `nil` if the job is
+ # not a child job.
+ #
+ # @example
+ # require "google/cloud/bigquery"
+ #
+ # bigquery = Google::Cloud::Bigquery.new
+ #
+ # multi_statement_sql = <<~SQL
+ # -- Declare a variable to hold names as an array.
+ # DECLARE top_names ARRAY<STRING>;
+ # -- Build an array of the top 100 names from the year 2017.
+ # SET top_names = (
+ # SELECT ARRAY_AGG(name ORDER BY number DESC LIMIT 100)
+ # FROM `bigquery-public-data.usa_names.usa_1910_current`
+ # WHERE year = 2017
+ # );
+ # -- Which names appear as words in Shakespeare's plays?
+ # SELECT
+ # name AS shakespeare_name
+ # FROM UNNEST(top_names) AS name
+ # WHERE name IN (
+ # SELECT word
+ # FROM `bigquery-public-data.samples.shakespeare`
+ # );
+ # SQL
+ #
+ # job = bigquery.query_job multi_statement_sql
+ #
+ # job.wait_until_done!
+ #
+ # child_jobs = bigquery.jobs parent_job: job
+ #
+ # child_jobs.each do |child_job|
+ # script_statistics = child_job.script_statistics
+ # puts script_statistics.evaluation_kind
+ # script_statistics.stack_frames.each do |stack_frame|
+ # puts stack_frame.text
+ # end
+ # end
+ #
+ def script_statistics
+ ScriptStatistics.from_gapi @gapi.statistics.script_statistics if @gapi.statistics.script_statistics
+ end
+
+ ##
# The configuration for the job. Returns a hash.
#
# @see https://cloud.google.com/bigquery/docs/reference/v2/jobs Jobs API
# reference
def configuration
@@ -418,9 +484,141 @@
LoadJob
elsif gapi.configuration.query
QueryJob
else
Job
+ end
+ end
+
+ ##
+ # Represents statistics for a child job of a script.
+ #
+ # @attr_reader [String] evaluation_kind Indicates the type of child job. Possible values include `STATEMENT` and
+ # `EXPRESSION`.
+ # @attr_reader [Array<Google::Cloud::Bigquery::Job::ScriptStackFrame>] stack_frames Stack trace where the
+ # current evaluation happened. Shows line/column/procedure name of each frame on the stack at the point where
+ # the current evaluation happened. The leaf frame is first, the primary script is last.
+ #
+ # @example
+ # require "google/cloud/bigquery"
+ #
+ # bigquery = Google::Cloud::Bigquery.new
+ #
+ # multi_statement_sql = <<~SQL
+ # -- Declare a variable to hold names as an array.
+ # DECLARE top_names ARRAY<STRING>;
+ # -- Build an array of the top 100 names from the year 2017.
+ # SET top_names = (
+ # SELECT ARRAY_AGG(name ORDER BY number DESC LIMIT 100)
+ # FROM `bigquery-public-data.usa_names.usa_1910_current`
+ # WHERE year = 2017
+ # );
+ # -- Which names appear as words in Shakespeare's plays?
+ # SELECT
+ # name AS shakespeare_name
+ # FROM UNNEST(top_names) AS name
+ # WHERE name IN (
+ # SELECT word
+ # FROM `bigquery-public-data.samples.shakespeare`
+ # );
+ # SQL
+ #
+ # job = bigquery.query_job multi_statement_sql
+ #
+ # job.wait_until_done!
+ #
+ # child_jobs = bigquery.jobs parent_job: job
+ #
+ # child_jobs.each do |child_job|
+ # script_statistics = child_job.script_statistics
+ # puts script_statistics.evaluation_kind
+ # script_statistics.stack_frames.each do |stack_frame|
+ # puts stack_frame.text
+ # end
+ # end
+ #
+ class ScriptStatistics
+ attr_reader :evaluation_kind, :stack_frames
+
+ ##
+ # @private Creates a new ScriptStatistics instance.
+ def initialize evaluation_kind, stack_frames
+ @evaluation_kind = evaluation_kind
+ @stack_frames = stack_frames
+ end
+
+ ##
+ # @private New ScriptStatistics from a statistics.script_statistics object.
+ def self.from_gapi gapi
+ frames = Array(gapi.stack_frames).map { |g| ScriptStackFrame.from_gapi g }
+ new gapi.evaluation_kind, frames
+ end
+ end
+
+ ##
+ # Represents a stack frame showing the line/column/procedure name where the current evaluation happened.
+ #
+ # @attr_reader [Integer] start_line One-based start line.
+ # @attr_reader [Integer] start_column One-based start column.
+ # @attr_reader [Integer] end_line One-based end line.
+ # @attr_reader [Integer] end_column One-based end column.
+ # @attr_reader [String] text Text of the current statement/expression.
+ #
+ # @example
+ # require "google/cloud/bigquery"
+ #
+ # bigquery = Google::Cloud::Bigquery.new
+ #
+ # multi_statement_sql = <<~SQL
+ # -- Declare a variable to hold names as an array.
+ # DECLARE top_names ARRAY<STRING>;
+ # -- Build an array of the top 100 names from the year 2017.
+ # SET top_names = (
+ # SELECT ARRAY_AGG(name ORDER BY number DESC LIMIT 100)
+ # FROM `bigquery-public-data.usa_names.usa_1910_current`
+ # WHERE year = 2017
+ # );
+ # -- Which names appear as words in Shakespeare's plays?
+ # SELECT
+ # name AS shakespeare_name
+ # FROM UNNEST(top_names) AS name
+ # WHERE name IN (
+ # SELECT word
+ # FROM `bigquery-public-data.samples.shakespeare`
+ # );
+ # SQL
+ #
+ # job = bigquery.query_job multi_statement_sql
+ #
+ # job.wait_until_done!
+ #
+ # child_jobs = bigquery.jobs parent_job: job
+ #
+ # child_jobs.each do |child_job|
+ # script_statistics = child_job.script_statistics
+ # puts script_statistics.evaluation_kind
+ # script_statistics.stack_frames.each do |stack_frame|
+ # puts stack_frame.text
+ # end
+ # end
+ #
+ class ScriptStackFrame
+ attr_reader :start_line, :start_column, :end_line, :end_column, :text
+
+ ##
+ # @private Creates a new ScriptStackFrame instance.
+ def initialize start_line, start_column, end_line, end_column, text
+ @start_line = start_line
+ @start_column = start_column
+ @end_line = end_line
+ @end_column = end_column
+ @text = text
+ end
+
+ ##
+ # @private New ScriptStackFrame from a statistics.script_statistics[].stack_frames element.
+ def self.from_gapi gapi
+ new gapi.start_line, gapi.start_column, gapi.end_line, gapi.end_column, gapi.text
end
end
protected