Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 19 additions & 5 deletions src/bigquery.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
} from '@google-cloud/common/build/src/util';
import bigquery from './types';
import {logger, setLogFunction} from './logger';
import IListParams = bigquery.jobs.IListParams;

Check warning on line 59 in src/bigquery.ts

View workflow job for this annotation

GitHub Actions / lint

'IListParams' is defined but never used

// Third-Party Re-exports
export {common};
Expand Down Expand Up @@ -376,17 +377,17 @@
private _universeDomain: string;
private _defaultJobCreationMode: JobCreationMode;

createQueryStream(options?: Query | string): ResourceStream<RowMetadata> {

Check warning on line 380 in src/bigquery.ts

View workflow job for this annotation

GitHub Actions / lint

'options' is defined but never used
// placeholder body, overwritten in constructor
return new ResourceStream<RowMetadata>({}, () => {});
}

getDatasetsStream(options?: GetDatasetsOptions): ResourceStream<Dataset> {

Check warning on line 385 in src/bigquery.ts

View workflow job for this annotation

GitHub Actions / lint

'options' is defined but never used
// placeholder body, overwritten in constructor
return new ResourceStream<Dataset>({}, () => {});
}

getJobsStream(options?: GetJobsOptions): ResourceStream<Job> {

Check warning on line 390 in src/bigquery.ts

View workflow job for this annotation

GitHub Actions / lint

'options' is defined but never used
// placeholder body, overwritten in constructor
return new ResourceStream<Job>({}, () => {});
}
Expand Down Expand Up @@ -596,7 +597,7 @@
wrapIntegers: boolean | IntegerTypeCastOptions;
selectedFields?: string[];
parseJSON?: boolean;
useInt64Timestamp?: boolean;
listParams?: bigquery.tabledata.IListParams;
},
) {
// deep copy schema fields to avoid mutation
Expand Down Expand Up @@ -1597,7 +1598,7 @@
const parameterMode = isArray(params) ? 'positional' : 'named';
const queryParameters: bigquery.IQueryParameter[] = [];
if (parameterMode === 'named') {
const namedParams = params as {[param: string]: any};

Check warning on line 1601 in src/bigquery.ts

View workflow job for this annotation

GitHub Actions / lint

Unexpected any. Specify a different type
for (const namedParameter of Object.getOwnPropertyNames(namedParams)) {
const value = namedParams[namedParameter];
let queryParameter;
Expand Down Expand Up @@ -2245,7 +2246,7 @@

options = extend({job}, queryOpts, options);
if (res && res.jobComplete) {
let rows: any = [];

Check warning on line 2249 in src/bigquery.ts

View workflow job for this annotation

GitHub Actions / lint

Unexpected any. Specify a different type
if (res.schema && res.rows) {
rows = BigQuery.mergeSchemaWithRows_(res.schema, res.rows, {
wrapIntegers: options.wrapIntegers || false,
Expand Down Expand Up @@ -2472,7 +2473,7 @@
wrapIntegers: boolean | IntegerTypeCastOptions;
selectedFields?: string[];
parseJSON?: boolean;
useInt64Timestamp?: boolean;
listParams?: bigquery.tabledata.IListParams;
},
) {
if (value === null) {
Expand Down Expand Up @@ -2540,9 +2541,21 @@
1672574400.123456
2023-01-01T12:00:00.123456789123Z
*/
const pd = new PreciseDate();
pd.setFullTime(PreciseDate.parseFull(BigInt(value) * BigInt(1000)));
value = BigQuery.timestamp(pd);
const listParams = options.listParams;
const timestampOutputFormat = listParams ? listParams['formatOptions.timestampOutputFormat'] : undefined;

Check failure on line 2545 in src/bigquery.ts

View workflow job for this annotation

GitHub Actions / lint

Replace `·?·listParams['formatOptions.timestampOutputFormat']` with `⏎········?·listParams['formatOptions.timestampOutputFormat']⏎·······`
const useInt64Timestamp = listParams ? listParams['formatOptions.useInt64Timestamp'] : undefined;

Check failure on line 2546 in src/bigquery.ts

View workflow job for this annotation

GitHub Actions / lint

Replace `·?·listParams['formatOptions.useInt64Timestamp']` with `⏎········?·listParams['formatOptions.useInt64Timestamp']⏎·······`
if (timestampOutputFormat === 'ISO8601_STRING') {
// value is ISO string, create BigQueryTimestamp wrapping the string
value = BigQuery.timestamp(value);
} else if (useInt64Timestamp === false && timestampOutputFormat !== 'INT64') {

Check failure on line 2550 in src/bigquery.ts

View workflow job for this annotation

GitHub Actions / lint

Replace `useInt64Timestamp·===·false·&&·timestampOutputFormat·!==·'INT64'` with `⏎········useInt64Timestamp·===·false·&&⏎········timestampOutputFormat·!==·'INT64'⏎······`
// value is float seconds, convert to BigQueryTimestamp
value = BigQuery.timestamp(Number(value));
} else {
// Expect int64 micros (default or explicit INT64)
const pd = new PreciseDate();
pd.setFullTime(PreciseDate.parseFull(BigInt(value) * BigInt(1000)));
value = BigQuery.timestamp(pd);
}
break;
}
case 'GEOGRAPHY': {
Expand Down Expand Up @@ -2736,6 +2749,7 @@
pd = new PreciseDate(value);
} else if (typeof value === 'string') {
if (/^\d{4}-\d{1,2}-\d{1,2}/.test(value)) {
// TODO: Replace with logic here that allows for higher precision.
pd = new PreciseDate(value);
} else {
const floatValue = Number.parseFloat(value);
Expand Down
1 change: 0 additions & 1 deletion src/job.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@
/**
* internal properties
*/
_cachedRows?: any[];

Check warning on line 58 in src/job.ts

View workflow job for this annotation

GitHub Actions / lint

Unexpected any. Specify a different type
_cachedResponse?: bigquery.IQueryResponse;
};

Expand Down Expand Up @@ -598,7 +598,6 @@
rows = BigQuery.mergeSchemaWithRows_(resp.schema, resp.rows, {
wrapIntegers,
parseJSON,
useInt64Timestamp: qs['formatOptions.useInt64Timestamp']
});
}

Expand Down
3 changes: 2 additions & 1 deletion src/table.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@
import bigquery from './types';
import {IntegerTypeCastOptions} from './bigquery';
import {RowQueue} from './rowQueue';
import IDataFormatOptions = bigquery.IDataFormatOptions;

// This is supposed to be a @google-cloud/storage `File` type. The storage npm
// module includes these types, but is current installed as a devDependency.
Expand Down Expand Up @@ -1876,10 +1877,10 @@
wrapIntegers,
selectedFields,
parseJSON,
useInt64Timestamp: qs['formatOptions.useInt64Timestamp'],
listParams: qs,
});
} catch (err) {

Check failure on line 1883 in src/table.ts

View workflow job for this annotation

GitHub Actions / lint

Delete `⏎`
callback!(err as Error | null, null, null, resp);
return;
}
Expand Down
97 changes: 72 additions & 25 deletions system-test/timestamp_output_format.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

const bigquery = new BigQuery();

describe.only('Timestamp Output Format System Tests', () => {

Check failure on line 22 in system-test/timestamp_output_format.ts

View workflow job for this annotation

GitHub Actions / lint

'describe.only' is restricted from being used
const datasetId = `timestamp_test_${randomUUID().replace(/-/g, '_')}`;
const tableId = `timestamp_table_${randomUUID().replace(/-/g, '_')}`;
const dataset = bigquery.dataset(datasetId);
Expand All @@ -37,34 +37,31 @@

after(async () => {
try {
await dataset.delete({force: true});

Check failure on line 40 in system-test/timestamp_output_format.ts

View workflow job for this annotation

GitHub Actions / lint

Delete `··`
} catch (e) {
console.error('Error deleting dataset:', e);

Check failure on line 42 in system-test/timestamp_output_format.ts

View workflow job for this annotation

GitHub Actions / lint

Delete `··`
}
});

it('should call getRows with TIMESTAMP_OUTPUT_FORMAT_UNSPECIFIED and useInt64Timestamp=true', async () => {
const [rows] = await table.getRows({
'formatOptions.timestampOutputFormat': 'TIMESTAMP_OUTPUT_FORMAT_UNSPECIFIED',

Check failure on line 48 in system-test/timestamp_output_format.ts

View workflow job for this annotation

GitHub Actions / lint

Replace `··'formatOptions.timestampOutputFormat':` with `'formatOptions.timestampOutputFormat':⏎·······`
'formatOptions.useInt64Timestamp': true

Check failure on line 49 in system-test/timestamp_output_format.ts

View workflow job for this annotation

GitHub Actions / lint

Replace `········'formatOptions.useInt64Timestamp':·true` with `······'formatOptions.useInt64Timestamp':·true,`
});
assert(rows.length > 0);
assert.strictEqual(rows[0].ts.value, expectedValue);
});

it('should call getRows with TIMESTAMP_OUTPUT_FORMAT_UNSPECIFIED and useInt64Timestamp=false', async () => {
try {
await table.getRows({
'formatOptions.timestampOutputFormat': 'TIMESTAMP_OUTPUT_FORMAT_UNSPECIFIED',
'formatOptions.useInt64Timestamp': false
});
assert.fail('The call should not have succeeded');
} catch (e) {
assert.strictEqual((e as Error).message, 'Cannot convert 1672574400.123456 to a BigInt');
}
const [rows] = await table.getRows({
'formatOptions.timestampOutputFormat': 'TIMESTAMP_OUTPUT_FORMAT_UNSPECIFIED',

Check failure on line 57 in system-test/timestamp_output_format.ts

View workflow job for this annotation

GitHub Actions / lint

Insert `⏎·······`
'formatOptions.useInt64Timestamp': false
});
assert.strictEqual(rows[0].ts.value, expectedValue);
});

it('should call getRows with FLOAT64 and useInt64Timestamp=true', async () => {
// Step through this one.
try {
const [rows] = await table.getRows({
'formatOptions.timestampOutputFormat': 'FLOAT64',
Expand All @@ -77,17 +74,12 @@
});

it('should call getRows with FLOAT64 and useInt64Timestamp=false', async () => {
try {
const [rows] = await table.getRows({
'formatOptions.timestampOutputFormat': 'FLOAT64',
'formatOptions.useInt64Timestamp': false
});
assert(rows.length > 0);
assert.strictEqual(rows[0].ts.value, expectedValue);
assert.fail('The call should not have succeeded');
} catch (e) {
assert.strictEqual((e as Error).message, 'Cannot convert 1672574400.123456 to a BigInt');
}
const [rows] = await table.getRows({
'formatOptions.timestampOutputFormat': 'FLOAT64',
'formatOptions.useInt64Timestamp': false
});
assert(rows.length > 0);
assert.strictEqual(rows[0].ts.value, expectedValue);
});

it('should call getRows with INT64 and useInt64Timestamp=true', async () => {
Expand Down Expand Up @@ -122,15 +114,70 @@
}
});

it('should call getRows with ISO8601_STRING and useInt64Timestamp=false', async () => {
it.skip('should call getRows with ISO8601_STRING and useInt64Timestamp=false', async () => {
const [rows] = await table.getRows({
'formatOptions.timestampOutputFormat': 'ISO8601_STRING',
'formatOptions.useInt64Timestamp': false
});
assert.strictEqual(rows[0].ts.value, '2023-01-01T12:00:00.123456789123');
});

it('should call getRows with timestampOutputFormat undefined and useInt64Timestamp=true', async () => {
const [rows] = await table.getRows({
'formatOptions.useInt64Timestamp': true
});
assert(rows.length > 0);
assert.strictEqual(rows[0].ts.value, expectedValue);
});

it('should call getRows with timestampOutputFormat undefined and useInt64Timestamp=false', async () => {
const [rows] = await table.getRows({
'formatOptions.useInt64Timestamp': false
});
assert.strictEqual(rows[0].ts.value, expectedValue);
});

it('should call getRows with TIMESTAMP_OUTPUT_FORMAT_UNSPECIFIED and useInt64Timestamp undefined', async () => {
const [rows] = await table.getRows({
'formatOptions.timestampOutputFormat': 'TIMESTAMP_OUTPUT_FORMAT_UNSPECIFIED'
});
assert(rows.length > 0);
assert.strictEqual(rows[0].ts.value, expectedValue);
});

it('should call getRows with FLOAT64 and useInt64Timestamp undefined', async () => {
try {
const [rows] = await table.getRows({
'formatOptions.timestampOutputFormat': 'FLOAT64'
});
assert.fail('The call should not have succeeded');
} catch (e) {
assert.strictEqual((e as Error).message, 'Cannot specify both use_int64_timestamp and timestamp_output_format.');
}
});

it('should call getRows with INT64 and useInt64Timestamp undefined', async () => {
const [rows] = await table.getRows({
'formatOptions.timestampOutputFormat': 'INT64'
});
assert(rows.length > 0);
assert.strictEqual(rows[0].ts.value, expectedValue);
});

it('should call getRows with ISO8601_STRING and useInt64Timestamp undefined', async () => {
try {
await table.getRows({
'formatOptions.timestampOutputFormat': 'ISO8601_STRING',
'formatOptions.useInt64Timestamp': false
const [rows] = await table.getRows({
'formatOptions.timestampOutputFormat': 'ISO8601_STRING'
});
assert.fail('The call should not have succeeded');
} catch (e) {
assert.strictEqual((e as Error).message, 'Cannot convert 2023-01-01T12:00:00.123456789123Z to a BigInt');
assert.strictEqual((e as Error).message, 'Cannot specify both use_int64_timestamp and timestamp_output_format.');
}
});

it('should call getRows with timestampOutputFormat undefined and useInt64Timestamp undefined', async () => {
const [rows] = await table.getRows({});
assert(rows.length > 0);
assert.strictEqual(rows[0].ts.value, expectedValue);
});
});
Loading