Skip to content

Conversation

@cmmoran
Copy link
Contributor

@cmmoran cmmoran commented Oct 18, 2025

  • Non breaking API changes
  • Tested - (yes. tested, I have not modified the gorm test cases)
  • Do only one thing

What did this pull request do?

Currently, func (schema *Schema) LookUpField(name string) *Field checks:

  • schema.FieldsByDBName
  • schema.FieldsByName

and returns nil in the event that the field is not found in either case.

This enhances the behavior slightly. The original function is intact, in addition, if a schema.Namer has been defined, schema.FieldsByDBName is checked once more with the namer-driven column name.

User Case Description

Admittedly, this is quite self-serving. I've written heavily modified so much that it may as well not be a fork a gorm-oracle plugin. One of the many idiosyncrasies of oracle is that it stores all non-quoted, non-reserved-word identifiers as UPPERCASE. This breaks from sanity, logic, good common-sense, most language conventions, and gorm's default handling. If a column: tag is set for a field, this value is used (without Namer.ColumnName transformation) exactly as-is if the NamingCaseSensitive flag is set to false. If NamingCaseSensitive is set to true, gorm will quote the exact value of the column: tag. This wouldn't be an issue if oracle treated "foo" and foo the same. But, alas, oracle does not equate "foo" and FOO. However, "FOO" and FOO are considered "same" in oracle-ese. It bears noting that my gorm-oracle plugin provides the necessary schema.Namer logic that will handle the proper quote handling of identifiers that must be quoted (reserved words, user-provided quoted identifiers, etc). But without this change, the column metadata returned by oracle (and used by gorm.Scan) will never match the column:foo unless the tag is specified column:FOO.

"Why not just use column:FOO?"

Because it's ugly. I don't want to litter my code with column:SOME_STUPID_UPPER_CASE_NAME. It's also unnecessary to require two different structures for oracle and any other db when one structure would work just fine; if gorm supported it.

As an aside, for some weird reason, gorm does not include a "default naming case" option. When NoLowerCase is set to true, the DBName becomes something useless less-than-useful: UserID field name becomes USERID in oracle with default gorm. Arguably, this can easily be solved by gorm providing a default case handler: ScreamingSnakeCase, CamelCase (or PascalCase whichever you prefer), or SnakeCase or whatever. This would allow users to avoid forcibly setting the column: tag when it otherwise would not have been necessary had gorm provided a means to convert the field name with more precision.

"Why not just omit column: altogether and live with gorm's default naming?"

No.

@propel-code-bot
Copy link
Contributor

propel-code-bot bot commented Oct 18, 2025

Introduce Namer-based fallback in Schema.LookUpField

Adds a small, non-breaking enhancement to Schema.LookUpField so that, after the regular FieldsByDBName and FieldsByName lookups fail, the function tries a third lookup using a namer-generated column name (when schema.namer is present). This supports dialects such as Oracle that automatically upper-case identifiers and rely on custom Namer logic for correct mapping.

Key Changes

• Modified schema/schema.goLookUpField now: (1) short-circuits if schema.namer is nil; (2) derives namerColumnName := schema.namer.ColumnName(schema.Table, name); (3) attempts FieldsByDBName lookup with the derived name before returning nil.
• Added inline comment // Lookup field using namer-driven ColumnName for clarity

Affected Areas

schema/schema.go – method LookUpField

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

@jinzhu
Copy link
Member

jinzhu commented Oct 26, 2025

Thank you for your PR, But I think we could simply set a default namer that uses uppercase when initializing the Oracle driver and it won't introduce any runtime performance overhead.

@cmmoran
Copy link
Contributor Author

cmmoran commented Oct 29, 2025

That would work if the caser worked better than the current one. Currently the option for that behavior exists via NoLowerCase. The problem with that is fields like CreatedAt become CREATEDAT which is unhelpful at best and dumb usually. A simple change to use a more robust caser package or enhance the current one to support snake_case BEFORE upper-casing everything would be a step in the right direction at least.

@cmmoran
Copy link
Contributor Author

cmmoran commented Oct 29, 2025

Also,

But I think we could simply set a default namer that uses uppercase...

That won't work if someone specifies

type Bar struct {
	gorm.Model
	Foo string `gorm:"column:FOO"`
}

The default namer would change that to FOO. Great.

Then when the user would attempt something like:

var bar &Bar{}
db.Model(&Bar{}).Where("foo = ?", "bar").Find(bar)

the user would be sad. Because the string foo does not match the field.Name or the field.DBName which is used in gorm.Scan() to map a column value back to a schema field.

I get the concern about performance. My suspicion is that it would have little impact because of how often field.Name and field.DBName result in a hit. Only negative cases would even have a chance to impact performance. At worst, the code still works without confusion with a marginal cost to convert the input name to the expected DBName this would be, as you say, performance impacting in tight loops which I would imagine any additional logic would impact.

Since "case insensitive" was the expectation (no quotes used even though gorm FORCES quotes whenever column:<name> is specified if the database is case-sensitive but that's another matter) the query works as expected with a minor (if any) performance hit.

Otherwise, as-is, the query will fail unexpectedly because foo does not exactly match Foo or FOO as far as the schema mapping is concerned.

Incidentally, thank you for this fantastic library. I greatly appreciate the work you have put into this. I enjoy using gorm and will use it for many years. :)

@propel-code-bot propel-code-bot bot changed the title Feature: add Namer-driven column name lookup in schema field retrieval Add Namer-based column lookup to Schema.LookUpField Oct 31, 2025
@jinzhu jinzhu merged commit a57abbe into go-gorm:master Oct 31, 2025
26 checks passed
ting-lan-wang added a commit to oracle-samples/gorm-oracle that referenced this pull request Nov 12, 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.

2 participants