Skip to content

fix(csv): use configured field separator in parallel chunk path#2601

Merged
cmgrote merged 5 commits into
mainfrom
owen/csa-484
Jul 13, 2026
Merged

fix(csv): use configured field separator in parallel chunk path#2601
cmgrote merged 5 commits into
mainfrom
owen/csa-484

Conversation

@atlan-owen

@atlan-owen atlan-owen commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

Summary

Fixes runtime handling of non-comma field separators in asset import (CSA-484, related to CSA-476 / gandalf#275). Two changes:

  1. FileBasedDelta.getAssetChecksums() hardcoded ',' when parsing both the current and previous CSV files (getHeader + reader builder). Any delta-enabled import (assets_delta_semantic=full) of a semicolon-delimited file fails with IOException: Unable to find the column 'typeName'. This commit plumbs the configured separator through DeltaProcessorFileBasedDelta. Defaults to ',', so cube-assets-builder / relational-assets-builder (whose compared files are internally generated as comma CSVs) are unchanged.
  2. CSVReader.streamRows() hardcoded ',' in the parallel chunk write/read path. Empirically this was internally consistent (chunks written and re-read with the same comma separator), so it did not crash on its own — but it silently rewrote user data through a different dialect than configured, and any future divergence between the write and read sites would corrupt parsing. Promoted fieldSeparator to private val and used it consistently.

Evidence (verified against a live tenant, fs3)

New integration test SemicolonAIMTest: imports a semicolon-delimited CSV of 102 assets (enough rows to split across multiple parallel chunk files), with descriptions containing commas and quoted semicolons, then runs a second full-delta pass (revised description + one dropped table).

create phase (chunked parallel import) delta phase (full recalculation)
main (no fix) ✅ passes Unable to find the column 'typeName' (Importer.kt:244 → FileBasedDelta)
this branch ✅ passes ✅ passes — revised description applied, dropped table archived

11/11 tests pass on this branch; unit suite 65/65 (package-toolkit/runtime).

Also includes CSVFieldSeparatorTest (unit) demonstrating the parse failure when a semicolon file is read with a comma separator.

Customer impact

Semicolon is the default CSV separator for European-locale Excel. Euronext (ZD-126118) and BBVA (ZD-125771) both hit this. Note: uploads are currently blocked upstream by the gandalf validator (CSA-476, gandalf#275) — both changes need to ship for the customer flow to work end-to-end.

🤖 Generated with Claude Code

…484)

CSVReader.streamRows() hardcoded comma in chunk write/read, crashing
on non-comma-delimited files with CsvParseException. Promote fieldSeparator
to a class field and use it at lines 190, 202, 219.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: atlan-owen <owen.price@atlan.com>
@atlan-owen atlan-owen requested a review from cmgrote as a code owner July 1, 2026 23:44
@linear

linear Bot commented Jul 1, 2026

Copy link
Copy Markdown

CSA-484

CSA-476

atlan-owen and others added 2 commits July 6, 2026 17:33
FileBasedDelta.getAssetChecksums() hardcoded ',' when parsing both the
current and previous CSV files, so any delta-enabled import of a
non-comma-delimited file failed with 'Unable to find the column
typeName'. Plumb the configured separator through DeltaProcessor into
FileBasedDelta (default ',' leaves cube/relational-assets-builder
unchanged, as their compared files are internally generated).

Adds SemicolonAIMTest: end-to-end semicolon import (multi-chunk
parallel path) plus a full-delta second run, verified against a live
tenant.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Signed-off-by: atlan-owen <owen.price@atlan.com>
The field-separator guard only checked '.length > 1', so an empty
string ('') passed validation and then blew up on the subsequent
'[0]' access with StringIndexOutOfBoundsException. Tighten the guard
to require exactly one character across all packages that accept a
configurable separator (asset-import, cube-assets-builder,
relational-assets-builder, lineage-builder, enrichment-migrator).

In relational-assets-builder the guard also ran *after* the '[0]'
extraction; moved it ahead so validation happens first.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Chris (He/Him) <cgrote@gmail.com>
@cmgrote cmgrote requested a review from bladata1990 as a code owner July 13, 2026 09:25
@cmgrote cmgrote enabled auto-merge July 13, 2026 09:32
cmgrote and others added 2 commits July 13, 2026 10:45
Add EmptyFieldSeparatorTest verifying that both an empty and a
multi-character field separator are rejected up-front with exit
code 2, before any file parsing that would otherwise throw
StringIndexOutOfBoundsException on the '[0]' access.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Chris (He/Him) <cgrote@gmail.com>
@cmgrote cmgrote merged commit c15357b into main Jul 13, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants