Skip to content

fix: validate column before query#87

Merged
ren0503 merged 2 commits intomasterfrom
fix/ren/84-validate-column-before-query
Jan 7, 2026
Merged

fix: validate column before query#87
ren0503 merged 2 commits intomasterfrom
fix/ren/84-validate-column-before-query

Conversation

@ren0503
Copy link
Contributor

@ren0503 ren0503 commented Dec 29, 2025

No description provided.

@ren0503 ren0503 added this to the SQL ORM Release v2.4.1 milestone Dec 29, 2025
@coderabbitai
Copy link

coderabbitai bot commented Dec 29, 2025

Summary by CodeRabbit

  • Bug Fixes

    • Added runtime validation of query column names and guards to skip invalid columns, preventing malformed queries and crashes and improving reliability.
  • Tests

    • Added comprehensive tests covering many query operations with invalid and valid column names to ensure stable behavior and correct results.

✏️ Tip: You can customize this high-level summary in your review settings.

Walkthrough

Adds runtime SQL column-name validation to QueryBuilder via a new unexported helper that uses validator.IsAlphanumeric, adds early-return guards to many query-building methods to ignore invalid columns, and introduces an integration test exercising invalid and valid column usage.

Changes

Cohort / File(s) Summary
QueryBuilder validation
builder.go
Imports validator, adds unexported isValidColumn helper (calls validator.IsAlphanumeric), and adds early-return guards in many QueryBuilder methods (Equal, Not, Or, In, MoreThan, MoreThanOrEqual, LessThan, LessThanOrEqual, Like, ILike, Between, NotEqual, NotIn, IsNull) to skip building when column names are invalid.
Negative / integration tests
builder_test.go
Adds Test_IsValidColumn which migrates a test entity, seeds data, and exercises many QueryBuilder methods with various invalid column names to ensure invalid inputs are ignored and valid columns still function.

Sequence Diagram(s)

(Skipped — changes are internal validation and tests without multi-component sequential flow requiring visualization.)

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 I hop through fields of SQL and code,
I sniff each name on every road,
Only letters earn my grin,
Dashes, dots — I leave them thin.
Quiet paws, queries tidy, in.

