Skip to content

Conversation

@ilyafdev
Copy link

@ilyafdev ilyafdev commented Nov 24, 2025

Summary by CodeRabbit

  • New Features
    • Added support for exclusion-based filtering operations.

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

@coderabbitai
Copy link

coderabbitai bot commented Nov 24, 2025

Walkthrough

Refactors placeholder replacement logic into a new internal helper function replaceArgs and updates existing filter String methods to use it. Adds a new public filter constructor NotIn to support additional filtering operations.

Changes

Cohort / File(s) Summary
Filter refactoring and extension
pkg/repo/filters.go
Extracts placeholder replacement logic into new internal helper replaceArgs() function; updates existsFilter.String(), subqueryFilter.String(), and rawFilter.String() to use the helper; adds new public constructor NotIn(value any) Filter

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

  • Areas to review:
    • Verify that the replaceArgs() helper correctly handles all placeholder replacement scenarios for existing filters
    • Confirm that the new NotIn() constructor properly implements the Filter interface and follows the same patterns as other filter constructors
    • Check that the refactored String methods produce identical output to their previous implementations

Poem

A rabbit hops through filter rows,
With NotIn blooming where refactor goes,
Old code simplified, new logic clear,
Placeholders dance—cohesion near! 🐰✨

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 25.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title mentions using strings.Replacer for arg replacement, but the summary shows refactoring placeholder logic into a helper function and adding a NotIn filter. The title is partially related but doesn't capture the main changes.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix-filters

Tip

📝 Customizable high-level summaries are now available in beta!

You can now customize how CodeRabbit generates the high-level summary in your pull requests — including its content, structure, tone, and formatting.

  • Provide your own instructions using the high_level_summary_instructions setting.
  • Format the summary however you like (bullet lists, tables, multi-section layouts, contributor stats, etc.).
  • Use high_level_summary_in_walkthrough to move the summary from the description to the walkthrough section.

Example instruction:

"Divide the high-level summary into five sections:

  1. 📝 Description — Summarize the main change in 50–60 words, explaining what was done.
  2. 📓 References — List relevant issues, discussions, documentation, or related PRs.
  3. 📦 Dependencies & Requirements — Mention any new/updated dependencies, environment variable changes, or configuration updates.
  4. 📊 Contributor Summary — Include a Markdown table showing contributions:
    | Contributor | Lines Added | Lines Removed | Files Changed |
  5. ✔️ Additional Notes — Add any extra reviewer context.
    Keep each section concise (under 200 words) and use bullet or numbered lists for clarity."

Note: This feature is currently in beta for Pro-tier users, and pricing will be announced later.


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.

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

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2e4f197 and 1fe3966.

📒 Files selected for processing (1)
  • pkg/repo/filters.go (5 hunks)
🔇 Additional comments (1)
pkg/repo/filters.go (1)

339-345: LGTM! NotIn constructor properly mirrors In filter.

The implementation correctly validates the input and uses the existing notInFilter struct, maintaining consistency with the In filter constructor.

Comment on lines 283 to 285
func (f *existsFilter) String(column string, argIdx int) string {
// Replace placeholders in subquery with actual argument indices
subquery := f.subquery
for i := 0; i < len(f.values); i++ {
// Replace $1, $2, etc. with actual indices
placeholder := fmt.Sprintf("$%d", i+1)
actualPlaceholder := fmt.Sprintf("$%d", argIdx+i)
subquery = strings.ReplaceAll(subquery, placeholder, actualPlaceholder)
}
return subquery
return replaceArgs(f.subquery, f.values, argIdx)
}
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

Verify that the refactor preserves existing behavior.

Since the replaceArgs function has placeholder replacement limitations, verify that the original inline implementation (before this refactor) had the same constraints, or if this introduces a regression.

Also applies to: 297-300, 313-315


🏁 Script executed:

#!/bin/bash
# Verify the old implementation of placeholder replacement in these three filter types
# Check the git history to see what logic was replaced

