Skip to content

Core: Tolerate explicit null config in LoadViewResponseParser#17250

Open
thswlsqls wants to merge 2 commits into
apache:mainfrom
thswlsqls:fix/loadviewresponse-tolerate-null-config
Open

Core: Tolerate explicit null config in LoadViewResponseParser#17250
thswlsqls wants to merge 2 commits into
apache:mainfrom
thswlsqls:fix/loadviewresponse-tolerate-null-config

Conversation

@thswlsqls

Copy link
Copy Markdown
Contributor

Closes #17249

Summary

  • LoadViewResponseParser.fromJson() guards the optional config field with json.has(CONFIG), so an explicit "config": null from a REST server reaches JsonUtil.getStringMap and throws IllegalArgumentException.
  • Switch the guard to json.hasNonNull(CONFIG), which treats a null config as absent and yields an empty config.
  • This matches the sibling LoadTableResponseParser.fromJson() (line 96), which already uses hasNonNull for the same optional config map; both parsers write config only when non-empty.
  • Backward compatible: a present config still parses.

Testing done

  • Added TestLoadViewResponseParser#nullConfig asserting "config": null parses to an empty config (red before the fix, green after).
  • ./gradlew :iceberg-core:test --tests "*TestLoadViewResponseParser*" :iceberg-core:spotlessCheck :iceberg-core:checkstyleMain :iceberg-core:checkstyleTest :iceberg-core:revapi — all passed.
  • Full :iceberg-core:check not run.

A REST server may send "config": null in a load view response. The reader
used json.has(CONFIG), so a null value fell through to getStringMap and
threw IllegalArgumentException. Use json.hasNonNull to match the sibling
LoadTableResponseParser, which already skips a null config and yields an
empty config map.

Generated-by: Claude Code
@github-actions github-actions Bot added the core label Jul 16, 2026
@nastra

nastra commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

Thanks for spotting this, but I think we have a few more places that have a similar pattern that we should fix too:

Location Field(s) Issue
CreateViewRequestParser properties has(PROPERTIES) + getStringMap — writes only when non-empty
RemoteSignRequestParser properties same pattern
RemoteSignRequestParser body, provider has() + getString — writes only when non-null
PlanTableScanRequestParser case-sensitive, use-snapshot-schema has() + getBool — has defaults when absent, but explicit null throws
PlanTableScanRequestParser filter has(FILTER) + ExpressionParser.fromJson — null throws
TableScanResponseParser delete-files, file-scan-tasks has() + JsonUtil.get (requires non-null)
RESTFileScanTaskParser delete-file-references, residual-filter has() + getIntegerList / ExpressionParser.fromJson
OAuth2Util expires_in, scope has() + getInt / getString on OAuth token responses

The same has() + non-null getter pattern that broke LoadViewResponseParser
on an explicit "config": null exists in other REST parsers. JsonUtil.getString,
getBool, getStringMap and JsonUtil.get all reject a NullNode, while has() only
checks that the key is present, so an explicit null throws instead of falling
back to the absent-field behavior.

Switch to hasNonNull() for the optional fields where treating an explicit null
as absent matches the field's documented default:

  CreateViewRequestParser  properties
  RemoteSignRequestParser  properties, body, provider
  PlanTableScanRequestParser  case-sensitive, use-snapshot-schema
  TableScanResponseParser  delete-files, file-scan-tasks
  RESTFileScanTaskParser  delete-file-references
  OAuth2Util  expires_in, scope

The filter fields (PlanTableScanRequestParser.filter and
RESTFileScanTaskParser.residual-filter) are left alone: apache#14657 added
testFilterFieldWithExplicitNullThrowsError to pin the throw when aligning the
field with the OpenAPI spec, and silently reading a null filter as "no filter"
would turn a malformed request into a full scan rather than an error.

Each parser gets a test covering the explicit-null input.

Generated-by: Claude Code
@thswlsqls

Copy link
Copy Markdown
Contributor Author

Fixed all of them except the two filter fields. JsonUtil.getString/getBool/getStringMap and JsonUtil.get all assert !pNode.isNull(), so an explicit null threw in each spot you listed — those now use hasNonNull() and each parser has a test for it.

I left PlanTableScanRequestParser.filter and RESTFileScanTaskParser.residual-filter alone: #14657 added testFilterFieldWithExplicitNullThrowsError when it aligned filter with the OpenAPI spec, so the throw looks deliberate there, and treating a null filter as "no filter" would silently turn a malformed request into a full scan instead of an error. Happy to change those too if you'd rather have them consistent with the rest.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Core: LoadViewResponseParser rejects explicit null config

2 participants