From 757e31e10a2a60222ccc452cb2221bc474ac4e7f Mon Sep 17 00:00:00 2001 From: Rafal Hawrylak Date: Fri, 27 Mar 2026 10:31:15 +0000 Subject: [PATCH] fix(bigquery): allow timestamp format overrides in createQueryStream ## Description This PR fixes a bug in createQueryStream where formatOptions were being stripped from the query object before reaching the internal request builder. This caused the library to always use the default ISO8601_STRING format, which is rejected by some BigQuery backends. By extracting these options in queryAsStream_ and passing them through to the request builder, users can now successfully opt-out of the new default behavior when necessary. ## Impact - createQueryStream now correctly handles formatOptions.timestampOutputFormat and formatOptions.useInt64Timestamp if provided in the options object. - Bypasses 'timestamp_output_format is not supported yet' errors in restricted environments. ## Testing - Updated unit tests in test/bigquery.ts to verify the 'Gatekeeper' fix. - Added a specific test case to verify that formatOptions are correctly passed through. - Verified that all existing BigQuery tests pass. --- handwritten/bigquery/src/bigquery.ts | 14 +++++++++++++- handwritten/bigquery/test/bigquery.ts | 20 ++++++++++++++++++++ 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/handwritten/bigquery/src/bigquery.ts b/handwritten/bigquery/src/bigquery.ts index d52d07343b5..53f251c479d 100644 --- a/handwritten/bigquery/src/bigquery.ts +++ b/handwritten/bigquery/src/bigquery.ts @@ -2458,7 +2458,15 @@ export class BigQuery extends Service { return; } - const {location, maxResults, pageToken, wrapIntegers, parseJSON} = query; + const { + location, + maxResults, + pageToken, + wrapIntegers, + parseJSON, + 'formatOptions.timestampOutputFormat': timestampOutputFormat, + 'formatOptions.useInt64Timestamp': useInt64Timestamp, + } = query as any; const opts = { location, @@ -2466,6 +2474,8 @@ export class BigQuery extends Service { pageToken, wrapIntegers, parseJSON, + 'formatOptions.timestampOutputFormat': timestampOutputFormat, + 'formatOptions.useInt64Timestamp': useInt64Timestamp, autoPaginate: false, }; @@ -2474,6 +2484,8 @@ export class BigQuery extends Service { delete query.pageToken; delete query.wrapIntegers; delete query.parseJSON; + delete (query as any)['formatOptions.timestampOutputFormat']; + delete (query as any)['formatOptions.useInt64Timestamp']; this.query(query, opts, callback); } diff --git a/handwritten/bigquery/test/bigquery.ts b/handwritten/bigquery/test/bigquery.ts index 74fbbedf1c7..1224f2e722e 100644 --- a/handwritten/bigquery/test/bigquery.ts +++ b/handwritten/bigquery/test/bigquery.ts @@ -3619,6 +3619,8 @@ describe('BigQuery', () => { pageToken: undefined, wrapIntegers: undefined, parseJSON: undefined, + 'formatOptions.timestampOutputFormat': undefined, + 'formatOptions.useInt64Timestamp': undefined, autoPaginate: false, }; @@ -3692,6 +3694,24 @@ describe('BigQuery', () => { assert(queryStub.calledOnceWithExactly(query, opts, sinon.match.func)); }); + + it('should pass formatOptions if supplied', done => { + const query = { + query: 'SELECT', + 'formatOptions.timestampOutputFormat': 'INT64', + 'formatOptions.useInt64Timestamp': true, + }; + + bq.queryAsStream_(query, done); + + const opts = { + ...defaultOpts, + 'formatOptions.timestampOutputFormat': 'INT64', + 'formatOptions.useInt64Timestamp': true, + }; + + assert(queryStub.calledOnceWithExactly(query, opts, sinon.match.func)); + }); }); describe('#sanitizeEndpoint', () => {