fix: improve CSV header validation and error messages#692
fix: improve CSV header validation and error messages#692Prathamesh9284 wants to merge 3 commits intoapache:mainfrom
Conversation
|
Thanks for your contribution! Left some comments for your PR, I prefer if we keep the accessors as-is so we don't accidentally deprecate anything people might be using. |
…d revert streamLines to its original form
...pi/wayang-api-sql/src/main/java/org/apache/wayang/api/sql/sources/fs/JavaCSVTableSource.java
Outdated
Show resolved
Hide resolved
...pi/wayang-api-sql/src/main/java/org/apache/wayang/api/sql/sources/fs/JavaCSVTableSource.java
Outdated
Show resolved
Hide resolved
|
I checked with the right file and it works. I also checked with an incorrect file which has this heading: And got this error message: "Column count mismatch in CSV file 'file:///Users/zoi/Work/WAYANG/wayang-examples/src/main/resources/input/customers.csv': expected 1 columns but found 4 (separator ';'). Line: '1;Alice Johnson;alice@example.com;USA'. Ensure the header uses 'name:type' format with commas and data rows use ';' as delimiter." The line it prints is the second line of my file, not the header line. Can we print the header line? |
|
I've updated the PR to handle this case. With the CSV file you shared using the header
It now prints the header line instead of the data line and clearly tells the user what to fix. |
| * @param path the filesystem path to the CSV file | ||
| */ | ||
| private void validateHeaderLine(final String path) { | ||
| final FileSystem fileSystem = FileSystems.getFileSystem(path).orElseThrow( |
There was a problem hiding this comment.
Would it be possible to do the check directly when we are reading the file? We are now opening the file twice which could be costly?
There was a problem hiding this comment.
@zkaoudi since streamLines() is static and is the place where file opening and iterator creation are already defined, I considered it the appropriate location to perform header validation. However, because it is static, it cannot access the instance-level separator, and we cannot modify its signature or behavior to pass the separator or expose the header.
Given these constraints, performing header validation within the same file-open operation would require changing streamLines(), which @mspruc wanted to avoid to preserve the existing definition. As a result, the file is currently opened twice.
Is there something we can do here to avoid the double file open while keeping the existing structure intact? I’d appreciate your guidance.
Summary
Closes #690
Improves CSV error handling in the SQL API filesystem source (
JavaCSVTableSource) to provide clear, actionable error messages when CSV files are malformed or misconfigured.Changes
parseLine: Shows expected vs actual column count, the separator used, the offending line, and a hint about the required Calcite header format (name:type)validateHeaderLinemethod: Validates the CSV header before data parsing begins — checks that the comma-separated column count matches the table schema and that each column follows thename:typeformatstreamLines: Throws a clear error if the CSV file has no lines at allstaticfromstreamLines: Required to access instance fields (fieldTypes,sourcePath) for header validationContext
Calcite's CSV adapter requires a typed header row (e.g.,
id:int,name:string,email:string) using commas, while data rows use Wayang's configurable separator (default;). Without a proper header, the previous error was:This gave no indication of what was actually wrong. The new errors clearly explain the issue:
CSV file '...': header has 1 comma-separated columns but table schema expects 4.CSV file '...': header column 'NAMEA' missing required type. Expected 'name:type' format.Column count mismatch in CSV file '...': expected 4 columns but found 1 (separator ';').