Problem
SqlStatementSelect.Builder.build() can fail with a raw NullPointerException when fromClause or selectList was not set. The constructor stores nullable builder fields and then unconditionally calls setParent() on two of them:
this.fromClause = builder.fromClause;
this.selectList = builder.selectList;
...
this.fromClause.setParent(this);
this.selectList.setParent(this);
The builder does not validate required fields before constructing the object.
Evidence
src/main/java/com/exasol/adapter/sql/SqlStatementSelect.java: constructor unconditionally dereferences fromClause and selectList.
src/main/java/com/exasol/adapter/sql/SqlStatementSelect.java: Builder.build() directly returns new SqlStatementSelect(this) with no validation.
- The same constructor null-checks
whereClause, groupBy, having, orderBy, and limit before setting parents.
- Other methods already treat these fields as nullable in places:
hasProjection() checks selectList != null, and getChildren() null-checks both fromClause and selectList.
- Current
SqlStatementSelectTest only verifies that builder() returns a builder and does not cover partial or empty builds.
Impact
SqlStatementSelect.builder().build() or any partial fluent construction without both fromClause and selectList crashes in the constructor with an unhelpful NullPointerException, before callers can inspect or complete the object. This is especially brittle for tests, mocks, and partial AST-building flows.
Suggested fix
Choose one of these approaches:
- For source-compatible behavior: wrap the
fromClause.setParent(this) and selectList.setParent(this) calls in null checks, consistent with the other clauses and getChildren().
- For stricter construction: validate required builder fields in
Builder.build() and throw a meaningful exception instead of a raw NPE.
Add tests for SqlStatementSelect.builder().build() and partial builds to document the chosen behavior.
Problem
SqlStatementSelect.Builder.build()can fail with a rawNullPointerExceptionwhenfromClauseorselectListwas not set. The constructor stores nullable builder fields and then unconditionally callssetParent()on two of them:The builder does not validate required fields before constructing the object.
Evidence
src/main/java/com/exasol/adapter/sql/SqlStatementSelect.java: constructor unconditionally dereferencesfromClauseandselectList.src/main/java/com/exasol/adapter/sql/SqlStatementSelect.java:Builder.build()directly returnsnew SqlStatementSelect(this)with no validation.whereClause,groupBy,having,orderBy, andlimitbefore setting parents.hasProjection()checksselectList != null, andgetChildren()null-checks bothfromClauseandselectList.SqlStatementSelectTestonly verifies thatbuilder()returns a builder and does not cover partial or empty builds.Impact
SqlStatementSelect.builder().build()or any partial fluent construction without bothfromClauseandselectListcrashes in the constructor with an unhelpfulNullPointerException, before callers can inspect or complete the object. This is especially brittle for tests, mocks, and partial AST-building flows.Suggested fix
Choose one of these approaches:
fromClause.setParent(this)andselectList.setParent(this)calls in null checks, consistent with the other clauses andgetChildren().Builder.build()and throw a meaningful exception instead of a raw NPE.Add tests for
SqlStatementSelect.builder().build()and partial builds to document the chosen behavior.