Skip to content

Comments

Fix sql(params_inline=True) not inlining subquery filter values#2116

Open
worksbyfriday wants to merge 1 commit intotortoise:developfrom
worksbyfriday:fix-subquery-params-inline
Open

Fix sql(params_inline=True) not inlining subquery filter values#2116
worksbyfriday wants to merge 1 commit intotortoise:developfrom
worksbyfriday:fix-subquery-params-inline

Conversation

@worksbyfriday
Copy link

Summary

Fixes #1800

Subquery.get_sql() unconditionally called get_parameterized_sql(), which creates a new Parameterizer even when the outer context expects inline values. This caused subquery filter values to be rendered as ? placeholders instead of being inlined.

The fix checks whether the SqlContext has an active parameterizer:

  • If yes (parameterized mode): use get_parameterized_sql() so values are collected into the outer query's parameterizer
  • If no (inline mode): use get_sql() so values are rendered directly

Before

query = MyModel.filter(id__in=Subquery(OtherModel.filter(field="test_value").values_list("id")))
query.sql(params_inline=True)
# SELECT ... WHERE "id" IN (SELECT "id" FROM "other_model" WHERE "field"=?)
#                                                                        ^ value missing

After

query.sql(params_inline=True)
# SELECT ... WHERE "id" IN (SELECT "id" FROM "other_model" WHERE "field"='test_value')
#                                                                        ^ value inlined

Changes

  • tortoise/expressions.py: Check ctx.parameterizer before choosing between get_sql() and get_parameterized_sql()
  • tests/test_query_api.py: Added regression test verifying subquery values are inlined

Test plan

  • New regression test passes (test_subquery_params_inline)
  • Existing subquery tests pass (test_queryset.py -k subquery)
  • Existing params_inline tests pass (test_case_when.py)
  • All query API tests pass (16 passed, 2 skipped)

When using sql(params_inline=True) on a query with Subquery filters,
the subquery's filter values were rendered as placeholders instead of
being inlined. This happened because Subquery.get_sql() unconditionally
called get_parameterized_sql(), which creates a new Parameterizer even
when the outer context expects inline values.

The fix checks whether the SqlContext has an active parameterizer:
- If yes (parameterized mode): use get_parameterized_sql() so values
  are collected into the outer query's parameterizer
- If no (inline mode): use get_sql() so values are rendered inline

Fixes tortoise#1800
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.

sql(params_inline=True) doesn't include filter values from subqueries

1 participant