🚥 Pre-merge checks | ✅ 1 | ❌ 2
❌ Failed checks (1 warning, 1 inconclusive)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
Description check ❓ Inconclusive No description was provided by the author, making it impossible to evaluate relevance to the changeset. Add a pull request description explaining the validation logic, why it's needed, and how it addresses the underlying issue.
✅ Passed checks (1 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main change: adding runtime validation of SQL column names before executing queries across multiple QueryBuilder methods.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings

📜 Recent review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 434f956 and 190036d.

📒 Files selected for processing (2)
  • builder.go
  • builder_test.go
🚧 Files skipped from review as they are similar to previous changes (1)
  • builder.go
🧰 Additional context used
🧬 Code graph analysis (1)
builder_test.go (4)
module.go (1)
  • Config (20-27)
repository.go (1)
  • Repository (20-22)
query_test.go (1)
  • Count (75-80)
builder.go (1)
  • QueryBuilder (23-25)
🔇 Additional comments (3)
builder_test.go (3)

175-204: LGTM! Clean test setup with good isolation.

The test setup correctly initializes the database, migrates the schema, and seeds exactly one test record. Using a separate database (test_valid_column) ensures proper test isolation.


207-236: Excellent coverage of invalid column patterns.

The array comprehensively tests SQL injection attempts, special characters, and operators that should be rejected by the isValidColumn validation. This provides strong security-focused test coverage.


392-409: LGTM! Solid positive test coverage.

These tests ensure that valid column names continue to work correctly after the validation logic is introduced. The precise assertions with require.Equal properly verify the expected behavior.

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 golangci-lint (2.5.0)

Error: can't load config: unsupported version of the configuration: "" See https://golangci-lint.run/docs/product/migration-guide for migration instructions
The command is terminated due to an error: can't load config: unsupported version of the configuration: "" See https://golangci-lint.run/docs/product/migration-guide for migration instructions


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@ren0503 ren0503 linked an issue Dec 29, 2025 that may be closed by this pull request
@codecov-commenter
Copy link

codecov-commenter commented Dec 29, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (1)
builder.go (1)

54-64: Move validation before building placeholders.

The validation check happens after building the placeholders array (lines 55-58). If the column is invalid, this work is wasted. Move the validation to the beginning of the method for consistency with other methods like Equal, Not, and Or.

The same issue exists in NotIn (lines 139-150).

🔎 Proposed fix
 func (q *QueryBuilder) In(column string, values ...interface{}) *QueryBuilder {
+	if !isValidColumn(column) {
+		return q
+	}
 	placeholders := make([]string, len(values))
 	for i := range values {
 		placeholders[i] = "?"
 	}
-	if !isValidColumn(column) {
-		return q
-	}
 	query := column + " IN (" + strings.Join(placeholders, ", ") + ")"
 	q.qb = q.qb.Where(query, values...)
 	return q
 }
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 9d7b83c and ee82d5e.

📒 Files selected for processing (1)
  • builder.go

Comment on lines +28 to +30
if !isValidColumn(column) {
return q
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Major: Silent validation failure obscures errors and could cause incorrect query results.

When validation fails, the method returns the unchanged QueryBuilder without any error, log, or indication. This means:

  • Queries silently omit the intended WHERE clause
  • Developers have no feedback that validation failed
  • Security-critical filters could be silently dropped, potentially causing data leaks

Consider one of these approaches:

  1. Return an error alongside the QueryBuilder
  2. Log a warning when validation fails
  3. Panic if invalid columns indicate a programming error

This comment applies to all 14 methods with validation guards.

Comment on lines +166 to +168
func isValidColumn(column string) bool {
return validator.IsAlphanumeric(column)
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Find the validator package and IsAlphanumeric implementation
rg -nP 'IsAlphanumeric' --type=go -B 2 -A 5

Repository: tinh-tinh/sqlorm

Length of output: 204


🏁 Script executed:

#!/bin/bash
# Check if validator is in the imports and from where
rg -nP 'package\s+validator|func\s+IsAlphanumeric' --type=go -A 5

Repository: tinh-tinh/sqlorm

Length of output: 42


🏁 Script executed:

#!/bin/bash
# Search for column usages with underscores in builder method calls
rg -nP '\.(Equal|Not|Or|In|MoreThan|LessThan|Like|ILike|Between|NotEqual|NotIn|IsNull)\s*\(\s*["\x60][a-zA-Z_][a-zA-Z0-9_]*' --type=go

Repository: tinh-tinh/sqlorm

Length of output: 744


🏁 Script executed:

#!/bin/bash
# Check the import statement for the validator package
head -20 builder.go | grep -E 'import|validator'

Repository: tinh-tinh/sqlorm

Length of output: 118


🏁 Script executed:

#!/bin/bash
# Search for any documentation, comments, or examples about column validation
rg -nP 'column|Column' --type=go builder.go -B 2 -A 2

Repository: tinh-tinh/sqlorm

Length of output: 3692


🏁 Script executed:

#!/bin/bash
# Look for the validator package files in vendor or any local definitions
find . -type f -name "validator.go" -o -name "validator" -type d

Repository: tinh-tinh/sqlorm

Length of output: 42


🌐 Web query:

github.com/tinh-tinh/tinhtinh validator IsAlphanumeric documentation

💡 Result:

Do you mean the IsAlphanumeric validator inside the TinhTinh repo (github.com/tinh-tinh/tinhtinh) or the isAlphanumeric from validator.js (npm/validator)? I can look up the specific documentation — which one should I fetch?


🏁 Script executed:

#!/bin/bash
# Check go.mod for validator package details
cat go.mod | grep -E 'tinhtinh|require'

Repository: tinh-tinh/sqlorm

Length of output: 120


🏁 Script executed:

#!/bin/bash
# Check if there's any documentation in comments about column validation
rg -nP '//.*column|/\*.*column' --type=go -i

Repository: tinh-tinh/sqlorm

Length of output: 42


🌐 Web query:

TinhTinh Go validator IsAlphanumeric dto package behavior implementation

💡 Result:

I’m not finding a clear match for “TinhTinh” + Go validator. Do you mean a specific GitHub repo or package (e.g., govalidator / go-playground/validator), or do you want how an IsAlphanumeric validator should behave/be implemented for a DTO in Go? If you point me to the repo or confirm which you mean, I’ll fetch the code and explain the behavior and implementation.


🏁 Script executed:

#!/bin/bash
# Try to find more about the validator package in go.sum
cat go.sum | grep tinhtinh

Repository: tinh-tinh/sqlorm

Length of output: 242


🌐 Web query:

site:github.com tinh-tinh/tinhtinh dto validator IsAlphanumeric

💡 Result:

I couldn't find a GitHub file matching "site:github.com tinh-tinh/tinhtinh dto validator IsAlphanumeric". The tinh-tinh organization and tinhtinh modules exist (Go packages) but no direct DTO validator/IsAlphanumeric hit under tinhtinh was returned by the search. [1][2]

If you want, I can:

  • search the tinhtinh repo tree on GitHub for "validator", "dto" or "IsAlphanumeric"; or
  • search more broadly for DTO validators (e.g., class-validator, validator.js) and examples of an "IsAlphanumeric" check.

Sources:
[1] Libraries.io entry for github.com/tinh-tinh/tinhtinh.
[2] validator.js (string validator reference).


🌐 Web query:

IsAlphanumeric validator Go implementation standard behavior

💡 Result:

Short answer: no — in the common Go validator (go-playground/validator) the plain "alphanum" / IsAlphanumeric validator is ASCII-only; there is a separate "alphanumunicode" validator that accepts Unicode letters/digits. [1][2]

Sources:

  • go-playground validator baked-in validators list showing "alphanum" and "alphanumunicode". [1]
  • go-playground/validator README (validators list / docs). [2]

Critical: IsAlphanumeric validation will reject valid SQL column names with underscores.

Standard IsAlphanumeric validators only accept [a-zA-Z0-9] and will reject snake_case column names like user_id, created_at, first_name — which are the standard SQL naming convention. This will silently fail at runtime (returns q without error), making bugs difficult to debug.

Either expand the validation to allow underscores and other valid SQL identifier characters, or document why this restrictive validation is intentional.

🤖 Prompt for AI Agents
In builder.go around lines 166 to 168, isValidColumn currently uses
validator.IsAlphanumeric which rejects common SQL identifiers containing
underscores; change the validation to allow underscores and valid identifier
forms (e.g. use a regex like ^[A-Za-z_][A-Za-z0-9_]*$ or a configurable pattern
that permits underscores and digits after the first character), and ensure
callers return an explicit error when a column name fails validation instead of
silently proceeding; update tests/docs accordingly.

@ren0503 ren0503 force-pushed the fix/ren/84-validate-column-before-query branch from ee82d5e to ed0da54 Compare January 7, 2026 13:53
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Fix all issues with AI agents
In @builder_test.go:
- Line 188: Replace the incorrect type reference sqlorm.Model with gorm.Model in
the struct definition (the line that currently reads sqlorm.Model
`gorm:"embedded"`); update the embedded field to use GORM's Model type so it
matches the earlier test usage and compiles (search for the embedded declaration
in builder_test.go and change sqlorm.Model to gorm.Model).
🧹 Nitpick comments (3)
builder_test.go (3)

197-204: Consider unconditional test data setup for reliability.

The conditional creation (if count == 0) makes the test dependent on database state. If the database isn't properly cleaned between runs, test behavior may change.

♻️ Proposed approach for deterministic test data

Consider either:

  1. Truncating the table before each test to ensure a clean state
  2. Using a unique database name per test run
  3. Explicitly creating known test data regardless of existing count

Example:

-	// Create test data
-	count, err := repo.Count(nil)
-	require.Nil(t, err)
-
-	if count == 0 {
-		_, err = repo.Create(&TestEntity{Name: "valid", Value: 1})
-		require.Nil(t, err)
-	}
+	// Ensure clean state and create test data
+	db.Exec("TRUNCATE TABLE test_entities")
+	_, err = repo.Create(&TestEntity{Name: "valid", Value: 1})
+	require.Nil(t, err)

238-390: Consider refactoring to reduce test duplication.

All 13 sub-tests follow an identical pattern with only the QueryBuilder method changing. While the current structure is readable, a table-driven approach could reduce duplication and make it easier to add new methods in the future.

♻️ Table-driven test example
testCases := []struct {
	name   string
	method func(*sqlorm.QueryBuilder, string)
}{
	{"Equal", func(qb *sqlorm.QueryBuilder, col string) { qb.Equal(col, "test") }},
	{"Not", func(qb *sqlorm.QueryBuilder, col string) { qb.Not(col, "test") }},
	{"Or", func(qb *sqlorm.QueryBuilder, col string) { qb.Or(col, "test") }},
	// ... other methods
}

for _, tc := range testCases {
	t.Run(tc.name+"_InvalidColumn", func(t *testing.T) {
		for _, invalidCol := range invalidColumns {
			docs, err := repo.FindAll(func(qb *sqlorm.QueryBuilder) {
				tc.method(qb, invalidCol)
			})
			require.Nil(t, err)
			require.Equal(t, totalCount, int64(len(docs)), "Invalid column %q should not filter results", invalidCol)
		}
	})
}

392-408: Expand valid column test coverage.

The valid column tests only cover Equal and MoreThan, while the invalid column tests cover 13 different methods. Consider adding valid column tests for the remaining methods to ensure validation doesn't break any functionality.

This ensures comprehensive validation that the column validation logic doesn't inadvertently block legitimate queries for methods like Like, Between, NotIn, etc.

📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ee82d5e and ed0da54.

📒 Files selected for processing (2)
  • builder.go
  • builder_test.go
🚧 Files skipped from review as they are similar to previous changes (1)
  • builder.go
🧰 Additional context used
🧬 Code graph analysis (1)
builder_test.go (5)
module.go (1)
  • Config (20-27)
model.go (1)
  • Model (11-16)
repository.go (1)
  • Repository (20-22)
query_test.go (1)
  • Count (75-80)
builder.go (1)
  • QueryBuilder (23-25)
🪛 GitHub Actions: Go
builder_test.go

[error] 188-188: undefined: sqlorm.Model

🔇 Additional comments (2)
builder_test.go (2)

207-236: Comprehensive invalid column list.

The test includes a thorough set of invalid column patterns covering SQL injection attempts and special characters. This provides good coverage for validation testing.


175-409: Test assumptions are correct and match the builder implementation.

Verification confirms:

  1. Invalid columns trigger early returns without errors: All query methods (Equal, Not, Or, In, MoreThan, etc.) check if !isValidColumn(column) { return q }, returning the unmodified QueryBuilder without applying filters.

  2. Queries return unfiltered results: Since no WHERE clause is added for invalid columns, all existing records are returned, matching the test expectation that len(docs) >= 1.

  3. Validation uses validator.IsAlphanumeric: The isValidColumn function at line 166-168 of builder.go correctly validates using validator.IsAlphanumeric(column), which accepts only letters and digits, rejecting all special characters tested in the invalid columns list.

The test implementation is sound and accurately reflects the production code behavior.

Comment on lines +238 to +390
// Test Equal with invalid columns
t.Run("Equal_InvalidColumn", func(t *testing.T) {
for _, invalidCol := range invalidColumns {
docs, err := repo.FindAll(func(qb *sqlorm.QueryBuilder) {
qb.Equal(invalidCol, "test")
})
require.Nil(t, err)
require.GreaterOrEqual(t, len(docs), 1, "Invalid column %q should not filter results", invalidCol)
}
})

// Test Not with invalid columns
t.Run("Not_InvalidColumn", func(t *testing.T) {
for _, invalidCol := range invalidColumns {
docs, err := repo.FindAll(func(qb *sqlorm.QueryBuilder) {
qb.Not(invalidCol, "test")
})
require.Nil(t, err)
require.GreaterOrEqual(t, len(docs), 1, "Invalid column %q should not filter results", invalidCol)
}
})

// Test Or with invalid columns
t.Run("Or_InvalidColumn", func(t *testing.T) {
for _, invalidCol := range invalidColumns {
docs, err := repo.FindAll(func(qb *sqlorm.QueryBuilder) {
qb.Or(invalidCol, "test")
})
require.Nil(t, err)
require.GreaterOrEqual(t, len(docs), 1, "Invalid column %q should not filter results", invalidCol)
}
})

// Test In with invalid columns
t.Run("In_InvalidColumn", func(t *testing.T) {
for _, invalidCol := range invalidColumns {
docs, err := repo.FindAll(func(qb *sqlorm.QueryBuilder) {
qb.In(invalidCol, "test", "test2")
})
require.Nil(t, err)
require.GreaterOrEqual(t, len(docs), 1, "Invalid column %q should not filter results", invalidCol)
}
})

// Test MoreThan with invalid columns
t.Run("MoreThan_InvalidColumn", func(t *testing.T) {
for _, invalidCol := range invalidColumns {
docs, err := repo.FindAll(func(qb *sqlorm.QueryBuilder) {
qb.MoreThan(invalidCol, 0)
})
require.Nil(t, err)
require.GreaterOrEqual(t, len(docs), 1, "Invalid column %q should not filter results", invalidCol)
}
})

// Test MoreThanOrEqual with invalid columns
t.Run("MoreThanOrEqual_InvalidColumn", func(t *testing.T) {
for _, invalidCol := range invalidColumns {
docs, err := repo.FindAll(func(qb *sqlorm.QueryBuilder) {
qb.MoreThanOrEqual(invalidCol, 0)
})
require.Nil(t, err)
require.GreaterOrEqual(t, len(docs), 1, "Invalid column %q should not filter results", invalidCol)
}
})

// Test LessThan with invalid columns
t.Run("LessThan_InvalidColumn", func(t *testing.T) {
for _, invalidCol := range invalidColumns {
docs, err := repo.FindAll(func(qb *sqlorm.QueryBuilder) {
qb.LessThan(invalidCol, 100)
})
require.Nil(t, err)
require.GreaterOrEqual(t, len(docs), 1, "Invalid column %q should not filter results", invalidCol)
}
})

// Test LessThanOrEqual with invalid columns
t.Run("LessThanOrEqual_InvalidColumn", func(t *testing.T) {
for _, invalidCol := range invalidColumns {
docs, err := repo.FindAll(func(qb *sqlorm.QueryBuilder) {
qb.LessThanOrEqual(invalidCol, 100)
})
require.Nil(t, err)
require.GreaterOrEqual(t, len(docs), 1, "Invalid column %q should not filter results", invalidCol)
}
})

// Test Like with invalid columns
t.Run("Like_InvalidColumn", func(t *testing.T) {
for _, invalidCol := range invalidColumns {
docs, err := repo.FindAll(func(qb *sqlorm.QueryBuilder) {
qb.Like(invalidCol, "%test%")
})
require.Nil(t, err)
require.GreaterOrEqual(t, len(docs), 1, "Invalid column %q should not filter results", invalidCol)
}
})

// Test ILike with invalid columns
t.Run("ILike_InvalidColumn", func(t *testing.T) {
for _, invalidCol := range invalidColumns {
docs, err := repo.FindAll(func(qb *sqlorm.QueryBuilder) {
qb.ILike(invalidCol, "%TEST%")
})
require.Nil(t, err)
require.GreaterOrEqual(t, len(docs), 1, "Invalid column %q should not filter results", invalidCol)
}
})

// Test Between with invalid columns
t.Run("Between_InvalidColumn", func(t *testing.T) {
for _, invalidCol := range invalidColumns {
docs, err := repo.FindAll(func(qb *sqlorm.QueryBuilder) {
qb.Between(invalidCol, 0, 100)
})
require.Nil(t, err)
require.GreaterOrEqual(t, len(docs), 1, "Invalid column %q should not filter results", invalidCol)
}
})

// Test NotEqual with invalid columns
t.Run("NotEqual_InvalidColumn", func(t *testing.T) {
for _, invalidCol := range invalidColumns {
docs, err := repo.FindAll(func(qb *sqlorm.QueryBuilder) {
qb.NotEqual(invalidCol, "nonexistent")
})
require.Nil(t, err)
require.GreaterOrEqual(t, len(docs), 1, "Invalid column %q should not filter results", invalidCol)
}
})

// Test NotIn with invalid columns
t.Run("NotIn_InvalidColumn", func(t *testing.T) {
for _, invalidCol := range invalidColumns {
docs, err := repo.FindAll(func(qb *sqlorm.QueryBuilder) {
qb.NotIn(invalidCol, "nonexistent1", "nonexistent2")
})
require.Nil(t, err)
require.GreaterOrEqual(t, len(docs), 1, "Invalid column %q should not filter results", invalidCol)
}
})

// Test IsNull with invalid columns
t.Run("IsNull_InvalidColumn", func(t *testing.T) {
for _, invalidCol := range invalidColumns {
docs, err := repo.FindAll(func(qb *sqlorm.QueryBuilder) {
qb.IsNull(invalidCol)
})
require.Nil(t, err)
require.GreaterOrEqual(t, len(docs), 1, "Invalid column %q should not filter results", invalidCol)
}
})
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion | 🟠 Major

Strengthen the test assertions to verify filters are ignored.

The current assertions use require.GreaterOrEqual(t, len(docs), 1, ...), which only confirms at least one result was returned. This doesn't definitively prove that the invalid column filter was ignored—it just shows some data came back.

A more robust approach would be to compare against the total count in the database, proving that no filtering occurred:

♻️ Stronger assertion approach

Before the sub-tests, capture the expected count:

+	// Get total count for validation that filters are ignored
+	totalCount, err := repo.Count(nil)
+	require.Nil(t, err)
+
 	// Test Equal with invalid columns
 	t.Run("Equal_InvalidColumn", func(t *testing.T) {
 		for _, invalidCol := range invalidColumns {
 			docs, err := repo.FindAll(func(qb *sqlorm.QueryBuilder) {
 				qb.Equal(invalidCol, "test")
 			})
 			require.Nil(t, err)
-			require.GreaterOrEqual(t, len(docs), 1, "Invalid column %q should not filter results", invalidCol)
+			require.Equal(t, totalCount, int64(len(docs)), "Invalid column %q should not filter results", invalidCol)
 		}
 	})

Apply the same pattern to all other sub-tests.

Committable suggestion skipped: line range outside the PR's diff.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In @builder_test.go:
- Line 188: Replace the incorrect embedded type sqlorm.Model with gorm.Model
where it's used (the struct embedding on the line containing `sqlorm.Model`) so
the test compiles; update the embedded tag to use `gorm.Model
\`gorm:"embedded"\`` (i.e., change the type name only) and run `go test` to
verify compilation.
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ed0da54 and 434f956.

📒 Files selected for processing (1)
  • builder_test.go
🧰 Additional context used
🧬 Code graph analysis (1)
builder_test.go (4)
module.go (1)
  • Config (20-27)
repository.go (1)
  • Repository (20-22)
query_test.go (1)
  • Count (75-80)
builder.go (1)
  • QueryBuilder (23-25)
🪛 GitHub Actions: Go
builder_test.go

[error] 188-188: Command 'go test -cover -coverprofile=coverage.txt ./...' failed with exit code 1. Error: undefined: sqlorm.Model in builder_test.go:188:10.

🔇 Additional comments (4)
builder_test.go (4)

175-185: LGTM! Clean test setup.

The test database setup follows the established pattern and properly isolates this test with a separate database name.


192-204: LGTM! Proper migration and seeding logic.

The conditional seeding ensures test data exists without creating duplicates on repeated runs.


207-236: Excellent comprehensive coverage of invalid column names.

The test cases cover SQL injection attempts, special characters, and various problematic patterns, ensuring robust validation of the column name sanitization logic.


392-408: LGTM! Important regression tests for valid columns.

These tests ensure that the new validation logic doesn't break legitimate column name usage, with strong assertions verifying exact expected behavior.

@ren0503 ren0503 force-pushed the fix/ren/84-validate-column-before-query branch from 434f956 to 190036d Compare January 7, 2026 14:00
@ren0503 ren0503 merged commit c754c01 into master Jan 7, 2026
2 checks passed
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.

Validate Column When Create Query Builder To Prevent SQL Injection

2 participants