feat: Add high precision TIMESTAMP values for queries#7147
feat: Add high precision TIMESTAMP values for queries#7147danieljbruce wants to merge 8 commits intomainfrom
Conversation
precision timestamps
handwritten/bigquery/src/job.ts
Outdated
| }); | ||
| try { | ||
| /* | ||
| Without this try/catch block, calls to getRows will hang indefinitely if |
There was a problem hiding this comment.
nit: getRows = jobsQuery endpoint ?
There was a problem hiding this comment.
Yes! This has been fixed now. This was a typo.
| import {describe, it, before} from 'mocha'; | ||
| import {BigQuery} from '../src'; | ||
|
|
||
| describe('High Precision Query System Tests', () => { |
There was a problem hiding this comment.
why do we need a separated file ? The previous PR we already deviated a bit from the pattern of having system tests in the https://github.com/googleapis/nodejs-bigquery/blob/main/system-test/bigquery.ts and added https://github.com/googleapis/nodejs-bigquery/blob/main/system-test/timestamp_output_format.ts, can we bundle all timestamp related tests into the same file ?
And gonna bring this again that we don't need the amount of combinations and system tests to check if the support for picosecond resolution is working. More tests doesn't necessarily means more coverage. With this PR and the previous one we are adding 28 query executions, where previously we had a total of around 50. Not saying that the coverage was perfect before, but adding too many system/integration test for a time format change seems bit too much, I'd lean more on unit tests. System tests makes CI slower, and I'm not seeing enough justification for the amount of combination and tests being added here.
We already got bitten by too much client side validation or tests trying to assert internal details of the service in the past that can cause problems. In this case, is not a SDK code, but is test that can fail in the future if things changes in the service.
See internal b/460198628
There was a problem hiding this comment.
why do we need a separated file ?
I realize having a separate file deviates from the pattern of putting every test in system-test/bigquery.ts, but I really believe that having a separate file is a better pattern. One of the biggest drawbacks with putting every test in one file is that you lose encapsulation. For instance, the before/after hooks in the bigquery.ts test file don't have anything to do with the new tests we are adding. So if we add the new tests to this file then future maintainers have to think about how everything else in this file including the before/after hooks influence these tests and we don't want that.
we don't need the amount of combinations and system tests to check if the support for picosecond resolution is working
Ok. I needed the tests myself to understand how the client was behaving, but maybe now we can comment some of them out to improve the CI performance. I would prefer to comment the tests out rather than delete them though because the commented tests could be useful later when we want to investigate the product's behaviour. Which ones do you want to comment out?
|
|
||
| describe('High Precision Query System Tests', () => { | ||
| let bigquery: BigQuery; | ||
| const expectedTsValueMicroseconds = '2023-01-01T12:00:00.123456000Z'; |
There was a problem hiding this comment.
I think this was suppose to be Nanosecond. We missed that the previous PR
There was a problem hiding this comment.
Yes. Good catch. I changed this in both places.
| describe('High Precision Query System Tests', () => { | ||
| let bigquery: BigQuery; | ||
| const expectedTsValueMicroseconds = '2023-01-01T12:00:00.123456000Z'; | ||
| const expectedTsValueNanoseconds = '2023-01-01T12:00:00.123456789123Z'; |
There was a problem hiding this comment.
and this picosecond. Same applies to the previous https://github.com/googleapis/nodejs-bigquery/pull/1596/changes#diff-e82cb9428a68678cc305e12e59f2e21761622b9fcfcf45d4caab5e80657e2b9a test file
There was a problem hiding this comment.
Yes. Good catch. I changed this in both places.
| expectedTsValue: expectedTsValueMicroseconds, | ||
| }, | ||
| { | ||
| name: 'TOF: FLOAT64, UI64: true (error)', |
There was a problem hiding this comment.
the service side is going to reject it and is not a reasonable combination that customers would use. Not sure if we need to assert this. If the service side changes behavior (and can happen) we are gonna have a flaky test. I'd add just one error combination here.
There was a problem hiding this comment.
I commented this test out. Let me know if you want more tests commented out.
| assert.deepStrictEqual(req, expectedReq); | ||
| }); | ||
|
|
||
| it('should create a QueryRequest from a SQL string', () => { |
There was a problem hiding this comment.
we can write similar tests to this one to assert the logic for default dataFormatOptions value. The existing tests assert only not passing any format from the customer and expecting ISO8601_STRING, but we can test passing any timestampOutputFormat or useInt64Timestamp and assert that this overrides the default value. This is faster than the system test and covers the change that is to use ISO8601_STRING as the default, depending on the format option provided by the customer
There was a problem hiding this comment.
Now I understand your preference for unit tests. I'll get to this one next.
danieljbruce
left a comment
There was a problem hiding this comment.
Just need to follow up on one more PR comment.
handwritten/bigquery/src/job.ts
Outdated
| }); | ||
| try { | ||
| /* | ||
| Without this try/catch block, calls to getRows will hang indefinitely if |
There was a problem hiding this comment.
Yes! This has been fixed now. This was a typo.
| import {describe, it, before} from 'mocha'; | ||
| import {BigQuery} from '../src'; | ||
|
|
||
| describe('High Precision Query System Tests', () => { |
There was a problem hiding this comment.
why do we need a separated file ?
I realize having a separate file deviates from the pattern of putting every test in system-test/bigquery.ts, but I really believe that having a separate file is a better pattern. One of the biggest drawbacks with putting every test in one file is that you lose encapsulation. For instance, the before/after hooks in the bigquery.ts test file don't have anything to do with the new tests we are adding. So if we add the new tests to this file then future maintainers have to think about how everything else in this file including the before/after hooks influence these tests and we don't want that.
we don't need the amount of combinations and system tests to check if the support for picosecond resolution is working
Ok. I needed the tests myself to understand how the client was behaving, but maybe now we can comment some of them out to improve the CI performance. I would prefer to comment the tests out rather than delete them though because the commented tests could be useful later when we want to investigate the product's behaviour. Which ones do you want to comment out?
|
|
||
| describe('High Precision Query System Tests', () => { | ||
| let bigquery: BigQuery; | ||
| const expectedTsValueMicroseconds = '2023-01-01T12:00:00.123456000Z'; |
There was a problem hiding this comment.
Yes. Good catch. I changed this in both places.
| describe('High Precision Query System Tests', () => { | ||
| let bigquery: BigQuery; | ||
| const expectedTsValueMicroseconds = '2023-01-01T12:00:00.123456000Z'; | ||
| const expectedTsValueNanoseconds = '2023-01-01T12:00:00.123456789123Z'; |
There was a problem hiding this comment.
Yes. Good catch. I changed this in both places.
| expectedTsValue: expectedTsValueMicroseconds, | ||
| }, | ||
| { | ||
| name: 'TOF: FLOAT64, UI64: true (error)', |
There was a problem hiding this comment.
I commented this test out. Let me know if you want more tests commented out.
| assert.deepStrictEqual(req, expectedReq); | ||
| }); | ||
|
|
||
| it('should create a QueryRequest from a SQL string', () => { |
There was a problem hiding this comment.
Now I understand your preference for unit tests. I'll get to this one next.
Description
This PR makes it so that all requests to the /queries endpoint support returning high precision results for the TIMESTAMP type. This ensures that users will always get the highest precision possible for TIMESTAMP typed values requested in queries provided they request getting a higher precision timestamp by specifying a type of TIMESTAMP(12):
googleapis/nodejs-bigquery#1596 adds similar support for the /data REST endpoint which may be useful for reference. And googleapis/java-bigquery#4010 contains a similar PR to this one, but for the Bigquery Java codebase.
Impact
Allows users to opt in to fetching high precision timestamps for calls to the /queries endpoint.
Testing
System tests were added to make sure no matter what formatOptions they provide, the values sent back by the server will be delivered to the user without losing any precision when requested.
Additional Information
Notice that the PR adds timestampPrecision: 12 only when the user explicitly uses the TIMESTAMP(12) types. This is because if we automatically opt users into timestampPrecision: 12 then their code will suddenly fail for certain queries that were working before. Therefore, we are going to make timestamp precision an opt-in property.