Skip to content

Avoid NullPointerException when building SqlStatementSelect with missing clauses #310

Description

@kaklakariada

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.

Metadata

Metadata

Assignees

Labels

bugUnwanted / harmful behavior

Type

Fields

No fields configured for Bug.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions