Repository navigation
Fetching structs containing datetimes fails silently (#103) - #575
Closed
peco-engineer-bot[bot] wants to merge 1 commit into
Closed
peco-engineer-bot[bot] wants to merge 1 commit into
peco-engineer-bot[bot] wants to merge 1 commit into
Conversation
Signed-off-by: peco-engineer-bot[bot] <3815206+peco-engineer-bot[bot]@users.noreply.github.com>
There was a problem hiding this comment.
Verdict: 1 Nit
Looks good, no blocking issues. The fallback in quoteBareDateTimes runs only after JSON.parse has already failed, and it skips string literals and escapes. Its regex can't match plain integers, negative numbers or exponent numbers, so the only behavior change is that values which used to come back as {}/[] are now parsed. The missing warn-log when parsing falls back to the default was already there before this PR and can be done as a separate follow-up.
Other findings
- ⚪ Nit — Optional: add a unit case for a MAP keyed by TIMESTAMP/DATE (e.g.
{2021-12-21 21:33:59.339:"a"}) and a top-level array ([2021-12-21], whereprevSignificantis''). Both work under the current scanner, but neither is covered by a test.
This branch was previously deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Automated fix for #103 — Fetching structs containing datetimes fails silently.
The server writes STRUCT/MAP/ARRAY values as JSON-like strings, but it leaves nested DATE and TIMESTAMP values unquoted.
JSON.parserejects that, andconvertJSON(lib/result/utils.ts) then quietly returned{}or[]. Now, whenJSON.parsefails,convertJSONputs quotes around any bare date or timestamp outside string literals and parses again. It still returns the default value if that second parse also fails. Results: the 3 new e2e tests in tests/e2e/complex_datetime.test.ts pass against the live warehouse, I added a unit test for edge cases (date-like text inside strings, negative numbers, exponent numbers), andnpm test(1528 passing), lint, prettier and type-check all pass.Why fix this in the client
Runtime uses the legacy Hive string representation for complex values, which intentionally emits nested dates and timestamps without quotes. This format is not guaranteed to be valid JSON; the client’s JSON-only parsing assumption causes the silent data loss. Handling the existing representation in the client fixes already deployed Runtime versions without requiring a server upgrade. Changing Runtime to emit JSON would alter the established wire representation and would still leave older versions needing client handling.
Root cause & plan
Root cause:
convertJSONin lib/result/utils.ts (used byconvertThriftValuefor STRUCT/MAP/ARRAY columns in both JsonResultHandler (arrowEnabled:false) and ArrowResultConverter (useArrowNativeTypes:false, complex types serialized as strings)) callsJSON.parseon the server's Hive-style string serialization of the complex value. That serialization emits nested DATE/TIMESTAMP values unquoted (e.g.{"created_at":2021-12-21 21:33:59.339}), which is not valid JSON, soJSON.parsethrows and the catch silently returns the default ({}or[]), dropping the whole value.Files:
lib/result/utils.ts,tests/e2e/complex_datetime.test.ts,tests/unit/result/utils.test.tsPlanned coverage:
SELECT named_struct('id', 1, 'ts', TIMESTAMP'2021-12-21 21:33:59.339', 'd', DATE'2021-12-21', 's', 'x') AS st, CAST(TIMESTAMP'2021-12-21 21:33:59.339' AS STRING) AS ts_str, CAST(DATE'2021-12-21' AS STRING) AS d_str. Assert row.st deep-equals {id:1, ts: row.ts_str, d: row.d_str, s:'x'} (server's own string rendering is the authority for the datetime text). Today st is {} so it fails. (struct with nested timestamp/date, JSON (non-Arrow) path)SELECT array(TIMESTAMP'2021-12-21 21:33:59.339', TIMESTAMP'2022-01-01 00:00:00') AS arr, map('a', TIMESTAMP'2021-12-21 21:33:59.339') AS mplus CAST-to-string companions; assert arr equals the two timestamp strings and m equals {a: }. Today arr is [] and m is {}. (array and map with nested timestamps, JSON path)Test plan
tests/e2e/complex_datetime.test.ts: struct with nested timestamp/date is parsed (JSON results)— fails (red) against the original code, passes (green) after the fixtests/e2e/complex_datetime.test.ts: array and map with nested timestamps are parsed (JSON results)— fails (red) against the original code, passes (green) after the fixtests/e2e/complex_datetime.test.ts: struct with nested timestamp/date is parsed (Arrow results without native types)— fails (red) against the original code, passes (green) after the fix🤖 Generated by engineer-bot (bug-fix flow) — review before merge.
Not changed in this PR (out of scope)
These facets could not be fixed here. Reason given for each — please follow up as needed:
convertThriftValue/convertJSONhave no logger/context, so adding one would mean changing signatures at every call site (JsonResultHandler, ArrowResultConverter), which goes beyond the minimal fix.