Skip to content

Conversation

@aofei
Copy link

@aofei aofei commented Dec 9, 2025

  • Do only one thing
  • Non breaking API changes
  • Tested

What did this pull request do?

Non-pointer struct Scanner types were not receiving Scan(nil) for NULL database values due to an early return that was added to preserve nil state for embedded pointer structs. This fix distinguishes between:

  • Pointer-type fields: keep nil
  • Fields in nil embedded pointer structs: skip to preserve nil state
  • Standalone struct scanners: call Scan(nil) for proper NULL handling

User Case Description

Fixes #7234

Copilot AI review requested due to automatic review settings December 9, 2025 12:55
@propel-code-bot
Copy link
Contributor

propel-code-bot bot commented Dec 9, 2025

Handle NULL scanning for struct Scanner fields

Adjusts schema.Field.Set so standalone struct-based sql.Scanner implementations receive Scan(nil) when database values are NULL. Introduces an isNilFieldPath helper to distinguish fields nested under nil embedded pointers (which should stay untouched) from concrete struct scanner fields, and adds regression coverage using the new NullScannerModel in tests/scanner_valuer_test.go.

Key Changes

• Updated schema/field.go to call Scan(nil) on non-pointer struct scanners while preserving existing pointer-field and embedded-pointer behavior
• Added isNilFieldPath helper to detect nil intermediates in embedded field paths before invoking scanner logic
• Extended tests/scanner_valuer_test.go with NullScannerModel scanner/valuer fixtures and TestScannerHandlesNullForNonPointerField to verify empty map initialization on NULL

Affected Areas

schema.Field.Set nil-handling logic
• Scanner/valuer regression tests for NULL handling

This summary was automatically generated by @propel-code-bot

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes a bug where non-pointer struct types implementing sql.Scanner were not receiving Scan(nil) calls for NULL database values. The fix adds logic to distinguish between three cases: pointer-type fields (keep nil), fields in nil embedded pointer structs (skip to preserve nil state), and standalone non-pointer scanner fields (call Scan(nil) for proper NULL handling).

Key Changes:

  • Introduced isNilFieldPath helper function to detect fields within nil embedded pointer structs
  • Added conditional logic to call Scan(nil) for non-pointer scanner fields when receiving NULL values
  • Added comprehensive test coverage for the NULL handling scenario with a custom scanner type

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.

File Description
schema/field.go Adds isNilFieldPath helper and updates struct scanner setter to distinguish between pointer fields, embedded nil struct fields, and non-pointer scanners, ensuring Scan(nil) is called appropriately
tests/scanner_valuer_test.go Adds TestScannerHandlesNullForNonPointerField test and extraSettings/NullScannerModel types to verify non-pointer scanner fields receive Scan(nil) for NULL values

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Non-pointer struct `Scanner` types were not receiving `Scan(nil)` for
NULL database values due to an early return that was added to preserve
`nil` state for embedded pointer structs. This fix distinguishes
between:
- Pointer-type fields: keep `nil`
- Fields in `nil` embedded pointer structs: skip to preserve `nil` state
- Standalone struct scanners: call `Scan(nil)` for proper NULL handling

Fixes go-gorm#7234

Signed-off-by: Aofei Sheng <[email protected]>
@propel-code-bot propel-code-bot bot changed the title fix: call Scan(nil) for non-pointer struct scanners on NULL values Fix NULL handling for non-pointer struct sql.Scanner fields Dec 9, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Error scanning null values into models when using null.String

1 participant