Skip to content
This repository was archived by the owner on Feb 7, 2026. It is now read-only.

Commit 0cd4c8e

Browse files
committed
feat: support per-job reservation assignment
1 parent ee597c6 commit 0cd4c8e

File tree

3 files changed

+49
-16
lines changed

3 files changed

+49
-16
lines changed

src/bigquery.ts

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ export type JobRequest<J> = J & {
7676
jobPrefix?: string;
7777
location?: string;
7878
projectId?: string;
79+
reservation?: string;
7980
};
8081

8182
export type PagedRequest<P> = P & {
@@ -114,6 +115,7 @@ export type Query = JobRequest<bigquery.IJobConfigurationQuery> & {
114115
job?: Job;
115116
maxResults?: number;
116117
jobTimeoutMs?: number;
118+
reservation?: string;
117119
pageToken?: string;
118120
wrapIntegers?: boolean | IntegerTypeCastOptions;
119121
parseJSON?: boolean;
@@ -1731,11 +1733,16 @@ export class BigQuery extends Service {
17311733
location: this.location,
17321734
};
17331735

1734-
if (options.location) {
1735-
reqOpts.jobReference.location = options.location;
1736+
if (reqOpts.location) {
1737+
reqOpts.jobReference.location = reqOpts.location;
17361738
delete reqOpts.location;
17371739
}
17381740

1741+
if (reqOpts.configuration && reqOpts.reservation) {
1742+
reqOpts.configuration.reservation = reqOpts.reservation;
1743+
delete reqOpts.reservation;
1744+
}
1745+
17391746
const job = this.job(jobId!, {
17401747
location: reqOpts.jobReference.location,
17411748
});
@@ -2327,6 +2334,7 @@ export class BigQuery extends Service {
23272334
useLegacySql: false,
23282335
requestId: randomUUID(),
23292336
jobCreationMode: 'JOB_CREATION_OPTIONAL',
2337+
reservation: queryObj.reservation,
23302338
};
23312339
if (!this._enableQueryPreview) {
23322340
delete req.jobCreationMode;

src/model.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ import {
2626
RequestCallback,
2727
JobRequest,
2828
} from '.';
29-
import {JobMetadata} from './job';
29+
import {JobMetadata, JobOptions} from './job';
3030
import bigquery from './types';
3131

3232
// This is supposed to be a @google-cloud/storage `File` type. The storage npm
@@ -424,8 +424,7 @@ class Model extends ServiceObject {
424424
}
425425
}
426426

427-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
428-
const body: any = {
427+
const body: JobOptions = {
429428
configuration: {
430429
extract: extend(true, options, {
431430
sourceModel: {
@@ -447,6 +446,11 @@ class Model extends ServiceObject {
447446
delete options.jobId;
448447
}
449448

449+
if (body.configuration && options.reservation) {
450+
body.configuration.reservation = options.reservation;
451+
delete options.reservation;
452+
}
453+
450454
this.bigQuery.createJob(body, callback!);
451455
}
452456

src/table.ts

Lines changed: 32 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ import {
5252
} from '.';
5353
import {GoogleErrorBody} from '@google-cloud/common/build/src/util';
5454
import {Duplex, Writable} from 'stream';
55-
import {JobMetadata} from './job';
55+
import {JobMetadata, JobOptions} from './job';
5656
import bigquery from './types';
5757
import {IntegerTypeCastOptions} from './bigquery';
5858
import {RowQueue} from './rowQueue';
@@ -923,8 +923,7 @@ class Table extends ServiceObject {
923923
const callback =
924924
typeof metadataOrCallback === 'function' ? metadataOrCallback : cb;
925925

926-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
927-
const body: any = {
926+
const body: JobOptions = {
928927
configuration: {
929928
copy: extend(true, metadata, {
930929
destinationTable: {
@@ -955,6 +954,11 @@ class Table extends ServiceObject {
955954
delete metadata.jobId;
956955
}
957956

957+
if (body.configuration && metadata.reservation) {
958+
body.configuration.reservation = metadata.reservation;
959+
delete metadata.reservation;
960+
}
961+
958962
this.bigQuery.createJob(body, callback!);
959963
}
960964

@@ -1045,8 +1049,7 @@ class Table extends ServiceObject {
10451049
const callback =
10461050
typeof metadataOrCallback === 'function' ? metadataOrCallback : cb;
10471051

1048-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
1049-
const body: any = {
1052+
const body: JobOptions = {
10501053
configuration: {
10511054
copy: extend(true, metadata, {
10521055
destinationTable: {
@@ -1080,6 +1083,11 @@ class Table extends ServiceObject {
10801083
delete metadata.jobId;
10811084
}
10821085

1086+
if (body.configuration && metadata.reservation) {
1087+
body.configuration.reservation = metadata.reservation;
1088+
delete metadata.reservation;
1089+
}
1090+
10831091
this.bigQuery.createJob(body, callback!);
10841092
}
10851093

@@ -1218,8 +1226,7 @@ class Table extends ServiceObject {
12181226
delete options.gzip;
12191227
}
12201228

1221-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
1222-
const body: any = {
1229+
const body: JobOptions = {
12231230
configuration: {
12241231
extract: extend(true, options, {
12251232
sourceTable: {
@@ -1245,6 +1252,11 @@ class Table extends ServiceObject {
12451252
delete options.jobId;
12461253
}
12471254

1255+
if (body.configuration && options.reservation) {
1256+
body.configuration.reservation = options.reservation;
1257+
delete options.reservation;
1258+
}
1259+
12481260
this.bigQuery.createJob(body, callback!);
12491261
}
12501262

@@ -1399,8 +1411,7 @@ class Table extends ServiceObject {
13991411
return [jobResponse, jobResponse.metadata];
14001412
}
14011413

1402-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
1403-
const body: any = {
1414+
const body: JobOptions = {
14041415
configuration: {
14051416
load: {
14061417
destinationTable: {
@@ -1427,7 +1438,12 @@ class Table extends ServiceObject {
14271438
delete metadata.jobId;
14281439
}
14291440

1430-
extend(true, body.configuration.load, metadata, {
1441+
if (body.configuration && metadata.reservation) {
1442+
body.configuration.reservation = metadata.reservation;
1443+
delete metadata.reservation;
1444+
}
1445+
1446+
extend(true, body.configuration?.load, metadata, {
14311447
sourceUris: toArray(source).map(src => {
14321448
if (!util.isCustomType(src, 'storage/file')) {
14331449
throw new Error('Source must be a File object.');
@@ -1437,7 +1453,12 @@ class Table extends ServiceObject {
14371453
// the file's extension. If no match, don't set, and default upstream
14381454
// to CSV.
14391455
const format = FORMATS[path.extname(src.name).substr(1).toLowerCase()];
1440-
if (!metadata.sourceFormat && format) {
1456+
if (
1457+
!metadata.sourceFormat &&
1458+
format &&
1459+
body.configuration &&
1460+
body.configuration.load
1461+
) {
14411462
body.configuration.load.sourceFormat = format;
14421463
}
14431464
return 'gs://' + src.bucket.name + '/' + src.name;

0 commit comments

Comments
 (0)