fix(ai): SQL base EXPLAIN-exhaustion isValid + real-bool crash - #1696
fix(ai): SQL base EXPLAIN-exhaustion isValid + real-bool crash#1696preethisighavi wants to merge 2 commits into
Conversation
Mirrors the fix already applied to the graph base (rocketride-org#1584): after every EXPLAIN attempt fails, isValid is now forced to False with the error carried, instead of silently returning the LLM's last isValid: true. isValid parsing now goes through ai.common.utils.parse_bool instead of .lower() == 'true', which crashed on a real JSON boolean. Fixes rocketride-org#1601
🤖 Internal: Discord sync markerAuto-managed by the Discord notification workflow. Stores the linked Discord message ID and forum thread ID. Do not edit or delete. |
📝 WalkthroughWalkthroughSQL validity parsing now accepts real boolean values across database execution paths. When EXPLAIN validation fails on every attempt, the final result is explicitly marked invalid and includes the validation error. Regression tests cover both behaviors. ChangesSQL validation result handling
Estimated code review effort: 3 (Moderate) | ~20 minutes Suggested reviewers: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
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 |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@packages/ai/src/ai/common/database/db_instance_base.py`:
- Around line 374-380: Update get_sql() in
packages/ai/src/ai/common/database/db_instance_base.py (lines 374-380) to
preserve and return result['error'] for invalid SQL validation results, and
update writeQuestions() to report that error instead of the rejected SQL text.
Add coverage in packages/ai/tests/ai/common/database/test_db_base.py (lines
269-272) by calling get_sql() and asserting valid is False with the exact
EXPLAIN error.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: dd56968f-2ccd-4617-9534-d1c19ef1f924
📒 Files selected for processing (2)
packages/ai/src/ai/common/database/db_instance_base.pypackages/ai/tests/ai/common/database/test_db_base.py
Addresses CodeRabbit review on PR rocketride-org#1696: after the earlier fix, _buildSQLQuery() correctly carries result['error'] on EXPLAIN exhaustion, but get_sql() discarded it in its invalid-result branch and writeQuestions() showed the rejected SQL as plain text instead. Both now surface the real EXPLAIN error, so callers can tell an EXPLAIN rejection apart from a genuinely off-topic question. Adds test_get_sql_surfaces_explain_error_not_rejected_sql.
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@packages/ai/tests/ai/common/database/test_db_base.py`:
- Around line 294-311: Add regression coverage for writeQuestions() that
configures an EXPLAIN failure and asserts the returned text/answer fields
contain the EXPLAIN error rather than the rejected SQL. Keep the existing
get_sql() test unchanged and exercise the separate fallback path in
db_instance_base.py.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: c3469ddf-bfe0-4c90-ba29-dbd633a8816e
📒 Files selected for processing (2)
packages/ai/src/ai/common/database/db_instance_base.pypackages/ai/tests/ai/common/database/test_db_base.py
| def test_get_sql_surfaces_explain_error_not_rejected_sql(): | ||
| """get_sql() must return the EXPLAIN error, not the rejected SQL as prose. | ||
|
|
||
| Before this fix, the invalid branch always returned {'answer': sql_query, | ||
| 'valid': False}, so a caller could not tell an EXPLAIN rejection (rejected | ||
| SQL text) apart from a genuinely off-topic question (LLM prose answer). | ||
| """ | ||
| fake_global = _FakeGlobal(explain_error='column "userz" does not exist') | ||
| inst = _sql_instance(fake_global) | ||
| inst._buildSQLQueryOnce = lambda question_text, *, limit, previous_sql, error: { | ||
| 'isValid': 'true', | ||
| 'query': 'SELECT * FROM userz', | ||
| } | ||
|
|
||
| result = inst.get_sql({'question': 'all users'}) | ||
|
|
||
| assert result == {'error': 'column "userz" does not exist', 'valid': False} | ||
|
|
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win
Add regression coverage for writeQuestions() error propagation.
The new test covers get_sql() only. The separate fallback changed in db_instance_base.py Lines [582-588] could regress to emitting rejected SQL while this test still passes. Add a test asserting that writeQuestions() surfaces the EXPLAIN error through its text/answer lanes.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@packages/ai/tests/ai/common/database/test_db_base.py` around lines 294 - 311,
Add regression coverage for writeQuestions() that configures an EXPLAIN failure
and asserts the returned text/answer fields contain the EXPLAIN error rather
than the rejected SQL. Keep the existing get_sql() test unchanged and exercise
the separate fallback path in db_instance_base.py.
Mirrors the fix already applied to the graph base (#1584): after every EXPLAIN attempt fails, isValid is now forced to False with the error carried, instead of silently returning the LLM's last isValid: true. isValid parsing now goes through ai.common.utils.parse_bool instead of .lower() == 'true', which crashed on a real JSON boolean.
Fixes #1601
Why this matters
Without this fix, a query the database already rejected could still get executed downstream (masked as a generic error), and any LLM response using a real JSON boolean for 'isValid' (instead of the string "true") would crash the request entirely.
Summary
isValid: true)AttributeErrorType
Bug fix
Testing
Summary by CodeRabbit
Bug Fixes
isValidfield when validating SQL, correctly handling boolean values across formats.EXPLAINvalidation exhausts all attempts, the query is now force-marked invalid and returns the final validation error message (not the rejected SQL).Tests
EXPLAIN/validation exhaustion behavior and for handling native JSON booleanisValidvalues.