fix(rql): emit groupBy columns as quoted identifiers#1691
Conversation
Replace goqu.L(fmt.Sprintf(...)) and goqu.L(col) in the groupBy helpers with goqu.C / goqu.I so column names render as quoted identifiers instead of raw SQL fragments. The existing whitelist in AddGroupInQuery continues to gate the input; the SQL builder no longer relies on it. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (2)
📝 WalkthroughSummary by CodeRabbit
WalkthroughThis PR refactors RQL query builders to use parameterized expressions instead of raw SQL string concatenation for GROUP BY and select-value clauses. ChangesRQL Query Builder SQL Safety Refactor
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Suggested reviewers
🚥 Pre-merge checks | ✅ 2✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. 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. Comment |
Coverage Report for CI Build 27195324845Coverage increased (+0.1%) to 43.371%Details
Uncovered ChangesNo uncovered changes found. Coverage RegressionsNo coverage regressions found. Coverage Stats
💛 - Coveralls |
Summary
Switch the RQL
groupBySQL helpers (pkg/utils/rql.go) to emit column names as quoted identifiers viagoqu.C/goqu.Iinstead of splicing them as raw SQL withgoqu.L(fmt.Sprintf(...))andgoqu.L(col).Changes
buildGroupByColumns:goqu.L(col)→goqu.C(col).buildSelectColumns:fmt.Sprintf("%s AS values", col)→goqu.C(col).As("values"); two-column CONCAT usesgoqu.L("CONCAT(?, ',', ?)", goqu.I(c0), goqu.I(c1)).As("values").AddGroupInQuerysignature, whitelist behavior, and return shape unchanged.pkg/utils/rql_test.gowith table-driven coverage for: whitelist accept/reject, SQL output for every production whitelist column, and helper unit tests.Technical Details
event,actor_type,resource_type,target_type,org_id,org_name,activity,status,source,verified) are all lowercase identifiers, created unquoted in the table migrations —eventand"event"resolve to the same column in Postgres, so the SQL change is behaviorally equivalent for the two RPCs that use this helper (ListAuditRecords,ListProspects).values/count; sqlx scanning via the existingdb:"values"/db:"count"struct tags is unaffected (Postgres strips identifier quotes when reporting column names).ExportAuditRecordsusesAddRQLSortInQueryonly and is not on this path.Test Plan
go test ./pkg/utils/...— all unit tests pass, including 8-case SQL-output regression for production whitelist columns.go build ./...passes.golangci-lint run ./pkg/utils/...— 0 issues.internal/store/postgres/audit_record_repository_test.go::TestList_Grouping(requires Docker — run before merging).internal/store/postgres/prospect_repository_test.gogroup-by cases (requires Docker).SQL Safety (if your PR touches
*_repository.goorgoqu.*)?placeholders,goqu.Ex{}, orgoqu.Record{}— neverfmt.Sprintfor+building a query that gets executed.ToSQL()callers capture and forward params (query, params, err := stmt.ToSQL(); db.…Context(ctx, …, query, params...)). Neverquery, _, err := ….?placeholders inside single-quoted SQL literals ingoqu.L(usemake_interval(hours => ?)-style functions instead).//nolint:forbidigoor// #nosec G20xannotation has a one-line justification on the same line that a reviewer can verify.🤖 Generated with Claude Code