Erroneously calculated UNF for column with date-time data during ingest (in some cases)
Nobody has claimed this yet.
- Dominant language
- Java
- Stars
- 1.1k
- Forks
- 564
- Avg merge
- 2d 2h
- Merged PRs (30d)
- 29
Description
Hello. I've found something which seems to be an ingest-related bug.
In the method IngestServiceBean#calculateUNF(Datafile, int, String[]) (source) when we enter the "time" branch of if, there is a variable timeFormat which is used to fill the auxilliary array of date formats (dateFormats). The problem can appear when this format contains milliseconds and time zone – in that case we have two-step parsing of current value:
try {
logger.fine("trying the \"full\" time format, with milliseconds: "+timeFormat+", "+dataVector[i]);
fullFormatParser.parse(dataVector[i]);
} catch (ParseException ex) {
// try the simplified (no time zone) format instead:
logger.fine("trying the simplified format: "+simplifiedFormat+", "+dataVector[i]);
simplifiedFormatParser.setLenient(false);
try {
simplifiedFormatParser.parse(dataVector[i]);
timeFormat = simplifiedFormat;
} catch (ParseException ex1) {
logger.warning("no parseable format found for time value "+i+" - "+dataVector[i]);
throw new IOException("no parseable format found for time value "+i+" - "+dataVector[i]);
}
}
If it happens that the first parsing fails and the second succeeds, the value of timeFormat is overwritten and all format data in auxiliary array dateFormats for the subsequent values will use that overwritten value. For example if we have vector with values of following formats { F, F, S, F, S, F, F } (where F stands for full, and S for simplified, using the terminology from the method), then the content of dateFormats will be { F, F, S, S, S, S, S }.
That erroneous format data causes parsing exceptions being thrown by UNF library. Fortunately these values are not ignored entirely, but nevertheless are not normalized, so that the final UNF is format-dependent.
The fix is very simple, but its consequences may be profound.
Also it seems that there are some places in the ingest mechanism, which can be modified to achieve significantly better performance:
- methods in UNF library are creating many copies of input vector with no apparent reason; also there is some strange usage of static variables which can possibly cause issues when two or more threads are performing UNF calculation; furthermore, some calculated intermediate values are stored in some static list, that seems to be never used for any other reason than adding these values;
TabularSubsetGeneratorusesScanner, which is rather slow;- when calculating statistics some vectors are read as
Long[]oronly to be immediately converted toFloat[]Double[]. (EDIT:Float[]case is somewhat more nuanced).
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with IngestServiceBean#calculateUNF(Datafile, int, String[]) in src/main/java/edu/harvard/iq/dataverse/ingest/IngestServiceBean.java, focusing on the time branch and mixed full or simplified formats. Reproduce the reported format sequence and inspect how dateFormats is populated and consumed by the UNF library. Done means mixed date-time values are normalized consistently without format-dependent UNF failures; treat the other performance observations as separate scope.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- java
- Domain
- backend, data, performance
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100