git show HEAD~1:pkg/repo/filters.go | grep -A 10 "func (f \*existsFilter) String"
echo "---"
git show HEAD~1:pkg/repo/filters.go | grep -A 10 "func (f \*subqueryFilter) String"
echo "---"
git show HEAD~1:pkg/repo/filters.go | grep -A 10 "func (f \*rawFilter) String"

Length of output: 1208



---

🏁 Script executed:

```shell
#!/bin/bash
# Find and display the current replaceArgs function implementation
rg -n "func.*replaceArgs" --type=go -A 15 pkg/repo/filters.go

Length of output: 442


Replace replaceArgs implementation to match original behavior - critical regression.

The refactor introduces a regression. The new replaceArgs function (lines 382-394) only replaces placeholders followed by , or ), while the original inline code replaced all occurrences of bare $N placeholders:

  • Old behavior: strings.ReplaceAll replaces all $1, $2, etc. globally
  • New behavior: Only replaces $1,, $1), $2,, $2) – missing cases like WHERE id = $1 AND status = $2

Restore the original replacement logic or extend replaceArgs to handle placeholders in all contexts, not just those adjacent to punctuation.

🤖 Prompt for AI Agents
In pkg/repo/filters.go around lines 283-285, the existsFilter.String currently
calls replaceArgs which was refactored to only match placeholders followed by
',' or ')' causing a regression (it misses bare occurrences like "WHERE id = $1
AND ..."). Restore original behavior by updating replaceArgs to replace all
occurrences of the placeholder token $N globally (e.g., loop over values and
call strings.ReplaceAll for fmt.Sprintf("$%d", i) or use a regex that matches
standalone $N regardless of following punctuation), ensuring every $N in the
subquery is replaced, not just those followed by commas or parentheses.

Comment on lines +382 to +394
func replaceArgs(queryString string, values []any, argIdx int) string {
replaces := make([]string, 0, len(values)*2)
for i := range values {
replaces = append(
replaces,
fmt.Sprintf("$%d,", i+1), fmt.Sprintf("$%d,", i+argIdx),
fmt.Sprintf("$%d)", i+1), fmt.Sprintf("$%d)", i+argIdx),
)
}

replacer := strings.NewReplacer(replaces...)
return replacer.Replace(queryString)
}
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

Critical: Incomplete placeholder replacement logic.

The current implementation only replaces placeholders followed by , or ), missing many valid cases such as placeholders at the end of strings, followed by spaces, or other delimiters like ], ;, >, etc.

Example failure:

-- Input with argIdx=5
"SELECT id FROM users WHERE name = $1"
-- Expected: "SELECT id FROM users WHERE name = $5"
-- Actual: "SELECT id FROM users WHERE name = $1" (unchanged!)

This could lead to incorrect SQL generation and parameter binding errors.

Apply this diff to use a regex-based approach that handles all placeholder patterns:

+import (
+	"regexp"
+)
+
+var placeholderRegex = regexp.MustCompile(`\$(\d+)\b`)
+
 func replaceArgs(queryString string, values []any, argIdx int) string {
-	replaces := make([]string, 0, len(values)*2)
-	for i := range values {
-		replaces = append(
-			replaces,
-			fmt.Sprintf("$%d,", i+1), fmt.Sprintf("$%d,", i+argIdx),
-			fmt.Sprintf("$%d)", i+1), fmt.Sprintf("$%d)", i+argIdx),
-		)
-	}
-
-	replacer := strings.NewReplacer(replaces...)
-	return replacer.Replace(queryString)
+	return placeholderRegex.ReplaceAllStringFunc(queryString, func(match string) string {
+		var n int
+		fmt.Sscanf(match, "$%d", &n)
+		if n > 0 && n <= len(values) {
+			return fmt.Sprintf("$%d", n+argIdx-1)
+		}
+		return match
+	})
 }

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