Skip to content

impl(bigquery): generate job/request IDs and mark query RPCs idempotent - #6219

Open
alvarowolfx wants to merge 2 commits into
googleapis:mainfrom
alvarowolfx:impl-bq-query-id-gen
Open

impl(bigquery): generate job/request IDs and mark query RPCs idempotent#6219
alvarowolfx wants to merge 2 commits into
googleapis:mainfrom
alvarowolfx:impl-bq-query-id-gen

Conversation

@alvarowolfx

Copy link
Copy Markdown
Contributor

Towards #5844 #6218

@product-auto-label product-auto-label Bot added the api: bigquery Issues related to the BigQuery API. label Jul 29, 2026

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces unique ID generation for BigQuery jobs and query requests using UUIDs to enable request idempotency. It updates the execution paths to set idempotency options and adds corresponding unit tests. The review feedback suggests refactoring generate_job_reference into an associated function to avoid borrowing &self and eliminate an unnecessary clone of project_id, which also simplifies its unit test.

Comment thread src/bigquery/src/query/run_query.rs Outdated
Comment thread src/bigquery/src/query/run_query.rs
@codecov

codecov Bot commented Jul 29, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 96.02%. Comparing base (1659b43) to head (1c20bc2).
⚠️ Report is 13 commits behind head on main.

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #6219   +/-   ##
=======================================
  Coverage   96.02%   96.02%           
=======================================
  Files         269      269           
  Lines       67282    67330   +48     
=======================================
+ Hits        64606    64654   +48     
  Misses       2676     2676           

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@alvarowolfx
alvarowolfx marked this pull request as ready for review July 30, 2026 14:44
@alvarowolfx
alvarowolfx requested a review from a team as a code owner July 30, 2026 14:44
mock.expect_query().returning(move |req, _| {
let req_id = &req.query_request.as_ref().unwrap().request_id;
assert!(req_id.starts_with(QUERY_REQUEST_ID_PREFIX), "{req_id:?}");
assert!(req_id.len() <= 36, "{req_id:?}"); // bigquery limits request id to 36 characters

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would prefer this as a const, but since it is unused maybe thats fine. Maybe const _BIGQUERY_REQ_ID_LIMIT = 36 or something in the code?

Job, JobConfiguration, JobReference, JobStatus, QueryRequest, QueryResponse,
};
use google_cloud_gax::response::Response;
use uuid::Uuid;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this might be unnecessary with use super::*;

if !location.is_empty() {
job_ref = job_ref.set_location(location.to_string());
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit(style): consider removing the new line before the implicit return.

job_ref
}

fn generate_prefixed_id(prefix: &str) -> String {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since the size of the ID matters for each of the places we use this (to varying degrees), it would be nice to have a comment explaining why this is in range for both of them / maybe defining what the returned size of the id will be as a guarantee of this function.

}

fn generate_job_reference(project_id: &str, location: &str) -> JobReference {
let job_id = generate_prefixed_id(JOB_ID_PREFIX);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: could be nice to have a link to any specs for what this ID should look like.

.execute()
.await
} else {
let query_request_id = generate_prefixed_id(QUERY_REQUEST_ID_PREFIX);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: could be nice to have a link to any specs for what this ID should look like (including that 36 limit mentioned below)

supernit: for symmetry across if-else block, consider moving this initialization to let query_request = generate_query_request(...);

.insert_job()
.with_request(self.request)
// jobs.insert is idempotent because every request
// carries a generated UUID job_id.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

supernit: remove UUID (or add it above), since you also add the prefix it is not a pure UUID

mock.expect_insert_job().returning(|_, _| {
mock.expect_insert_job().returning(|req, _| {
let job_ref = req.job.as_ref().unwrap().job_reference.as_ref().unwrap();
assert!(job_ref.job_id.starts_with(JOB_ID_PREFIX), "{job_ref:?}");

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: This technically has a length limit too (but its very large). But could still be worth checking explicitly? Your call.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

api: bigquery Issues related to the BigQuery API.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants