Substring Search and Unnest String throw a NullPointerException on an empty cell
- Dominant language
- Scala
- Stars
- 314
- Forks
- 187
- Avg merge
- 1d 21h
- Merged PRs (30d)
- 214
Description
### What happened?
Substring Search and Unnest String throw a NullPointerException when the column they are configured on is empty in any row. Both read the field and call `toString` on it with no null check: `SubstringSearchOpExec.scala:33` is `tuple.getField(desc.attribute).toString`, and `UnnestStringOpExec.scala:33` does the same inside its `split` call.
An empty value is ordinary input here. A blank CSV cell arrives as null, since univocity returns null for an empty field and `AttributeTypeUtils.parseField` passes it through by design, its first line being `if (field == null) return null`.
The execution then pauses on that row, with the exception shown in the operator's console.
Expected: a row with an empty value either passes through, or is skipped, or fails with a message naming the column. A NullPointerException is not one of those.
### How to reproduce?
Upload a CSV with a blank cell:
```
id,text
1,hello world
2,
3,goodbye world
```
Build `CSV File Scan` to `Substring Search`, point Substring Search at `text` with substring `world`, and run. The execution pauses on row 2 and the operator's console shows the NullPointerException. Repeat with `Unnest String` on the same column.
### Version/Branch
1.3.0-incubating-SNAPSHOT (main)
### Relevant log output
```shell
[WARN] [WF35-SubstringSearch-c996db-main-0] [DataProcessor] [DP-thread] - Cannot invoke "Object.toString()" because the return value of "org.apache.texera.amber.core.tuple.Tuple.getField(String)" is null
org.apache.texera.amber.operator.substringSearch.SubstringSearchOpExec.findSubstring(SubstringSearchOpExec.scala:33)
org.apache.texera.amber.operator.filter.FilterOpExec.processTuple(FilterOpExec.scala:33)
org.apache.texera.amber.engine.architecture.worker.DataProcessor.processInputTuple(DataProcessor.scala:111)
org.apache.texera.amber.engine.architecture.worker.DPThread.$anonfun$runDPThreadMainLogic$2(DPThread.scala:211)
```
Contributor guide
Assessment
This issue has not been assessed yet.