Skip to content

Commit

Permalink
feat: auto convert numbers (#436)
Browse files Browse the repository at this point in the history
  • Loading branch information
alvarowolfx authored Apr 8, 2024
1 parent cf51780 commit f0505e7
Show file tree
Hide file tree
Showing 6 changed files with 156 additions and 11 deletions.
9 changes: 9 additions & 0 deletions protos/protos.d.ts

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

53 changes: 48 additions & 5 deletions protos/protos.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

26 changes: 25 additions & 1 deletion protos/protos.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion samples/append_rows_table_to_proto2.js
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ function main(
// Row 10
row = {
row_num: 10,
numeric_col: '123456',
numeric_col: 123456,
bignumeric_col: '99999999999999999999999999999.999999999',
};
rows.push(row);
Expand Down
17 changes: 13 additions & 4 deletions src/managedwriter/encoder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,11 +94,11 @@ export class JSONEncoder {
if (value === null) {
continue;
}
const pfield = this._type.fields[key];
if (!pfield) {
continue;
}
if (value instanceof Date) {
const pfield = this._type.fields[key];
if (!pfield) {
continue;
}
switch (pfield.type) {
case 'int32': // DATE
// The value is the number of days since the Unix epoch (1970-01-01)
Expand All @@ -114,6 +114,15 @@ export class JSONEncoder {
}
continue;
}
// NUMERIC and BIGNUMERIC integer
if (typeof value === 'number' || typeof value === 'bigint') {
switch (pfield.type) {
case 'string':
row[key] = value.toString(10);
break;
}
continue;
}
if (Array.isArray(value)) {
row[key] = value.map(v => {
if (!this.isPlainObject(v)) {
Expand Down
60 changes: 60 additions & 0 deletions system-test/managed_writer_client_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -437,6 +437,66 @@ describe('managedwriter.WriterClient', () => {
customer_updated_at: 1673236186564000,
});
});

it('should automatically convert numeric/bignumeric to expect BigQuery format', () => {
const updatedSchema = {
fields: [
...(schema.fields || []),
{
name: 'customer_points',
type: 'NUMERIC',
},
{
name: 'customer_funds',
type: 'BIGNUMERIC',
},
],
};
const storageSchema =
adapt.convertBigQuerySchemaToStorageTableSchema(updatedSchema);
const protoDescriptor: DescriptorProto =
adapt.convertStorageSchemaToProto2Descriptor(storageSchema, 'root');
const encoder = new JSONEncoder({
protoDescriptor,
});

// accept plain integers and bigint
const row1 = {
customer_name: 'Ada Lovelace',
row_num: 1,
customer_points: 1234,
customer_funds: BigInt(123456789),
};

// accept floats
const row2 = {
customer_name: 'Alan Turing',
row_num: 2,
customer_points: 1234.56,
customer_funds: '123456789.001234', // still accept in string
};

const Proto = Type.fromDescriptor(protoDescriptor);
const encoded = encoder.encodeRows([row1, row2]);

const encodedRow1 = encoded[0];
const decodedRow1 = Proto.decode(encodedRow1).toJSON();
assert.deepEqual(decodedRow1, {
customer_name: 'Ada Lovelace',
row_num: 1,
customer_points: '1234',
customer_funds: '123456789',
});

const encodedRow2 = encoded[1];
const decodedRow2 = Proto.decode(encodedRow2).toJSON();
assert.deepEqual(decodedRow2, {
customer_name: 'Alan Turing',
row_num: 2,
customer_points: '1234.56',
customer_funds: '123456789.001234',
});
});
});

describe('JSONWriter', () => {
Expand Down

0 comments on commit f0505e7

Please sign in to comment.